Client or integration
Codex CLI (also reproducible with a direct HTTP client).
Provider or upstream service
AgentRouter (agentrouter.org)
Version
OpenCodex 2.33.0.
Operating system
Linux server (x86_64).
Provider and model
AgentRouter / claude-opus-5.
OpenCodex version
2.33.0, official npm package; affected adapter files verified byte-for-byte against the published tarball.
Endpoint or capability
/v1/responses translated to an AgentRouter openai-chat provider at https://agentrouter.org/v1; client authentication/fingerprint and non-English prompts.
Summary
AgentRouter openai-chat providers fail with 401 unless a recognized Codex client fingerprint is manually configured, and minimal Portuguese requests still fail with 400 content-blocked because the 2.31 fix covers only the Anthropic adapter.
Current behaviour
Two independent failures remain after the AgentRouter language fix merged in #2162:
- A valid AgentRouter key on a normal
openai-chat provider is rejected with HTTP 401 unauthorized_client_error unless the operator manually adds an undocumented recognized-client fingerprint (User-Agent or originator) to provider.headers.
- Once fingerprint authentication succeeds, a minimal Portuguese request still returns HTTP 400
content-blocked. The same provider works from the real Codex CLI because Codex supplies a large English harness context before the Portuguese user prompt.
OpenCodex 2.33.0 implements AgentRouter language framing only in src/adapters/anthropic.ts. src/adapters/openai-chat.ts has no AgentRouter-specific host detection, fingerprint defaults, or language framing.
Controlled header matrix, same key/model/body/process:
| Provider headers |
Minimal EN request |
Real Codex PT request |
| none |
401 unauthorized client |
401 after five retries |
version: 0.149.1 only |
401 |
not run |
User-Agent: codex_cli_rs/0.149.1 only |
200 |
200 |
originator: codex_cli_rs only |
200 |
200 |
| UA + originator + version 0.149.1 |
200 |
200 |
| UA + originator + version 0.145.0-alpha.30 |
200 |
200 |
The old version is not required; the recognized Codex identity is what matters.
Expected behaviour
A first-class AgentRouter provider/preset using openai-chat should work with a valid key without requiring operators to discover and copy undocumented magic headers.
OpenCodex should either:
- supply a documented, stable AgentRouter-compatible client fingerprint by default for exact
agentrouter.org hosts; or
- expose a documented
clientFingerprint compatibility option and diagnose the upstream 401 clearly.
AgentRouter's non-English request policy should also be applied consistently to both the Anthropic and OpenAI Chat adapter paths, including translated /v1/responses and raw /v1/chat/completions passthrough.
Operator-specified headers must continue to override defaults, and non-AgentRouter providers must remain unchanged.
Reproduction
The exact minimal reproduction is provided below.
Minimal redacted request or reproduction
# 1. Configure a provider (valid key redacted):
# providers.agentrouter-test = {
# adapter: "openai-chat",
# baseUrl: "https://agentrouter.org/v1",
# authMode: "key",
# apiKey: "<redacted>",
# liveModels: false,
# models: ["claude-opus-5"],
# selectedModels: ["claude-opus-5"],
# defaultModel: "claude-opus-5"
# }
# 2. Send an English request with no custom provider headers:
curl -sS http://127.0.0.1:10100/v1/responses \
-H "Authorization: Bearer $OPENCODEX_API_AUTH_TOKEN" \
-H 'Content-Type: application/json' \
--data '{
"model":"agentrouter-test/claude-opus-5",
"input":"Reply with exactly: OK",
"stream":false,
"store":false,
"max_output_tokens":64
}'
# => HTTP 401 unauthorized client
# 3. Add either header and repeat:
# headers: { "User-Agent": "codex_cli_rs/0.149.1" }
# OR
# headers: { "originator": "codex_cli_rs" }
# => HTTP 200
# 4. With the recognized fingerprint, change input to Portuguese:
# "input":"Responda somente com: OK"
# => minimal direct request: HTTP 400 content-blocked
# 5. Run through the real Codex CLI, which supplies English harness context:
codex exec --ephemeral --skip-git-repo-check \
-m agentrouter-test/claude-opus-5 \
'Responda somente com: OK'
# => HTTP 200 / exact answer
Actual response or error
# Without recognized client fingerprint:
HTTP 401
{
"error": {
"message": "unauthorized client detected, contact support for assistance"
},
"type": "unauthorized_client_error"
}
# With recognized fingerprint, minimal Portuguese request:
HTTP 400
{
"error": {
"code": "content-blocked",
"type": "agent_router_api_error"
}
}
# With recognized fingerprint, real Codex CLI Portuguese request:
HTTP 200
turn.completed
Request IDs, credentials, account details, and host-specific data were removed.
Upstream documentation
AgentRouter does not appear to publish a public specification documenting the required User-Agent/originator client allowlist or the non-English content-scoring contract. The observable behavior above is based on controlled black-box compatibility testing against the service.
OpenCodex context:
Suggested mapping or implementation notes
- Register AgentRouter as a first-class compatibility policy/preset.
- For parsed hostnames exactly equal to
agentrouter.org or ending in .agentrouter.org, provide default static headers only when absent:
{
"User-Agent": "codex_cli_rs/<detected-current-version>",
"originator": "codex_cli_rs"
}
If impersonating Codex is not acceptable, use a stable OpenCodex-owned fingerprint coordinated/documented with AgentRouter, or require an explicit compatibility option.
- Use existing case-insensitive
mergeRegistryStaticHeaders() semantics so operator headers win.
- Share exact-host AgentRouter policy between
anthropic and openai-chat adapters.
- Cover translated
/v1/responses and raw Chat Completions passthrough.
- Preserve user content byte-for-byte, keep framing idempotent, and never match hostile lookalike hostnames such as
agentrouter.org.attacker.example.
- Map
unauthorized_client_error to an actionable diagnostic.
Additional context and attachments
The final local provider was validated across restart with:
- current Codex fingerprint
0.149.1;
- two consecutive Portuguese Codex requests returning 200;
- exact expected output;
- no patch in OpenCodex adapters;
- original AgentRouter providers disabled during isolated testing;
- custom provider created through the 2.33.0 management API.
The key conclusion is that #2162 fixed only Anthropic first-turn framing. It did not make AgentRouter openai-chat providers self-configuring, and it did not address AgentRouter's required client identity.
Checks
Client or integration
Codex CLI (also reproducible with a direct HTTP client).
Provider or upstream service
AgentRouter (
agentrouter.org)Version
OpenCodex 2.33.0.
Operating system
Linux server (x86_64).
Provider and model
AgentRouter / claude-opus-5.
OpenCodex version
2.33.0, official npm package; affected adapter files verified byte-for-byte against the published tarball.
Endpoint or capability
/v1/responsestranslated to an AgentRouteropenai-chatprovider athttps://agentrouter.org/v1; client authentication/fingerprint and non-English prompts.Summary
AgentRouter openai-chat providers fail with 401 unless a recognized Codex client fingerprint is manually configured, and minimal Portuguese requests still fail with 400 content-blocked because the 2.31 fix covers only the Anthropic adapter.
Current behaviour
Two independent failures remain after the AgentRouter language fix merged in #2162:
openai-chatprovider is rejected with HTTP 401unauthorized_client_errorunless the operator manually adds an undocumented recognized-client fingerprint (User-Agentororiginator) toprovider.headers.content-blocked. The same provider works from the real Codex CLI because Codex supplies a large English harness context before the Portuguese user prompt.OpenCodex 2.33.0 implements AgentRouter language framing only in
src/adapters/anthropic.ts.src/adapters/openai-chat.tshas no AgentRouter-specific host detection, fingerprint defaults, or language framing.Controlled header matrix, same key/model/body/process:
version: 0.149.1onlyUser-Agent: codex_cli_rs/0.149.1onlyoriginator: codex_cli_rsonlyThe old version is not required; the recognized Codex identity is what matters.
Expected behaviour
A first-class AgentRouter provider/preset using
openai-chatshould work with a valid key without requiring operators to discover and copy undocumented magic headers.OpenCodex should either:
agentrouter.orghosts; orclientFingerprintcompatibility option and diagnose the upstream 401 clearly.AgentRouter's non-English request policy should also be applied consistently to both the Anthropic and OpenAI Chat adapter paths, including translated
/v1/responsesand raw/v1/chat/completionspassthrough.Operator-specified headers must continue to override defaults, and non-AgentRouter providers must remain unchanged.
Reproduction
The exact minimal reproduction is provided below.
Minimal redacted request or reproduction
Actual response or error
Request IDs, credentials, account details, and host-specific data were removed.
Upstream documentation
AgentRouter does not appear to publish a public specification documenting the required
User-Agent/originatorclient allowlist or the non-English content-scoring contract. The observable behavior above is based on controlled black-box compatibility testing against the service.OpenCodex context:
Suggested mapping or implementation notes
agentrouter.orgor ending in.agentrouter.org, provide default static headers only when absent:{ "User-Agent": "codex_cli_rs/<detected-current-version>", "originator": "codex_cli_rs" }If impersonating Codex is not acceptable, use a stable OpenCodex-owned fingerprint coordinated/documented with AgentRouter, or require an explicit compatibility option.
mergeRegistryStaticHeaders()semantics so operator headers win.anthropicandopenai-chatadapters./v1/responsesand raw Chat Completions passthrough.agentrouter.org.attacker.example.unauthorized_client_errorto an actionable diagnostic.Additional context and attachments
The final local provider was validated across restart with:
0.149.1;The key conclusion is that #2162 fixed only Anthropic first-turn framing. It did not make AgentRouter
openai-chatproviders self-configuring, and it did not address AgentRouter's required client identity.Checks