LibreChat/api
Danny Avila c00acb36a0
🌌 feat: Add GPT-6 Astra Support (#15567)
* 🌌 feat: Add GPT-6 Astra Support

Registers OpenAI's GPT-6 Astra (`gpt-6-astra`) as a first-class model on the
canonical OpenAI endpoint.

Every model-specific behavior Astra requires — Responses routing for tool
calls, stripping the sampling and logprob parameters it rejects, and
substituting the `none`/`minimal` reasoning efforts it does not accept — lands
in `@librechat/agents` (danny-avila/agents#506) rather than here. None of it is
expressible at configuration time: tools bind after `getOpenAIConfig` runs, and
LangChain's request builders emit `temperature`/`top_p` from instance fields
regardless of what this layer sets. Keeping it in the SDK also means the
routing gate can be the documented rule (tools present) instead of the
over-approximation the config-time GPT-5.6 path is forced into.

What is left here is registration:

- 1,050,000-token context window and 128K max output
- Model dropdown (config.ts) and the `OPENAI_MODELS` example
- Standard pricing: $10/M input, $1/M cached input, $12.50/M cache writes,
  $50/M output
- The >272K long-context tier, which LibreChat already supports through
  `premiumTokenValues`/`premiumCacheTokenValues`: 2x input and cache rates and
  1.5x output for the full request

Batch/Flex (50%) and Fast mode (2x) have no representation in the pricing
model today and are not introduced here; they apply per-request rather than
per-model, so they need a request-shape signal this layer does not yet carry.

Tests pin the pricing against the documented multipliers rather than restating
the literals — cache writes as 1.25x input, and the premium tier as 2x/1.5x of
standard — plus threshold behavior either side of 272K, and that `gpt-6-astra`
resolves to its own key for snapshots and provider-prefixed ids instead of
collapsing onto a shorter `gpt-6` match.

Resolves #15560

Ref: https://developers.openai.com/api/docs/models/gpt-6-astra
Ref: https://developers.openai.com/api/docs/guides/latest-model

* 🧪 test: Guard the GPT-6 Astra Max Output Entry

[Copilot] The Astra tests asserted the context window but not the 128K max
output added alongside it in `anthropicMaxOutputs`' OpenAI counterpart, so that
entry could regress silently. The gpt-5.6 tier test above covers both, and the
delete-the-fix check showed the gap: removing the source entries failed only
the context assertions.

Assert `getModelMaxOutputTokens` alongside `getModelMaxTokens`, and fold the
snapshot/prefix cases into one loop so both dimensions are covered for every id
shape rather than only the bare one. Verified by deleting just the max-output
entry: both Astra tests now fail where previously neither did.

* 🪧 feat: Declare the First-Party OpenAI Endpoint to the Agents SDK

The agents SDK gates GPT-6 Astra's request constraints — Responses-only tool
calls, rejected sampling parameters, unsupported reasoning efforts — on knowing
it is talking to the first-party OpenAI surface, and defaults them off. It takes
that as a declaration rather than inferring it, because a base URL cannot answer
the question: only this layer knows whether a URL is a faithful first-party
route, a gateway, or a proxy with its own semantics.

That decision already exists here, in `isCanonicalOpenAIBaseURL`, used by the
GPT-5.6 Responses default. Declaring it from the same checks keeps it in one
place instead of duplicating it downstream where the two could drift — and if
the endpoint logic ever moves, it moves once.

`firstPartyEndpoint` is declared on `OAIClientOptions` alongside the other agents
SDK fields this layer already sets (`promptCache`, `_lc_stream_delay`,
`includeReasoningContent`), so it typechecks against the current published SDK
and is consumed once the SDK release lands.

Two backward-compatibility expectations gain the field. That is the intended
signal: they assert the full emitted config precisely so a new field cannot slip
through unnoticed.

* 🗂 fix: Keep GPT-6 Astra Out of the Assistants Catalogs

[Codex P2] `sharedOpenAIModels` feeds `defaultModels[assistants]` and
`[azureAssistants]` as well as the OpenAI and agents catalogs. Astra serves tool
calls only from the Responses API, and the Assistants endpoints do not route
through `getOpenAILLMConfig`, so listing it there offered a configuration the
provider rejects.

Astra now sits in its own `responsesOnlyOpenAIModels` list, spread into the
OpenAI and agents catalogs only. Agents keeps it deliberately: that path does go
through `getOpenAILLMConfig`.

* 🎚 fix: Route GPT-6 Astra to the Responses API at Config Time

[Codex P1] `max_tokens` was shaped into `max_completion_tokens` here, from
`llmConfig.useResponsesApi`, while the agents SDK switched Astra to the
Responses API later at invocation time — so the request reached an endpoint
expecting `max_output_tokens` and was rejected.

Deciding the API here fixes that, and generalizes: any field whose shape depends
on the endpoint has the same problem, so the choice has to precede the shaping.
It also lands before Azure replaces `llmConfig.model` with a deployment name,
which is the only point that still knows the real model id.

Unlike the GPT-5.6 rule above, this does not depend on reasoning parameters.
Astra serves tool calls only from Responses, and OpenAI recommends Responses for
it generally, so a static decision loses nothing — which was the reason the SDK
was deciding it dynamically. The existing guards carry over: OpenRouter, custom
gateways, and an explicit `dropParams` opt-out keep their configured path.

The agents SDK is still required, for the request shaping Astra needs on either
API (danny-avila/agents#506); it no longer decides routing.

* 🏷 fix: Record the Served Model Before Azure Overwrites It

[Codex P1] `llmConfig.model` is unconditionally replaced with the Azure
deployment name, so the agents SDK received an alias and could not tell which
model it was talking to — a deployment not literally named `gpt-6-astra` got
none of the request shaping Astra requires.

Records the real id in `servedModel` immediately before the overwrite, which is
the last point that still knows it. The SDK prefers it over `model` when
deciding which model-specific constraints apply (danny-avila/agents#506).

Set for every first-party Azure request rather than only Astra: "what this
deployment serves" is a fact this layer knows and the SDK decides what to do
with, and keeping model-specific knowledge out of here is the point of the
split. The backward-compatibility expectation gains the field, which is that
test doing its job.

* 🎛 fix: Do Not Let a reasoning_effort Drop Disable Astra Routing

[Codex P1] The Astra routing reused the GPT-5.6 opt-out wholesale, which treats
`dropParams: ['reasoning_effort']` as opting out of the Responses API. That
holds for the 5.6 default, which routes *because* of reasoning — removing the
effort removes its reason to route. Astra's routing is not reasoning-driven, so
a rule clearing an unsupported stored effort silently put it back on Chat
Completions, where its tool calls fail.

Astra now honors only an explicit `useResponsesApi` drop. Reusing the guard
without re-deriving whether each clause applied was the error.

* ✂️ fix: Scope GPT-6 Astra to the First-Party OpenAI Endpoint

[Codex P1 + P2] Two findings, both Azure, resolved by removing the Azure support
rather than extending it.

Azure's first-party hosts do not satisfy `isCanonicalOpenAIBaseURL`, so a
configured `*.openai.azure.com` was neither routed to Responses nor declared
first-party; and moving Astra out of `sharedOpenAIModels` also removed it from
the Azure chat fallback, since `getOpenAIModels({ azure: true })` resolves
through `defaultModels[azureAssistants]`.

Both are moot once the scope is right: OpenAI does not document Astra as
available on Azure OpenAI. Its model page lists the API and OpenAI's own
subscription plans, with no third-party cloud surface. The Azure handling was
support for a deployment the model is not documented to reach, and it produced
most of the review findings on this branch and its agents SDK counterpart.

Routing and the first-party declaration are now scoped to
`EModelEndpoint.openAI`, and the Azure-only `servedModel` recording is gone
along with its SDK counterpart. Astra staying out of the Azure catalogs is now
the intended outcome rather than a regression.

* 🚫 fix: Keep Astra Out of the Initial Azure Catalog

[Codex P1] `initialModelsConfig` feeds the OpenAI catalog to Azure OpenAI as
well, so scoping Astra to the first-party OpenAI endpoint left it advertised on
Azure anyway — and being first in the list, it could become the default
selection where no prior choice exists. The server's Azure fallback already
excludes it, so the client would offer a model the server then rejects.

The Azure initial catalog now uses the OpenAI list minus the Responses-only
models, following the same scoping decision the routing guard makes.

The initial Assistants catalog was already safe: `fitlerAssistantModels`
requires `gpt-4` or `gpt-3.5`, which Astra does not match. Pinned that in a test
rather than leaving it to a regex written for another purpose.

* ⬆️ chore: Bump `@librechat/agents` to 3.7.20 for GPT-6 Astra Constraints
2026-09-04 10:23:29 -04:00
..
app 🫙 fix: Drop Blank Content Blocks From Promptless Sends (#15530) 2026-09-02 20:15:00 -04:00
cache ⚡ perf: Avoid Parallel Full and Paged Prompt Loading on Startup (#15031) 2026-08-25 21:21:17 -04:00
config 🫆 chore: Remove Published Credential Defaults (#14680) 2026-08-07 07:25:05 -04:00
db 🐇 refactor: Decouple Meilisearch From Document Saves (#15109) 2026-08-21 22:26:44 -04:00
models
server 🕯️ feat: Search Text in Attached Workspaces (#15525) 2026-09-04 10:07:06 -04:00
strategies 🔐 fix: Keep OpenID Metadata Out of Logs and Traces (#15470) 2026-09-01 13:22:12 -04:00
test 🔐 fix: Redirect OAuth Browser Navigations Instead of Rendering JSON (#15440) 2026-08-31 21:13:47 -04:00
utils ⚡ feat: Add Gemini 3.8 Flash Support (#15519) 2026-09-02 15:06:40 -04:00
jest.config.js
jsconfig.json
package.json 🌌 feat: Add GPT-6 Astra Support (#15567) 2026-09-04 10:23:29 -04:00
typedefs.js 🛂 test: Cover Tool Approval Workflows End to End (#14427) 2026-07-26 21:58:25 -04:00