A thinking-only stop still routes through the empty-stop handler
(isEmptyAssistantStop treats a non-actionable stop as empty) and bills
output tokens for its reasoning, so the billed-output branch would falsely
report that content was generated and dropped by a provider filter. Gate the
branch on a truly zero-block stop (content.length === 0) so thinking-only
stops keep the context/`/shake images` recovery hint.
Fixes#8511
An empty assistant `stop` that exhausts the retry cap always reported the
context/`/shake images` hint, even when the provider billed output tokens
for the turn. Billed output on a zero-block stop means content was generated
and then dropped downstream (a filter/refusal flattened to
`finish_reason: "stop"` by a proxy, or a lossy API translation), so the
images/context advice is actively misleading there.
Branch the capped `finalError` in `#handleEmptyAssistantStop` on
`assistantMessage.usage.output`: keep the context hint when nothing was
generated, and otherwise name the billed output-token count and point at a
provider-side filter/translation. Also log `outputTokens` alongside the
existing warning fields.
Fixes#8511
Reparent service-tier metadata before removing discarded empty turns. Persist a branch marker for content-bearing children so reload never selects the discarded subtree.
Fixes#5179
Empty assistant stops were reparented off the active leaf in memory only. The session loader rebuilds the active branch from the last physical journal entry, so a capped empty stop (or one killed mid-retry) resurfaced as the active leaf on reload. Added SessionManager.dropLeafEntry to physically remove the entry and rewrite the file, and route every empty-stop discard through it.
Fixes#5179
- Replaced time-based sleeps and polling loops with event-driven promise resolvers and fake timers across agent and tool tests.
- Migrated test suites to share in-memory auth storage and fixtures using lifecycle hooks.
- Updated catalog model definitions, metadata, and configurations.
- Added shared auth storage and model registry for concurrent and eager compaction tests.
- Replaced per-test auth storage creation and cleanup routines with shared lifecycle management.
- Removed local auth storage variables and individual cleanup hooks from test harness instances.
- Implemented in-house, zero-dependency utility modules in `pi-utils` covering DOM manipulation, markdown parsing, templating, browser automation helpers, and terminal buffers.
- Migrated packages across the repository to consume the new internal utilities and `omptype` schema validators instead of external dependencies.
- Removed multiple external runtime and development dependencies including Zod, Marked, LRU cache, Turndown, and Puppeteer browser packages.
Waited for the final assistant message_end persistence slot before reparenting past the capped empty turn.
Added a delayed extension hook regression proving the prompt cannot settle before persistence and the active branch remains clean.
Removed the final zero-content assistant after the empty-stop retry cap so its failed-request usage cannot re-anchor context maintenance.
Made the terminal error name model switching and /shake images as recovery options.
Fixes#5959
- Prevented compaction from reopening a settled terminal answer unless queued work or an active goal remains.
- Ran auto-learn capture in an abortable detached agent with constrained tools and isolated provider state.
- Replaced primary-turn capture coverage with private-capture regression tests.
Fixes#5715
Removed accepted empty Auto-Learn capture stops from live and persisted context, including the hidden capture prompt when it directly parents the no-op stop.
Extended the regression to prove the next real prompt does not replay the stale Auto-Learn nudge.
Fixes#5211
Cleared the terminal empty-stop acceptance flag for every agent-initiated prompt so non-opt-in custom turns cannot inherit Auto-Learn capture behavior.
Added a regression covering a non-opt-in custom turn after a non-empty Auto-Learn capture response.
Fixes#5211
Marked Auto-Learn capture turns as accepting terminal empty assistant stops so the empty-stop guard does not retry the expected no-reply completion.
Added a focused AgentSession regression covering the auto-continue capture turn.
Fixes#5211
Emitted a failed auto-retry event when empty assistant stop responses exhaust their retry cap so the TUI can show an error instead of silently settling.
Fixes#5128
Extension commands (e.g. /sonnet) and TypeScript custom commands that
consume the input without calling the LLM return early from
session.prompt() with no agent turn. In ACP mode this left the pending
prompt promise unresolved, hanging the client forever.
Change session.prompt() to return Promise<boolean>: true when the LLM
was invoked, false when the command was fully handled locally.
#runPromptOrCommand calls #finishPrompt immediately on a false return so
the ACP turn completes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When Anthropic Claude returns stopReason: "toolUse" but the assistant
message contains no actual toolCall, the session would append a spurious
toolResult entry. This creates tool_result blocks without matching
tool_use blocks — structurally invalid for Anthropic's API validator.
The symptom is overloaded_error on every subsequent request (in: 0 out: 0),
even though servers aren't overloaded. Other providers handle the same
corrupted history more leniently, making the problem appear Anthropic-specific.
The #isEmptyAssistantStop guard now checks for stopReason === "toolUse"
with no text and no toolCall. When the retry cap is hit, tool-use orphans
are still removed from active context (unlike regular empty stops) because
they corrupt message history. A regression test covers both the retry and
cap scenarios.
For affected sessions: run /compact to drop the corrupted history tail.
Fixes review feedback from chatgpt-codex-connector.
- Aligned handoff, reminder, and system-prompt expectations with shortened copy.
- Added HTTP transport test for required initialize failures.
- Guarded SSE startup timeout against stale connection races.