Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,46 @@
## [0.32.0] - 2026-10-08

### Behavior Changes
- Non-interactive runs (a prompt on the command line) that stop at a context limit now exit with code 2 instead of 1 and keep the session, with a `--resume <session>` hint. This covers a request refused before sending (`request_input_limit`), local compaction that cannot make the conversation fit (`context_compaction_hard_fit`), and a context overflow reported by the provider (`provider_context_overflow`). With `--json`, these are reported as a `context_paused` event (with `code`, `sessionId`, and `recovery`) instead of an `error` event.
- In non-interactive runs, a run-budget pause now always stops the run with exit code 2 and a `--resume <session>` hint; with `--json` it emits a `run_budget_paused` event (with `code`, `sessionId`, `evidence`, and `recovery`). Budget pauses only happen when `agent.runBudget.escalation` is set to `contain` or `pause`. `--auto-approve` approves tools only and never grants more budget. In 0.31.x, `pause` combined with `--auto-approve` granted the parent run-budget extensions automatically. With the default `warn`, nothing changes.
- Before each model request, term2 now refuses a request whose estimated input does not fit the model's context window from the model catalog, after reserving the output allocation and a 10% estimation margin. The new `agent.maxRequestInputTokens` setting can only lower this limit, never raise it. Models with a small or under-reported context window may therefore refuse requests that 0.31.x sent. Settings files from earlier versions contain `agent.maxOutputTokens: 32000`, which counts as an explicit choice, so up to 32,000 tokens (capped at the model's maximum output) are reserved. If a small-window model refuses requests, lower or remove that setting.
- Turns with an active durable goal make at least one extra model request for the new goal stop check, plus one per reminder. When the reminders run out, the turn ends with the "Goal stop check unresolved…" notice (`goal_check_unresolved`; printed on stderr in non-interactive mode) and the goal stays active.
- New defaults apply to fresh installs only. Earlier versions saved their defaults into `settings.json`, and those saved values are kept on upgrade: context compaction stays off (`agent.contextCompaction.enabled: false`) until you enable it, and the saved `agent.maxOutputTokens: 32000` counts as explicit, so the new quarter-of-context-window output cap does not apply.
- Downgrading to 0.31.x: 0.31.x cannot load a settings file with `agent.runBudget.escalation: "contain"` ("Failed to parse settings file"), so set it back to `warn` or `pause` before downgrading. 0.31.x also drops `agent.maxRequestInputTokens` and writes `agent.maxOutputTokens: 32000` back into the file. Otherwise, a settings file created by 0.32.0 loads in 0.31.x.

### Features
- Active session goals now have a stop check. While a durable goal is active, the agent reports its progress through a new `goal_check` tool (`achieved`, `blocked`, `not_achieved`, or `deferred`) before a turn can end. If it tries to stop without a valid check, term2 reminds it and the same turn continues. Reminders are capped: two in a row without new work, or six per user message. At the cap the turn ends and the goal stays active.
- A valid `achieved` goal check that ends a turn now closes the durable goal on its own, just like `/goal achieved`. The goal is saved as achieved and its status line is shown (on stderr in non-interactive mode). `blocked`, `deferred`, and `not_achieved` checks never change the goal, and subagents and `run_code` scripts cannot close it. A check counts only for the goal the agent was shown: if you replace the goal with `/goal set` (from the prompt or the control socket) while a turn is running, the earlier check is not recorded or does not count, and the agent is asked to check the new goal instead.
- Requests that cannot fit the model's known context window are paused before sending, with your conversation and completed work kept, instead of failing at the provider. `agent.maxRequestInputTokens` sets an optional lower input ceiling (default: none beyond the model's capacity).
- New opt-in `contain` run-budget escalation (`agent.runBudget.escalation: "contain"`): when a run exhausts its budget, it pauses so you can decide whether to grant more; warnings and stall evidence stay advisory. In non-interactive mode it exits with code 2 and prints the `--resume <session>` command to continue; `--auto-approve` never grants budget. The default stays `warn`.
- `TERM2_SUPERVISED=1` is an environment override for an unattended-run profile: an 80,000-token request input ceiling, an 8,192-token output allocation, and local context compaction at 60,000 tokens. It applies to any term2 process started with the variable set, including interactive sessions, and is never written to `settings.json`. It does not change the run-budget escalation.

### Bug Fixes
- A one-time tool approval or rejection now applies only to the call you answered. Previously, a later call that reused the same call ID could inherit the decision with different arguments, for example on OpenAI-compatible providers that number calls `call_0`, `call_1`, … in every response. Such calls now prompt again. Tool calls without an ID get one unique to their response. With several pending calls that share an ID, a decision settles exactly the call it was made for. Subagents and `run_code` child agents inherit only your "always" decisions, and a blanket rejection always uses its own message.
- OpenRouter requests now forward the selected reasoning effort and keep explicitly configured OpenRouter options.
- Session search no longer stalls on very common search terms. When the session index is unavailable, browsing and search run off the UI thread.
- Codex WebSocket sessions no longer send a chained request over a replacement connection that cannot resolve the previous response; they recover from full history instead. A WebSocket closed with code 1000 before the response finished is now retried.
- `/retry-tool` rewinds to the correct position in the conversation.
- After a crash or forced exit during a tool call, resuming the session marks that call's outcome as unobserved and tells the agent to verify the current state before retrying, instead of dropping the call from the resumed conversation, where the agent could blindly repeat it.
- `/goal set`, `/goal achieved`, and `/goal abandon` now confirm the goal that was just written, not the previous one.
- A saved `agent.maxModelRequestDurationMs` of exactly 300000 is no longer rewritten to 0 (no deadline) at startup; it is kept as a 5-minute request deadline. Earlier versions treated that one value as a leftover of an old default; no other value was rewritten.
- Context estimates no longer count history twice after a self-contained request, which could trigger compaction or a context pause too early.

### Improvements
- Context compaction is enabled by default for new installs (`agent.contextCompaction.enabled`, auto mode at 80% of the context window). Existing settings files keep `enabled: false`; set it to `true` to opt in. Local compaction keeps your own messages, recent paired tool rounds, and tool receipts, and runs again only after the conversation has grown.
- When `agent.maxOutputTokens` is not set in `settings.json`, the output allocation is capped at a quarter of a known model's context window (and at most 32,000 tokens), so small models keep room for input. New installs no longer write this key. Files from earlier versions contain `32000`, which counts as explicit; remove the key to get the cap.
- One-shot subagents now inherit the selected output limit, stream output limit, request deadline, and stream idle timeout; a role's own output limit still takes precedence.
- `/retry-turn` now regenerates the entire latest user turn from its original prompt.
- `/clear` now marks the start of the new conversation with a labelled divider. The working indicator renders above the live divider, the bottom area is more compact, and the rail skin shows quota in its status line.

### Internal/Chores
- Before release, the run-budget escalation default was set back to `warn` (`contain` is opt-in). Non-interactive mode parks every run-budget check-in, and the non-interactive approval policy refuses all run check-ins, so `--auto-approve` cannot grant budget or turns under any escalation.
- `scripts/release.sh` now refuses to tag unless it runs on `main`, a fetch of the remote's `main` succeeds, and HEAD is the remote's `main` (or one unpushed release commit on top of it). HEAD must also be the `chore(release): vX.Y.Z` commit with `package.json` at `X.Y.Z`. The tag is pushed only after `main` was pushed and confirmed on the remote; a failed `main` push never pushes the tag.
- Test fixtures no longer write into the repository tree: settings and skills fixtures use temporary directories, and the sandbox network-approval test no longer writes `.term2/sandbox-network-hosts.json` into the checkout.
- CI now runs the full check suite on pull requests, and focused test runs start faster.
- Added an opt-in workflow-evolution experiment ledger, run from a checkout (`docs/workflow-evolution.md`) and not exposed through the `term2` command, and a supervised-worker launcher under `tools/supervised-term2`, which is not part of the published package.
- README and website refresh, including a demo recording.

## [0.31.1] - 2026-10-04

### Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qduc/term2",
"version": "0.31.1",
"version": "0.32.0",
"description": "A terminal-based AI assistant that can help you get things done on your computer",
"license": "MIT",
"author": "qduc",
Expand Down
Loading