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.