What's new in Bodega One Code.
Every release, every fix, every improvement, documented here. We ship fast and we tell you what changed.
Release timeline
- v1.0.0-beta.35.1Improvement
Maintenance: the spurious llama.cpp model-mismatch warning that nagged on every message is gone (it compared names instead of the actual model files), the in-app What's New shows the running release's notes instead of "[Unreleased]", and the app paints faster by loading the Settings and Help panels (over 40% of the interface code) only when you open them
- Changed: The app loads noticeably faster. The Settings and Help panels - over 40% of the interface code - no longer load before first paint. They load from disk the first time you open them, which at local speed is imperceptible.
- Fixed: The "llama.cpp is serving ... but this request needs managed-..." warning no longer fires when nothing is wrong. Picking a local model stored an internal registry id that goes stale when the same file is re-registered, and the mismatch warning compared names instead of models - so it nagged on every message while the right model answered. Model identity is now resolved to the actual file on both sides before any warning, a real mismatch warns once rather than every message, and the warning names models the way the picker does instead of showing internal ids or file paths.
- Fixed: What's New shows this release's notes, not "[Unreleased]". The dialog picked the top section of the changelog whatever it was; it now finds the section for the version you are running, and a release can no longer be tagged with an uncut changelog at all.
- v1.0.0-beta.35Feature
The fix for beta.34's "lost backend connection" (its installer shipped without the backend's runtime dependencies, now caught by a start-up test of the packaged backend on every build), plus Concentrate added as a cloud gateway that reaches 172 models across 21 upstream providers on one key, a Hooks settings panel that finally shows which lifecycle hooks failed to load and why, an editor for the named permission profiles that decide what the agent may do without asking, and a dropdown to choose which llama.cpp build (CUDA 12/13, Vulkan, CPU) Bodega installs
- Concentrate is available as a cloud provider. It is a gateway: one API key reaches 172 models across 21 upstream providers, so you can try models from several vendors without opening an account with each. Add your key under Settings -> Cloud API Keys as with any other cloud provider - it is stored the same way, and Air-Gap mode blocks it the same way. The model picker lists the full catalogue grouped and ordered by upstream rather than as one flat list.
- Lifecycle hooks now have a screen. Settings has a Hooks panel where you can write your own hooks, approve or revoke the hooks a project ships in its own config, and - the part that was previously invisible - see the hooks that failed to load and why. A typo'd event name, a missing command, or a hooks: block left in the command-line-only config file used to be dropped with nothing but a line in the log; the panel now names each one. If you have ever written a hook and watched it do nothing, this is where you find out why.
- A permission-profile editor. You can create and edit the named permission profiles that decide what the agent may do without asking. Until now the profiles existed but there was no way to author them, which made the setting that selects one effectively inert.
- You can pick which llama.cpp build Bodega installs. Settings -> Models -> My Models -> llama.cpp engine now has a Build type dropdown listing the builds available for your machine (CUDA 12, CUDA 13, Vulkan, CPU, and so on), alongside the automatic pick it has always made for you. It also shows which build is actually on disk, so you can tell whether a choice has taken effect rather than assuming it. Previously the automatic pick was the only pick, and the setting that looked like it controlled this did nothing.
- The agent can string a few browser steps together in one go. Finding the right page used to cost a whole turn per action - navigate, look, click, look again - which is slow on a local model and burns through its patience before it reaches the thing you asked about. It can now send a short sequence of navigate / click / read-the-page / screenshot steps as a single request. Nothing about your approvals changes: each step still asks exactly what it would have asked on its own, at the moment it happens. Typing into a field and submitting a form are deliberately left out of these sequences - those always come to you as their own request, against the page as it stands right then. And if a step doesn't find what it was looking for, the rest is abandoned and the agent is told which step failed, rather than carrying on against a page it never actually reached.
- The agent can now read a file by line number, not just by character offset. Everything else it works with already speaks lines - search results, stack traces, type errors - so asking for "line 412" used to mean guessing which character that was. A read can now say which line to start at and how many lines to return, and the text comes back numbered like cat -n. Very long lines (a minified bundle, a one-line JSON blob) are shown cut short with a note saying so, instead of one line swallowing the whole window.
- Jupyter notebooks are refused politely instead of dumped. A .ipynb file is JSON with the code mixed into the saved output, and any plot in it is stored as an image blob. Reading one filled the conversation with data nothing could use. The agent now gets a short explanation of why it got no content.
- Qwen3.8-27B added to the model catalog. Qwen's 27B dense vision-language model: 262K native context, native tool calling, thinking on by default, and it reads images through its own projector. Needs llama.cpp build b7990 or newer, which the catalog now checks before offering the download.
- You can update the llama.cpp binary from Settings → Models → My Models → llama.cpp engine. Until now the only install path was the one-time onboarding screen, so once you were set up there was no way to move off the build you first installed - which is a problem when a newer model needs a newer build. The panel shows the build you have and the build Bodega expects, and offers an update when they differ. Updating is always something you ask for: nothing updates at launch or in the background, and if llama-server is running you're asked to stop it first - a running executable is never overwritten.
- The app now shows which build it's running. Commit, timestamp, and whether it's a dev or packaged build now appear in Settings → About and in the diagnostics bundle.
- Ask the agent about a GitHub issue or PR without leaving the conversation. It reads the title, body, state, and for a pull request the diff and review comments, as structured data rather than a scraped page. Read-only - it never comments, merges, or changes anything. Large diffs are trimmed and say so, with the total, so nothing is quietly cut short.
- Custom agents work in Chat Mode. The same agents you've built for Code Mode, selectable from the chat header, off one shared list - an agent isn't a copy per mode. Chat Mode already ran the same tools underneath, so an agent behaves the same in either place.
- The agent browser is available in Chat Mode, in a drawer you open when you want it.
- Take back a declined site. If you decline "keep the agent signed in" for a site, that choice sticks across restarts - deliberately. Settings → Safety now lists declined sites with an Ask again action, so changing your mind no longer means editing a file by hand.
- The agent browser has its own panel now, so you can watch a localhost preview and let the agent browse at the same time. Until now those shared one space: the moment the agent opened a page, your Preview panel went blank, and you had to pick one. They're separate panels now - open the Agent Browser from the activity bar or with /browser, drag it wherever you like, and your dev server keeps rendering next to it.
- Your chat now shows what it's about. Bodega already gave every conversation a name based on your first message, but it only ever appeared in the sidebar list. The name now sits at the top of the chat itself, so when you come back to a window you left open you can tell at a glance which conversation you're in. Long names are shortened with the full text on hover, and a brand-new chat shows nothing until it has something to name itself after.
- The agent can now fill in forms - search boxes, login fields, anything with a text input. Until now the agent browser could look at a page and click things, but had no way to type into it, which made basic tasks like logging in or searching structurally impossible. It now can, with several layers of protection: a password (or other credential) field is always refused outright - there's no way to approve typing into one, and the agent is told to ask you to type it yourself. Any other value is scanned for things that look like a leaked API key or token before you're ever asked to approve it. Every single type asks for your approval, showing you the exact field and value, every time - nothing is remembered from one type to the next. Clicking a form's submit button after the agent has typed into that form now goes through the same real-values approval a direct submit uses, instead of the lighter "you're clicking a button" approval.
- Persistent site logins for the agent browser - now live, if you turn them on. Settings → Safety → Keep the agent signed in is enabled again, and turning it on asks you to confirm first. It stays off until you do: if you had it on in an earlier build, it has been reset, because that earlier switch approved a feature that was never actually wired and the confirmation you'd have seen didn't say what this one says. Grant a site and it gets its own cookie jar, kept apart from every other site and from the rest of the app. Revoke one site or all of them from Settings at any time, and turning on Air-Gap mode wipes every one of them, naming the sites before it clears them. Sites you decline are remembered, and there's now an Ask again action if you change your mind. This is new, and one part of it is worth saying plainly: a late fix corrected a bug where a login didn't survive a restart and browsing away from a granted site could write cookies into that site's jar. The fix is covered by tests but hasn't been through a full manual pass yet. If a login doesn't survive a restart, or you see one site's data show up under another, that's a bug worth reporting rather than expected behaviour.
- A pending project skill now tells you it's waiting. When you open a project whose own .bodega/skills/ haven't been approved, a chip shows how many are waiting and links straight to Settings to review them. Previously the skill simply didn't load and the only trace was a line in the log. Approval is tied to the file's exact contents, so editing an approved skill asks again. Also available from the CLI as bodega skills trust and bodega skills approve - but not yet against the engine the current CLI bundles. The released CLI pins an older engine that has no skills/trust/approve route, so those two commands error until the next CLI release refreshes the engine. Approve from the app in the meantime.
- Agent browsing beyond localhost - opt-in, off by default. The agent could already drive your own dev server in the Preview tab; it can now, when you turn on browser.widened_enabled in Settings, navigate to real websites too - in an isolated, non-persistent browsing session with no shared cookies or storage with the rest of the app. Every new site needs your one-time approval. Two things always ask again separately, even on an already-approved site: submitting a form, and loading an address whose query string carries data you didn't see in the original approval - a mechanical guard against a page quietly appending your data to a link. Private/local-network addresses stay blocked no matter what. Never available under Air-Gap mode, and turning Air-Gap on mid-session immediately tears the browsing session down. This is opt-in with real residual risk - see the in-app Help page on agent tools for the honest version, not a "solved" one. Turn it on/off in Settings → Safety → Agent Web Browsing (non-localhost) - enabling asks for confirmation first, and the change takes effect on your next new chat or session, not mid-turn.
- Ask Bodega about Bodega. The agent knew almost nothing about the product it runs inside, and was told not to discuss it - so a question like "can this read PDFs?" got a shrug, or worse, a confident guess. It now ships the help documentation as searchable data and can look things up, answering about its own tools, modes and settings from what is actually documented rather than from imagination. It still will not repeat your project paths, your settings values or anything sensitive back to you.
- Approval learning: you can now accept the suggestions it makes. Approval decisions you make during agent sessions are saved locally to your database, and after you approve the same kind of moderate-risk shell command five times in Ask mode with no rejections, Bodega suggests learning it. Review and accept or dismiss suggestions in Settings → Privacy & Safety, and revoke any accepted rule at any time - revoking takes effect immediately, on the very next matching command. Accepting only changes Act mode: Ask mode always asks you first, no matter what you've accepted. Accepting a rule is app-only - a headless CLI run can never widen its own permissions.
- Bodega can read PDFs, Word, Excel and PowerPoint files. It used to decode any file you pointed it at as text - a PDF came back as a page of garbled characters, reported as a successful read, with nothing to tell the agent or you that it hadn't actually read anything. It now converts PDF, DOCX, XLSX and PPTX (plus RTF and legacy .doc/.ppt/.xls) to readable text, both when the agent opens a file itself and when you attach one to a chat message. Scanned (image-only) PDFs and encrypted files are correctly reported as unreadable rather than silently producing garbage. Other file types the agent can't decode - images, unknown binaries - are now named and sized instead of being fed through as mojibake.
- The command-line tool can now propose and apply a small memory or persona change. bodega refine "<instruction>" computes what it would change and shows you before doing anything; add --apply to actually write it, and the change can be undone with bodega harness revert. This had been built and tested in the command-line tool for a while with nothing on the other end to answer it. The app half is now here - but the released CLI still bundles an older engine that lacks the harness/refine route, so bodega refine errors until the next CLI release refreshes that pin. It works end to end against this app build; it does not work end to end from the shipped CLI yet.
- You can now install plugins from inside the app. A plugin bundles a set of skills and MCP servers into one folder or .zip (the same open format other AI tools use, so plugins built for elsewhere generally work here too). Settings → Integrations → Plugins lets you pick a folder or zip, shows exactly what it contains - every skill, every MCP server, any elevated permissions it's asking for - before anything is written, and nothing is approved automatically: you tick the specific permissions you want to grant, skill by skill. An MCP server that needs network access while air-gap mode is on is flagged right in the preview instead of failing silently. Installed plugins are listed with what they added, and can be removed - removal only touches what that plugin itself installed, never something you separately created under the same name. This was previously CLI-only.
- "Manage allowed sites" in the agent browser's overflow menu, in both Code Mode and Chat Mode. It opens Settings → Safety directly, so changing which sites the agent may stay signed in to no longer means hunting through settings from a different panel. It reads and writes the same grant list the consent card does - there is no second place where permissions live.
- Settings now say which mode they apply to. Every settings section is labeled Code Mode, Chat Mode, or both, and a new help page spells out what each one actually affects in each mode. Nothing moved and nothing changed behaviour - this is labeling, because "does this apply to my chat?" was not answerable from the UI before.
- Changed: The "Coming soon" strip is gone from Models -> Discover. Every model listed there is now one you can actually download. The two small draft models that were sitting behind that label - Qwen 3 1.7B and Llama 3.2 1B, used to speed up a larger model - are downloadable, because the feature they were waiting on has shipped. The one entry that had no downloadable version at all was removed.
- Changed: The beta period no longer expires. Builds carried a hard cutoff of 2026-11-01, after which activation returned an error and the app showed a terminal lock screen. That's gone - not pushed further out, removed. If you activated under any earlier cutoff, you come back active on your next launch; nothing to re-do.
- Changed: Malformed tool calls are now counted. When a model produces a tool call Bodega cannot parse, the recovery costs a full step of the task. That has always been true and never been measured. It is now recorded per model tier, so the decision about whether to enforce stricter output formats can be made from data instead of a hunch.
- Security: What you approve is now what runs. When the agent asked permission for a tool call, a later step could still adjust that call's arguments after you had already said yes - so an approval prompt showing one value could be followed by a slightly different value actually executing. Three such adjustments (a near-miss operation name being corrected, a file-tool alias being normalised, and a missing argument being filled in) now all run *before* the prompt is built, on both approval paths, so the prompt shows the final call. Nothing here needed re-approving, because there is no longer a difference to re-approve.
- Security: "Strict" command sandbox is now actually stricter than "Moderate". The two settings ran the same check, so choosing Strict changed nothing you could observe while Settings and the docs described it as tighter. Strict now means no shell command auto-approves - every one waits for you, read-only included. The Settings text and the docs also said the sandbox applies in Ask mode; it is the opposite. Shell commands never auto-approve in Ask or Plan mode, and the sandbox level governs Act mode only. Both now say so.
- Security: Closed a gap in where a saved cloud API key may be sent. The check that stops a stored key from being sent to an internal address was missing carrier NAT (100.64.x), the 0.x range, the broadcast address, and integer-form IPs - ranges the app's other network guards already blocked. web_fetch likewise refused the broadcast address only after a DNS lookup, which it skips for a literal IP. All the private-range guards are now held to one shared list of adversarial addresses by a test, so a range added to one and forgotten in another fails loudly instead of silently.
- Security: A project Air-Gap Vault now blocks choosing a cloud provider, not just using one. The check that refuses to select a cloud model while air-gap is on was written to consider the project's vault, but every caller in the shipped app left that argument empty, so it only ever read the global switch. A project with its own Air-Gap Vault on, while the global toggle was off, could still set a cloud provider as its primary - the largest outbound path in the product. All six call sites now resolve the active project's vault. Nothing here says anyone's data was taken; it says the vault was narrower than the setting implied on this path, and now matches it.
- Security: A project Air-Gap Vault now also holds outside the tool layer. Turning on the vault for a project always stopped that project's tools from reaching the network, but several things that are not tools were still checking only the global air-gap switch: the verification and review layer (which embeds file contents and diffs in what it sends), the mixture fan-out, HTTP hooks, wiki and repo-map generation, and skill learning. With the global switch off and a project vaulted, those could still call out. They now read the project's vault. Nothing here says anyone's data was taken - it says the guarantee was narrower than the setting implied, and now matches it. A source-level check was added first so the full list was enumerated rather than guessed at, and it fails the build if a new one appears.
- Security: Embeddings and inline code completion now honour the vault too. An earlier draft of this entry said they didn't - that was wrong, and the fix shipped in this same release. Inline completion (fill-in-the-middle) reads the project's vault before it will call out, and the embedding service applies the vault both to cloud embedding backends and to any non-local embedding address. If you rely on a project vault rather than the global switch, these two are covered.
- Security: One embedding path is still global-only, named so you know the edge. A single lower-level embedding call site checks the global air-gap switch rather than the project's vault. In practice it sits behind the service-level gates above, but if you want a hard guarantee for that path today, use the global switch rather than a per-project vault. This is the one remaining gap and it is on the list to close.
- Security: The memory embedding write and a memory-row uniqueness check are now scoped per user, closing two places that assumed a single account rather than checking whose data they were touching. Bodega is a single-user product today, so this is hardening ahead of the case where it isn't - not a fix for a leak anyone hit.
- Security: A project with air-gap on could still reach the network through two tools. github_context (which carries your GitHub token) and consult_mixture (which can send code to cloud models) each checked only the *global* air-gap switch, so a project-level air-gap with the global switch off didn't stop them. Both are now blocked at the same gate as every other outbound tool. Reaching GitHub also can no longer become a standing auto-approval.
- Security: "Wipe all sites" now stops pages before clearing them. A page still running on a site you were signed into could write its cookies back moments after the wipe. Revoking a single site already worked this way; wiping everything didn't.
- Security: Approving a project skill validates the name, so a crafted request can't reach a file outside the project's skills folder.
- Security: The agent's browser could end up painting somewhere the panel isn't. Opening the Preview tab moved the browser panel, but the page kept drawing at its old spot - usually off the bottom of the window, so the browser looked empty or vanished. It tracks the panel properly now, including when you drag the panel to a different part of the layout, and the page doesn't reload when you move it.
- Security: Agent browser screenshots taken right after navigating could come back tiny and useless (a sliver of pixels instead of the page). The agent would screenshot a page it had just opened before the browser view had actually finished laying itself out, so the capture caught the in-between moment instead of the real page. It now waits for the view to be properly sized before capturing, and if a capture still comes back too small it retries once automatically. If it's still bad after that, the agent is told plainly that the screenshot failed (with the size it actually got) instead of being handed a useless image and left to guess.
- Security: A safety check on the agent's browser had never actually run. A backstop meant to stop an ungated page from loading in the agent browser was reading a field that doesn't exist in the version of Chromium we ship, so it quietly did nothing every time instead of doing its job. It now uses a signal that's really there, and blocks the page from opening at all rather than just cancelling the first load. Nothing was exposed by this - the checks in front of it were doing the work - but a backstop that never fires isn't a backstop.
- Security: Bodega now cleans up leftover browser data it has no record of. If cookie storage for a site was left on disk without a matching "keep me signed in" record - something that could happen during testing - it was invisible in Settings and couldn't be removed from there. Bodega now finds and clears that data at startup, so what Settings shows you is what's actually on disk.
- Security: Closed a gap where a specific kind of private key could slip past the output filter unredacted. Bodega scans command output and previewed page content for things that look like leaked secrets before showing them to the AI. That scan recognized several private-key formats, but missed the plain, un-labeled kind used by many modern tools - it could have shown up unredacted. It's now caught, along with a few other secret formats (OpenRouter, Google, and Azure keys, and "Bearer" tokens) that weren't recognized before.
- Security: The bug-report export (repro bundle) had its own, older secret scanner that missed some of the same formats. If you generated a bug-report bundle to share with someone, an OpenRouter key, a Google API key, or a short GitHub fine-grained token could have slipped through unredacted in that file - even though the same secret would already have been caught elsewhere in the app. The bundle exporter now uses the same secret-detection list as the rest of Bodega, so it can't drift out of sync again.
- Security: A shell command could smuggle a second command past approval. Bodega judges how risky a shell command is by splitting it into its parts and looking at each one. It split on |, ||, && and ; - but not on a single &, which is what separates commands on Windows, nor on a line break, which separates them on macOS and Linux. So git status & something else was read as one harmless command, scored as safe, and in Act mode ran without asking you. Both separators are now recognised. Affects the app and the command-line tool, which share the same check.
- Security: A project you cloned could load skills nobody approved, with their full permissions intact. Skills you import yourself already get a review step and have their risky abilities stripped out until you approve them. A skill that shipped inside a project's own .bodega/skills/ folder skipped that step entirely - it loaded on clone with every permission it asked for, and could even be picked automatically just from its description matching what you asked for. Project skills now go through the same approval gate as imported ones, keyed to the exact contents of the skill file so an edit to it re-asks. If the approval record can't be read, nothing is trusted.
- Fixed: macOS builds sign again, and Linux installers drop a dead native binary. The document converter added in this cycle ships one native build per platform; the packaging step was copying its symlinks in a way that pointed outside the app bundle, which macOS code signing rightly refuses, and Linux installers were carrying a second copy of the converter built for a C library they can never use. Packaging now keeps links relative, ships exactly one converter build per installer, and fails the release build loudly if either rule is ever broken again - including on the Intel-Mac build, which is produced on Apple-silicon machines and previously picked up the wrong build.
- Fixed: An approval card could show one command and approve a different one. When two tool calls of the same kind were waiting for approval at once, both rows showed a card, and both cards resolved the same single pending approval - so the row reading rm -rf build could carry the Allow button belonging to the ls -la request. A card now binds to the exact request it is showing, and to the session it was raised in, so an approval in Chat Mode can no longer appear over a Code Mode conversation.
- Fixed: A conversational turn that tried to use a tool no longer answers with a blank bubble. Some questions are answered without tools; if the model reached for one anyway, the attempt was discarded and you saw an empty reply, or worse, "I'll open that page now" with nothing behind it. Bodega now says plainly that the step was not carried out, and asking again runs it. Questions phrased as an instruction ("yes, and take a screenshot") are also routed to the tool-capable path in the first place.
- Fixed: A custom agent's own instructions reached the model on some turns and not others. On a small context window Bodega builds a shorter system prompt, and that shorter version left out the custom agent's prompt entirely - along with the built-in Chat/Code instructions. Everything else about the agent still worked, so it looked active while behaving like the default one. It affected local models only, and only since the August context-window change, which is why the same agent behaved correctly on a cloud model and lost its personality on a local one in the same conversation. The shorter prompt now carries those instructions, trimming them if they are very long rather than dropping them, and says so in the log when it trims.
- Fixed: A custom agent that points at a model you do not have now says so. If the model a custom agent is pinned to was never downloaded, selecting the agent quietly fell back to whatever was loaded. Settings -> Custom Agents and the agent picker both flag the missing model now.
- Fixed: When llama.cpp fails to start, you get the reason. The server's own error output was being read and thrown away, and the automatic retry a couple of seconds later erased it - so a model that crashed on load looked the same as one that started fine. The error is now kept, written to the log, shown in the model status, and included in a diagnostics bundle. Stopping a model on purpose is still reported as a stop, not a crash.
- Fixed: Model status updates as soon as a model finishes loading, instead of on the next refresh up to 30 seconds later. The periodic refresh is still there as a fallback.
- Fixed: The agent browser records both answers when it decides about a redirect. It only ever wrote down refusals, so "allowed" and "the check never ran" left the same trace - no trace. The same was true of declining to open a browser under Air-Gap, which claimed in its own source to be recorded and was not.
- Fixed: The transcript now names the model that actually answered. If a provider is set to serve one model at a time, or a local server already has a different model loaded, your request is quietly answered by whatever is resident. The assistant message is written the moment you press send - before any reply exists - so it could only ever be stamped with the model you *asked* for, and nothing corrected it afterwards. A message could therefore carry a model name that had nothing to do with it. The name is now rewritten from what the provider reports on the wire, and only when the two differ.
- Fixed: You are told when your model choice is overridden. A single-active-model provider silently substituted its own default on every turn. A warning for exactly this case had been built and was never displayed anywhere. It is now a warning toast, once per response, naming both models and where to change them.
- Fixed: The browser no longer reports "navigated" for a page that never opened. The agent's navigate said it had succeeded as soon as the request was handed off, not when a page actually appeared. A site that redirects - reddit.com to www.reddit.com, for instance - could have its redirect cancelled, leave the panel empty, and still be reported as loaded, at which point the agent would describe a page it had never seen. Success now means a document loaded. A load that dies reports the failure and tells the agent not to claim the page is open; a load still in flight is reported as neither.
- Fixed: Eight local models were hidden from Discover on 32 GB machines. Catalog entries carry a minimum-RAM figure, and a 32 GB machine does not report 32 GB - firmware reserves some, so the operating system sees about 31. Every entry needing 32 GB therefore failed its own check and was filtered out of the list, including Qwen3.8 27B and a model some machines were running at the time. The minimum is now checked with a small tolerance, so a machine is not excluded by the number printed on its own box. Genuinely too-large models are still hidden.
- Fixed: Vision models no longer hand out a context window they cannot back. A vision model loads two things onto the card: the weights and a separate image projector. Bodega only counted the weights when it decided how big a default context to ask for, so every vision model in the catalog sized its cache against between half a gigabyte and two gigabytes of memory that was already spoken for. The projector is now measured on disk and subtracted first. On a 24 GB card with a 1.4 GB projector this is about 6,000 tokens of window that were previously promised and not there. Still open: the "fits on your machine" badge in Discover, and the VRAM timeline, are both still weights-only - a vision model can show as fitting and then start with a squeezed context. Widening that badge changes which models every machine is offered, so it is deliberately not in this release.
- Fixed: DeepSeek's reasoning model was billed at roughly six times its real rate. deepseek-reasoner is served as the cheaper V4-Flash model, but the spend tracker still priced it against the retired R1 rate. It now shares Flash's price entry, and Bodega notices in general when a provider serves a different model than the one asked for instead of quietly pricing the one it asked for.
- Fixed: Scheduled and cached prices are now understood. Rates that change on a date, and peak/off-peak windows, used to be flattened into a single number that went wrong the day the schedule changed; cached input tokens were billed at the full input rate. Both are now priced against the clock the usage was stamped with. Still open: Anthropic charges 1.25x for writing to the cache and there is no rate for that yet, so a cache-cold Anthropic turn still reads slightly cheaper than it was.
- Fixed: Switching llama.cpp build types actually reinstalls now. Once you were on the current build, asking for a different build type quietly did nothing and reported success - the download was skipped because only the version number was being compared.
- Fixed: Two GPUs are no longer read as one. llama.cpp spreads a model across every card of the same brand, and Bodega already added up their total memory, but the "how much is free right now" reading still came from a single card - so a two-card machine could be told a model wouldn't fit when it would. Free memory is now measured across the same set of cards, and only when every one of them reports a figure; if any card is silent, Bodega falls back to the single-card reading rather than publishing a number that is quietly short by a whole GPU.
- Fixed: A malformed read position is refused instead of silently reading the top of the file. Asking to read from "2abc" or from position 1.5 used to be quietly turned into position 0, so the agent got the beginning of the file back and had no way to know it had asked for something else - and would ask again the same way.
- Fixed: Saving a memory, project memory, or project instructions could fail outright on a database that had already taken a recent update. Fixed.
- Fixed: Unified-memory machines (DGX Spark, Strix Halo, and similar) were told they had no GPU. Hardware detection expected a separate GPU and CPU memory pool; on a machine where they're the same pool it reported zero GPU layers, labeled the machine "No GPU detected - Minimal tier," marked every catalog model as not fitting, and recommended the smallest model available. It now recognizes this class of hardware. Apple Silicon was already handled, but its usable-memory estimate assumed all system RAM was available to the model - Metal actually grants roughly 70-75% of it, so the estimate is now closer to what's real.
- Fixed: Multi-GPU: llama.cpp now gets credit for pooled VRAM across matching cards. It splits a model across same-vendor GPUs by default, but Bodega's fit and recommendation checks only ever counted the largest single card, so a model that genuinely fit across two cards was marked as too big. Ollama still gets only the largest single card, because that's how it actually loads a model. Cards from different vendors are never pooled together.
- Fixed: A model that needs a newer llama.cpp than you have is now blocked before download, with a message naming the build it needs and the one you're running. Muse Glimmer 30B needs a specific build; loading it on an older one crashed the local model server.
- Fixed: MLX no longer appears as a provider on Windows and Linux (it's Apple-Silicon only), and MLX auto-detection can no longer mistake a running llama.cpp server for an MLX one - they were sharing the same port.
- Fixed: A relative file path read with no project attached now says which folder it actually resolved against, instead of silently reading from wherever the path happened to land.
- Fixed: Agent-browser screenshots and tool calls used to disappear from the transcript the moment a turn finished, so you couldn't expand and review them afterward. They now persist with the message and stay readable after the fact, in both Chat and Code mode.
- Fixed: The agent-browser toggle and custom-agent picker were missing from Chat Mode's empty state. They only appeared once a chat was already in progress, since the header that holds them wasn't mounted on the greeting screen. It's mounted now, from the first screen.
- Fixed: Sending the agent to a real page could crash the whole browser panel. If a navigate landed before Electron had finished attaching the webview, it threw synchronously and took the panel down with it. That now resolves as a retryable tool error instead of crashing.
- Fixed: Chat Mode sometimes showed raw tool_call {...} markup, with a stray /think token, as the assistant's answer. The parser only recognized one wrapper format; a response in a different but still tool-shaped format now goes through the normal retry path instead of being shown as-is.
- Fixed: The agent reported a stranger's account as yours. Asked who was signed in, it read the author of the first post in the feed and answered with that handle - confidently, and wrong every time the top post wasn't yours. It now says it can't tell, because the page doesn't actually reveal it. An honest "I don't know" replaces a confident guess.
- Fixed: The agent-browser panel's width in Chat Mode reset to default on every reload. Your chosen split is now remembered.
- Fixed: A project skill waiting on approval now tells you. Open a project whose own .bodega/skills/ haven't been approved and a chip appears with the count, linking straight to Settings. Before, the skill simply didn't load and the only trace was a line in a log. Approval is tied to the file's exact contents, so editing an approved skill asks again.
- Fixed: Search suggested an option that doesn't exist. When a code search found nothing it advised trying a case-insensitive search - code_search has no such setting, so the retry was identical and found nothing again.
- Fixed: Queued messages that failed stayed in the queue forever, shown as though they were still going to run.
- Fixed: The agent browser's own findings surface in code mode, not only in chat.
- Fixed: Agent browser screenshots weren't showing up in Code mode. The screenshot thumbnail depended on a session pointer that Code mode's agent panel never set, so nothing rendered even though the capture itself worked correctly. It now reads the right session and the screenshot shows up in the stream.
- Fixed: Closing the agent browser and then asking the agent to open a site again now actually shows it. If you closed the agent browser's own X button and then asked the agent to revisit the same site, the agent would navigate there successfully - but the panel stayed hidden until you clicked "Open agent browser" yourself, even though the page had really loaded. Any agent-driven visit now brings the panel back into view, whether it's a new site or the same one as before. The X still closes it, and it stays closed until the agent does something new.
- Fixed: Approval cards for the agent browser now say more about what's actually happening. The "allow agent browsing" prompt used to show only the site's domain - now it also shows the specific page the agent is asking to open, when that's more than just the homepage. The "click" prompt used to show the whole page address as if it were the site name; it now leads with the site plainly, so you don't have to parse a URL to see where you're approving a click.
- Fixed: Quitting Bodega One now frees the VRAM your local model was using. Bodega runs your local model (llama.cpp) as its own background process so it can hand it off between chats without reloading it every time. But on Windows, quitting the app force-closed everything so fast that the local model process never got the chance to shut itself down - it kept running in the background, still holding onto several gigabytes of GPU memory, until you noticed it in Task Manager and killed it by hand. Bodega now tells the model to unload cleanly the moment you quit, so that memory is back and available for anything else within a couple of seconds. An earlier attempt at this fix told the app the model had shut down without actually checking - it now waits and confirms the model process is really gone before saying so, and tries again if the first attempt didn't take.
- Fixed: The agent's browser window could cover the composer and model picker, making them unusable. When the agent browsed a website, the browser window would sometimes land right on top of your message box and model picker - so typing a follow-up could go into the website instead of to Bodega, and clicking the model picker could click the website instead. The browser window now avoids that area automatically, and it's also draggable now if you want to move it out of the way yourself.
- Fixed: A model you downloaded while Bodega was open didn't show up in the model picker until you restarted the app. If you ran ollama pull (or added a model any other way) while Bodega was running, the model picker kept showing the old list - even though Bodega's own connection check could see the new model just fine. Restarting was the only way to make it appear. There's now a refresh button right in the model picker's search box that looks again for real, so a newly downloaded model shows up without restarting anything.
- Fixed: Vision worked for downloaded llama.cpp models but never for ones you added yourself. If you picked a vision model from the built-in catalog, Bodega automatically grabbed its matching "vision helper" file for you. But if you already had a vision model on your computer and pointed Bodega at it directly (sideload), it had no way to find that helper file - vision silently never worked, even though everything looked registered correctly. Bodega now looks in the same folder as the model for a plausible helper file and pairs them automatically when there's exactly one reasonable match. If it's not sure (for example, two different vision models sharing one folder, or a helper file that doesn't look like it belongs to your model), it leaves them unpaired instead of guessing wrong - pairing the wrong files can crash the model server. If you already hit this, you don't need to do anything: just open your models list again and it fixes itself automatically. (There's no separate "re-scan" button in the app yet - opening the models list is what triggers the check.)
- Fixed: Long converted documents were quietly cut off at 50,000 characters, with the agent told it had the whole file. A page reader's pagination is meant to keep going; this had capped every read at a fixed limit and reported it as complete. It now paginates like everything else, so the agent can keep reading a long document instead of reasoning from a partial one.
- Fixed: Built-in skills were missing from every installed copy of Bodega. The twelve skills that ship with the app were documented, listed in the help, and never actually installed - the app looked for them in a folder that was not included in the build. Slash commands that relied on them did nothing. They are now included, and a packaged build that finds none of them now says so loudly at startup rather than starting up looking healthy. The command-line tool needs the same fix in its own release.
- Fixed: Undoing a remembered note or a saved knowledge card now actually works. The command-line tool could ask to undo one of these two kinds of changes, but the app had no way to do it and always refused. Both are undoable now, restricted to your own account, and a request that can't be safely undone still refuses rather than pretending it worked.
- Fixed: Memory searches quietly ignored a filter that was never populated. Memory rows carried a branch field that nothing ever wrote, while three search paths filtered on it. Nothing was broken in practice, but the code implied a feature that did not exist. Removed rather than half-built.
- Fixed: Local models that think before answering were being told not to. Qwen3 and similar models reason by default. Bodega was sending an explicit "don't think" instruction on every request unless you had opened Settings and changed it - so anyone who never touched that setting got the weaker path. It now stays out of the way unless you actually turn thinking off, and turning it off still works. Bodega had already measured what this costs on a different model family and fixed it there; this closes the same hole on the local path.
- Fixed: GLM models had no thinking toggle at all. The control never appeared, so there was no way to turn their reasoning off. It appears now.
- Fixed: The agent can check its own work again. After writing a file, an agent that read it back to verify what it had just done would have that read cancelled and be told to stop reading and write more files. Reading a file you just wrote is now allowed, once per file per write, and no longer counts against you as time-wasting. The guard that stops an agent exploring forever without writing anything is unchanged.
- Fixed: A turn that read more than eight files got none of them. When an agent read a lot of files at once, a message reminding it to be selective was inserted in a position that caused every one of those file reads to be discarded before the agent saw them. It received the reminder and nothing else. Present since 1.0.0-beta.31.10.5. Six more places with the same ordering mistake were found and fixed, and there is now a check that reports this class of failure instead of losing the content silently.
- Fixed: Verification could grade a write against the wrong file. A written file was matched to what the task asked for by filename alone, so a write to test/index.ts could be checked against a deliverable declared as src/index.ts - passing or failing the wrong file. Matching now respects the directory when one was specified, with a bare-filename fallback for deliverables that didn't specify one.
- Fixed: Bodega's own answer to "what does this app do?" pointed at the wrong tool for reading PDFs, and named tools that weren't documented at all, including the tool that answers questions about Bodega itself. Six missing tools were documented, and the retrieval that decides which help page to show got two rounds of fixes: a question phrased differently than its matching heading could return nothing, and a page that just happened to repeat a search term many times could outrank the page that actually answered it.
- Fixed: The first-run hardware check could hang indefinitely on "Detecting...". A timeout existed but only covered some of the places that triggered the check; a stuck GPU query in one of the others left new users stuck on the loading screen with no way forward. The timeout is now built into the check itself, so every caller is covered.
- Fixed: An abnormally-closed backend could leave the local model server running and holding onto VRAM. Bodega now checks for and cleans up its own orphaned model server at startup.
- Fixed: A background chat session sharing the model server with the main window was budgeted against double its real context window, because the shared budget wasn't being divided by how many sessions were actually sharing it.
- Fixed: A note or fact you explicitly asked Bodega to remember never lost confidence over time, even after it stopped being true. Memory entries built from things you said in passing correctly fade in relevance the older they get. Entries you saved on purpose (save_memory, or anything a tool wrote directly) were being treated as permanently at maximum confidence instead - they never faded and never got flagged as possibly stale. They now decay too, more slowly than an inferred fact since you said it on purpose, but not forever.
- Fixed: Reading part of a file could authorise overwriting all of it. The guard that stops the agent writing a file it has not read only checked whether the file had been read at all, not how much of it. Read 8% of a large file, write the whole thing back, and the other 92% was gone with nothing to warn you. The guard now tracks which ranges were actually read and refuses a full-file write on a partial view. The related case - where the agent had matched an exact snippet rather than read the file - used to be refused with a message that made no sense ("you have read only 0 of 0 characters"); it now says what it actually wants.
- Fixed: The read tool advised a line range it could not yet honour. On a large file it told the model to read a line range at a point when the tool still only addressed characters. The advice was accepted, silently dropped, and the same read repeated from the start - a loop the tool caused itself. The tool now genuinely supports line-addressed reads (see "read a file by line number" above), so the advice and the behaviour agree.
- Fixed: Reading a Windows file and writing it back no longer rewrites every line ending. Line endings were being converted to Unix style on the way in, so content the agent showed you and then wrote back came out as a whole-file diff. The file is now left as it is on disk; a byte-order mark is still stripped, since it broke snippet matching.
- v1.0.0-beta.34Feature
Connect Bodega straight to hosted tool servers (GitHub, Linear, Notion, Sentry) with air-gap refusing them up front, the new Bodega Observatory that surfaces what has actually been verified on the Map tab, full-conversation prompt caching on Anthropic models rather than just the preamble, and an installer about 40% smaller (909 MB down to 553 MB unpacked, a 136 MB Windows installer), plus Qwen 3.8 Max and Qwen 3.7 Flash, a failing test command now vetoing a pass outright, a task that runs out of time reported as timed out instead of finished, and a rate-limit pacing fix that reclaims the roughly 18.8% of long-run time previously spent asleep for nothing
- Connect to hosted tool servers directly. Bodega could only run tool servers as a local program on your machine. Hosted ones - GitHub, Linear, Notion, Sentry - had to be wrapped in a local shim first, if you knew to do that. You can now add one by its address, with a token, from Settings. Air-gap mode refuses them and says so up front rather than letting you fill in a form that cannot work.
- Bodega Observatory. The Map tab now shows what has been verified, not just what exists. Each file carries its latest verification result, a rail lists recent findings and files that have grown past their size limit, and every row opens the file at the right line. Off by default; turn it on in Settings under AI Behavior. Files nothing has verified show a neutral mark rather than a green one - absence of a check is not a pass.
- Prompt caching now covers the conversation, not just the preamble. On Anthropic models, Bodega already reused the cached system prompt and tool definitions between turns. The conversation itself was re-sent and re-billed in full on every step of a long task. It is now cached too, and the cached region rolls forward as the conversation grows. How much this saves depends on how often the conversation gets summarised, since summarising rewrites the history and starts the cache over.
- A record of what each request is actually made of. Every request now reports how its context was spent - the fixed preamble, the project state, the per-turn additions, the tool definitions, and the conversation - alongside how much was read from cache. Visible in the debug panel. This exists because almost every claim about context size in this project was an estimate read off the code rather than a measurement.
- Per-file verification results for edits, not just new files. Verification produced no per-file result at all when the agent modified existing files, which is most real work. It does now.
- Two new Qwen cloud models. Qwen 3.8 Max, Alibaba's new flagship, and Qwen 3.7 Flash, a cheaper vision-capable tier, are both available now through the Qwen (Alibaba DashScope) provider. Qwen 3.7 Flash is also available through OpenRouter.
- Changed: In code mode, Bodega now writes a rough version of the file you asked for early, then improves it in place, rather than working the problem out in the terminal and only writing a file once it has the full answer. Debugging and questions that do not name a file to produce are unaffected.
- Changed: Turning thinking on or off now works for cloud Qwen models. The control had no effect at all when talking to Qwen through Alibaba's own API - the model kept reasoning (or not) on its own regardless of what you picked. The toggle now reaches the model.
- Changed: The newest Qwen models were losing their reasoning by default. Fixing the toggle above introduced a second problem: once the toggle reached the model, it reached it every time, including when you never touched it. Two of the Qwen models this release adds show their reasoning by default on Alibaba's own API; leaving the control alone was silently turning that off. It now takes an explicit choice from you to turn thinking off on those models - leaving the control alone keeps their own default.
- Changed: The paid licence activation screen has been removed. Nobody had ever purchased through it, so no existing activation is affected. Beta email activation, which is how every current user signs in, is unchanged.
- Changed: The installer is about 40% smaller - 909 MB down to 553 MB unpacked, and the Windows installer is now 136 MB. Most of that was ours rather than the framework's: unused copies of libraries that were already bundled, every language pack for an English-only app, development-only packages shipped to users, and - the largest single piece - stale development builds that were never cleared before packaging. Earlier releases very likely shipped those development builds.
- Changed: Files the agent edited show a neutral mark rather than a green tick. A green tick used to appear on an edited file purely because the file existed afterwards, which is true of every edit whether it worked or not. Existing is no longer treated as evidence of anything on an edit, so edited files show a neutral mark unless something real was checked - a test, a proof gate, a framework check. Newly created files are unaffected. You will see fewer green ticks on ordinary work; nothing has broken.
- Security: A leftover benchmarking setting could no longer widen where the agent is allowed to write. A setting used only by the internal benchmarking harness to let a disposable test container write outside its task folder was read from an environment variable, and environment variables are inherited by child processes. An earlier attempt at this fix cleared the variable in the app's own startup process, but the backend can also be launched on its own - by the command-line tool, for example - and that path was never covered. If the variable happened to still be set in the terminal a launch started from, an unattended run (an overnight batch, a background session, or a headless run started from the command line) could write anywhere on disk instead of being kept inside the project, with nothing shown to the user. The setting is no longer read from the environment at all. It now has to be passed explicitly to the backend process itself, a channel nothing inherits automatically, so nothing a parent shell happens to have set can reach it. Any time the write boundary is actually widened is still logged.
- Security: Sending data out through a one-line script is blocked properly now. The agent can run short scripts inline, and the rule meant to stop those from reaching the network was checking for the wrong thing. Measured against real commands it had it backwards: it blocked ordinary local work like running a build, while letting four common ways of posting a file to a remote address through untouched. The check now looks at where the script is actually sending data. Reaching a remote address is refused; reaching a server on your own machine still works, so local development is unaffected.
- Security: A command written in your prompt is no longer run automatically during verification in an interactive session. This release taught Bodega's verification step to also run the exact command you name in your own request - "verify by running the tests," for example - so a wrong claim of success can be caught against your own stated check, not just Bodega's guesses. That command now only runs on its own in an unattended run (an overnight batch, a background session, or a headless run started from the command line), where you have already accepted that the agent executes shell without asking each time. In an ordinary chat session it no longer runs by itself; every other part of verification - compiling, running your project's own test suite, checking the file exists and looks right - is unaffected and keeps running exactly as before, in every mode.
- Fixed: The thinking control was missing for models installed through the app's own model manager. Models pulled or sideloaded via the app's llama.cpp model manager get an internal id that the composer's Thinking toggle could not read a model family from, so the control silently never appeared, even for models that support thinking. The id is resolved to the real model name before that check runs now.
- Fixed: Local models on a consumer GPU ran out of room before they started work. Bodega sizes a local model's context to what your VRAM can safely hold. On a large model that lands in a middle band - big enough not to count as a small window, small enough to be tight - and the full fixed preamble was being sent anyway, taking roughly half the available space before the conversation began. Long tasks then spent their budget compacting instead of working. Local runs in that band now get the short preamble. Cloud models are unaffected.
- Fixed: The model picker was showing every model a provider offers, including ones that cannot hold a conversation. A cloud provider with a large catalog - Qwen/DashScope alone can list over 150 - dumped everything into one flat, alphabetical list: text models mixed in with text-to-speech, image generation, video, translation, and embedding models, plus half a dozen dated copies of the same model. Finding the current flagship meant scrolling past all of it or typing its version number from memory. The picker now shows chat-capable models first, with the newest version on top, collapses dated snapshots down to one row, and keeps everything else one search away rather than gone - nothing is ever permanently hidden.
- Fixed: A long task that runs out of time mid-answer is now reported as having run out of time, instead of presenting a cut-off answer as complete. Bodega could stop a response partway through when its own time budget ran out, but still show the partial text as if the model had finished normally.
- Fixed: A task could be reported as passing while its own test command was failing. When a task states how to check itself, for example a test command or a build step, Bodega runs it as part of verification. That result was scored as one signal among several, so a high score elsewhere could outvote it and the work was reported complete with the stated check still red. A failing check now vetoes the pass outright, as does one that never ran. Verification is stricter as a result, so some work that used to be reported as done will now come back for another pass.
- Fixed: Long tasks spent up to a fifth of their time asleep, on purpose, for nothing. Bodega paces its own requests so it does not trip a provider's per-minute token limit. When a single request was larger than that whole per-minute budget, the pacing code searched for a point in the next minute where the request would fit, found none, and then waited the maximum 45 seconds anyway before sending it unchanged. No amount of waiting can make one oversized request fit inside a smaller budget, so the wait bought nothing. A long coding conversation crosses that line routinely, which meant a 45-second pause on most later steps. Measured across 217 recorded benchmark runs, this was 18.8% of total elapsed time. Bodega now sends the request immediately in that case and relies on the provider's own response and the existing retry, which is what happened after the wait regardless. Two related problems went with it. The default per-minute budget used for providers that do not publish one was 40,000 tokens, well under a normal agentic conversation, and is now 100,000. And a personal endpoint on your own machine or network was being paced against a cloud limit it does not have, which is now treated as local and not paced at all. One trade-off worth stating: if your plan has a genuinely tight token limit and your provider sends no rate-limit information with its responses, Bodega now discovers that limit by hitting it rather than by anticipating it. Set your real limits under llm.rate_limit_overrides if this affects you. This closes the specific waste - waiting a fixed amount of time for nothing - but it does not make pacing go away. A long task that generates a lot of output in each step will still cross a provider's per-minute limit and still wait for it; that wait is legitimate now, and how much of it you see mostly tracks how verbose the model's answers are, not this fix.
- Fixed: Claude Opus 5 Fast could not be used at all. It was listed as a model, but no such model exists: every message sent with it selected failed immediately with a not-found error. Anthropic offers the faster tier as an option on the standard Opus 5 model rather than as a separate model, and Bodega was not requesting it. Selecting it now sends what the faster tier actually requires. Note that access to it depends on your own account having the capacity available; without it, Anthropic returns a rate-limit error rather than a reply.
- Fixed: Turning thinking off now turns thinking off. On local models the control had no effect at all - the setting was discarded before it reached the model, which kept thinking regardless. On the newest Claude models, Off and Fast Mode relied on simply not asking for thinking, which those models treat as thinking on. Both now say so explicitly. On Claude models served through another provider, where the control could never have worked, it no longer appears.
- Fixed: Cloud Boost with Gemini as the boost model now respects your reasoning setting. It was silently dropped - Boost sent every request through a path that only knew how to turn reasoning on or off for OpenAI-style models, and Gemini's own reasoning parameter is shaped differently, so the choice never reached the model. Boost requests to Gemini now carry it.
- Fixed: Blocked commands now say which rule stopped them. The agent was told only that a command was blocked, so it would retry variations of the same thing instead of trying a different approach. It now names the kind of rule and, where there is one, suggests a way to do the same job safely.
- Fixed: Searches that find nothing now explain why. An empty result looked the same whether the pattern was wrong, the path did not exist, or the search could not handle a pattern spanning multiple lines. That last case now works instead of silently finding nothing.
- Fixed: DeepSeek was running with its reasoning turned off. DeepSeek reasons by default. Bodega's reasoning control defaults to "off", and for every other provider that means "send no instructions and let the model behave normally". For DeepSeek it meant something different - an explicit instruction not to think - so anyone who had never opened that setting was using the model with its headline capability disabled. Measured on a public benchmark of 89 programming tasks: 33 solved with the instruction being sent, 47 without it. Same model, same tasks. Only the default changed. Choosing "Off" yourself still turns thinking off, and a per-model or per-message choice still wins as before.
- Fixed: The task-list reminder reaches the model again. It was skipped whenever the turn's text began with a brace, which is most turns while tools are running, so on long tasks the agent gradually lost track of its own plan.
- Fixed: The agent stopped refusing its own ordinary commands. Three safety rules were matching far more than they were written to match, and the agent could lose whole tasks retrying variations of a command that was never going to be allowed. Deleting a build directory - rm -rf build-output inside your project - was read as an attempt to wipe the entire filesystem, because the rule accepted any absolute path rather than the root itself. The rule now looks at how deep the path goes: the top of the filesystem is refused, a directory inside your project is not. Anything containing the letters of a shutdown command was refused, including -halt-on-error (an ordinary LaTeX flag), -no-reboot (an ordinary emulator flag), and searching your own logs for the word. These are now recognised by position - a shutdown is a command being run, not a word appearing in a flag or a search string. Reading a private key was confused with any variable or property named key, so print(item.key) in a one-line script was refused as if it were leaking a certificate. The check now distinguishes a file path from a property name. Reading an actual key file is still refused, and every one of these rules keeps blocking the dangerous form it was written for.
- Fixed: Verification no longer marks a check failed when it could not run. A correct, working file could be scored 35 out of 100 and reported as a failure with nothing actually wrong. Checks that do not apply to what you asked for - no framework to look for, no content requirements to match, no test to run - were counted as zero rather than left out, so the score was measured against work that was never part of the request. A one-line Python script that ran correctly could not reach a passing score at any setting. Those checks are now excluded from the total, and the report says "n/a" for them instead of showing a zero out of thirty that reads like a failed test. Files are also credited for existing even when they are short - a small file is not a missing one. Two related repairs: a task with no framework to check was quietly awarded those points for free, which is the same mistake in the opposite direction; and a check that was attempted but could not be judged - a missing interpreter, a timeout - no longer counts against the score, because it observed nothing. This is a real improvement but not a complete one. The one-line script above went from 35 to 50 and still does not pass. Closing the remaining gap means removing a minimum-length rule on file content, and doing that let a stub Go file certify as verified on a check that inspected nothing. That is worse than the problem being fixed, so the rule stays until the verifier can tell the two cases apart.
- Fixed: The iteration limit you set is now the one that is used. If you raised the limit for how long the agent may keep working, that choice could be quietly overruled and a longer task would stop early. The app was deciding whether you had chosen a value by checking whether a row existed in its settings, which is not the same question - routine internal updates write rows too, and a value that happened to match the built-in default was indistinguishable from never having been set. Your choice is now recorded when you make it. If you set the limit before this release, save it once more so it is recorded properly.
- Fixed: Add Server said nothing when it could not be used. Adding a tool server with the name left blank did nothing at all and gave no reason. The button now says what is missing.
- Fixed: Compacting a short conversation no longer contradicts itself. Pressing Compact announced that it was compacting, then immediately said there was too little to compact. It now reports only what happened.
- Fixed: Long answers from DeepSeek were being cut off far too early. The two newest DeepSeek models were configured to stop after roughly a twenty-fourth of the output they can actually produce, and that figure was sent to the service as a hard ceiling rather than just recorded on our side, so long generations really were truncated. Their two general-purpose models were also carrying the context size of the previous generation. Corrected against the live service rather than the documentation.
- Fixed: Your answer was being saved twice. Every reply was written to the transcript two times, by two different parts of the app that did not know about each other. One copy carried the token count, the other carried the model's reasoning, and neither had both. Now one copy is written, with everything on it. This also means the conversation replayed back to the model no longer contains each of its own answers twice. Overnight and scheduled runs get the model's reasoning saved for the first time; they never had it. One case is knowingly left: a reply interrupted part-way through is still written twice.
- Fixed: Asking for help no longer depends on which language you named. When a request was too vague to act on, Bodega would ask a couple of questions before starting. Whether it asked at all depended on the language: a vague Python request got questions, an equally vague Bash, Node, PowerShell or shell request got none. Now they all do. Well-specified requests are still left alone.
- Fixed: Saying "C++" or "C#" no longer gets you asked what language you want. Neither name could ever be recognised, so a request naming them was treated as naming nothing.
- Fixed: Suggestions when Bodega asks which framework you want. It could only offer options for Python, TypeScript and Ruby, and stayed silent rather than ask for anything else. It now covers JavaScript, Go, Java, Rust, PHP, Swift, Kotlin, C, C++ and C#.
- Fixed: Long tasks on a small context window stop losing their place every few steps. Part of the context window is taken up by fixed material that cannot be summarised away. Bodega was measuring how full the window was against the whole window, including that fixed part, so on a small window it summarised the conversation roughly every third step and reclaimed almost nothing each time. One task spent eighty-six tool calls re-reading the same nine files. It now measures against the part it can actually reclaim, and will not summarise when there is nothing worth reclaiming.
- Fixed: Summaries stopped piling up on top of each other. Each summarisation left the previous summary in place and added another, so the space available shrank a little more every time and the next summarisation came sooner. Summaries now replace rather than accumulate.
- Fixed: A background task could have its working copy deleted while it was still running. When the agent delegates a piece of work, it does that work in a separate copy of your project. The cleanup that removes abandoned copies could not tell a live one from a crashed one, and ran every fifteen seconds. It could remove the copy out from under the running task, and separately could offer it to you as an abandoned copy to confirm deleting. Both are fixed, and the final delete step refuses a copy that is in use regardless of how it was asked.
- Fixed: "Nothing to apply" is no longer reported when the check itself failed. Comparing a background task's work against your project could fail silently and report zero changes, which is indistinguishable from a task that genuinely changed nothing. It now says the comparison failed.
- Fixed: Tools from connected servers now ask permission in chat, not only in code mode. With approvals set to ask, tools provided by a connected external server ran without prompting in chat mode. They prompt everywhere now.
- Fixed: Connected servers with more tools than fit on one page. Only the first page of a server's tools was read, so the rest silently did not exist.
- Fixed: Server arguments containing spaces. An argument with a space in it - a Windows path, a piece of JSON - was split into pieces before being passed on.
- Fixed: Tool results that are not text. A result containing only an image was reported as a success with nothing in it, and an error carrying no text was reported as a success outright. Both now say what actually happened.
- Fixed: Cancelling a tool now cancels it on the server. Stopping a run, or a tool hitting its time limit, left the request running on the other end with nobody waiting for it. The time limit is also configurable now.
- Fixed: Recorded checks from overnight runs. Verification results from headless and scheduled runs were never recorded, so nothing from those runs was ever re-checked later for regressions.
- Fixed: A file with almost nothing to check no longer reports a confident pass. A plain text or data file, where you did not say what it should contain, was graded on two things - that it exists and is not empty - and then reported 100 out of 100. The score is unchanged; what it says is not. It now reads as unverified rather than passed, which is what it always was.
- Fixed: Quoting something in passing no longer invents a requirement. Bodega looked for phrases like "containing" or "with the text" anywhere in your message and then treated every quoted string as required file content. Mentioning a quoted name in an unrelated sentence could fail work that was correct. The phrase now has to actually be describing the file it precedes.
- Fixed: When a forbidden library costs points, Bodega says which one. It quietly deducted and moved on, so a result could come back lower with no explanation.
- Fixed: Asking for something "without using X" is now understood. It was ignored entirely - only libraries Bodega inferred were incompatible counted, never the ones you ruled out yourself. A rule you stated is now enforced; one that was merely inferred still only deducts, because a guess should not block work.
- Fixed: File ranges expand based on what is on disk. Asking for "file1 to file5" now checks whether those files already exist before deciding you meant a range of new ones, instead of trying to read your intent from the sentence.
- Fixed: A pass with nothing behind it is treated as unverified, not as a refusal. A separate check added earlier this release asks whether a pass is backed by an actual test or run, not just the absence of a failure - because a whole test suite silently failing to run reads the same as it not existing. That check had a bug: languages whose contracts only ever run a compile check - TypeScript, Go, Rust, Java, Ruby, PHP, and configuration or documentation tasks - never produce anything the check counts as a test in the first place, so it was refusing all of them regardless of whether the work was correct. It now tells "nothing to check" apart from "checked and came back empty," and only the second one counts against the work. Before this fix, that distinction did not exist for those languages: every contract of theirs read as "checked and came back empty," whether the work was right or not. You may still see overnight Loops park instead of applying, and GitHub automation open a draft pull request instead of a ready one, but now only when a test genuinely ran and came back empty - not merely because the language does not have one to run.
- v1.0.0-beta.33Feature
The verification release: finished work is no longer reported as failed and a check that could not run no longer counts as a failure (across 89 real tasks the old quality gate had wrongly failed 29 completed ones), plus Claude Opus 5 as a cloud model with a faster variant, a per-run time budget, an OpenRouter preferred-provider list, capable models freed from the small-model safety rails, Kimi K3 selectable, and a dropped connection no longer running your task twice
- Claude Opus 5. Available as a cloud model, along with a faster variant. 1M context, and the app picks the right thinking behaviour for it automatically.
- A setting for how long a single run may take. If you run the agent inside something that stops long jobs on its own - a CI job, a test harness - you can now give the agent a shorter budget than the thing running it, so it finishes and reports properly instead of being cut off mid-task.
- A preferred provider list for OpenRouter. OpenRouter passes your request on to one of several companies that actually run the model, and it does not keep you on the same one between requests. Each of them remembers your recent context separately, so bouncing between them meant that memory was almost never there to reuse and every request started over. You can now name which ones you prefer, in order. On a long task this cuts both the bill and the waiting, and if a preferred one is busy or down your request still goes through elsewhere rather than failing. Off by default, and it changes nothing for any other provider.
- Changed: Kimi K3 is selectable. Moonshot's current flagship - one million tokens of context, image input, reasoning always on - was already supported but was not named anywhere in the setup, so there was no way to know the model id. The Kimi provider now lists it.
- Changed: The verification and drift strips above the composer look like the rest of the app. The quality-check card painted its whole background red, amber or green, which no other status surface in Bodega does; both strips now use the same neutral panel with a small status dot, and sit together as one block instead of two competing bars. The drift row also dropped its jargon - it now says "Check whether previously verified results still hold" rather than naming an internal mechanism.
- Changed: The agent stops second-guessing capable models. A set of safety rails built for small local models were being applied to every model, on every task. They capped how many times a file could be edited, turned some edits into reads, and interrupted with reminders. On a capable model doing real work these cost steps and sometimes ended the run early. They now step aside for strong models working unattended, and stay exactly as they were for smaller models and for anything you're supervising.
- Changed: Quality checks now act on what they find. When a check catches a real, demonstrable failure - code that doesn't compile, a command that errors - the agent gets the actual error text back and fixes it, instead of the failure being noted and the answer shipped anyway.
- Changed: Work done through the terminal now counts. The agent often writes files by running shell commands. Progress tracking and quality checks only watched the file editor, so that work was invisible to them and many finished tasks were never checked at all.
- Changed: The agent can do several things at once again. Five separate places in its instructions told it to make one tool call per message. Nothing in the app required that, and it meant reading three files took three round trips instead of one. It can now group independent work into a single step, while anything that depends on an earlier result still waits for it. Small local models keep the one-at-a-time guidance, which is where it was always meant to apply.
- Changed: Less filler in what the agent reads back. Every result it got included things it could not use: the command it had just sent, echoed back verbatim; empty fields; timestamps it never looks at. That was roughly a tenth of everything it read, and on a long task it crowds out the parts that matter. Failures still carry the full detail, because that is when the extra context is worth its space.
- Changed: Long tasks get the time they are actually allowed. When the agent runs inside something with its own time limit, it now reads that limit and sizes its own work to fit, instead of applying one fixed budget everywhere. Tasks that were being stopped with most of their time unused now run to completion.
- Changed: Project information is arranged for reuse. The unchanging part of what the agent knows about your project - your rules, the file list, the repository map - now comes before the parts that change every turn. Providers that cache repeated context can reuse far more of it, which is faster and cheaper, and it helps local models most.
- Security: A secret sitting next to ordinary text is redacted again. Shell output is scanned for credentials before you or the model ever see it. The scanner measured how random a run of characters looked, but it measured the whole run it happened to grab - so padding a key with sixty characters of filler averaged the randomness away and the key printed in full. It now measures a sliding window, so filler next to a secret no longer hides it. It also strips terminal colour codes before looking: a single escape sequence in the middle of a token used to break every pattern we match.
- Security: A detached side chat now honours the project's privacy vault. The vault is a per-project switch that keeps that project's work off the network. Which project applied was decided by the app window making the request, and a side chat popped out into its own window does not know which project is open - so it sent nothing, and the vault quietly did not apply. The project is now determined by the session itself, and a request cannot override it.
- Security: Project scans stay inside the project. A shortcut or junction inside a folder pointing somewhere else on the machine was followed, and file paths and code symbols from outside the project could end up in the model's context.
- Fixed: Long tasks stop forgetting what they already made. On a task with more steps than fit in the model's context, Bodega summarises the earlier part of the conversation to make room. That summary is written by the model, and on a smaller local model it routinely dropped the record of which files had already been created - so the agent made the same file again, hit the loop guard that exists to stop exactly that, and stopped early with only part of the work done. A five-file task finished with two. Bodega now restates, as plain fact after each summarisation, which files were asked for and which already exist on disk. Read from the disk itself, not from a record of what the agent believed it had done.
- Fixed: Asking for "3-5 files" is understood as a range. When you gave a count as a range, only part of it was read, so the finished-work check could be measuring against the wrong number of files. Ranges are now read as ranges. And when the agent cannot work out what you asked for, it says the request is incomplete and asks, instead of picking a number and building against its own guess.
- Fixed: A range of files you asked it to READ is no longer mistaken for files to create. "Merge part1.csv to part9.csv" was read as a request for nine new files, because the word "to" was treated as a range marker regardless of what the sentence asked for. The finished-work check then reported failures for files that were never supposed to exist, and the agent went off trying to produce them. We tried several times to work out from the sentence whether a range meant "read these" or "create these", and it could not be made reliable, so the app no longer guesses. A range written with "to" or a hyphen is taken as the two files you actually named, and the task is reported as unverified rather than reported as a success over a partial list. A range written with "through" still expands into every file in it. Numbering that changes width partway through a range, like part8 through part12, is counted correctly now.
- Fixed: On Windows, a command that throws away its output no longer leaves a file called $null in your project. Commands run through the Windows command prompt, where $null is an ordinary filename rather than a way to discard output, so a command written to keep quiet quietly created a file instead. It succeeded, so nothing reported anything. The output is now discarded properly, and the agent is told about the correction so it stops writing it. Text inside quotes is never rewritten, so a commit message that happens to mention $null is left exactly as written, including messages containing escaped quotes, which the first two attempts at this got wrong. Where it cannot be certain whether the text is quoted, the command is left untouched.
- Fixed: The Skills switches work. Turning a skill off, or turning off automatic skill activation, silently failed every time and reverted with an error. Both switches sent the setting in the wrong shape, so it was rejected before it was ever stored.
- Fixed: Editing a skill no longer erases it. The editor loaded the skill's text from an address that did not exist, failed quietly, and saving then wrote the empty result over your instructions. Saving is now refused when the text could not be loaded.
- Fixed: Three ways to lose unsaved work are closed. Closing a tab from its right-click menu discarded unsaved edits without asking, unlike every other way of closing a tab. Quitting with unsaved files discarded them with no prompt. And opening certain files - a binary, or anything very large - from the breadcrumb bar, the problems list, or a terminal link produced an empty editor whose first save truncated the real file on disk to nothing.
- Fixed: A dropped connection no longer runs your task twice. If the connection broke mid-answer, the app resent the request while the original was still running, so file edits and commands could be applied twice. It now asks the backend whether the original is still alive and rejoins it. If it cannot reach the backend to ask, it stops and tells you so rather than guessing - reopen the session to see where the run got to. Resending on a guess is how the work got done twice in the first place.
- Fixed: That check now covers the case it was written for: the connection dropping while the answer is still arriving. It only handled a connection that failed to open, or one that closed cleanly, so the most common break of all went straight past it. Losing the network partway through a reply now does the same thing as any other drop: the app asks the server whether the run is still going and rejoins it. Before, it either resent the turn, which could apply the same file edits twice, or sat there looking like a slow model with nothing to tell you.
- Fixed: Losing the connection in the first seconds of a reply is handled too. When the app asked the backend whether your run was still alive, the backend only counted a run as started once the model produced its first output. Everything before that answered "nothing is running" - and with a local model that gap covers loading the model into memory and can last tens of seconds. A connection lost in that window got a wrong answer and the request was sent again, so the same task could run twice. The backend now claims the session the moment it takes the request, not when the model first speaks, and it holds that claim even if you close the window, because a run that carries on in the background is still a run. Losing the connection while a local model is loading no longer risks the request being carried out twice.
- Fixed: Reloading the window asks before discarding unsaved files, the same as quitting. Ctrl+R used to throw the work away without a word.
- Fixed: Quitting from Chat Mode asks too. The unsaved-work check only existed while the editor was on screen, so quitting from chat discarded open edits silently - and made every quit from chat wait two seconds first.
- Fixed: Preview actions do not repeat themselves after a reconnect. Reconnecting replays the run to catch you up, and anything the agent had clicked in the preview was clicked a second time.
- Fixed: OpenAI's Europe endpoint is recognised as OpenAI. It was being treated as an unknown local server, which meant a short connection timeout, no model list caching, and no usage or cost reporting.
- Fixed: "Persist memory" is gone, because it never did anything. Nothing read it, and its description claimed memories were lost when the app closed. They were not.
- Fixed: Editing a project-scoped knowledge card keeps it in that project instead of quietly making it global.
- Fixed: The app starts even when the terminal component cannot load. A missing terminal library stopped the whole app from starting, with an unhelpful error. Now everything else runs and only the terminal reports the problem.
- Fixed: Local models are no longer cut off after five minutes. A hard time limit killed a healthy answer mid-sentence. Long answers are now judged on whether they are still making progress.
- Fixed: Streaming no longer breaks on some providers. A usage-reporting field was being sent to every recognised provider, including ones that reject unknown fields outright. It now goes only to providers known to accept it.
- Fixed: Answer-quality results no longer show a wrong score card. A checked answer displayed five red zero-scores under a green pass. Those bars do not apply to answers and are gone; the actual finding is shown instead.
- Fixed: Side chat fixes. Switching sessions showed one conversation's messages under another's heading, and the "send this to the main chat" action could fire into the wrong session, or one that had been deleted.
- Fixed: A failed run notifies you even if you walked away - previously the notification was skipped in exactly that case, leaving the session stuck on "running".
- Fixed: Finished work is no longer reported as failed. This is the big one. The quality check treated "I could not observe this working" the same as "I watched this fail" - so a task the agent had genuinely completed came back marked failed, the command exited with an error, automated runs refused to apply the change, and the agent was sent off to repair work that was already correct. On a run of 89 real-world tasks measured against an independent grader, we solved 35 and told you we had failed on 29 of them. Two rules caused nearly all of it: a task was failed when nothing had exercised the new behaviour, and a task was failed when a piece of text we expected to find in a file was not there. Now only something we actually watched go wrong can fail a task. When we cannot confirm the work, it says so plainly instead of calling it broken, and it does not go back and redo work you have already paid for. A pass still means the same thing it always did: we saw it work.
- Fixed: A missing test no longer counts as a failed one. The reverse case, found in the same review. A check that could not run - because the environment was not there, or because it timed out - was allowed to sit alongside a check that really did fail, and the real failure could be outvoted. A check that observed a failure now always carries.
- Fixed: Long runs stopped ending as errors. When the agent reached the time limit you set, one path finished cleanly and reported its work, while another threw the run away as if something had gone wrong. Reaching a limit you configured is a normal ending, and it now reports as one, with whatever was completed.
- Fixed: The agent gets the number of steps you asked for. Setting a higher step limit had no effect: an internal recommendation quietly overruled it, often to a quarter of what was requested, and nothing said so. What you set now wins.
- Fixed: Writing a large file could be cut off partway. A safeguard meant to catch a stalled model was watching for text coming back, but a model writing a long file sends it as instructions rather than text, so a productive run looked frozen and was stopped mid-write. Affects every provider except Anthropic, which was already handled.
- Fixed: Edits that would break a file are caught before they land. A syntax check already guarded whole-file writes but not the targeted edits the agent makes most often. It now covers both, and only ever rejects an edit that breaks a file which was fine beforehand, so it cannot block a valid change.
- Fixed: Requests could freeze for up to a quarter of an hour. If a cloud provider stalled, each retry started its own fresh timer instead of counting against one deadline, so a single request could sit there for around fifteen minutes with no way to interrupt it. Affected every cloud provider, including Cloud Boost, where it also burned budget. There is now one deadline covering the whole request, and a provider asking us to wait can no longer ask for an unbounded wait.
- Fixed: The agent gave up early on longer tasks. Some models were being given a much smaller step budget than they could actually use, because of how their size was detected, and turning the limit up in settings had no effect. Models now carry their own working length.
- Fixed: The agent refused to create project files. Standard project manifests - pyproject.toml, setup.py, Cargo.toml, go.mod and similar - were treated as out of scope and blocked, repeatedly, on tasks whose whole point was packaging. They are now always allowed, and a refusal no longer repeats.
- Fixed: The agent stopped reading files that were right there. On tasks phrased as "create" or "write", it could decide the folder was empty without checking, and refuse to read existing files. It now checks first.
- Fixed: Task lists didn't work outside the app. Running the agent from the command line without a session, its to-do tracking silently failed on every run.
- Fixed: Internal notes could appear as the answer. When the agent stopped itself because it was going in circles, the internal explanation was sometimes delivered as the reply. You now get a real answer, or an honest description of what went wrong.
- Fixed: Failed runs said nothing about why. A run that ended without a verdict reported no reason at all. It now reports what happened, how long it ran, and how much it did.
- Fixed: Prompts starting with a dash were rejected. The command line treated the first line of such a prompt as an unknown option and refused to start.
- Fixed: Edits could be reported as saved without being saved. A safety check meant to make the agent read a file before overwriting it was performing the read instead of the write, and then reporting success. The agent believed its change had landed, hit the same failure again, and only discovered the truth by re-reading the file. A change whose target text is already in the file now simply applies, since finding that text proves the agent knew what was there.
- Fixed: Edits that removed code were silently dropped. A second check discarded any rewrite that made a file smaller and reported it as done. Deleting the part that does not work is often the most valuable edit there is, and file size says nothing about intent. Rewrites now apply whenever the content actually differs.
- Fixed: Python files could not be saved on some machines. If a machine has python3 but no plain python, the syntax check treated the missing program as a syntax error in your code and blocked every Python file the agent tried to write. It now looks for both, and a missing checker means the file is saved, not blocked. The same fault made a missing test toolchain read as "your code fails its tests".
- Fixed: Quality checks could pass work that was never checked. A task that edited existing files could score full marks on nothing more than the file having changed, with no check actually run. Overnight and automated runs act on that verdict, so unverified work could be committed as verified. A verdict now requires something observed, and a run that could not be graded says so instead of reporting success.
- Fixed: Quality checks read what the agent claimed, not what was on disk. If a file was rewritten after its first write, or changed by a shell command, the check looked at the earlier version. Repairs were being verified against the problem they had just fixed. Checks now read the file.
- Fixed: The agent was refused ports nothing was using. Two ports were treated as reserved whether or not anything of ours was listening on them, including when you are using a cloud model and the local model server cannot be running at all. The agent was told the port was taken, and spent its time hunting a process that did not exist. Ports are now only held when something is actually holding them, and if one genuinely is, the message says so plainly instead of sending you looking.
- Fixed: Ordinary data was being hidden as if it were a password. The check that keeps secrets out of the model's view was matching on shape rather than content, so long runs of ordinary text - DNA sequences, hashes, encoded data - were blanked out. On one task the agent could not see the data it had been asked to work on. Secrets are still caught, including every recognisable key format, but ordinary data comes through.
- Fixed: Failures reported nothing useful. A run that ended badly could report only "Something went wrong", which was also the sole record of it. The real cause now comes through. Related: provider error text was being sent on without being cleaned first, which could have carried an API key from a rejected request.
- Fixed: Runs could hang without producing anything. Work done before the agent starts - reading your project, preparing context - had no time limit, so a slow step could consume an entire run in silence. Those steps are now bounded and skipped if they take too long, since they are optimisations rather than requirements, and a run that produces nothing at all now ends with a reason instead of waiting to be killed.
- Fixed: Long responses were being cut off. A limit meant to stop stuck connections was also ending healthy ones, because it measured elapsed time rather than whether anything was still arriving. It now watches for actual silence, so a model that is thinking is left alone and a dead connection is still caught.
- Fixed: The agent stopped with its own plan unfinished. It would write out the steps it intended to take, complete the first, and finish. It now keeps going while its own list has open items, within limits, and a run left with most of its time unused will not finish early.
- Fixed: Cost and token usage were missing for OpenRouter. We were not asking the provider to report usage, so spend showed as nothing at all and looked like the provider simply did not supply it. Cost, token counts and cache usage now come through. Worth knowing if you set a spending limit: because that spend was not being recorded, limits on your own API keys had nothing to count and never stopped anything. They now work as written. The money was always being spent - it just was not being counted - so if you set a limit some time ago and forgot about it, this is the release where it starts taking effect.
- Fixed: The app could sit there doing nothing at the start of a run. The backend reported itself healthy the moment it could answer at all, before its database had finished opening. A request sent in that window waited with no output and no error - in the worst case for twelve minutes - and because nothing had been sent yet, none of the usual stall detection could see it. The health check now distinguishes "running" from "ready", a request will not wait more than 45 seconds before saying so, and a slow start is written to the log instead of being invisible.
- Fixed: A slow provider at startup could hold up everything. Checking the model provider on launch had no time limit, so a provider that accepted the connection and never replied stopped the app from starting at all. It now gives up after 15 seconds and starts anyway, which is what already happened when a provider was simply offline.
- Fixed: A single command could be cut off at one minute. Shell commands were allowed to ask for up to two minutes, but were stopped at one regardless. Long installs and builds died halfway, and - worse than losing the command - the agent could no longer run what it had just written, so it lost the ability to find its own mistakes.
- Fixed: The count of changed files was usually zero. It was matched against a list of tool names that did not include the one the agent actually uses to write files, so ordinary edits were never counted. Reports of what a run changed were wrong, and anything reading that number treated finished work as if nothing had happened.
- Fixed: Tokens produced were reported far too low. Only prose was counted, and everything the agent wrote through a tool - which is most of the code it produces - was invisible. Billing was never affected, but the usage figures were, and they were most wrong on exactly the runs that did the most work.
- Fixed: Runs that used up their time were never quality-checked. Verification only ran when the agent decided it was finished. A run stopped by its time limit skipped the check entirely, so the work most likely to be incomplete was the work least likely to be examined.
- Fixed: A failed check could be talked past. After one repair attempt, a failing proof - code that does not run - could no longer force another, so the run ended on the agent's explanation of the failure with most of its time still unused. Repairs are now allowed as long as there is time for them, and the check result decides, not the explanation.
- Fixed: "The file was written" was taken from the agent's word, not the disk. Three separate places decided a deliverable existed by looking at what the agent had tried to do rather than what was actually there. A write to a similarly named file, or one that never landed, counted - and counting it switched off the safeguard meant to catch precisely that.
- Fixed: A stalled model could sit there for ten minutes and nothing noticed. The agent watches for a stalled connection two ways, and both were watching the wrong thing. One reset its timer whenever any data arrived - including the "still working" pings some providers send, which are not progress. The other switched itself off permanently the moment the first word of a reply arrived. So a reply that started and then stopped, while the provider kept pinging, was invisible to both. Measured across a long test run, this quietly consumed more than three hours of working time. Both now watch for actual progress, and when one does stop a run it says what it saw instead of a bare timeout.
- Fixed: Quality checks did not run at all on nearly half of automated runs. There are several ways an agent run can end, and only one of them was checking the work. A run that hit its time limit, or ended on an error, or stopped early after writing files, finished with no verdict at all - so the report said nothing, and anything downstream deciding whether to apply the work had nothing to go on. Every ending now produces a verdict or an explicit "could not check this, and here is why". Recovered verdicts never claim success: work that could not be properly checked is marked unverified and held for review.
- Fixed: A quality check could pass work whose own tests had failed. Two separate ways: on edits, the score was a percentage of the checks that happened to run, so a thinner set of checks produced a *higher* score - "the file was touched and it still compiles" came out as full marks. On new code, individual checks were scored and then capped at the end, so two passing checks absorbed the penalty for two failing ones, and the report listed failures as blocking while the verdict passed anyway. Both are closed: a check that failed because the code is broken now blocks; a check that could not run because something was missing from the machine still doesn't count against you, but no longer earns a pass either - the run is held for review instead.
- Fixed: The agent copied your files instead of using them. Given a task pointing at files outside the project folder, it would read them, recreate them inside the project, and work on the copies - and where it could not copy something, it wrote code to invent a replacement and used that. The cause was one line in its instructions claiming it could not touch anything outside the project, which was not true, and left it no other way to finish the job. It now works on the files a task actually names, and will tell you when something is genuinely off limits rather than working around it.
- Fixed: Naming a file you wanted read could get it overwritten. When working out what a request asks for, every filename mentioned was treated as something to create. Ask it to read one file and write another, and both went on the create list - so the input could be overwritten, and the quality check then graded the file it had just been told to clobber.
- v1.0.0-beta.32.1Feature
Automatic model routing that shows its work (a fast model to read, a code model to edit, a stronger model to plan, with a one-shot retry on a stronger model when a step fails the quality checks), point Bodega at a model running on another machine, and new Qwen models (Qwen3-Coder-30B, a vision-capable Qwen3.6-35B, and the Qwen3.7-Plus cloud model), plus readable plan reviews, smoother streaming, and fixes for Ollama models that need a single system message
- Automatic model routing, with nothing hidden. The agent can now pick the right model for each step of a task on its own: a fast model for reading and searching, a code model for edits, a stronger model for planning and verification. It always shows which model handled what, and if a step fails the quality checks it retries once on a stronger model and tells you it did. Off unless you turn it on for an existing install; on by default for new ones.
- Point at a model on another machine. You can now run against a model served on another computer on your network. Air-gap mode still refuses any non-local endpoint, so a remote model is treated as an explicitly online mode.
- New Qwen models. Added Qwen3-Coder-30B (2507) and a vision-capable local Qwen3.6-35B, plus the Qwen3.7-Plus cloud model.
- Changed: Plan reviews are readable now. The "Review plan" card renders the plan as formatted text with step and file counts in the header, instead of a raw monospace dump.
- Changed: Streaming responses render more smoothly. Long answers no longer re-parse the whole message on every frame; completed sections are frozen while only the newest text updates, new words fade in as they arrive, and code stays readable while it streams. Tuned to feel good on local models.
- Changed: The app is lighter on your machine. Removed a settings write that happened every few seconds, shares one GPU query across the status strip instead of several, and narrows a set of components that were re-rendering on unrelated settings changes.
- Fixed: Some community models on Ollama returned nothing at all. Models whose chat template insists on a single leading system message rejected every request, because the app splits its system prompt in two for cache efficiency. The app now detects that rejection, merges the system prompt, retries automatically, and remembers the model needs it permanently - no setting to flip, nothing to redo after a restart. Verified against the exact model from the report. Thanks to the user whose diagnostics bundle made this a ten-minute diagnosis.
- Fixed: No more silent stalls when the assistant wants to ask you something. A clarification prompt could sit in dead air with nothing on the wire; the connection now stays visibly alive while the question waits. The assistant also no longer asks "what programming language?" when your request already says - a fully specified "write a SQL query" runs immediately.
- Fixed: Local models no longer lose the plot on a simple greeting. Saying hi in code mode was being treated as a work order: the app forced tool execution and loaded the message with task scaffolding, which made mid-size local models invent a phantom prior task. Greetings are now recognized as conversation, the extra scaffolding stays out of them, and the coaching meant for genuinely weak models no longer fires for capable mid-size ones.
- Fixed: Task lists no longer fail when the model writes them the natural way. The TODO tool rejected a properly formatted list and only accepted a quoted workaround, which could stall a run in a retry loop until it hit the iteration limit. Both forms are accepted now, for every tool.
- Fixed: A run that keeps talking instead of acting now delivers its answer. After a few nudges, the app returns what the model wrote instead of burning the whole iteration budget and ending with "reached the iteration limit."
- Fixed: The GPU memory strip actually shows up now. It was wired into a component the app never renders, so it was invisible in every mode. It now lives in the always-on status bar in both chat and code mode. On Windows it also reads free memory directly from the NVIDIA driver tools when the system query does not report it, and a machine whose GPU stats are unreadable shows a muted indicator instead of nothing.
- Fixed: Local models that write tool calls in their own invented syntax are understood anyway. Mid-size models produce a different homemade wrapper around tool calls nearly every run; the app now recovers the call from any of the shapes seen in live testing, and when a shape is truly unreadable it shows the model the exact expected format and lets it retry instead of printing the raw markup as the answer.
- Fixed: Questions about what the assistant remembers now actually check memory. "What do you know about me" and similar questions were routed down a fast path with no tool access, so the model either guessed or emitted a memory lookup nothing executed. Those questions now run where the memory tool works.
- Fixed: The Smart Auto toggle now lives in one place. The old copy in the experimental tab (which could silently fight with the new Routing section over the same setting, including on unrelated saves) is gone.
- Fixed: The sidechat "inject into main" dialog is readable and clickable. It now renders above the whole app with a blurred backdrop instead of inside the sidebar where panels bled through it, and a small notice above the composer shows that a block is queued for your next message.
- Fixed: A finished response can no longer be misread as cut off. The last piece of a streamed response arriving without a trailing newline was dropped, which could trigger a needless retry or a false "truncated" notice.
- Fixed: Model routing display fixes: the final step of a run (including a quality-check escalation) now appears in the routing strip, concurrent runs no longer mix their steps together, and switching sessions clears the previous session's context-fill readout immediately.
- Fixed: Assorted editor fixes: a diff-review disposal race that logged errors during streaming edits, an undo that could close the review while the file still held the change (it now reports the failure instead), and several per-token re-subscriptions that wasted work during streaming.
- Fixed: The GPU memory strip no longer disappears on a slow or briefly failed reading. On some machines the live GPU strip in the status bar could vanish entirely instead of showing its data. It now stays visible: it shows a brief "GPU" indicator while the first reading loads, keeps showing the last good reading through a momentary hiccup, and only hides when the machine genuinely has no readable GPU.
- Fixed: A stored cloud key can no longer be sent to an unexpected address. When testing a provider connection without re-entering the key, the app now checks that the destination is the provider's own host before attaching your saved key, closing a path where a crafted address could receive it. Testing a local provider with a freshly typed key is unaffected.
- Fixed: Consistent wording and controls in the side chat. The "add to main conversation" action now uses one consistent label, and the per-project offline switch now matches every other switch in settings.
- v1.0.0-beta.32Feature
Editor code navigation, full-text search across past conversations, verification badges in the gutter, a live GPU load view, per-project air-gap, a read-only side chat while you code, overnight batch runs, Agent Skills import, and new models (Kimi K3, the GPT-5.6 family, Qwen3.7 Max)
- Code navigation in the editor. Go to definition, hover for types and docs, find all references, and parameter hints while typing a call now work in the editor for TypeScript, JavaScript, and Python. The language server for a file's language starts the first time you use it and unloads when idle, so it does not hold memory while you are not navigating.
- Search your past conversations by content. The search box in both Chat and Code mode now searches the full text of your previous messages, not just titles, and includes archived sessions. Results show a snippet with the match.
- Verification badges in the editor gutter. After the agent proposes changes, each changed file shows a pass, warning, or fail badge in the gutter from the quality checks, with per-line notes when code review is turned on. Badges appear on the proposed diff before you keep or discard it.
- A live view of what is loaded on your GPU. A status strip shows the resident model, free memory, and whether a second model would fit, so you can see the headroom before loading one.
- Recent-projects welcome screen and per-project settings. A richer project picker with recent projects, pinning, search, and the current branch inline. Each project can set its own default model. Opening a folder now asks whether to trust it before applying that folder's saved configuration, which closes a hole where a repository's committed config could apply automatically.
- Per-project air-gap. A project can be marked to stay offline regardless of the global setting. Its tool calls, shell, Git and GitHub automation, and cloud model access are held local. A project can tighten to offline but can never loosen a globally offline setting.
- Side conversation while you code. In Code mode you can open a side chat that reads your current session read-only and runs a model you choose, for a quick second thread without disturbing the main run. One result can be handed back into your main conversation.
- Run a batch of tasks overnight. Queue several tasks to run on your own GPU while you are away. Each runs verified in its own isolated copy of the project, and you get one scorecard summary in the morning with per-task apply and discard.
- Recovery help when a run gets stuck. When a run stalls, crashes, or hangs, a small local model can diagnose why and suggest how to unstick it, and it works even with no network. Off by default.
- Bring agents that use the open Agent Skills format. Import a skill package that uses the shared SKILL.md format. Imported skills are body-only by default, do not auto-run on their own, and any tool or command permissions they carry are shown for you to approve before they take effect.
- Ask a local model for a second opinion mid-run (consult_mixture) and delegate a bounded subtask to a local sub-agent (delegate_subtask). The sub-agent works in an isolated copy of the project and its changes are quality checked before they can touch your files. Both are off by default and can be turned on in settings.
- Faster type-checking (experimental). An optional setting swaps the TypeScript check used during verification for a faster native compiler. Off by default.
- New models in the picker. Kimi K3 (1M context), the GPT-5.6 family (Sol, Terra, and Luna), and Qwen3.7 Max are now available for the providers that serve them, including OpenRouter.
- A dedicated QEL settings tab. The quality-check controls moved out of Experimental into their own tab, with clear toggles for execution proofs, modification proofs, the semantic and answer-grounding judges, post-loop code review, contract-aware review, and the experimental type-check gate.
- Changed: Spend caps now cover every place a cloud call can happen. Background runs, overnight batches, Git assist, and autocomplete all count toward your spend cap and appear in the cost view, closing gaps where some cloud usage was not being recorded.
- Changed: More accurate GPU fit checks for parallel runs. The limit on how many sessions can run at once now measures free memory rather than total, and understands that a shared local server uses one set of weights across slots, so it stops over-committing memory.
- Changed: The side conversation now lives in Code mode, where a second thread while you work is useful, and its button sits next to the Code panel toggle.
- Fixed: Local Qwen, DeepSeek-R1, and QwQ models no longer get stuck repeating themselves. These model families document that low-temperature decoding causes repetition loops, but unlisted local tags were running at a low fallback temperature. Every affected family now uses its vendor's recommended sampling (Qwen3.x and Qwen2.5 at 0.7, DeepSeek-R1 and QwQ at 0.6, Nemotron Nano at 0.6, Gemma and gpt-oss at 1.0).
- Fixed: Go to definition no longer opens a duplicate tab when the target is a file you already have open (Windows).
- Fixed: Empty chat view fills the window instead of leaving blank space below the composer.
- Fixed: Diagnostics settle before they are read, so a language server that reports progressively no longer briefly shows a stale error after a clean edit.
- Fixed: The side conversation no longer crashes when opened on a session that has no side conversations yet, and its buttons now match the rest of the app.
- Fixed: The API server meters and caps cloud spend on its streaming and agentic endpoints. Previously a client using either of those could run cloud usage that was not counted toward your spend cap or shown in the cost view.
- Fixed: Web fetch blocks a wider set of private and loopback addresses, closing gaps that could reach local-only services.
- Fixed: File edits requested through an alternate operation name are gated behind approval like any other write.
- Fixed: A side conversation stays strictly read-only and can no longer trigger project shell commands through verification.
- Fixed: Editor language-server messages with non-ASCII characters (accents, emoji, CJK) no longer corrupt the language-server channel.
- Fixed: Applying a parallel run keeps uncommitted work in its isolated copy and no longer sweeps in unrelated local changes.
- Fixed: Local model context sizing is safer when a model shares GPU slots, avoiding an out-of-memory loop on load.
- Fixed: Side conversation replies no longer show leftover tool text. A smaller model could leak a fragment of raw tool syntax at the end of a reply; it is now cleaned before display.
- Fixed: The side conversation now sees your open project. It answered "no folder is attached" even with a project open because the open project's path was never handed to it. Its bubbles also now match Chat mode's styling.
- Fixed: Air-gap now also blocks embeddings to a non-local Ollama address. If your Ollama URL points at another machine, air-gap mode refuses to send document text there (layer 17).
- Fixed: Cloud-routed inline fixes in the editor now count toward your spend cap and appear in the cost view.
- Fixed: More local model families now use their vendor's recommended sampling. Llama 3.1 through 4 (0.6), Devstral (0.15), and GLM-Z1 (0.6), each confirmed against the vendor's own published configuration.
- Fixed: A folder of smaller fixes from the hardening audit: memory recovery no longer drops user scoping or embeddings, base URLs with embedded credentials are rejected on save, a far-future scheduled batch fires at the right time, a deferred batch item now actually waits out its backoff, mixture reference drafts cannot forge section delimiters, failed delegations no longer consume the retry budget, quality-report text is credential-scrubbed, and worktree cleanup finds projects whose names contain special characters.
- Fixed: Startup no longer misreports local model context limits. Model context was computed before GPU memory detection finished, logging false warnings and briefly clamping context sizes on capable hardware.
- v1.0.0-beta.31.10.5Improvement
Smaller models now apply code fixes instead of just describing them, cloud-hosted agent runs are no longer cut short, run and cost summaries name the model that actually served the turn, and local models start leaner
- Changed: Local models start leaner. A local model now starts with a smaller core set of tools and loads the rest on demand, rather than carrying every tool's full description from the first message. This frees up context on small models without changing what the model can ultimately do.
- Fixed: Smaller models now apply code fixes instead of just describing them. On a bug-fix or edit task, a smaller model would often write out a correct-looking explanation of the change but never actually edit the file, leaving you with nothing. Several causes are fixed together: the built-in Debug, Generate, Test, Refactor, and Perf skills were accidentally hiding the precise-edit tool from the model; edits are now matched more forgivingly so a minor whitespace difference in the target text no longer fails the edit outright; and when a run finishes with an explanation but no edit, the agent is prompted once to apply the change.
- Fixed: Agent runs on a cloud-hosted model are no longer cut short. The five-minute safety limit was tuned for fast local models. A capable model served over a cloud provider is slower per step because of network round-trips, and long runs were being stopped mid-task. Cloud-served runs now get the longer budget, and the time the agent spends waiting out a provider's rate limit no longer counts against that budget.
- Fixed: When an edit can't be placed, the error now shows the nearest matching lines in the file, so it's clear what to target instead of a generic "not found".
- Fixed: Run and cost summaries now name the model that actually served the turn. A run on one model could be labeled with a different provider default, which also mis-priced the per-message cost estimate.
- Fixed: More accurate task understanding and context handling. Task requirements are now read from the project's own files (language and framework) instead of being guessed from the request wording, which fixes occasional misclassification. Several context-size calculations were corrected so long runs are measured and trimmed against the real window, and a reported-token quirk that made long runs look like they had overflowed (when they had not) is resolved.
- v1.0.0-beta.31.10.4Feature
No more phantom terminal windows when an MCP server fails on Windows, settings panels stop shoving themselves out of view, and an experimental deferred-tool-loading setting trims local-model context
- Experimental: deferred tool loading for local models. A new setting under Agent (agent.deferred_tools, off by default) sends the model a smaller core set of tools up front and lets it pull in the rest on demand, which trims the tokens spent on tool definitions every turn. It's off by default while we measure it, applies only to local models when set to "local only", and never changes which tools are allowed or how approvals work. If you don't turn it on, nothing changes.
- Fixed: Terminal windows no longer pop up when an MCP server fails to start. On Windows, a configured MCP server that couldn't start (for example a server whose runtime isn't installed) caused a visible console window to flash open every few seconds, forever. Two fixes: MCP server processes now start hidden, and a server that keeps failing now backs off and stops after five attempts, showing a clear "failed" status in Settings with the last error and a Connect button to retry manually.
- Fixed: Clicking a settings control no longer shoves the panel out of view. Clicking an option in sections like FIM or Codebase Embeddings could shift the whole settings panel upward and leave a permanent block of empty space at the bottom, in both Chat and Code mode. The browser was scrolling a container that users can't scroll back; that container type can no longer be scrolled at all. Dropdown pickers in Settings were also moved out of the scrolling area so an open picker can't distort the panel's height.
- Fixed: The diagnostics bundle now labels MCP servers by what they actually are (stdio, with or without network access) instead of a misleading "network" tag, and shows a clear "failed (gave up)" status.
- v1.0.0-beta.31.10.3Feature
Self-updating model catalog plus a July model refresh (Grok 4.5, GLM-5.2, Qwen3-VL 32B, MiniCPM-V 4.5), a redesigned model browser with GPU-fit checks, a vision companion picker, and grounded-answer and second-opinion review checks
- The model catalog now updates on its own, no app update needed to get new models. Bodega can pull a refreshed catalog (model list, hardware-fit info, and downloadable GGUF entries) from a single Bodega-hosted file. This is on by default and is a plain model list only: no telemetry, one fixed URL, and it never runs in air-gap mode. There's a clear toggle in Settings under Models to turn it off. When it's off, the Discover screens show a small note that new models won't appear until you turn it back on or install the next app update. You can still refresh manually with the button in Models.
- July 2026 model refresh. Added Grok 4.5 and GLM-5.2 to the cloud model list (with pricing), corrected the Kimi context length, and added two new local vision models, Qwen3-VL 32B and MiniCPM-V 4.5, with their image projector files so they download and run out of the box.
- A cleaner way to browse models. The Discover screens now group models by family (Qwen, Llama, Gemma, Mistral, DeepSeek, and so on) in collapsible sections, and each model card shows capability tags (tools, vision, thinking, FIM, draft, MoE) so you can see what a model does at a glance. Cards now also tell you whether a model fits your GPU, and which quantization fits best, before you start the download rather than after.
- Vision companion picker. You can now pick which vision model pairs with your text model for image questions. The picker lists your installed vision-capable models with their engine, VRAM cost, and how the swap works (Ollama swaps internally, llama.cpp hot-swaps the server process), and remembers your choice as the default pairing.
- Manage your background worktrees. The Fleet panel now shows worktrees queued for automatic cleanup, lets you confirm or cancel each one, and warns you when they start taking up significant disk space. A new "Manage worktrees" view lists per-session storage and lets you reclaim disk on demand.
- Answers to questions about your code now get a groundedness check. When Bodega answers a question after reading your files, it quietly checks that the answer is actually backed by what it read, flagging a reply that cites a file it never opened, or that's too thin to trust. It's advisory only: you get a note, never a blocked answer.
- Modification tasks can use your project's own lint and tests as proof. When Bodega changes or fixes existing code, it can run your project's own lint and test scripts once at the end as evidence the change holds up. A clean pass strengthens the result, a real failure is surfaced as an advisory note rather than silently ignored. On by default, and does nothing when there's no lint or test script to run.
- Optional second-opinion review of changes. You can turn on a review that asks a second model to check a change against what the task actually asked for, as an extra set of eyes on the diff. It's advisory only and off by default.
- Agent-driven automation runs now show up in run history alongside scheduled loop runs, so a run started by an agent is no longer invisible after it finishes.
- Changed: Reasoning effort controls now match what each model actually supports. The effort control (off through max) now appears for exactly the models that honor it, with the right levels per model, whether that model is your primary or one you picked for a single panel. DeepSeek now maps to its real off/high/max tiers, Gemini 3.x uses its new thinking levels instead of the retired numeric budget, and turning reasoning off on an Ollama model now actually turns it off. Models that don't support graded effort show a simple thinking on/off toggle instead of levels that did nothing.
- Changed: The Model Roles settings were rebuilt. Each role is now a proper model picker card that shows the provider, what an empty role falls back to, and a one-click reset, with a real save button that knows when you have unsaved changes.
- Changed: Status colors are readable in light themes. Success, warning, error, and info text and banners were re-tuned so they meet contrast guidelines across all four themes, fixing the green-on-green and similar washed-out cases in the light themes. A test now guards these color pairs so they can't regress.
- Changed: Onboarding was refreshed to match the current look. The first-run flow now uses the current color tokens throughout, so the light themes render correctly, and some dead onboarding code was removed.
- Changed: Verification messages now tell you what's blocking and what's just advice. Verification results clearly separate blocking issues from advisory notes, and long diagnostic output is capped so a report stays readable instead of flooding the panel.
- Changed: Drift Radar is now a single surface. The separate Drift panel was folded into the Debug panel's Drift tab, and when an oracle has legitimately changed you now get a one-click Retire action to clear the noise.
- Changed: The diagnostics bundle now captures more. Export Diagnostics now includes model catalog state, the vision pairing, worktree cleanup and disk state, and a summary of recent verification results, and it now catches uncaught errors and promise rejections that previously slipped past the report.
- Fixed: Local models on llama.cpp could fail to respond. Some models (Qwen3.5 among them) use a strict chat template that rejected how Bodega packaged the prompt, so every message came back as a failure. The prompt is now packaged in a form those templates accept, without changing the caching behavior that keeps local models fast.
- Fixed: Switching your primary provider could leave the app in a split state. After changing your primary model provider, a chat could still be routed to the old provider (for example a local GGUF sent to Ollama, which then reported the model as missing), a provider card could show "offline" while its models were clearly connected, and the agent panel header could keep showing the previous model after a swap. Provider state is now reconciled in one place so these stay in sync, and a downloaded GGUF is always recognized as a local model.
- Fixed: Chat sends are more reliable. A message retried after a dropped connection no longer creates a duplicate, and a queued follow-up message can no longer be silently dropped when you cancel or when the app restarts mid-run.
- Fixed: The model picker no longer lists other providers' models. A single-vendor cloud provider (for example Qwen) could surface unrelated models returned by the provider's API. Those are now filtered out.
- Fixed: Local model context sizing is now regression-proofed. The context size a model card shows now matches what the inspector shows, and the default context window is derived from your card's total VRAM rather than whatever happened to be free at the moment, with tests so it can't quietly break again.
- v1.0.0-beta.31.10.2Feature
Qwen3-Coder-Next 80B (sharded GGUF), SmolLM3-3B, and Mistral Small 3.2 24B land in the catalog, plus GGUF download, provider-enable, and local-context fixes
- Qwen3-Coder-Next 80B is now downloadable. Qwen's flagship open code model ships as a multi-file (sharded) GGUF, which the downloader couldn't handle before. Bodega now fetches every shard, resumes each one independently if the download drops, and loads them as a single model - and removing the model deletes all of its shards, not just the first. Q4_K_M is about 45 GB across four files (needs a 48GB+ VRAM card).
- Two new models in the catalog: SmolLM3-3B, a compact reasoning + tool model that runs on low-VRAM machines, and Mistral Small 3.2 24B, an updated build with better instruction-following than 3.1. Both were verified against HuggingFace so their downloads resolve.
- Fixed: GGUF downloads no longer fail with a false "size mismatch." A complete, valid download could be rejected because it was checked against a size estimated from the catalog's rounded GB figure rather than the real file. Downloads are now validated against the size the server actually reports, so anything fully received finalizes. This is what was blocking the Qwen3.6 27B download.
- Fixed: Cloud providers you set up now show up in the model picker. Pasting an API key is meant to switch its provider on, but when the provider's entry didn't exist yet - common right after a settings reset - the key saved without enabling it, so providers like Anthropic, OpenRouter, DeepSeek, and Qwen stayed hidden even though their keys were stored. A saved key now reliably enables its provider.
- Fixed: Local model context is no longer capped far too low. A model's default context window was sized against however much VRAM happened to be free at the moment it loaded. With a browser or other apps open, that could shrink a 27B model on a 32 GB card to roughly 8K tokens and leave it stuck there for the session. Context is now sized against the card's total VRAM, and the value on the model card matches what the running model actually uses.
- Fixed: The moondream2 vision model downloads again. Its GGUF files moved to a new HuggingFace repository; the catalog now points at the right one.
- v1.0.0-beta.31.10.1Fix
Hotfix: the Linux app runs on older distributions again (Ubuntu 22.04, Debian, RHEL 8/9), and orientation questions no longer end as a bare tool work-log
- Fixed: The Linux app now runs on mainstream distributions. The bundled SQLite native module required GLIBC 2.38, so the Linux AppImage crashed on startup on every Linux older than Ubuntu 24.04 - Ubuntu 22.04 LTS, Debian 11/12, RHEL 8/9, Amazon Linux. The whole app was affected (every launch loads the database first). The Linux build now runs on an older-GLIBC runner (2.35) and compiles the backend SQLite from source, with a build-time guard that fails the release if it still needs a too-new GLIBC. Windows and macOS were never affected.
- Fixed: Questions can no longer end as a tool work-log. Asking an orientation question ("what does this project do?") could end with the model going silent after its tool calls - and the reply became "Done! Here's what I did:" plus a list of tool names, answering nothing. Every retry nudge was gated to command-style tasks, so question turns had no rescue. Now any turn that ends with tool activity but no text gets one final tools-off model call to answer from what was gathered (the same rescue the iteration-cap exit already had), and the last-resort static summary now leads with actual findings - the codebase-map answer rides along, file reads collapse into one named list, and repeated tool names dedupe.
- v1.0.0-beta.31.10Feature
HuggingFace model deep links: open a GGUF in Bodega straight from Hugging Face via the bodega:// protocol, plus cold-start and packaged-build protocol-registration fixes
- bodega://models/huggingface/{owner}/{repo} deep links. The bodega:// protocol handler routes its first real destination: a HuggingFace model link opens Settings → Models → Discover with the repo ready to download - llama.cpp primary auto-searches the GGUF browser for it (the disclosure pops open); Ollama primary prefills the custom pull input with the hf.co/ form; air-gapped machines get a clear toast instead of a silent no-op. This is the "Use this model" flow for the HuggingFace Local Apps listing. Deep-link payloads are strictly validated in the main process before anything reaches the renderer (raw-pathname matching, bounded length, charset-locked), and unknown query params are tolerated so future hints (e.g. ?file=) won't break older builds. The parser is unit-tested against injection shapes.
- Fixed: Cold-start deep links no longer vanish on Windows/Linux. A bodega:// click with the app closed launched it to nothing: the initial-launch argv scan only extracted file paths, so protocol URLs were handled only when a copy was already running (second-instance). The launch argv is now scanned for protocol URLs too, and the routed action queues until the renderer has finished loading - same pattern the file-association path already used.
- Fixed: Packaged macOS/Linux builds never registered the bodega:// protocol. The electron-builder config lacked the protocols declaration, so packaged macOS builds had no CFBundleURLTypes (runtime registration only covers dev-mode) and Linux desktop entries had no x-scheme-handler MimeType - deep links errored at the OS level before the app ever saw them. Declared; Windows was already covered by runtime registration.
- v1.0.0-beta.31.9.1Feature
Local model auto-selection and context-window fixes, QEL correctness on removals, CRLF-safe edits, and ACP auth-method advertising
- ACP initialize advertises authMethods. The agentic-coding-protocol handshake omitted the field entirely; Bodega is local-first (no account, no sign-in), so it now emits an explicit empty authMethods: [] - a complete, spec-correct response for a strict ACP client or the agent registry validator, which makes the terminal surface registry-ready.
- Fixed: The gpt-oss phantom model is gone. OllamaProvider booted with a hardcoded gpt-oss placeholder default; any code path that read the default before a healer replaced it reported - or requested - a model the user never installed (agentic run summaries mislabeled gpt-oss while another model actually served the tokens). The placeholder is removed: the default is empty until lazily resolved from the *installed* model list via the embedder-aware picker (never an embedding model, never a name that isn't present), and the "no model selected" guidance stays for a machine with nothing installed.
- Fixed: Local model auto-selection never lands on an embedder. The reconfigure healer took the alphabetically-first installed model, so a machine whose first model was an embedder (e.g. qwen3-embedding:4b) got an un-chattable default and every request failed "does not support chat." It now uses the same embedder-aware curated picker.
- Fixed: File edits survive CRLF checkouts. str_replace matched the old string byte-for-byte, but a model cannot see carriage returns in the content it reads, so on a CRLF working tree (Windows / git autocrlf) every edit failed "old_string not found" until the run gave up. Matching is now line-ending tolerant and preserves the file's own EOL style in the replacement.
- Fixed: QEL no longer fails correct removals. A "remove X" / "delete X" task extracted the named construct and then verified it was still *present* - demanding the continued existence of the thing the task asked to eliminate, an unsatisfiable check that thrashed the repair loop and mislabeled correct work as failed. Verification now derives the expectation from the verb (add/change → present, remove/delete → absent), and rename X to Y verifies the new name instead of the old one.
- Fixed: Big local models get their real context window. The VRAM-safe window estimator sized models against an *instantaneous free-VRAM snapshot* - so a 27B sized while an 8B was still resident got an 8,356-token window on a 32GB card (the correct post-eviction answer is ~19K), the bad-moment probe was memoized for the whole session, and a model sized while itself resident had its weights subtracted twice. The estimator now sizes for the post-load world (total VRAM minus a fixed reserve - Ollama evicts the resident model on load); instantaneous free VRAM still drives the can-these-coexist check, where it belongs.
- Fixed: A degraded cloud model list can no longer override your model choice. When a rate-limited provider returned a partial /models response, the auto-default healer treated the user's explicitly-chosen model as "not available" and silently replaced it with a curated pick (a rate-limited Kimi session was flipped to gpt-4o). Not-in-list healing now applies only to local providers, whose lists are complete enumerations; on cloud presets a user-set model always wins. Empty-response summaries also now carry real results for diagnostics and test runs instead of "Used get_diagnostics".
- v1.0.0-beta.31.9Feature
CLI docs in the app, shared-database concurrency hardening for running two Bodega apps at once, safer background commands and ports, and a tool-deny-list security fix
- The docs hub covers the CLI. A new "Bodega One Code (CLI)" section in the in-app docs: what the terminal surface is, install one-liners for all three platforms, first-run setup, the command table, headless/CI behavior, and how the CLI shares this app's providers, settings, and sessions through the family data dir.
- Security: --deny-tools can no longer be evaded by tool-name aliases. The per-request tool deny list matched the exact name the model emitted, but the executor resolves aliases before running a tool (bash/run/git/terminal → shell, write_file/create_file → file_system, edit_file → str_replace). So a denied shell was bypassed by emitting bash, and a denied file_system by emitting write_file. The deny check now canonicalizes both the incoming name and each deny-list entry. This is a shared-backend fix: it protects every surface that runs the agentic loop - the desktop app, the bodega CLI (--deny-tools), and the headless agent. Found via live battle-testing.
- Fixed: Voice transcription keeps the uploaded audio's real format. The speech-to-text route ignored the upload's declared Content-Type and stamped every temp file .webm, so an OGG voice note (how Telegram and Discord voice messages arrive via the bodega-agent, gap A3b) reached extension-sniffing STT engines mislabeled. The route now reads the part's Content-Type, writes a matching temp extension, and passes the MIME through to the STT service. The desktop app's own recorder (webm, no declared part type) behaves exactly as before.
- Fixed: The shared database is now safe when two Bodega apps run at once (S1 follow-through - four concurrency fixes). The family-shared data dir means the IDE backend and the Telegram-agent backend can open the *same* bodega.db as separate OS processes, which surfaced four check-then-act races (all found by battle-testing, each proven with a true two-process stress test and pinned by regression tests): 1. *Lost writes* - no busy_timeout was set, so a second concurrent writer's write was silently dropped (~0.5% under contention). Now busy_timeout=5000, set as the FIRST pragma: 0 losses in 1800 contended writes. 2. *Stranded first-session data* - the migration race-loser did a single done-marker check and fell back to the legacy dir, stranding its writes there. It now polls (bounded) for the winner, matching the Go CLI. 3. *Clobbered encryption key* - two fresh backends could both generate .bodega-cipher-key, the loser overwriting the winner's key and making its already-encrypted secrets permanently undecryptable (8/8 races corrupted). Key creation is now atomic (exclusive-create; a race loser adopts the winner's key): 0/8. 4. *Boot crash on concurrent schema init* - two backends booting together both ran the check-then-ALTER migrations; the second crashed with "duplicate column name" (6/6), and the fresh-DB WAL conversion could also fail with an immediate SQLITE_BUSY (~1 in 6). The entire open + schema sequence is now serialised across processes by a lockfile (stale-TTL reclaimed, bounded wait, fail-open so a lock problem can never block boot): 8/8 clean two-process first boots.
- Fixed: Family-shared canonical data dir (gap S1, desktop half). The desktop IDE, CLI, and agent historically resolved *three different* data dirs, so a provider key / MCP server / session set in one was invisible to the others. The IDE now resolves the neutral canonical location shared with the CLI + agent (%LOCALAPPDATA%\BodegaOne on Windows, ~/Library/Application Support/BodegaOne on macOS, ${XDG_DATA_HOME:-~/.local/share}/bodegaone on Linux), wired through every main-process anchor (backend spawn env, diagnostics resolver, worktree base, air-gap.lock). Migration is strictly safe - copy-not-move (a legacy dir is never touched), auto-migrating only the unambiguous single-legacy-source case; when multiple populated legacy dirs exist it keeps using the IDE's own userData dir (zero regression, the 48MB store stays put) and drops a .consolidation-pending.json marker for a deliberate consolidation step. A hot source (an app actively writing its DB) defers migration. BODEGA_USER_DATA_DIR still overrides everything (QA scripts / demo-fresh-install). Behaviourally identical to the CLI's Go implementation; 6 unit tests mirror the CLI's safety suite. NOTE: needs an Electron live-smoke before a main release - the migration logic is unit-verified but the full app-boot integration is not yet live-tested.
- Fixed: Background commands can no longer leave orphaned processes behind. A dev server started in the background could survive closing the app (its helper process escaped the shutdown cleanup) and keep a port occupied - which could then block the local model server from starting. Shutdown now verifies the whole process tree is gone.
- Fixed: Background commands can't take over Bodega's own ports. A backgrounded command that tries to serve on a port Bodega itself uses (backend, local model server, embeddings) is refused up front with a suggestion to pick another port.
- Fixed: A port conflict is reported as a port conflict. When the local model server can't start because its port is taken, the error now says so - instead of the misleading "context window too high" message.
- v1.0.0-beta.31.8.1Fix
Hotfix: the in-app preview no longer opens Bodega's own local model server instead of your project
- Fixed: "Open the preview" no longer opens Bodega's own model server. Asking the assistant to open the preview could land on the local model server's built-in chat page (a "Hello there" screen on localhost:8080) instead of the project, because the dev-server port scan counted Bodega's own servers as dev servers.
- Fixed: The dev-server scan skips Bodega's own ports. Auto-detection no longer considers the ports Bodega itself listens on (the backend, the local model server, and the embeddings server), so it can only ever find a real dev server or fall back to serving the project folder.
- Fixed: Asking to preview one of Bodega's own addresses is corrected, not obeyed. If the assistant is told (or guesses) an address that belongs to Bodega's own servers, the preview opens the actual project instead and says why.
- Fixed: Preview navigation to Bodega's own servers is blocked with guidance. Direct navigation to one of those addresses now returns a clear pointer to the correct way to open the project preview instead of showing the wrong page.
- v1.0.0-beta.31.8Feature
Optional quality gate for Bodega Mixture, faster startup, and air-gap plus approval hardening
- Optional quality gate for Mixture reference drafts. With Bodega Mixture on, a weak or off-topic reference draft could still be handed to the aggregator and drag down the final answer. A new opt-in setting (mixture.qel_gate) screens each reference draft before synthesis and drops the ones that fail, so the aggregator only works from drafts worth keeping. Off by default.
- Changed: Faster startup and snappier sessions. Project file listings are now cached instead of re-scanned on every request, session messages load through a new database index, non-essential startup checks are deferred until after the app is up, and the agentic loop does less redundant work per step.
- Changed: External clients can now wait for the full toolset. The backend used for editor integrations signals a second "ready" once MCP servers and skills have finished loading, so an external client can tell when the complete toolset is available instead of connecting into a partial one.
- Security: Air-gap mode blocks more ways to reach the network from the shell. Additional download and scripting tools that can fetch remote content (including certutil, bitsadmin, perl, ruby, and php) are now blocked while air-gapped, and the check is resistant to quoting tricks that previously slipped past it.
- Security: Hooks that rewrite a command can no longer bypass approval. If a configured hook rewrites a tool call into something dangerous, the rewritten command is re-checked with a fresh security context and always requires your approval; web fetches and searches also always prompt in Ask mode.
- Security: Concurrent streams on one session are properly serialized. Two responses can no longer run against the same session at once, and a session that is actively streaming can no longer be deleted out from under itself.
- Fixed: Cloud Boost reasoning settings no longer depend on the local base model. The remaining places where a boosted cloud run could inherit settings from the local base model (such as reasoning behavior) now consistently use the cloud model that is actually running.
- Fixed: Building a project from scratch no longer triggers helper skills meant for existing code. A "build X" request in an empty folder could auto-activate a skill written for modifying an existing codebase, sending the model down the wrong path. Skills now check the shape of the task before activating.
- Fixed: Verification reads routes and function names more accurately. The contract extractor that checks a finished task against your request no longer mistakes HTTP verbs for function names or trips on trailing punctuation in route paths, so verification scores fewer false misses.
- v1.0.0-beta.31.7Feature
Claude Sonnet 5 (1M-token context) and Claude Fable 5 join the model list, faster repeated turns on local models, and Cloud Boost fixes for Claude models
- Claude Sonnet 5 and Claude Fable 5. Sonnet 5 is a new Anthropic flagship with a 1M-token context window. Fable 5 is back after being temporarily withdrawn from general availability; both are available for Anthropic, OpenRouter, and Cloud Boost.
- Faster repeated turns on local models. llama.cpp and Ollama now reuse the prompt cache and keep the model warm between turns, so follow-up messages in a conversation start responding sooner.
- Fixed: Cloud Boost no longer stalls on long tasks with Claude models. Running a Claude model (Sonnet 5, Fable 5, or Opus) through Cloud Boost while a local model was the base could make it stall and return nothing on longer requests, because the boosted request was mis-handled as if it were a local model. Cloud Boost now treats these as cloud models, so they use native thinking and respond normally.
- Fixed: Capable models keep their full step budget on long tasks. A few recoverable tool errors part-way through a long task could downgrade a strong model to a short step limit for the rest of the session; strong models now keep their full budget (the safety limit still applies to smaller local models).
- Fixed: A from-scratch build no longer runs to the step limit after it is done. On a "build X" request, a code-refactoring helper could switch on by mistake and push the model to keep writing and running extra verification files it had nowhere valid to save, using up the remaining steps after the work was already finished. Build requests no longer trigger that helper.
- Fixed: "Open the preview" no longer errors with a text-only local model. Asking a local model without vision support to screenshot the preview could fail with a server error, and the preview could open the wrong page. Screenshots now fall back gracefully for text-only models (the model is pointed to the captured image instead), and the assistant is steered to open the correct preview URL.
- Fixed: Switching local models is more reliable. Starting, stopping, swapping, and recovering the local model server are now serialized, so rapid model switches (including vision hand-offs) no longer race or crash.
- Fixed: The app still starts if its license file can't be read. An unreadable or undecryptable license now falls back to unlicensed instead of stopping the app from booting.
- Fixed: The Mixture progress card always finishes. After a Mixture turn ended, the progress card could keep spinning; it now resolves to a final state.
- v1.0.0-beta.31.6Feature
Bodega Mixture (Mixture-of-Agents): run several models in parallel and synthesize one answer, plus preview static sites with no dev server
- Bodega Mixture (Mixture-of-Agents). A new optional engine that runs several "reference" models in parallel on your turn, then has one "aggregator" model synthesize the single response you see. Enable it in Settings under Models, then pick "Mixture" from the model picker. Reference models run with no tools and the conversation text only; the aggregator owns all tools and writes the reply. Local reference models are near-free, so an all-local mixture costs about one cloud call, and an optional QEL quality gate can verify the synthesized output. Off by default; all mixture.* settings are global-only. Honors air-gap (cloud references are dropped when offline) and falls back to a normal single-model turn when fewer than two references are available.
- Preview static sites and games without a dev server. The in-app Preview could only attach to a running dev server like Vite or Next, so a plain project (a bare index.html with script files and no build step, like a generated HTML5 game) had no way to preview and just told you to start a dev server. Now, when no dev server is running and the project has an index.html at its root, Bodega serves the folder locally and opens it in the Preview panel. Ask the agent to "open the preview", or use the "Preview this folder" button in the Preview panel's empty state. Served on loopback only (air-gap safe), with dotfiles withheld.
- Fixed: Long Cloud Boost builds no longer stop early at a five-minute mark. A fixed five-minute time limit on the agentic loop could cut off a capable cloud model (such as Opus via Cloud Boost) partway through a long build, after which a "continue" was mis-read as a fresh, simple task and capped at twelve steps. The loop's time budget now scales with the model's capability tier (longer for large and boosted or cloud models), and a "continue" on an in-progress task stays in the full agentic lane with the full step budget.
- Fixed: Local models no longer get stuck at a 4,096-token window. A local GGUF with no embedded context-length metadata had its window silently clamped to 4,096 even on a high-VRAM card, and the output-token reservation (sized from a separate, larger estimate) could then exceed that window, so every message, even a one-word "yo", was rejected as "too long". Bodega now sizes an unknown-metadata model's window from available VRAM instead of collapsing to 4,096, keeps a custom --ctx-size in sync between the server and the token budget, and never lets the output reservation exceed the window. Restart the app to pick up the corrected window.
- Fixed: Mixture reference models can now be added from the Settings UI. The Mixture editor saved the reference-model list in a format the backend rejected, so clicking "Add" in Settings silently did nothing and an already-configured list never rendered its rows. Adding, removing, and reading reference models now works (the picker dropdown also groups by provider, shows your local Ollama and llama.cpp models, and uses clean model names).
- v1.0.0-beta.31.5Improvement
Security and reliability rollup: approval-gate and air-gap hardening, Cloud Boost stability, and model-management fixes
- Security: MCP tools now go through the approval prompt in Ask and Plan modes. A tool from a connected MCP server could previously run without a per-tool prompt, even one that changes external state (opening a pull request, sending a message). They now ask first, the same as the built-in write tools.
- Security: Air-gap mode now also covers voice transcription, inline code completion, and the goal reviewer. Each of these could reach a remote endpoint when pointed at a non-local address; with air-gap on they now refuse anything that isn't local, like the chat and embedding paths already did.
- Security: Web fetch is hardened against DNS rebinding. It now validates every address a hostname resolves to and refuses when it can't confirm the target is public, instead of trusting a single lookup.
- Security: The local API and WebSocket reject requests whose Host header isn't the loopback address, closing a DNS-rebinding path that could let a web page in your browser reach the local server.
- Security: Prompts supplied by a shared project config are sanitized before use. A committed project config can set panel prompts; those are now stripped of markup that could forge instructions in the system prompt.
- Security: Output credential scanning runs before long output is truncated, so a secret split across the truncation boundary can no longer slip through.
- Security: Hunk staging (git apply) is confined to your allowed project folders, the same sandbox every other git operation already used.
- Fixed: Cloud Boost no longer crashes partway through a task. When Boost (a cloud model like Opus) drove a long code build, the conversation could be trimmed in a way that left a tool result without its matching tool call, which the cloud API rejected and stopped the run. The history sent to the cloud model is now always structurally valid, and trimming keeps tool call/result pairs together.
- Fixed: The context meter reflects the model that's actually running. With Cloud Boost on, the meter stayed on your local model and its (small) window, so a short conversation could read as over 100% full and force needless compaction. It now shows the active boost model's real window, both while the run is in progress and in the inspector, even when a local llama.cpp model is set as the primary.
- Fixed: A run that stops because your provider is out of credit now tells you why. When a cloud run ran out of API credit (or the key was invalid or revoked, or the provider was disabled) partway through a task, it showed a generic "reached the iteration limit" message with no error, so it looked like the agent gave up on its own. It now surfaces the actual provider error, and the "iteration limit" message only appears when the run genuinely used all of its steps.
- Fixed: The max-iterations setting is honored on capable models. A stale internal cap limited the Agent panel to 25 steps regardless of your max-iterations setting, which only bit higher-capability cloud/boost models (local models finished under the cap, so it was invisible there). Capable runs now use your configured budget (default 50) instead of stopping early at 25.
- Fixed: The local model's context size is read correctly. A custom --ctx-size in a model's llama.cpp arguments is now used as the window the app budgets against, so the meter matches what the server actually runs instead of falling back to a small default.
- Fixed: Clean model names in the Cloud Boost picker and the Spending dashboard. They now use the same readable names as every other picker (for example "Claude Opus 4.8 (1M context)" instead of the raw id).
- Fixed: The Spending chart labels today on its axis and no longer clips a tall day. The daily-spend chart drew the most recent day's bar but only labeled every fifth day, so the axis looked like it ended a few days early; the latest day is now always labeled. A day with a large total also drew a bar that ran off the top edge and overlapped the legend, so the chart now reserves room above the bars for the top axis label and the legend.
- Fixed: Undo now removes files (and folders) the agent created, instead of emptying them. Reverting an agent-created file in the Changes panel or the task-complete card used to write the file's "before" content back, but for a brand-new file that content is empty, so undo left a 0-byte file and the new folders behind. Undo now deletes a created file and prunes the now-empty folders it created (a modified file is still restored to its original content). Folder pruning only ever removes truly-empty directories and never touches anything outside your project, so no other files can be affected.
- Fixed: GGUF files dropped into the models folder now show up in the app. Bodega's model registry only tracked GGUFs added through a Model Hub download or an explicit sideload, so a .gguf copied straight into the llama.cpp models folder never appeared in Settings → llama.cpp models and couldn't be loaded by name. Bodega now scans the models folder on startup and whenever you open the model list, auto-registering any new GGUFs it finds (embedding and vision-projector files are skipped). A manual rescan is also available so a just-copied file shows up without restarting.
- Fixed: Truncated model downloads are now caught instead of silently failing later. A GGUF download that ended short of its expected size could be marked finished, then fail to load with a confusing error. Downloads now verify the final size, clean up the partial file on failure, and resume from where they stopped when you retry.
- Fixed: Switching models mid-conversation now actually loads the new model. A model swap requested while a response was streaming could leave the old model in place. The swap now applies reliably.
- Fixed: Sideloaded GGUFs survive a provider switch. A model you added by hand could drop out of the list after switching providers and back. It now persists.
- Fixed: A model deleted from disk is flagged instead of failing on load. If the file behind a registered model is gone, the list now marks it as missing rather than letting you pick it and hit an opaque load error.
- Fixed: A model that needs a vision projector but is missing one degrades gracefully. Instead of a hard failure, you get a clear message that the projector file is required.
- Fixed: Failed model pulls no longer report success. A download that errored or was cancelled could still surface as "ready." The real terminal status is now reported.
- Fixed: The embedding model is no longer picked as your chat model. Embedding-only models (for example text-embedding-* and Qwen3-Embedding-*) are excluded from automatic chat-model selection.
- Fixed: Cloud providers that hit a network error stay visible with an error. A transient connection failure could make a configured cloud provider vanish from the picker. It now stays listed and shows the error.
- Fixed: Testing a cloud API key tells transient failures apart from bad keys. A "couldn't reach the provider" result now shows amber ("try again") instead of red "invalid key," so a network hiccup is not mistaken for a wrong key.
- Fixed: Finished background and parallel runs no longer count against your session limit. Completed runs were still being counted, which could lock you out of starting new ones until you restarted. They are now released when they finish.
- Fixed: A background run that errors surfaces the error. A failed background or detached run could look stuck instead of reporting what went wrong. The error now reaches you.
- Fixed: Orphaned llama-server processes are cleaned up. A llama-server left behind by a crashed or cancelled run is now terminated rather than holding the port.
- Fixed: First-run setup no longer finishes silently when the model never connects. If the local model fails to come up during setup, you now get a warning instead of setup completing as if everything were ready.
- Fixed: A failed settings save during first-run is reported. If saving your setup choices fails, you are told, rather than the flow completing with stale config.
- Fixed: Air-gap mode blocks the embedding model from reaching a remote host at startup. Boot no longer pre-warms a cloud embedding endpoint when air-gap is on.
- Fixed: Large local models get more time to load before timing out. Big GGUFs that legitimately take a while to load are no longer cut off early.
- Fixed: The llama.cpp models list shows an error with Retry when the backend is unreachable. A failed fetch previously looked like a clean "no models installed" empty state.
- Fixed: A transient failure to read your project folder no longer wipes the code index. An empty scan caused by a locked or briefly-unavailable folder is treated as a probable read failure, not a signal to delete the index.
- Fixed: Deleting a session now stops its background run and removes its worktree instead of leaving the run going and the folder orphaned.
- Fixed: A schema upgrade that rebuilds a table is now crash-safe, so an interrupted upgrade can't lose run history.
- Fixed: Deleting a file outside the app no longer silently discards unsaved edits in its open tab.
- Fixed: The memory auto-extract off-switch now stops every auto-extraction path, not just one of them.
- Fixed: A failed test run no longer reports as a clean pass when the runner crashes without a results summary.
- Fixed: Cloud setup tells you when saving the API key failed instead of showing a successful connection.
- Fixed: Per-provider model actions are correct: the delete button only shows for providers that support local deletion, the code-completion model picker clears a stale model when you change provider, and session export uses the app's real backend port.
- Fixed: Smaller streaming and editor fixes: duplicated text after a stream retry, the editor theme and language switches not taking effect, and the previous session's terminal output lingering after a switch.
- Fixed: Applying a parallel-run winner stops the other runs before cleaning up their folders, avoiding corruption from a half-finished write.
- Fixed: Chat stream locks are ownership-checked so a finishing stream can't release a newer one.
- Fixed: The follow-up message queue claims each message atomically, so a queued message can't be processed twice.
- v1.0.0-beta.31.4Feature
Local-model and provider reliability: custom OpenAI-compatible servers, native tool-calling control, and tool-slip recovery
- Force native tool calling per model. A new per-model control (Advanced Sampling panel → "Tool calling": Auto / Force on / Force off) makes Bodega send native OpenAI tool definitions to a model it didn't auto-detect as tool-capable - for a capable model behind vLLM or llama-swap exposed under a custom name.
- MCP file-tool overlap warning. When an enabled MCP server exposes file tools that overlap Bodega's built-in file tool, MCP settings now flag it - two ways to read and write files can confuse smaller local models. Detection only; nothing is disabled automatically.
- Turn off auto memory-extraction. A new memory.auto_extract setting (on by default) stops the agent from mining facts out of conversations into the persistent memory store.
- Fixed: "Auto" could pick an embeddings model as the chat model. The filter that keeps embedding-only models out of chat auto-selection missed size-suffixed names (Qwen3-Embedding-0.6B/-4B/-8B, text-embedding-3-*), so on a custom OpenAI-compatible endpoint serving both, Auto could land on the embedder. It now recognizes those names while still leaving real chat and coder models alone.
- Fixed: Tool calls weren't repairable on native-tool models. When a model emitted a tool call missing a required argument, only non-native models got an actionable "fix the parameters and try again" nudge - native-tool models (including local models served with tool calling) got just the raw error and would repeat or stall until a circuit breaker stepped in. Now every model gets a nudge that names the missing parameter with a per-tool hint.
- Fixed: In-loop verification always failed on Windows. The auto-verify step appended a Unix-only no-op that isn't a command on Windows, so every verification reported a failure there. It now uses a cross-platform no-op.
- v1.0.0-beta.31.3Feature
Post-loop code review, rubric grading, smart approval, and per-model sampling
- Post-loop code review. After a creation task passes QEL, an optional quality pass reviews the files the agent actually changed (SRP violations, naming, obvious bugs) and surfaces the findings as a collapsible Code Quality section inside the existing verification card. It is non-blocking - it never gates completion - caps at five findings, skips files over 50 KB, bails to an empty result after 5 seconds, and sanitizes every finding before it lands in the trace. Off by default; turn it on with qel.code_review, and point it at a specific reviewer model with qel.code_review_model (empty = use the generating model). Creation tasks only. The finding shape rides the existing qel_trace event as an optional codeReview field - no new SSE event.
- Rubric outcome grader. Attach a free-text quality rubric to a task and, after QEL passes, a one-shot grader evaluates the output against it and pins a { verdict, score, justification } result to the verification card. It is opt-in per request (the rubric rides the request body), runs on a dedicated small grader model when one is configured (qel.grader_model, falling back to the generating model), and short-circuits to *inconclusive* under air-gap, on an empty rubric, or on any grader error - it never breaks the stream. The result rides qel_trace as an optional rubricResult field - no new SSE event.
- Smart approval (intent-steered auto-allow). In Ask mode, when the agent calls a low-risk read-only tool that clearly matches what you just asked for, it can auto-approve the call instead of interrupting you with an approval prompt. Write tools (shell, file_system, str_replace) are hard-blocked and always require a human click. The classifier runs *last* inside the approval handler - after every existing security gate - so it can only shrink the human-approval surface, never widen one. This first version is a static, no-LLM classifier: it auto-passes a known read-only set (grep, glob, web_search, web_fetch, query_knowledge, query_memory) at high confidence and scores intent/tool pairing against your last message for the rest. Off by default; enable with permission.smart_approval and tune the bar with permission.smart_approval_confidence_threshold (default 0.80). Both global. The tool_approval event gains two optional fields (smartApprovalAttempted, smartApprovalReasoning) - no new SSE event.
- /learn - author a skill from a source. A new learn_skill tool reads a source (a workspace directory via the sandboxed file-system tool, or a URL via the SSRF-protected web-fetch tool), runs one constrained authoring turn to draft a spec-conformant skill YAML, and validates it with the existing frontmatter parser. The draft is shown as a preview, then - on approval - written via the existing POST /skills route + registry reload. The write is permission-gated (Ask/Plan return 403 unless the request is explicitly approved; Act writes directly), and a /learn message is intercepted before trigger-matching so a user skill named "learn" can't shadow the command. URL sources are blocked under air-gap (directory sources still work locally); the source is truncated to ~10 KB before authoring, a surrounding markdown fence is stripped before validation, and malformed YAML returns an error rather than a write.
- Auto-skill capture. After a creation task passes QEL cleanly with enough tool calls to constitute a real workflow (≥5 calls, ≤1 repair iteration), the run can be captured as a lightweight, user-scoped knowledge card so a similar future request is auto-recalled at session start. Tool output is sanitized before it lands in the card, persistence is user_id-scoped, and it is off by default (skills.auto_capture). Local-only - safe under air-gap.
- Per-model advanced sampling. Each installed model now has an Advanced Sampling panel, opened from the new Settings control on the model row, for per-model top_p, top_k, min_p, repeat_penalty, repeat_last_n, seed, and stop overrides alongside the existing temperature, max-tokens, and context controls. Samplers a given backend can't accept are greyed out per provider (top_k and min_p are local-only; repeat_penalty and repeat_last_n apply to Ollama), so you can't set a value the server will reject. Overrides are passed through to Ollama (inside options) and to local OpenAI-compatible servers including llama.cpp; cloud providers receive only the samplers they support.
- Changed: Proactive auto context-compaction. The agentic loop now compacts the conversation at a configurable fill threshold at iteration boundaries, instead of waiting for the hardcoded 85% emergency point or a manual /compact. A long run trims itself before it hits the wall. Set the threshold with llm.auto_compact_threshold (default 75; 0 disables proactive compaction and leaves only the 85% emergency backstop; valid values are 0 or 50–95). The compaction machinery is unchanged - the summary is still pinned as the second system message for KV-cache stability, and it still falls back to mechanical trimming if the summary call fails.
- Changed: Per-file churn badges in the parallel-run diff. Each changed file in a parallel-run diff column now shows +insertions (green) / -deletions (red), so a reviewer can see at a glance which files carry the weight of a change. Binary files show a binary marker instead of counts. The parallel-run status feed now also carries the real per-session churn aggregate (it was hardcoded to zero) - cached per session and recomputed only when the diff changes, so the 2-second status poll adds no git overhead. No new SSE event.
- Changed: Aider-Polyglot benchmark prerequisites. Groundwork for publishing an honest harness-lift number: the POST /sessions/:id/abort route now also aborts a headless run (so a benchmark harness can cancel a hung task and free the concurrency slot), HeadlessSessionRunner honors an optional maxDurationMs cap (a task can't wedge a batch), and a new adapter spec (source-of-truth/specs/benchmark-aider-adapter.md) documents the run procedure - fresh session per task, hidden tests as the oracle, harness-vs-raw-model LIFT.
- Fixed: Junk emails reaching the beta list. The first-run beta gate requires an email, so a share of entries were deliberate garbage (random local part, made-up TLD) typed to get past it. The first-run screen and the backend now both check the address against a shared validator before it is accepted or sent onward: the TLD must be a real one (a two-letter country code or a recognized general TLD), and a short list of disposable providers is refused. Local activation still succeeds either way - the check only keeps the contact list clean. A plausible-but-fake address still passes; only a confirmation email would catch that.
- Fixed: QEL failed correct code over absent optional patterns. A correct creation (for example, a Python module with tests) could score a failing 68/100 because optional language-idiom patterns that happened to be absent still counted against the score, and the Python compile/import proof only ran for server or app entry points. Optional language patterns are now bonus-only - their absence can no longer drag the score down - and the Python proof falls back to any .py deliverable. The same file now passes.
- Fixed: Wrong temperature-schedule description. The Agent settings note described the dynamic temperature schedule backwards. It now matches what the loop actually does: steadier during planning, slightly higher during file writes.
- v1.0.0-beta.31.2Feature
Quality-of-life rollup: steadier agentic loops, hardened providers, in-app preview fixes
- open_preview tool - one discoverable action that auto-detects the running dev server's port and opens the Preview panel (reusing the existing preview relay; no command execution).
- shell run_in_background - start a long-lived process (dev server, watcher) without blocking the call; returns the pid + early output, keeps running until the session is deleted or the app exits, tree-killed on cleanup. Same approval + blocked-pattern + credential-scan guarantees as the foreground path. (Pairs with open_preview.)
- Cloud Boost default-model dropdown - pick from the provider's curated/live model list instead of typing a model id.
- Fixed: Capable models hit the iteration limit mid-build. A cloud-Opus build of a full multi-module game stopped unfinished at iteration 24. The effective budget was clamped by the model profile's recommendation (xlarge was only 20), so raising the user ceiling alone did nothing. Bumped the size-class recommendations (xlarge 20→35, large 15→20, medium 10→12) and the default ceiling (25→50) with a migration; the no-progress / degeneration circuit breakers still bound runaway loops.
- Fixed: Project builds stranded by the boilerplate firewall. When the contract extractor mis-read a prompt (e.g. parsing "Three.js" as the lone deliverable from a "build a 3D game" request), ModeFirewall blocked package.json, tsconfig.json, and vite.config.ts as "not in the contract" - so the model made calls but wrote no files and looked stuck. Load-bearing web/JS scaffold is now exempt when the contract looks like a web/JS project; other ecosystems keep blocking superfluous boilerplate.
- Fixed: Contract extractor mined prose into a garbage contract (the root cause of the above). A "build a 3D game with Three.js, steering (A/D)" prompt produced a lone deliverable Three.js, fake routes (/D, /right, /outrun from inline slashes), and fake functions (steering from "steering (A/D)"). Now: ~40 known library filenames (three.js, react.js, d3.js, chart.js, …) are never treated as deliverables; a route's leading / must not follow an alphanumeric (so "A/D" prose isn't a route); and a function call must have no space before ( (so "steering (A/D)" prose isn't a function). Real filenames, GET /api/users, and drawCar(ctx) still extract.
- Fixed: Force-completed runs over-claimed success. On an escape-hatch / force-complete exit, the summary read "Task complete: 1 file created" even when the QEL check had failed - directly contradicting the "⚠️ Quality check scored X/100" warning appended right below it. The lede is now an honest "Wrote N file(s):" (or "Finished - no files were written."), leaving the success/failure verdict to the QEL line.
- Fixed: Chat: duplicate turn on a truncated-stream retry + dropped queued sends. A mid-stream retry could re-post the user turn, and follow-ups queued during a run could be lost on completion. Both fixed.
- Fixed: BYOK per-message cost showed $0 for Fireworks (accounts/fireworks/models/<slug> never matched) and cold-cache OpenRouter, plus longest-prefix mis-pricing. Pure id-resolution, no price guessing.
- Fixed: Cloud rate-limit over-throttling. The pre-flight budget paced every cloud request against a conservative hardcoded default (Anthropic 30K ITPM), adding 15–45s waits per iteration for higher-tier accounts. It now learns the real per-window limit from the provider's own response headers (override > observed > default).
- Fixed: Rate-limit buckets were shared across all OpenAI-compatible providers (one 429 on Groq throttled Together/OpenRouter/DeepSeek/Fireworks too) - now keyed per preset.
- Fixed: OpenAI complete() parity with stream(): records the actual returned model, logs non-OK responses, fast-fails an unreachable host, honors Retry-After.
- Fixed: Anthropic: broadened context-overflow detection for newer/1M-context errors; complete() connect-timeout + per-model max_tokens + a free (count_tokens) health check; extended-thinking blocks now round-trip so reasoning + tool-use no longer 400s. (AnthropicProvider.ts split under the 700-line cap to land these.)
- Fixed: Ollama: tool-result linkage (preserved tool_call_id + derived tool_name), faster health recovery (3s fail-cache), broken-tool-template poison handling in complete().
- Fixed: OpenRouter one-sided pricing no longer drops the model; Claude display names keep their variant qualifiers ("Opus 4.8 Fast" vs "Opus 4.8"); Fireworks serverless slugs resolve to their dotted profiles; Featherless warmup persistence is idempotent; cloud-provider list completed (cohere/fireworks/qwen/kimi) + Groq onboarding.
- Fixed: Preview opened the wrong port. Vite increments from 5173 (and users set custom ports like 5180), but both detectors only knew 5173/5174 - so the live server was invisible and a stale port showed. Both the terminal-output detector and the backend port scan now cover the Vite dev/preview increment band.
- Fixed: Preview opened the external browser instead of the in-app panel, and "open preview" could hang the model. Two fixes (Joe 2026-06-23): (1) dev servers run with BROWSER=none, so a Vite/CRA server.open: true no longer pops the system browser - Bodega's in-app Preview owns it. (2) A foreground dev-server command (npm run dev, vite, next dev, …) is now auto-detected and run in the background instead of blocking until the exec timeout (which had made weaker models repeat themselves into the doom-loop guard). When the server prints its localhost URL, the in-app Preview opens to it automatically - no second open_preview step.
- Fixed: Sandbox escape via a symlinked parent directory closed (realpath-walk to the nearest existing ancestor).
- Fixed: Per-user scoping for memory routes and loop concurrency; PreToolUse hooks + permission profiles now also gate read-only tools (a **/.env deny stopped a read).
- Fixed: Code-mode silent save/stage failures now surface; Command Sandbox dropdown persists; loop scheduler no longer resets unrelated loops' timers; fleet parallel runs recognize the backend complete status; settings import validation + reset-all air-gap sync; first-run onboarding fixes + a Reset-All confirmation dialog.
- Fixed: QEL/Drift verification card stayed pinned across sessions, with no way to dismiss it. The inline card in the agent panel only cleared on the next send, so it lingered after switching to or creating a new session. Switching sessions now clears the trace, and the card has a × to dismiss the block (the Drift strip goes with it); it reappears on the next verification run. The dismiss is view-only - the Debug → QEL tab keeps the data.
- v1.0.0-beta.31.1Feature
Hotfix: OpenRouter and Fireworks provider reliability, plus OpenRouter cost tracking
- OpenRouter integration polish. Accurate per-message cost tracking from OpenRouter's live pricing; the model picker organized by vendor and popularity (most-used first) with search across the full catalog; previously hidden Llama and Gemini models restored to the list; and app-attribution headers so Bodega One registers on OpenRouter's app directory.
- Fixed: OpenRouter "Cannot reach OpenRouter" banner. A single slow health poll (OpenRouter's large model catalog occasionally taking longer than its fetch window) would flip the app to "disconnected" and blank the model picker. The health check now needs two consecutive failed polls before showing the banner, one healthy poll clears it instantly, and the cloud model-list fetch gets a longer timeout so the catalog finishes and caches instead of re-failing.
- Fixed: OpenRouter "Request timed out" on a cold model. OpenRouter returns headers immediately, then holds the stream open while it warms up the upstream model. If that ran long it sent an error before any token, and the app was silently swallowing it and ending with an empty reply. Pre-token stream errors now surface, cloud providers automatically retry the transient ones (safe, since nothing was streamed yet and the first request already warmed the model), and the cloud connect window was widened so a slow-but-healthy start is not cut off.
- Fixed: Fireworks empty model picker. Fireworks' model-list endpoint errors for serverless accounts, so the picker came up blank and the provider looked broken. Bodega now ships a curated list of current Fireworks serverless models (DeepSeek V4 Pro/Flash, GLM 5.2, Qwen3.7 Plus, Kimi K2.5, MiniMax M3, Nemotron 3 Ultra, GPT-OSS 120B/20B), each verified to chat, stream, and tool-call. The key-validation probe was refreshed to a current model as well.
- v1.0.0-beta.31Feature
Lifecycle hooks, permission profiles, Drift Radar, and proof-carrying commits
- Lifecycle hooks (PreToolUse / PostToolUse). You can now run your own shell command before or after the agent uses a tool - to lint, format, validate, or block a change before it happens. A PreToolUse hook can stop a tool (exit 2) or rewrite its input; a PostToolUse hook observes the result. Hooks you write in your own settings are trusted; hooks committed in a repo's .bodega/config.json are never run until you approve them (per exact command + project - a cloned repo can't run a hook behind your back). HTTP hooks are deferred for now; shell hooks cover the common lint/format/gate case. Off when you have none configured.
- Named permission profiles. Define reusable named rule sets that narrow what the agent may do - deny a tool by name, or allow/deny file writes by path glob (e.g. a readonly profile, or one that confines edits to src/** and blocks src/secrets/**). A profile can only *restrict* access (never widens it) and composes with Ask/Plan/Act. Off until a profile is activated.
- Regression contracts (the oracle store). When a creation task passes QEL verification, Bodega now remembers the verified contract (deliverables + framework + the score it passed at) for that project - a durable "this worked" baseline. It de-duplicates automatically and is the foundation for upcoming drift/regression detection.
- Drift Radar. Bodega can now re-prove the contracts it has already verified for a project against your current code - telling you which previously-working deliverables still hold, which regressed, which had their proof break, and which simply changed (a retire candidate). Run it on demand from the new Drift tab in the code-mode debug panel, or let an optional nightly sweep watch in the background and raise a top-bar pill plus an in-app/OS notification the moment something newly regresses (reusing your existing Fleet notification settings). It is report-only - it never edits, applies, or auto-retires anything - and does no network or process spawning, so it's air-gap-safe. The background sweep is off by default (enable it under Settings, default nightly at 03:00).
- Custom llama.cpp arguments. Power users can now pass raw llama-server flags that aren't in the GUI - to tune for their exact hardware (e.g. --n-cpu-moe, --override-tensor, batch sizes, --no-mmap). Set them globally under Settings → Models → Advanced llama.cpp flags, or per-model for the currently-loaded model; a live preview shows the resolved command. Custom args override the GUI fields (last-wins). Flags Bodega must own (model selection, the 127.0.0.1 binding) are ignored with a notice, and --rpc is blocked under air-gap. The setting is global-only - a project's committed config can never inject server flags.
- Watch-mode comment triggers. A new Loop trigger kind watches a project folder and acts on inline comments when you save: // bodega: <instruction> runs that instruction on the file, and // fix this AI! asks the agent to fix the nearby issue. The change runs through the same QEL-verified, worktree-isolated apply gate as every other Loop (parked for review by default), and the trigger comment is removed after a verified change. Off by default behind two switches (the Loops master toggle + a dedicated *Watch for comment triggers* toggle in Settings → Automation); guarded against re-fire loops and double-dispatch on rapid saves.
- OpenTelemetry audit export (opt-in, loopback-only). Bodega can now export its existing agent-run telemetry (LLM calls, tool calls, proof gates, violations, run completions) as OpenTelemetry (OTLP) trace spans to an OTLP collector you run on localhost - for audit, compliance, or just seeing a run as a waterfall in Jaeger/Grafana Tempo. It's off by default and loopback-only: the endpoint is checked against a localhost allowlist before every send, so a non-loopback URL is refused (even with air-gap off). No new dependencies, and free-text fields are truncated before they leave the process. Enable it with telemetry.otlp_export_enabled + telemetry.otlp_endpoint (default http://localhost:4318/v1/traces).
- Air-Gap Attestation. Settings → Safety → Network Privacy now has a Copy attestation action that produces a signed, tamper-evident record of your air-gap posture: whether air-gap is on, how many outbound fetches were recorded, and how many blocked outbound attempts the enforcement layers counted since the app started - broken down by category (GitHub, git push, MCP, model downloads, etc.). It's HMAC-signed with a secret that never leaves your machine, so the record can't be edited after the fact. Honest by design: it attests *recorded fetches and counted refusals*, not a guarantee that zero bytes ever left the machine. Generating or verifying it makes no network calls.
- Proof-Carrying Commits. When you commit QEL-verified work, Bodega can attach a signed Bodega-QEL git trailer to the commit message - the score, pass/fail, execution-proof result, model, and a hash of the contract that was verified. The trailer is signed with an HMAC keyed to a secret that never leaves your machine, so a "verified" claim can't be forged or edited after the fact. A new Verify history action in the source-control panel walks recent commits and re-checks each trailer, marking them verified / tampered / unsigned. Tick Add QEL proof beside the commit button to include it. Fully local - building or checking a trailer makes no network calls.
- Contract preview in the composer. As you type a task, a small card shows what the agent will be held to before you send - the files it's expected to produce, the framework it detected, and any API routes it'll touch. It's the same execution contract QEL verifies the result against, surfaced up front so you can catch a misread ("it thinks this is a Flask app") before spending a run. Fully non-blocking and read-only: it never starts a run or persists anything, and it stays hidden for plain conversational messages.
- MCP per-server tool filtering + required servers. An MCP server config can now carry an enabledTools allowlist or a disabledTools denylist, so only the tools you choose from a server are exposed to the agent (instead of all-or-nothing per server). A server marked required fails fast - it isn't silently retried, and a failure to connect is surfaced - so a run can't quietly proceed without a tool source it depends on. Filtering sits below the air-gap/enabled security floor (it can only ever remove tools, never re-admit a blocked one).
- Path-scoped project rules. A project-rules file (.bodega-rules / CLAUDE.md / .clinerules / .cursorrules) can now carry rule fragments that apply only when the agent works on matching files - fence them with <!-- bodega:rules paths="app/**,**/*.sql" --> … <!-- /bodega:rules -->. The matching fragments are injected alongside your always-on global rules, chosen from the files the turn touches (open editor tabs + the files you name). Rules files with no fenced blocks behave exactly as before. Cuts wasted context and raises rule relevance.
- Configurable shell environment policy. A new shell.env_policy setting controls which environment variables reach shell commands the agent runs: core (default - the existing curated allowlist, unchanged), none (bare shell essentials only), or full (pass everything through). shell.env_allow_extra lets you name specific extra variables (e.g. a build token) to pass under the stricter policies. The default is byte-identical to today; full is still scanned for leaked credentials in command output. The policy is a global setting on purpose - a committed project config can't widen it.
- Changed: Forced routing tier resolves through the backend. When you pin a routing tier with the Fast / Smart / Code pill, the model is now resolved by the backend's router (its real slot config) instead of the renderer's settings mirror - so the model shown in the status bar is exactly what the backend will serve. Matches the new bodega run --tier / /tier in the CLI. Auto routing is unchanged; the consult is short-timeout with a local fallback, so it never blocks a send.
- Fixed: QEL verifies vanilla JavaScript correctly. Plain .js/.jsx deliverables (no TypeScript, no tsconfig) were being checked with npx tsc, which fails instantly in a dependency-free project and sank otherwise-correct creations to a failing score. JavaScript now gets a parse-only node --check per file (matching the existing Ruby and PHP gates), and language-pattern plus proof-gate coverage was widened to .mjs/.cjs/.php/.c/.cpp/.swift so valid code in those languages isn't scored zero. A missing third-party import is treated as an environment gap rather than a code error, and a config-only run that writes no deliverables no longer earns a free completeness pass.
- Fixed: Stale regression contracts no longer hide new regressions. After you retired and re-verified an oracle contract, Drift Radar could keep reporting it as regressed from before, masking a genuine new failure. Findings now carry a baseline timestamp and the transition state resets on retire/reactivate, so a re-verified oracle reports its next regression as expected.
- Fixed: QEL and Drift results show inline in the code-mode agent panel. They previously appeared only in the Debug tab. The llama.cpp model name now renders correctly in the model-role picker, and embedding-index logging no longer floods the console when indexing is off or the provider isn't configured.
- Fixed: Release downloads never 404 mid-release. There was a 5 to 18 minute window during a release where downloads returned 404: the GitHub release went public before all platform assets finished uploading. Releases now upload assets into a draft and only flip to public and latest once every platform completes.
- v1.0.0-beta.30.1Feature
Hotfix: per-model context and thinking settings apply again, plus doom-loop detection
- Stuck agents get caught (doom-loop detection). If the agent calls the exact same tool with the exact same arguments over and over - a dead-end loop that burns time without making progress - it's now nudged to change approach, and if it keeps going, the run is wrapped up and graded rather than spinning forever. Genuinely repeatable actions like re-running tests or shell commands are exempt, so real work is never cut off.
- A clear warning when the context is set too high. If you set a local model's context window beyond what your hardware can allocate, the model card now warns you before you load it, and if a load does fail for that reason you get a plain "context window too high - lower it in Settings" message instead of a cryptic crash.
- Fixed: Per-model context size applies again. Setting a context window on an individual llama.cpp model had no effect - every model silently fell back to a 4K window, so longer conversations broke for no apparent reason. The per-model value (or, failing that, the model's own trained length) is now wired into how the local server starts.
- Fixed: A full context window no longer crashes the chat. When a local llama.cpp model ran out of context mid-reply, the overflow was misread as a fatal error instead of a recoverable one, and the chat died. It's now recognized and handled gracefully so the conversation can recover.
- Fixed: Ollama context overflows are recognized too. The same class of "out of context" error coming back from Ollama is now caught and handled as an overflow rather than surfacing as a generic failure.
- Fixed: The per-model thinking toggle works on local models. For llama.cpp models that support thinking (Qwen3, DeepSeek-R1, QwQ), the reasoning control you set per model was saved but never applied - the model thought (or didn't) on its own regardless. The toggle now takes effect: turn it off to get fast, direct answers, or on to let the model reason. Coder and embedding variants are left alone, since forcing thinking on them errors.
- v1.0.0-beta.30Feature
Agent memory across tasks, self-improving Loops, stricter QEL grading
- Loops learn from their own history. A scheduled Loop now reads its recent runs and carries forward what failed, so it stops repeating the same mistakes every cycle. A Loop whose quality is steadily dropping auto-pauses instead of grinding on. Loops can also pace themselves (backing off when a run changes nothing), expire on a date, cap their total runs, and be defined in a committed .bodega/loop.md file so a repo can ship its own automations.
- The agent learns across tasks. It records what worked on past similar tasks and surfaces those lessons on the next one, reflects after each run to distill a short lesson, and learns from the tools you reject. All of it stays on your device, scoped to you and the project, and honors air-gap. This is in-context memory, not model fine-tuning.
- Changed: Learning data is scoped per user. Groundwork for shared deployments: every learned rule, recorded mistake, cached tool pattern, and model-performance record is now tagged to its owner so nothing crosses between accounts.
- Fixed: Quality checks now fire when they matter. The Quality Enforcement Layer used to skip grading when a model thrashed and the loop force-completed, or when a request was phrased loosely ("make me a dashboard") instead of naming files. Those runs slipped through marked as passed. They are now graded honestly with a real score and a repair path, no matter how the run ended or how the request was worded. Verified live across a small local model, a large local model, and a cloud model.
- v1.0.0-beta.29.6Feature
Hotfix: multi-file cloud edits fixed, denied tools actually blocked
- Regression tests for the bidirectional tool-pairing backstop and the server-side deny-list enforcement.
- Fixed: Multi-file tasks no longer fail with a 400 on cloud providers. A turn that called several tools at once (e.g. editing multiple files) could error with a provider 400 on OpenAI-compatible / native-function-calling backends, because the assistant tool-call and tool-response messages were only reconciled one way. The backstop is now bidirectional, so multi-tool turns pair up correctly. Local / XML-tool providers were never affected.
- Fixed: Duplicate tool responses are no longer emitted for a native-function-calling tool call - part of what tripped the provider 400.
- Fixed: A denied tool is now actually blocked. A tool named in a deny list could still execute (act mode auto-approved it before the denial was checked). Denial is now enforced server-side, before the tool runs, in every permission mode.
- v1.0.0-beta.29.5Feature
Lightweight file viewer, a fully offline editor, steadier local models
- Lightweight file viewer. Opening a file with Bodega One (a file association or "Open with") now launches a fast, theme-consistent viewer window instead of booting the whole app and loading a model. Markdown shows a formatted preview; any file opens in a real Monaco editor with line numbers, a minimap, and syntax highlighting. You can edit, save with Ctrl/Cmd+S, and get an unsaved-changes prompt on close. "Open in Bodega One" promotes the file into the full app when you want it.
- Fixed: Local-model boot reliability (llama.cpp). Local models now recover from a crashed llama-server instead of wedging, no longer fall back to Ollama once you have picked a local GGUF, and load in the background so the window stays responsive while weights load. Speculative-decoding (MTP) draft models resolve from the correct location, with a migration for installs that used the old path.
- Fixed: Editor works fully air-gapped. The Code-mode editor now ships its Monaco bundle inside the app instead of fetching it from a CDN at runtime. With air-gap on, opening the editor makes no outbound requests. The editor still loads on demand, so the main bundle stays within its size budget.
- Fixed: Beta sign-up no longer drops contacts. First-run email capture now writes every submission to a durable on-device queue before contacting Loops, then retries in the background. If you were offline or hit a network error at sign-up, your contact is held and sent later instead of being silently lost. Air-gap still sends nothing until you turn it off.
- v1.0.0-beta.29.4Fix
Local models fix: downloaded GGUFs show up in My Models again
- Fixed: Downloaded models now show in My Models. A GGUF you downloaded could go missing from My Models (and stay unloadable) whenever llama-server wasn't already running, because the list came from the live server instead of what's installed on disk. Installed GGUFs now always appear under the llama.cpp preset, so you can load one even before the server starts.
- Fixed: No more stuck "Unknown GGUF id" startup. If a model id from a previous Ollama setup was left as the llama.cpp default, the server refused to start. Bodega now ignores and clears that stale id and stays idle until you pick a model, instead of failing the whole local-model setup.
- Fixed: No silent fall-back to Ollama. With no model loaded, llama.cpp could quietly switch to Ollama and then log a connection error every 30 seconds forever (even when Ollama wasn't installed). It now stays on llama.cpp, idle.
- Fixed: Clearer "Test Connection". Testing the llama.cpp connection with no model loaded now explains that a model must be loaded first, instead of a raw "fetch failed".
- v1.0.0-beta.29.3Feature
Local-provider install progress, resumable model downloads, refreshed catalog
- Refreshed model catalog. Five current GGUF models join the llama.cpp catalog (Qwen3-Coder-30B, Gemma 4 12B, DeepSeek-R1-0528-Qwen3-8B, Qwen3.5-9B, and Qwen3-VL-30B), and the managed llama-server binary moves to b9670. (beta.29.2)
- Name on the first-run beta gate. Beta activation now captures your name alongside your email. (beta.29.1)
- Fixed: Local-provider install progress. Installing llama.cpp or Ollama from Settings → Providers now streams real download progress, keeps running when you leave the tab, and has a Cancel button. It no longer looks cancelled when you navigate away, and the llama.cpp card no longer offers to install a binary that is already present. (beta.29.2)
- Fixed: Model downloads survive a restart. A GGUF download that is still running re-attaches its progress bar after a full app restart instead of showing an idle Download button. (beta.29.3)
- Fixed: "What's New" shows your version. The release notes no longer render a stale "Unreleased" heading on a shipped build. (beta.29.3)
- v1.0.0-beta.29Feature
Routing rules, Verified Private Automation, a smarter agentic loop
- Routing rules: an ordered, first-match-wins rule list (Settings, AI Behavior, Routing) that decides which model handles what. Match on mode (chat or code), ask type, agent step (read, write, plan, verify), file path, message size, or how much you have spent today, then route to a specific model or keep it local. OR and NOT conditions, custom classifier patterns, per-project rules shipped in .bodega/config.json, an Auto-pill preview, a dry-run tester, and four one-click starter recipes
- Hard limits still clamp every routed decision afterward: a rule can never bypass air-gap, VRAM limits, or your spend caps, and a project rule can never route your requests invisibly
- Verified Private Automation: point Bodega at a plain task or a GitHub issue and it works in an isolated git worktree on your machine, writes the code, runs full QEL verification (boots your server and probes a real route, runs your tests, checks the contract), and opens a pull request with the verification trace in the description. A passing run gives you a ready PR; a failing one opens a draft, so an unverified change is never presented as merge-ready
- Cursor and Copilot do this by shipping your code to their cloud. Bodega runs it on your hardware and proves its work before it commits, so nothing leaves your machine but the branch and the PR
- Run an automation with one of your own custom agents (its system prompt, model, and tool allowlist drive the verified run). Three starter agents ship as one-click templates: Code Reviewer, Test Runner, and Doc Checker. Every custom agent now has a run history with status, QEL score, files changed, and the full trace per run
- Goals: type /goal and what done means, and the goal survives every message, resumes its task list where the last run stopped, and turns an approved plan into tasks. The agent cannot declare victory on its own: when it thinks a goal is done, a second model you choose attacks the result to find what breaks, and anything it finds becomes new work
- The agent sees type errors as it writes: after every TypeScript, JavaScript, or Python edit, diagnostics from a bundled language server land in the tool result, so it fixes the error in the same pass. Nothing to install, works on bug-fix tasks, works headless in Fleet and Loops, works under air-gap
- New dispatch_scout tool sends a read-only sub-agent to explore the codebase and report back a short digest, so the search does not fill your context. New get_diagnostics tool pulls the current type errors for a file before the agent touches it
- Test-driven repair: when a build task fails verification twice and the project has a test runner, a capable model writes one failing test, proves it fails for the right reason, then fixes until it passes. Plus two new skills: /decompose turns an objective into a goal with three to seven verifiable tasks, and /onboard tours an unfamiliar repo and saves what it learned as project knowledge
- The editor language server graduated from experimental and now works for everyone out of the box: red squiggles, go-to-definition, and hover types, with the server shipped in the app so there is nothing to install
- The reasoning dial now shows every tier a model actually has (GPT-5 gains Minimal; Claude 4.6 and later gain Extra High and Max), and switching models clamps your setting to the nearest tier so a request is never rejected
- Cost tracking for your own models: set token prices for self-hosted, custom, or internal-gateway models and their cost shows in the dashboard like any cloud provider, on your machine, in air-gap
- Export a session as a self-contained web page that opens in any browser with no network, or a self-hostable read-only viewer you run on your own infrastructure. It is a local file you choose to share, and nothing is uploaded
- Driving Bodega from another editor over ACP is verified and documented: Zed, JetBrains AI Assistant, or any ACP client can run it as a headless agent over stdio, every tool call still gated by your approval
- New models and two new providers: a catalog refresh adds fourteen models and two cloud providers, MiniMax and Z.ai, and corrected cloud prices across the board so the dashboard and pre-send estimates match what you are billed
- Changed: Claude Fable 5 is no longer available after Anthropic withdrew it from general availability, so the catalog card and picker entry are gone and it is filtered out even if the API still returns it. If you had it selected, pick Claude Opus 4.8
- Changed: a visual pass over the whole app. Buttons read as their accent color instead of filled purple boxes, toggles are a thinner minimal design, and the Chat / Code switch is cleaner
- Fixed: routing rules now fire correctly on live sends (not just the dry-run tester), and a budget condition inside an OR or NOT group now reads your real spend. Plus a Monaco 0.55 spacebar input fix and accessibility toggles that apply the moment you flip them
- v1.0.0-beta.28Feature
Run Tasks, Runs Inbox, rules import from other editors, app-wide polish
- Run Tasks: one-click dev-server launch from the terminal tab bar, and a labeled "Run tasks" chip in the agent panel's action row so it's not hidden. Auto-detects dev/start/serve/watch scripts from your project's package.json, supports custom named tasks via a run_configs key in .bodega/config.json, runs each task in its own terminal tab, and "Run all" launches everything at once. Stopping sends Ctrl+C so the process exits cleanly and the logs stay readable.
- The agent can open the Preview tab when you ask it to. "Open the preview at localhost:5173" now opens the tab, loads the URL, and brings it forward. Previously the agent could only navigate a preview you had already opened.
- Runs Inbox. One topbar surface for everything waiting on you (fleet sessions needing approval or ready to apply, loop runs parked for review or below their QEL bar) with click-through to the owning panel. Hidden when empty; the Fleet and Loops pills keep narrating live activity.
- Coming from another editor? Bring your rules. Opening a project with Cursor, Copilot, Cline, Windsurf, or Continue rules offers a one-click import into .bodega-rules (append-only, never overwrites yours, re-import skips what's already in). Manual re-run lives in Settings → Profile.
- Auto-approve read-only tools in Ask mode (off by default). Searching and reading (code search, grep, glob, symbol lookup, Map/memory/knowledge queries) can skip the approval prompt while every file write, web call, and shell command still asks. Shell can never auto-approve.
- Pre-send cost estimate. On cloud models the status bar shows roughly what your next message will cost ("~$0.012/msg") next to the Context meter, priced from the current context plus a typical reply. Local models show nothing. There's nothing to pay.
- Review only what changed. The source-control Review button now skips files that are unchanged since your last review and says so, with a "Review everything" escape hatch. Review → fix → review loops stop re-paying for the whole diff.
- Loops tell you when they'll fire. Interval and Map-staleness loops show a live "next in 14 min" countdown on their rows, and the topbar loops pill gained a per-loop Run-now button.
- Run Tasks checks your dependencies. Opening Run Tasks in a project with a package.json but no node_modules offers one-click npm install in its own terminal tab.
- Every model swap shows progress. Stage labels and elapsed time during llama.cpp model loads now appear for all swaps (not just vision-triggered ones) instead of a stage-less spinner.
- Changed: One focus ring. Keyboard focus now draws the same accent ring on 35 controls across the app instead of a mix of browser defaults and one-off styles.
- Changed: One grid, one shield. The fleet four-square glyph and the safety shield are now single shared icons everywhere they appear. The Settings copy of the fleet icon had quietly drifted to rounded corners.
- Changed: TopBar survives narrow windows. The center section clips cleanly instead of overlapping the window controls, and the project name steps aside first. The Chat/Code pills always stay reachable.
- Changed: Status colors read correctly on light themes across fleet surfaces and toasts (semantic status tokens replace hardcoded dark-theme colors).
- Changed: Faster where it drags. Bodega Map staleness checks hash 16 files at a time instead of one; llama.cpp model loading no longer blocks the backend on boot (the dead startup spinner is gone); embedding index builds detach instead of hanging the request; project search, the spending dashboard, and the model picker do less work per render.
- Fixed: Cost tracking showed $0.00 for Claude Opus 4.8 and Fable 5: the pricing table was missing both flagships and carried stale rates for Opus 4.6/4.7 and Haiku 4.5.
- Fixed: The air-gap warning about configured cloud providers never fired for Anthropic (or any current provider): it was checking a deprecated setting.
- Fixed: Long-lived editor connections via ACP grew memory forever; idle sessions are now evicted after 30 minutes (never mid-turn).
- Fixed: Quitting Bodega mid-run no longer kills headless loops mid-write. Shutdown aborts them cleanly and waits for writes to land.
- Fixed: Sending from the agent panel briefly shifted the whole app upward with dead space underneath. Message scrolling now stays inside the message list.
- Fixed: "Dev servers detected" chips outlived their servers. Candidates are now liveness-probed every few seconds, so a killed server's chip clears itself.
- Fixed: A failed send buried your prompt under an error banner with no way out. The banner now has a close button and restores your draft into the composer.
- Fixed: When no model was selected, requests went out with a placeholder model name (gpt-oss) and failed confusingly. You now get a clear "No model selected" pointing at Settings → Models.
- Fixed: Welcome-screen template chips did nothing when the agent panel was closed. They now open the panel with the template prefilled.
- Fixed: Dragging a panel tab too far no longer detaches it into a stray floating mini-window (the source of the phantom-window report).
- Fixed: The keyboard-shortcuts overlay (Ctrl+/) was missing eight shortcuts that actually work, including Open Agent panel (Ctrl+L) and Toggle Git panel (Ctrl+Shift+G). It now renders from the same table the audit checks.
- Fixed: llama.cpp setup: if the extracted llama-server binary isn't where the installer expects (antivirus quarantine is the usual cause), setup now searches the extracted folder before failing. And the error finally says what to check instead of just "binary was not found".
- Fixed: The Windows installer's finish page no longer renders its checkboxes illegibly in dark system themes.
- v1.0.0-beta.27Feature
Bodega Loops (scheduled agents), QEL execution proofs, 2x faster verification
- Bodega Loops (Automations): a named agent task on a cron schedule, a fixed interval, or Bodega Map staleness (fire when N of your module summaries fall out of date with the code). Each loop picks its own custom agent or a specific provider and model
- Every loop run executes headless in an isolated git worktree and lands as a reviewable diff with its QEL score and full trace. Park for review is the default; auto-apply only when the score clears the bar you set; dry run never applies. Scheduled runs require worktree isolation, respect spend caps, and inherit air-gap
- Loops dashboard in the Code sidebar, quick-start recipes in Settings (nightly doc sync, dead-code sweep, test backfill, Map self-maintenance), run history with traces, and a topbar pill that goes red and stays red if a run fails
- QEL execution proofs: for a server task, QEL boots the generated app in the sandbox, forces an ephemeral port, and sends one request to the route the task asked for. A response under 500 is the strongest pass evidence; a boot crash or 5xx is a real failure; environmental issues stay neutral. Loopback only, secrets-free, 12-second cap, process tree always killed
- QEL now covers more languages: JS and TS tests run under vitest (the way Python tests ran under pytest), Ruby and PHP get syntax gates, and SQL and Dockerfiles get structural lints
- QEL calibration harness: 43 labeled known-good and known-bad scenarios run through the real verifier at every model tier, with CI floors that fail the build if broken work passes. The first sweep caught two scoring holes
- The semantic judge now runs air-gapped on a localhost model and can park a marginal pass it is confident is wrong, instead of only adding bonus points
- Verification runs once per turn instead of up to four times, with proof gates in parallel: roughly half the wall-clock for the same checks
- Terminal: a sticky header showing which long-running command the scrolling output belongs to, a real Output panel (backend logs with filters, search, follow-tail), a real Debug Console, and searchable command history
- Open files with Bodega One: double-click a `.md`, `.json`, or `.ts`, or use Open with, no project folder required. Works from the shell too
- Source control: hunk-level staging (stage exactly the lines you mean to commit), a conventional-commit type picker, and project search history of your last 10 queries
- Bodega Map: Mermaid export, click an edge to explain why A depends on B, and an Ask-the-Map Fast mode that answers near-instantly from existing summaries
- Custom agents show who is driving in the status bar (AgentName and model), with export/import of the whole roster as a JSON bundle. Fleet Parallel compare view shows each session's QEL badge and total cost with a one-click re-race
- Security: the local API server now refuses to start under air-gap and rejects requests if toggled mid-session, closing a no-network hole. Loop runs are hardened end to end (isolation required, project paths bounded, iteration caps enforced, concurrency cap race-free)
- Fixes: QEL no longer fails correct TypeScript when there is no `tsconfig` (the real cause of "0% pass on local models"); edit and fix verification works again after being dead code since beta.25; the spend cap now covers background, Fleet, and loop runs and records their cost
- v1.0.0-beta.26.1Improvement
Claude Fable 5 support, Anthropic pricing display corrected
- Claude Fable 5 (and a Claude Fable 5 (1M) variant) is selectable in the model picker and Discover catalog. Anthropic's most capable widely-released model, generally available June 9, runs at a 1M-token context window with always-on adaptive reasoning, vision, and tools
- Corrected stale Anthropic cost estimates in the model picker and added the missing per-message cost badges for Opus 4.8 and the 1M-context variants (including the new Fable 5 (1M))
- v1.0.0-beta.26Feature
ACP server, custom agents, Map as a callable tool, spend caps
- ACP server: `bodega --acp` starts Bodega headless and the agent gets driven over stdio JSON-RPC by an external editor. Register it in Zed's `agent_servers` and Bodega's agent runs inside Zed with the same permission gates and `acp.allowed_projects_dir` confinement as in-app. Closes the bidirectional ACP loop after beta.25's ACP-host work
- Custom agents: a profile is a system prompt, pinned model, tool allowlist, read-only flag, and iteration cap, built in Settings. The allowlist is enforced at the execution gate as an intersection with the panel's tools, so a profile can only narrow what runs, never widen it
- Bodega Map exposes itself to the agent as a callable `query_map` tool. The agent queries the codebase graph mid-task and gets a grounded answer with sources
- Map staleness tracking (amber dot when a file changes and its cached summary is now wrong), a generated project-overview page, per-symbol line-jump from the node drawer, and a cancellable Generate-Map run
- Local code review: a Review button in the Git panel runs AI review on the working diff using your configured model. No PR, no remote, no cloud requirement
- Per-hunk diff accept/reject surfaced one click from the Agent panel's change list
- Claude Fast mode: a Fast toggle next to the reasoning control that skips extended thinking, shown only for Claude models
- Managed llama.cpp embedding server replaces standing up Ollama for embeddings. Picker lists the GGUF models you already have
- Spend caps: a hard ceiling on total cloud spend, not just Cloud Boost. When you hit it, new requests stop
- Air-Gap Active indicator in the top bar so you can see at a glance whether zero-network is on
- Terminal Ctrl/Cmd-click on a code path (`src/foo.ts:42`, `(42,10)` form, stack-trace frames) opens that file in the editor at the line
- Terminal real copy/paste: Ctrl+Shift+C and Ctrl+Shift+V, plus a right-click menu. Plain Ctrl+C still sends SIGINT
- In-app docs hub: the Help panel is now a real docs hub with section rail, search, and a written guide for every feature
- Settings restructured into seven labeled groups: Look & Feel, Models & Providers, AI Behavior, Workspace, Integrations, Privacy & Safety, About & Support. Fleet got its own entry; Knowledge got its own icon
- Finished sessions show their QEL verification score in the chat sidebar
- Hardening: Windows backend tree-kill on quit + parent-death watchdog (fixes the orphan-port-3000 bug), logger EPIPE on shutdown swallowed, security pass 0 critical / 0 high, air-gap extended to Git AI features so a commit-message or review request cannot leak a diff to the cloud
- 6,203 backend / 1,682 frontend tests green at tag
- v1.0.0-beta.25Feature
Fleet Parallel, ACP host, queryable Codebase Wiki
- Fleet Parallel: fan one task out to multiple models in isolated git worktrees, then QEL scores the resulting diffs so you pick the winning attempt
- ACP support: Cursor, Claude Code, Gemini CLI, and Codex now run inside Bodega's fleet via Agent Client Protocol, routed through Bodega's sandboxed filesystem and shell so air-gap mode still holds
- Codebase Wiki: the dependency-graph view wired into the embedding index, producing a queryable knowledge layer that can explain a file, document the repo, or answer questions grounded in real code
- Pre-ship 6-agent review fleet (security, architecture, perf, tests, docs) ran in parallel
- Context Inspector display fix: was quietly applying the local GPU's 64K VRAM ceiling to cloud models with 1M context. The agent was never actually capped; the display just lied. Three hardcoded "local" call sites fixed
- Command-classification fix: typing "yo" in code mode no longer gets classified as a command and burns 12 iterations of the agent trying to "do" a greeting
- 6,203 backend / 1,682 frontend tests green at tag
- v1.0.0-beta.24.1Fix
Windows portable install hotfix + clearer local-model memory errors
- Fixed: The Windows portable install (irm … | iex) failed for everyone with "Could not locate sha512 … in latest.yml". The portable .zip was never listed in electron-builder's update manifest, so the installer's integrity check could never pass. The installer now verifies the download against GitHub's per-asset SHA-256 digest (with latest.yml as a fallback), and the release pipeline writes the portable hash into latest.yml so the manifest is complete.
- Fixed: A local model that's too big for your memory showed a useless "Something went wrong." When a model exceeds free VRAM or system RAM (e.g. a 14B on a 16 GB card with little free memory), Bodega now tells you that's the problem and suggests a smaller model, instead of pointing you at a diagnostics export.
- Fixed: The model picker truncated the model name behind capability badges (e.g. q… beside code/tools/fim). The name stays readable now; badges are capped so they can't crowd it out.
- v1.0.0-beta.24Feature
Local two-model vision on llama.cpp, guided tour, in-app changelog
- Local two-model vision now runs on llama.cpp (the managed engine): attach an image to a local text-only coding model and Bodega hot-swaps in a bound local VLM to answer, then swaps your coding model back. One round trip, you stay in context
- Vision-swap inline narration card, plus the overlay-occlusion fix so it no longer renders behind the full-screen swap overlay
- Guided tour overhaul: a real walkthrough of Chat, Code, Fleet, the model picker, and settings
- In-app changelog in Settings, plus a What's New popup trimmed to just the current release
- llama.cpp onboarding hardening: Windows install reliability, friendlier errors, skip redundant re-downloads
- Four live-smoke bug fixes, three of them ship-blockers, including a first-run model-wipe bug latent since beta.17
- Beta extended to November 1
- +168 backend / +154 frontend tests (5,130 / 1,278 total), zero regressions
- v1.0.0-beta.23Feature
Dockview migration + split editor + two-model VLM orchestration
- Drag any panel anywhere: Editor, Explorer, Terminal, Agent, Preview, Fleet, Outline
- Split editor: two Monaco panes side by side with Ctrl+\
- Two-model VLM orchestration: local text-only coding models can route vision questions through a bound local VLM
- Settings opens as an editor tab in code mode
- Cloud provider payment_required classifier across 8 providers (OpenAI, Anthropic, DeepSeek, OpenRouter, Mistral, Together, Groq, Fireworks)
- +73 frontend tests, +103 backend tests, no regressions
- v1.0.0-beta.21Feature
Agent vision: screenshot the rendered preview
- PreviewInteractionTool: agent screenshot, DOM inspection, console capture, navigate, click
- Preview is now a real editor tab, auto-opens on dev server detection
- llama.cpp vision support: LLaVA 1.6 Mistral 7B and Moondream2 with paired mmproj download
- Vision chip on cloud and local VLMs in the model picker
- Grouped and collapsible model dropdowns
- v1.0.0-beta.20Feature
Fleet: background agent sessions in isolated git worktrees
- Fleet: send any session to background, keeps running on its own branch with 4 concurrent runs per project
- Persistent sessions survive SSE disconnect; re-attach with full mid-stream state
- Multi-provider routing recovery: each session sticks to the provider it started with
- Auto-commit AI changes: every agent file write becomes a real git commit
- Multi-file QEL oscillation guard catches local models stuck rewriting the same file
- v1.0.0-beta.19Improvement
2.15 MB renderer bundle reduction + SettingsService god-file split
- Ollama timeout now hardware-tier aware (360s for sub-6 GB VRAM machines)
- Terminals open in your active project directory
- file_system.read accepts offset and length params, so agents can paginate huge files
- Featherless and DeepSeek-V3 native tool calling works end-to-end
- Biggest god-file split: SettingsService from 915 to 335 lines into 5 modules
- v0.9Beta
Beta launch
- Open beta begins rolling out to the waitlist
- All features from v0.8 stable, plus a direct beta feedback channel in Discord
- Windows, macOS, and Linux installers available
- v0.8Improvement
QEL v2: 5-step verification pipeline
- Quality Enforcement Layer rebuilt with 5 formal verification stages
- Contract Extraction: prompt parsed into machine-checkable deliverables in <5ms, no LLM call
- Incremental Verification: pattern + compile check after every file write
- Proof gates now prevent the agent from marking a task complete before it compiles
- Targeted Repair: per-file, line-level fix instructions, not "try again"
- v0.7Feature
BYOLLM stable: 10+ provider presets
- LLM provider system moved from experimental to stable
- 10 provider presets: Ollama, LM Studio, OpenAI, Anthropic, Groq, Together AI, MistralAI, Gemini, DeepSeek, Llama
- Provider switching takes effect immediately. No restart required
- Per-session model override: set a different model for a single conversation
- v0.6Feature
Monaco editor + Code Mode GA
- Monaco editor integrated as the primary code editor
- Code Mode released as generally available: file tree, multi-terminal, diff viewer
- Autonomous coding agent writes real diffs instead of inline suggestions
- Permission modes: Ask, Plan, and Act control how much the agent does autonomously
- v0.5Feature
Chat Mode + 4-layer memory system
- Chat Mode released: full-screen AI conversation with streaming responses
- 23 built-in tools available in Chat Mode: file read/write, shell, web search, multi-agent spawning, and more
- 4-layer memory system: session context, project context, user preferences, long-term facts
- Memory persists across sessions. The AI remembers your project without re-prompting
Looking for setup help? Visit our documentation · See the roadmap · Full release notes on GitHub