Skip to content

feat(proxy): forward Anthropic speed:fast to Codex priority tier#170

Merged
james-6-23 merged 1 commit into
james-6-23:mainfrom
caocuong2404:feat/forward-anthropic-speed-fast-to-codex-priority
May 26, 2026
Merged

feat(proxy): forward Anthropic speed:fast to Codex priority tier#170
james-6-23 merged 1 commit into
james-6-23:mainfrom
caocuong2404:feat/forward-anthropic-speed-fast-to-codex-priority

Conversation

@caocuong2404

@caocuong2404 caocuong2404 commented May 26, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Map Claude Code / Anthropic speed:"fast" to upstream Codex service_tier:"priority" (matches official Codex CLI ServiceTier::Fast mapping).
  • Omit service_tier when speed is absent or not fast; do not parse Anthropic request-side service_tier (Priority Tier is a separate capability).
  • Log resolved service_tier on /v1/messages for Usage admin fast-mode stats; document behavior in docs/API.md and docs/ARCHITECTURE.md.

Test plan

  • go test ./proxy/... -run 'Anthropic|ServiceTier|Speed'
  • Claude Code with /fast ON → upstream WS body includes service_tier: priority
  • Usage admin shows fast intent when upstream downgrades to default

Envidence

Claude Code:

image

Codex upstream request log:

image

Admin UI Show:

image

Summary by CodeRabbit

  • New Features

    • Added /v1/messages endpoint with Anthropic Messages compatibility.
    • Requests with speed:"fast" now map to a priority service tier; responses may be streamed (SSE) or returned as aggregated JSON.
    • Resolved service-tier information is surfaced in response headers and usage logs.
  • Documentation

    • Updated API and architecture docs with Anthropic Messages translation rules and behavioral notes.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds Anthropic Messages (POST /v1/messages) docs and implements mapping of Anthropic speed:"fast" → Codex service_tier:"priority" in translation, captures upstream-reported response.service_tier, resolves a final service tier, exposes it as x-service-tier, and records it in usage logs.

Changes

Anthropic Messages Service Tier Support

Layer / File(s) Summary
Documentation and API contract
docs/API.md, docs/ARCHITECTURE.md
Public API documentation introduces /v1/messages endpoint with speed-to-service_tier field mapping rules, and architecture documentation explains the translation path and tier resolution behavior.
Request translation logic
proxy/anthropic.go
anthropicRequest gains optional Speed field; translation layer checks speed, and when it equals "fast" maps to service_tier:"priority" in the Codex request payload via upstreamServiceTier("priority").
Translation and tier resolution tests
proxy/anthropic_test.go
Existing test assertions extended to verify service_tier is absent when speed is absent; new table-driven tests verify speed:"fast" maps to service_tier:"priority" and confirm tier resolution behavior across speed intent scenarios.
Handler request and response tier integration
proxy/handler_anthropic.go
Handler extracts serviceTier from translated Codex request, captures response.service_tier from both streaming and non-streaming upstream events, resolves final tier value, exposes it as x-service-tier header, and includes it in usage logging.

Sequence Diagram

sequenceDiagram
  participant Client
  participant TranslateAnthropicToCodex
  participant upstreamServiceTier
  participant CodexUpstream
  participant Handler
  participant UsageLogger
  Client->>TranslateAnthropicToCodex: POST /v1/messages (speed)
  TranslateAnthropicToCodex->>TranslateAnthropicToCodex: shouldUseCodexPriorityForAnthropicSpeed()
  TranslateAnthropicToCodex->>upstreamServiceTier: upstreamServiceTier("priority")
  upstreamServiceTier-->>TranslateAnthropicToCodex: priority tier value
  TranslateAnthropicToCodex->>CodexUpstream: send Codex request (maybe service_tier)
  CodexUpstream-->>Handler: response.completed (may include response.service_tier)
  Handler->>Handler: resolveServiceTier(actualServiceTier, serviceTier)
  Handler->>UsageLogger: record UsageLogInput.ServiceTier
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • james-6-23/codex2api#153: Related changes around how fast/priority tiers are determined and used for billing/usage logging.

Poem

🐰 I sniffed the speed and chased the tier,
Fast became priority—crystal clear.
From request to upstream, the tiers align,
Logged and headered, a tidy design.
Hop, hop—service routed, all lines fine!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main feature: forwarding Anthropic speed:fast to Codex priority tier, which is the core objective of this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@caocuong2404 caocuong2404 force-pushed the feat/forward-anthropic-speed-fast-to-codex-priority branch from 360e46e to bd19194 Compare May 26, 2026 08:45

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/API.md`:
- Line 312: The table cell containing the text "模型映射映射到 Codex 模型名(如 Claude →
`gpt-5.5`)" has a duplicated word "映射"; update that string to read "模型映射到 Codex
模型名(如 Claude → `gpt-5.5`)" (remove the duplicate "映射") so the description is
correct.
- Line 315: Docs state the fallback for reasoning.effort is "medium" but runtime
actually falls back to "high" when no output_config.effort is provided and
Anthropic thinking.type is not set; update the docs entry for reasoning.effort
to reflect the runtime default "high" (keeping the rest about preferring
output_config.effort, the Anthropic thinking.type/budget_tokens mapping, and
normalization to low/medium/high/xhigh intact) so documentation matches the
implementation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 7d7f37d4-0e29-4b0e-a8d1-fa73c1bd8189

📥 Commits

Reviewing files that changed from the base of the PR and between 1ca1d67 and 360e46e.

📒 Files selected for processing (5)
  • docs/API.md
  • docs/ARCHITECTURE.md
  • proxy/anthropic.go
  • proxy/anthropic_test.go
  • proxy/handler_anthropic.go

Comment thread docs/API.md Outdated

| 主题 | 行为 |
|------|------|
| **模型** | 经管理台模型映射映射到 Codex 模型名(如 Claude → `gpt-5.5`) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix duplicated wording in the model mapping description.

Line 312 contains 模型映射映射 (duplicate “映射”).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/API.md` at line 312, The table cell containing the text "模型映射映射到 Codex
模型名(如 Claude → `gpt-5.5`)" has a duplicated word "映射"; update that string to
read "模型映射到 Codex 模型名(如 Claude → `gpt-5.5`)" (remove the duplicate "映射") so the
description is correct.

Comment thread docs/API.md Outdated
| **模型** | 经管理台模型映射映射到 Codex 模型名(如 Claude → `gpt-5.5`) |
| **`speed`** | Anthropic 入参仅识别官方 `speed:"fast"`,并映射为 Codex `service_tier:"priority"`;其它 `speed` 值不触发 priority |
| **`service_tier`** | Anthropic 请求侧 `service_tier` 不在当前兼容范围内,不从该字段解析 fast mode |
| **`reasoning.effort`** | 优先使用 `output_config.effort`(经归一为 `low` / `medium` / `high` / `xhigh`);否则若存在 Anthropic **`thinking.type=enabled`**,按 `budget_tokens` 粗映射档位;否则默认 **`medium`**(避免未带 `output_config` 的客户端始终吃满 `high` 推理成本) |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Default reasoning.effort in docs conflicts with runtime behavior.

Line 315 says the fallback is medium, but current behavior is high (see proxy/anthropic.go Line 474-479 and proxy/anthropic_test.go Line 59-61). Please align docs and implementation to the same default to avoid cost/latency surprises.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/API.md` at line 315, Docs state the fallback for reasoning.effort is
"medium" but runtime actually falls back to "high" when no output_config.effort
is provided and Anthropic thinking.type is not set; update the docs entry for
reasoning.effort to reflect the runtime default "high" (keeping the rest about
preferring output_config.effort, the Anthropic thinking.type/budget_tokens
mapping, and normalization to low/medium/high/xhigh intact) so documentation
matches the implementation.

@caocuong2404 caocuong2404 force-pushed the feat/forward-anthropic-speed-fast-to-codex-priority branch from bd19194 to 20f37ef Compare May 26, 2026 08:47
Map official speed:"fast" to upstream service_tier priority, omit priority
when absent, and log resolved service_tier on /v1/messages for Usage admin
fast stats.
@caocuong2404 caocuong2404 force-pushed the feat/forward-anthropic-speed-fast-to-codex-priority branch from 20f37ef to 0e77bee Compare May 26, 2026 08:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
proxy/anthropic_test.go (1)

87-127: ⚡ Quick win

Add normalization cases for speed mapping.

Line 94 currently validates only exact lowercase "fast". Since translator logic trims and lowercases, add uppercase/whitespace variants to lock that contract in tests.

✅ Proposed test additions
 	cases := []struct {
 		name     string
 		field    string
 		wantTier bool
 	}{
 		{"absent omits priority", "", false},
 		{"speed fast maps to priority", `,"speed":"fast"`, true},
+		{"speed FAST maps to priority", `,"speed":"FAST"`, true},
+		{"speed with spaces maps to priority", `,"speed":"  fast  "`, true},
 		{"speed standard omits priority", `,"speed":"standard"`, false},
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@proxy/anthropic_test.go` around lines 87 - 127, The test
TestTranslateAnthropicToCodex_SpeedFastMapsToCodexPriority currently only checks
the exact lowercase "fast" string; add additional table-driven cases to assert
that trimmed/upper/mixed-case variants also map to service_tier "priority"
(e.g., fields containing `,"speed":" FAST "`, `,"speed":"Fast"`), keeping the
same assertions that "speed" is not forwarded in the Codex body; update the
cases slice in the test and keep the call to TranslateAnthropicToCodexWithModels
and subsequent gjson.GetBytes checks unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@proxy/anthropic_test.go`:
- Around line 87-127: The test
TestTranslateAnthropicToCodex_SpeedFastMapsToCodexPriority currently only checks
the exact lowercase "fast" string; add additional table-driven cases to assert
that trimmed/upper/mixed-case variants also map to service_tier "priority"
(e.g., fields containing `,"speed":" FAST "`, `,"speed":"Fast"`), keeping the
same assertions that "speed" is not forwarded in the Codex body; update the
cases slice in the test and keep the call to TranslateAnthropicToCodexWithModels
and subsequent gjson.GetBytes checks unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 113d30b9-66b3-4a4b-b1d2-90d4e94d608e

📥 Commits

Reviewing files that changed from the base of the PR and between 360e46e and bd19194.

📒 Files selected for processing (5)
  • docs/API.md
  • docs/ARCHITECTURE.md
  • proxy/anthropic.go
  • proxy/anthropic_test.go
  • proxy/handler_anthropic.go
✅ Files skipped from review due to trivial changes (2)
  • docs/ARCHITECTURE.md
  • docs/API.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
proxy/anthropic_test.go (1)

87-127: ⚡ Quick win

Add normalization coverage for speed input.

Please add one case like mixed-case/whitespace (" FAST "), since runtime mapping trims and lowercases before checking fast.

Proposed test case addition
 	cases := []struct {
 		name     string
 		field    string
 		wantTier bool
 	}{
 		{"absent omits priority", "", false},
 		{"speed fast maps to priority", `,"speed":"fast"`, true},
+		{"speed fast with spaces/case maps to priority", `,"speed":" FAST "`, true},
 		{"speed standard omits priority", `,"speed":"standard"`, false},
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@proxy/anthropic_test.go` around lines 87 - 127, Add a new table case in
TestTranslateAnthropicToCodex_SpeedFastMapsToCodexPriority to cover
normalization: include a case with field `,"speed":" FAST "` (mixed-case with
surrounding whitespace) and expect wantTier true; this verifies
TranslateAnthropicToCodexWithModels trims and lowercases the speed before
comparing to "fast" and ensures service_tier becomes "priority" and speed is not
forwarded to the Codex body.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@proxy/anthropic_test.go`:
- Around line 87-127: Add a new table case in
TestTranslateAnthropicToCodex_SpeedFastMapsToCodexPriority to cover
normalization: include a case with field `,"speed":" FAST "` (mixed-case with
surrounding whitespace) and expect wantTier true; this verifies
TranslateAnthropicToCodexWithModels trims and lowercases the speed before
comparing to "fast" and ensures service_tier becomes "priority" and speed is not
forwarded to the Codex body.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 120efeaa-43d9-43c3-ae6e-5c7792072f41

📥 Commits

Reviewing files that changed from the base of the PR and between bd19194 and 0e77bee.

📒 Files selected for processing (5)
  • docs/API.md
  • docs/ARCHITECTURE.md
  • proxy/anthropic.go
  • proxy/anthropic_test.go
  • proxy/handler_anthropic.go
✅ Files skipped from review due to trivial changes (2)
  • docs/ARCHITECTURE.md
  • docs/API.md

@james-6-23 james-6-23 merged commit e60b56b into james-6-23:main May 26, 2026
1 check passed
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.

2 participants