You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Codex server compaction never triggers when Claude Code appends a system-role message after the user turn (hooks / output styles) #204
Versions: claude-code-proxy 0.1.47 (macOS, behind a local shim), Claude Code 2.1.319, codex.serverCompaction: true.
What happens: a manual /compact in Claude Code 2.1.319 (and, by the same request shape, automatic compaction) reaches the proxy as a normal /v1/messages request with the x-claude-code-session-id header, but server_compaction_triggered is never logged and no compaction_trigger request goes to Codex. Claude Code still gets its portable text summary, so nothing looks broken.
Why (from a CCP_TRAFFIC_LOG=1 capture of the actual request):
The request keeps Claude Code's normal system prompt (cache-safe). It does not contain You are a helpful AI assistant tasked with summarizing conversations, so is_compact_request(system) is false.
The compaction instruction (CRITICAL: Respond with TEXT ONLY. Do NOT call any tools. … Your task is to create a detailed summary of the conversation so far …) is appended to the text of the last user message; both markers are present there.
But messages.last() is not that user message. When a UserPromptSubmit hook or an output style emits text, Claude Code appends a system-role message after the user turn (ours begins Concise output style is active. … UserPromptSubmit hook success: …). is_compact_messages_request only inspects request.messages.last() and requires role == "user" (src/providers/codex/translate/request.rs), so detection returns false. Roles of the captured request, in order: assistant, user, system, assistant, user, system.
Repro: Claude Code 2.1.319 with any UserPromptSubmit hook that prints a line (or an active output style), a Codex model through the proxy, two short turns, then /compact → no server_compaction_* event in the proxy log (three runs here: 0 events). Control: the same kind of body sent with curl to the proxy with the session header and the compaction instruction as the final user message → server_compaction_triggered and server_compaction_completed within 5 s.
Fix: look at the last user message, skipping trailing system-role messages (PR follows). A trailing assistant message should still mean "not a boundary".
Side observation for the docs: in 2.1.319 a /compact on a short context (one summary plus two turns) produced a new summary without any upstream request at all, so a boundary is not always one summary request.
Activity