Extract the cch hash from Claude Code's billing header in the system
prompt (x-anthropic-billing-header: ...cch=XXXXX;) and use it to derive
a deterministic conversation_id instead of generating a random UUID.
Same Claude Code session → same cch → same conversation_id → Cursor
server can reuse conversation state across multiple turns, preserving
tool call results and other context without re-encoding history.
Also cleans up temporary debug logging from previous iterations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Include system prompt prefix (first 200 chars) in session key derivation.
Claude Code sessions have unique system prompts containing cwd, session_id,
file paths, etc., making collisions between concurrent sessions from the
same user virtually impossible.
Session key now = SHA256(apiKey + model + systemPrompt[:200] + firstUserMsg)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Include client API key in session key derivation to prevent different
users sharing the same proxy from accidentally resuming each other's
H2 streams when they send identical first messages with the same model.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When an assistant message appears after tool results without a pending
user message, append it to the last turn's assistant text instead of
dropping it. Also add bakeToolResultsIntoTurns() to merge tool results
into turn context when no active H2 session exists for resume, ensuring
the model sees the full tool interaction history in follow-up requests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rewrite tool call mechanism from interrupt-resume to inline-wait mode:
processH2SessionFrames no longer exits on mcpArgs; instead blocks on
toolResultCh while continuing to handle KV/heartbeat messages, then
sends MCP result and continues processing text in the same goroutine.
Fixes the issue where server stopped generating text after resume.
- Add switchable output channel (outMu/currentOut) so first HTTP response
closes after tool_calls+[DONE], and resumed text goes to a new channel
returned by resumeWithToolResults. Reset streamParam on switch so
Translator produces fresh message_start/content_block_start events.
- Implement send-side H2 flow control: track server's initial window size
and WINDOW_UPDATE increments; Write() blocks when window exhausted.
Fixes RST_STREAM FLOW_CONTROL_ERROR on large requests (178KB+).
- Decode new InteractionUpdate fields: TurnEndedUpdate (field 14) as
stream termination signal, HeartbeatUpdate (field 13) silently ignored,
TokenDeltaUpdate (field 8) for token usage tracking.
- Include token usage in final stop chunk (prompt_tokens estimated from
payload size, completion_tokens from accumulated TokenDeltaUpdate deltas)
so Claude CLI status bar shows non-zero token counts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Read maxAssetDownloadSize+1 bytes and error if exceeded, preventing
silent truncation that could write a broken management.html to disk
- Log explicit warning when fallback URL is used without digest
verification, so users are aware of the reduced security guarantee
- Abort update when SHA256 digest mismatch is detected instead of
logging a warning and proceeding (prevents MITM asset replacement)
- Cap asset download size to 10 MB via io.LimitReader (defense-in-depth
against OOM from oversized responses)
- Add `auto-update-panel` config option (default: false) to make the
periodic background updater opt-in; the panel is still downloaded
on first access when missing, but no longer silently auto-updated
every 3 hours unless explicitly enabled
Apply SanitizeFunctionName on request and RestoreSanitizedToolName on
response for: gemini/claude, gemini/openai/chat-completions,
gemini/openai/responses, antigravity/openai/chat-completions,
gemini-cli/openai/chat-completions.
Also update SanitizedToolNameMap to handle OpenAI format
(tools[].function.name) in addition to Claude format (tools[].name).
Claude Code and MCP clients may send tool names containing characters
invalid for Gemini's function_declarations (e.g. '/', '@', spaces).
Sanitize on request via SanitizeFunctionName and restore original names
on response for both antigravity/claude and gemini-cli/claude translators.
- Introduced a new method `buildRecord` in `usageReporter` to encapsulate record creation, improving code readability and maintainability.
- Added latency tracking to usage records, ensuring accurate reporting of request latencies.
- Updated tests to validate the inclusion of latency in usage records and ensure proper functionality of the new reporting structure.
When Claude sends redacted thinking with empty text, the translator
was omitting the "text" field from thought parts. Google Antigravity
API requires this field, causing 500 "Unknown Error" responses.
Verified: 129/129 error logs with empty thought → 500, 0/97 success
logs had empty thought. After fix: 0 new "Unknown Error" 500s.