• Oganneson's avatar
    fix(openai): drop reasoning items from /v1/responses input on OAuth path · 7452fad8
    Oganneson authored
    Closes #1957
    
    The OAuth path forwards client requests to chatgpt.com/backend-api/codex/responses,
    where applyCodexOAuthTransform forces store=false (chatgpt.com's codex backend
    rejects store=true). Reasoning items emitted under store=false are NEVER
    persisted upstream, so any rs_* reference that a client carries forward in a
    subsequent input[] array triggers a guaranteed upstream 404:
    
        Item with id 'rs_...' not found. Items are not persisted when `store` is
        set to false. Try again with `store` set to true, or remove this item
        from your input.
    
    sub2api wraps this as 502 "Upstream request failed" and the conversation
    breaks on every multi-turn /v1/responses request that uses reasoning + tools
    (reproducible with gpt-5.5; gpt-5.4 happens to dodge it because the upstream
    does not emit reasoning items for that model).
    
    Affected clients include any that follow the OpenAI Responses API spec and
    replay prior assistant items verbatim — in practice this hit OpenClaw and
    similar agent harnesses on every turn ≥2 with tool use.
    
    The fix: in filterCodexInput, drop input items with type == "reasoning"
    entirely. The model never reads reasoning summary text from input (only
    encrypted_content can carry reasoning context across turns, and chatgpt.com
    under store=false does not emit it), so this is a no-op for the model itself
    and a clean removal of unreachable upstream lookups.
    
    Scope is intentionally narrow:
      * Only OAuth account requests (account.Type == AccountTypeOAuth) reach
        applyCodexOAuthTransform / filterCodexInput.
      * API-key accounts going to api.openai.com/v1/responses are unaffected
        (store=true works there, rs_* persists, multi-turn already works).
      * Anthropic / Gemini platform groups go through different transforms and
        are unaffected.
      * /v1/chat/completions is unaffected (no reasoning items).
      * item_reference items (different type) are unaffected — only type ==
        "reasoning" is dropped.
    
    Verification:
      * Existing tests pass: go test ./internal/service/ -run Codex|Tool|OAuth
      * New regression test asserts reasoning items are dropped under both
        preserveReferences=true and preserveReferences=false.
      * End-to-end repro on gpt-5.5 multi-turn + tools: pre-patch 502, post-patch
        200. Repro on gpt-5.4 unchanged. Three-turn deep loop on gpt-5.5 passes.
    7452fad8
openai_codex_transform.go 27.6 KB