Nanocoder v1.31.0 — nanocoder
What's Changed Added a first-class provider template for Cheaper Inference, an OpenAI-compatible gateway, to the /settings providers wizard. Selecting it fills in the base URL (https://api.cheaperinference.com/v1) so only an API key and a model name are…
Read full notes
What's Changed
- Added a first-class provider template for Cheaper Inference, an OpenAI-compatible gateway, to the
/settings providerswizard. Selecting it fills in the base URL (https://api.cheaperinference.com/v1) so only an API key and a model name are needed, and the wizard can fetch the account's model list over the standard/modelsendpoint. - Added a
showAgentBashOutputpreference (/settings→ Behavior → Tool Results and Thinking). By default a completed card for a command the agent runs shows the command and its status, and the command output is not kept; with compact tool display on, the card collapses into a tally line. This preference shows the output on that card, whether compact tool display is on or off, and for failed commands too. Commands you type yourself (!command) always show their output and are unaffected. - Publish a JSON Schema for
agents.config.jsonasschemas/agents.config.schema.json. It is generated deterministically from the on-diskDiskConfigtype (pnpm run generate:schema), ships with an Ajv validation suite plus a CI drift check, and enables editor autocompletion — either by dropping the$schemakey into your config or by wiring up the schema viajsonValidation/ a JSON Schema mapping in your editor. - Added automatic session titles. A session keeps its opening prompt as the title, and when that prompt is too thin to be useful the agent generates a descriptive name once, after the first turn that ran a tool or the first follow-up message. Manual renames are never overwritten.
Titling runs in the ACP agent, so it applies to the VS Code extension and other ACP clients; the CLI keeps its heuristic title.
It uses the session's own model by default - set sessions.titleModel / sessions.titleProvider to point it at a cheaper or local one, or sessions.smartTitles: false to turn it off.
Pointing titleProvider at a different provider sends it the opening user turns and a summary of the tools that ran, which includes file paths and bash command strings.
Two things worth knowing:
the tokens a title costs are billed by the provider but are not counted in /usage, since the call is made outside the conversation loop that builds usage records;
and existing sessions are retitled from their first message on their next autosave, which is a one-time visible reshuffle of the history list.
Also fixed the CLI's autosave deriving the session title from the latest user message and rewriting it on every save, which overwrote titles in the store the VS Code extension reads from. Closes #808.
- Added Anthropic prompt caching. The system prompt, tool schemas, and conversation history are now marked with cache breakpoints, so multi-turn sessions read the stable prefix back out of cache instead of paying full price for it every turn. Cost reporting is cache-aware throughout:
/usageand the per-response indicator price cache reads and writes at their own rates instead of billing every cache hit at the full input rate, and the per-response indicator surfaces the cached token count alongside the total. Opt out with"promptCaching": falseon the provider config. Closes #888. - Fix multi-line paste submitting the prompt partway through.
Nanocoder never enabled bracketed paste, so the terminal delivered a paste as bare bytes and the carriage return at each line break reached Ink's keypress parser as Enter. Pasting two lines sent the first line to the model and left the second in the input box. Paste handling relied entirely on heuristics (input rate, size, line count) that only ever saw text which had already made it into the buffer.
DECSET 2004 is now enabled in both screen modes. Paste payloads are lifted off stdin before Ink sees them and delivered to the input as a single event, so a pasted newline can no longer submit. The old heuristics remain as a fallback for terminals without bracketed paste support.
Fullscreen mode enables mouse reporting for wheel scrolling, which takes click-drag text selection away from the terminal. Selection there is Shift+drag (Option+drag in iTerm2), or turn mouse reporting off for the session with --no-mouse.
- Add JSON exports for
/export --jsonand.jsonfilenames, preserving full message content and session metadata for replay and evaluation workflows. Closes #1309. - Grouped each VS Code chat turn's thoughts, tool calls, edit cards, and task plan into one ordered, collapsible work summary while leaving the final answer visible. The summary reports completed, stopped, or failed duration and reopens for pending approvals. Thanks to @Gambit-Checkmate. Closes #858.
- Added support for a .nanocoderignore file. Patterns in it keep tracked-but-noisy files (lockfiles, generated fixtures) out of directory listings, file search and the file explorer, so they stop eating context even though .gitignore doesn't cover them. It is a context-hygiene tool rather than a secrets boundary: read_file and execute_bash don't consult it, and checkpoints deliberately skip it so hidden files are still snapshotted and restored. Thanks to @A-S-Manoj. Closes #755.
- Add configurable agent-loop retry limits to prevent token drain (#897). A new
nanocoder.retriessection inagents.config.jsonexposes the previously hardcoded caps:maxRepeatedToolCalls(default 3),maxEmptyTurns(default 2), andmaxMalformedRetries(default 2). When the repeated-tool-call limit is hit in an interactive session, Nanocoder now pauses and asks whether to continue (granting another window of attempts) or stop, instead of always hard-stopping; non-interactive runs keep the hard stop. The same limits now also protect the--plainruntime used bynanocoder runin CI and non-TTY environments, which previously had no repeated-call cap at all: each cap hard-stops with a clear error there. Note this also loosens--plainin two places: it used to return an error on the first empty response and on the first malformed tool call, and it now nudges or asks the model to self-correct up tomaxEmptyTurns/maxMalformedRetriesbefore stopping, so a silent or malformed-output model costs up to 3 model calls instead of 1. Set either limit to0to restore the old fail-fast behaviour. Calls to unknown tools count toward the repeated-call streak in both runtimes, so a model stuck on a nonexistent tool trips the same cap instead of looping until the turn ceiling. Delegated subagent runs, whose loop previously had no cap at all, now applymaxRepeatedToolCallstoo and stop with an error naming the setting.
One change reaches further than the retry limits themselves: a tool call naming a tool that does not exist is now kept in the assistant message's tool_calls rather than dropped from it. Without this the paired Unknown tool: X result was orphaned and pruned before the request went out, so the self-correction hint never reached the model and it re-emitted the same nonexistent call. This applies to all three runtimes that partition tool calls, including the ACP loop (--acp, used by editor clients), which is otherwise unaffected by the retry limits. The practical consequence is that providers now receive a tool call naming a tool that was not in the request's tool list.
- Add
nanocoder configto see your settings and which file each one came from.
Settings come from four places: built-in defaults, your global config folder, the project folder you're in, and NANOCODER_* environment variables. When a setting didn't do what you expected, finding out which file set it meant opening all four by hand.
Three commands:
nanocoder config list— every setting, its value, and the file it came fromnanocoder config show <key>— one setting in detail: its default, and any values it beatnanocoder config diff— only what your files change, plus values that are set but unused
All three take --json.
The part worth knowing. Settings are grouped into blocks, like autoCompact. Nanocoder takes the whole block from the first file that mentions it — it does not mix fields from two files. So if your global config sets threshold and notifyUser, and your project config sets only threshold, your notifyUser
…