Expose model reasoning-effort metadata to API-key sessions
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What variant of Codex are you using?
Third-party agent harness — HanaAgent (https://github.com/liliMozi/openhanako), consuming the Codex OAuth channel (openai-codex-responses / chatgpt.com/backend-api).
What feature would you like to see?
Expose each model's supported reasoning levels to API-key sessions, not only to ChatGPT-authenticated clients.
Who we are
We build HanaAgent, an open-source personal agent harness that talks to multiple model providers. We support OpenAI through the Codex OAuth channel, and we also support DeepSeek, Moonshot, Zhipu, and others.
The problem we hit
To render a correct reasoning-effort selector per model, a client needs to know which effort values each model accepts. Today GET /v1/models returns only id, created, object, owned_by, and shutdown_date — no reasoning metadata.
That forces every client to hard-code a table keyed by model id, which breaks in two ways:
- New models require a client release. When a model lands with a different effort subset (some stop at
xhigh, some includeultra), existing clients show a wrong or empty selector until they re-ship. - Wrong guesses fail hard, not gracefully. GPT-6 Astra rejects
reasoning.effort = "none"with HTTP 400. A client that assumesnoneis universally available produces a broken request for the user, not a degraded one.
Background: the data already exists
While reading the open-source openai/codex repository, we found that the Codex client already resolves exactly this information from a server-side catalog. In codex-rs/app-server/src/models.rs:
thread_manager
.list_models(RefreshStrategy::OnlineIfUncached, http_client_factory)
.await
and each resulting model carries:
supported_reasoning_efforts: reasoning_efforts_from_preset(preset.supported_reasoning_efforts),
default_reasoning_effort: preset.default_reasoning_effort,
The endpoint is https://chatgpt.com/backend-api/codex/models, and the response is cached at ~/.codex/models_cache.json. A representative entry:
{
"slug": "gpt-6-astra",
"display_name": "GPT-6-Astra",
"default_reasoning_level": "medium",
"supported_reasoning_levels": [
{ "effort": "low", "description": "Fast responses with lighter reasoning" },
{ "effort": "medium", "description": "Balances speed and reasoning depth for everyday tasks" },
{ "effort": "high", "description": "Greater reasoning depth for complex problems" },
{ "effort": "xhigh", "description": "Extra high reasoning depth for complex problems" },
{ "effort": "max", "description": "Maximum reasoning depth for the hardest problems" },
{ "effort": "ultra", "description": "Maximum reasoning with automatic task delegation" }
],
"supported_in_api": true
}
So the contract is already modeled, versioned, and shipped to clients — it is simply not reachable from an API-key session.
The request
Make the same information available to API consumers. Either shape would unblock us:
Option A — add reasoning metadata to GET /v1/models (or GET /v1/models/{id}):
{
"id": "gpt-6-astra",
"object": "model",
"owned_by": "openai",
"reasoning": {
"supported": true,
"supported_efforts": ["low", "medium", "high", "xhigh", "max", "ultra"],
"default_effort": "medium",
"mandatory": true
}
}
Option B — allow API-key credentials to read the existing catalog endpoint. No new schema needed.
Additional information
Prior art. Other providers already publish this. OpenRouter exposes reasoning.supported_efforts / default_effort / mandatory on its public models endpoint; Moonshot exposes think_efforts.valid_efforts / default_effort on GET /v1/models. Both let clients stay correct automatically as models change.
Secondary ask. For effort values outside a model's supported set, an explicit 400 would be preferable to silent coercion — silent handling hides client bugs until a user encounters them.
Our goal. We would rather read your contract than maintain a hard-coded table that goes stale with every model release. This is purely about client correctness, not about accessing anything that isn't already part of the model catalog.
Thanks for considering.
Contributor guide
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.
Research direction
Start in codex-rs/app-server/src/models.rs, where the existing model catalog is loaded and reasoning metadata is assembled, then trace how GET /v1/models serves API-key sessions. Compare the catalog fields with the current API response and determine which requested exposure shape fits. Done means API consumers can retrieve each model's supported and default reasoning efforts through an API-key session.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100