Skip to content

translate: send x-grok-conv-id affinity header for grok via openai_gateway - #1121

Merged
steventohme merged 1 commit into
mainfrom
devin/1787958477-grok-conv-id-gateway
Aug 28, 2026
Merged

translate: send x-grok-conv-id affinity header for grok via openai_gateway#1121
steventohme merged 1 commit into
mainfrom
devin/1787958477-grok-conv-id-gateway

Conversation

@devin-ai-integration

Copy link
Copy Markdown
Contributor

Summary

xAI's prompt-caching docs say the cache-routing knob on Chat Completions is the x-grok-conv-id HTTP header; prompt_cache_key is only honored on their Responses API. #1101 sends the body-level prompt_cache_key for openai_gateway targets, which xAI ignores on chat/completions — so grok served through a BYOK gateway (e.g. Snowflake Cortex) still misses the warm cache.

applySessionAffinity now also sets the header when the gateway target is a grok model:

case providers.ProviderOpenAI, providers.ProviderOpenAIGateway:
    if opts.TargetProvider == providers.ProviderOpenAIGateway &&
        strings.HasPrefix(opts.TargetModel, "grok") && opts.SessionAffinity != "" {
        headers.Set("x-grok-conv-id", opts.SessionAffinity)
    }
    // prompt_cache_key body handling unchanged
  • Gateway-only and grok-only: direct OpenAI never serves grok, and non-grok gateway models keep the body field alone (no unknown-header risk for them).
  • The header survives StripPromptCacheKey — a gateway 400ing on the body field says nothing about headers.
  • Verified live against the customer's Cortex endpoint: an identical chat/completions repeat with x-grok-conv-id returned cached_tokens=2304 (of 2348), while prompt_cache_key alone (body, either surface) returned 0 across all probes. Cache hits remain best-effort — repeats can still land cold replicas.

Tests: session_affinity_test.go — gateway grok gets the header, non-grok gateway and direct-OpenAI grok don't, header kept on the strip-and-retry path.

Link to Devin session: https://app.devin.ai/sessions/85739dd5156f4ffd9b4ce1941cd91e13
Open in Devin Desktop: https://app.devin.ai/desktop/session/85739dd5156f4ffd9b4ce1941cd91e13?variant=devin
Requested by: @steventohme

@greptile-apps

greptile-apps Bot commented Aug 28, 2026

Copy link
Copy Markdown

PR author is not in the allowed authors list.

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@claude

claude Bot commented Aug 28, 2026

Copy link
Copy Markdown

Claude finished @devin-ai-integration[bot]'s task —— View job


No comment-length issues found — no added comment blocks of 3 or more consecutive lines.

@steventohme
steventohme enabled auto-merge (squash) August 28, 2026 23:10
@steventohme
steventohme merged commit 6ebd642 into main Aug 28, 2026
15 checks passed
@steventohme
steventohme deleted the devin/1787958477-grok-conv-id-gateway branch August 28, 2026 23:17
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author
Runtime wire verification: x-grok-conv-id via openai_gateway

Ran this branch locally in docker compose against mock gateway upstreams and inspected the mocks' request logs.

✅ grok-4.6 via openai_gateway, two-turn session: every /v1/chat/completions request carried x-grok-conv-id=dac038eb757c666b53fa7af67faddedc — non-empty, identical across turns, and equal to the body prompt_cache_key.

✅ Non-grok gateway model (gpt-5.4-mini): header absent; body prompt_cache_key still injected as before.

✅ Strip-and-retry survival (strict gateway that 400s prompt_cache_key as unknown field): first dispatch → 400 with body key + header; pre-commit retry → 200 with no body key but the same x-grok-conv-id; client saw 200. Second turn memoized (single request, header still present).

⚠️ Two observations for follow-up:

  1. The first-turn /v1/responses probe carries prompt_cache_key but no x-grok-conv-id (the header lives only in the chat/completions emit path) — grok reasoning turns that stay on a Responses-capable gateway go out unhinted.
  2. grok-4.6 isn't in the local deployed-model registry, so a gateway alias for it can't even be created via the admin API (auth: unknown model id) — I had to patch the cluster artifacts + DB to route it locally (reverted after). Worth confirming the prod deployed set includes grok so this path is actually reachable.

(Direct first-party OpenAI absence not runtime-tested; the header is gated on ProviderOpenAIGateway and the non-grok case above proves the model gate.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant