Per-model default (fill-when-absent) reasoning effort for OpenAI routes, matching modelDefaultReasoningEfforts on Anthropic
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- backend-api-design
Research direction
Start with src/adapters/anthropic.ts to understand the existing per-model default lookup, then compare normalizePinnedChatEffort in src/server/chat-native.ts with applyPinnedEffort in src/server/responses/core-normalize.ts. Trace the relevant tests and configuration handling before changing both OpenAI paths. Done means absent effort gets the configured default, explicit effort remains unchanged, pins and caps retain precedence, and the fill is observable in logs.
Written by the indexing model from the issue text.
Description
Area
Proxy and routing
What are you trying to accomplish?
I want a per-model fallback reasoning effort for OpenAI-family models (e.g. gpt-6-astra): used only when the incoming request carries no effort, while an explicit client effort (low … max) still passes through unchanged.
This is the behaviour providers.anthropic.modelDefaultReasoningEfforts already gives Claude models today, so per-session effort selection keeps working and the proxy only fills the gap.
What prevents this today?
modelDefaultReasoningEfforts is only applied in the Anthropic adapter (src/adapters/anthropic.ts, parsed.options.reasoning ?? defaultReasoningEffort(provider, parsed.modelId)). On the OpenAI routes, both the chat-native path (normalizePinnedChatEffort in src/server/chat-native.ts) and the Responses path (applyPinnedEffort in src/server/responses/core-normalize.ts) support only:
modelPinnedReasoningEfforts/pinnedReasoningEffort: overrides any client effort- effort caps: lower high requests
Neither has a "fill only when absent" option, so the only way to guarantee a non-default effort is a pin, and a pin also removes the client's choice (max → xhigh, low → xhigh).
Real-world trigger: a client (Hermes Agent, NousResearch/hermes-agent#119681) silently dropped reasoning_effort for a named custom provider. From usage.jsonl, desktop sessions on gpt-6-astra sent 100+ requests over several days with requestedEffort absent, with prompts up to ~200k tokens (mostly cache reads) and reasoning output of 0 on most calls. The gap went unnoticed until answers came back too fast. After finding it, I covered the Claude models with modelDefaultReasoningEfforts (per-session selection still works), but for Astra the only option was a pin.
What should OpenCodex do?
When a request routed to an OpenAI-family provider has no reasoning effort, apply provider.modelDefaultReasoningEfforts[modelId] (same lookup semantics as on the Anthropic adapter, including __omit__). When the request already has an effort, leave it alone. Pins and caps keep their current precedence over the default.
Ideally the log records the fill, e.g. requestedEffort: "->xhigh" or "default:xhigh", so a client that stopped sending effort is visible in usage.jsonl instead of looking identical to a client-sent value. (Today the Anthropic fill is invisible in the log: those rows show no requestedEffort at all.)
Example usage or interface
ocx config set providers.openai.modelDefaultReasoningEfforts '{"gpt-6-astra":"xhigh"}'
Incoming reasoning_effort |
Today (pin) | Proposed (default) |
|---|---|---|
| absent | xhigh |
xhigh |
max |
xhigh |
max |
low |
xhigh |
low |
Alternatives or workarounds
modelPinnedReasoningEffortsforgpt-6-astra: works as a safety net but forces one effort for every client (Hermes, OmO, Codex) on that model.- Patching each client: fixes the root cause per client, but client updates can revert local patches, and the proxy is the one place every client passes through.
Additional context
- OpenCodex 2.77.0, Windows 11
- Inbound: Chat Completions (
inboundProtocol: chat), translated to Responses upstream (protocolTrace.mode: translated) - Related: #5453 (effort not logged on the Messages surface)
Checks
- I searched existing issues and documentation.
- This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
- I removed secrets and personal data.
- Dominant language
- TypeScript
- Stars
- 16.9k
- Forks
- 1.3k
- Avg merge
- 4h 24m
- Merged PRs (30d)
- 574
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from lidge-jun/opencodex
-
添加全局代理功能Openenhancement proxy
Difficulty 4/5 3-5 days Newbie friendliness 48/100
Maintainers usually reply within 1 day
-
bug tools
Difficulty 3/5 1-2 days Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
bug cli platform service
Difficulty 3/5 1-2 days Newbie friendliness 65/100
lidge-jun/opencodex#6575 · 2 comments ·
Maintainers usually reply within 1 day
-
bug proxy
Difficulty 5/5 Over a week Newbie friendliness 35/100
lidge-jun/opencodex#6568 · 3 comments ·
Maintainers usually reply within 1 day
-
bug gui
Difficulty 4/5 3-5 days Newbie friendliness 52/100
lidge-jun/opencodex#6567 · 1 comment ·
Maintainers usually reply within 1 day
All issues in lidge-jun/opencodex
Similar issues
-
enhancement good first issue priority: low size: XS
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
Difficulty 1/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
streamplace/streamplace#1351 ·
Maintainers usually reply within 2 days
-
Link Checker ReportOpenautomated issue report
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
databendlabs/databend-docs#3511 ·
-
automated issue report
Difficulty 2/5 1-3 hours Newbie friendliness 65/100