Repository navigation
@tanstack/ai-openai@0.30.0
Minor Changes
-
#1716
20954cc- The adapters now work with GitHub Copilot and with a ChatGPT plan token.- The Responses adapter streams one tool call when the item id changes on each event. GitHub Copilot sends a new item id on each event of a stateless response.
- The Responses adapter runs the tools of a turn when
response.completedhas an emptyoutput. The ChatGPT plan route streams the tool call, then sends an emptyoutput. Before this change, the run ended withstopand the tool did not run. - The OpenAI-compatible Chat Completions adapter reads the thinking that GitHub Copilot streams on
delta.reasoning_text. - The OpenAI-compatible docs list more providers and show the setup and the sign-in for GitHub Copilot and for a ChatGPT plan.
-
#1697
cef1911- Keep the prompt cache when tools or system prompts are added during a conversation.- Before each model call,
chat()compares the tools and the system prompts with the earlier calls. On a model with a mid-conversation channel, an added tool, or a system prompt added at the end, goes out in the conversation. The start of the request stays the same. openaiTextongpt-5.4-mini,gpt-5.5,gpt-5.6-luna,gpt-5.6-sol,gpt-5.6-terra,gpt-6-astra,gpt-6-luna, andgpt-6-sol: an added tool is anadditional_toolsinput item, and an added prompt is adevelopermessage. The Responses adapter of@tanstack/openai-basesends these when a subclass setsmidConversationChannels, and it sends thenamespaceof such a tool's call back on the next request.anthropicTextonclaude-opus-4-8,claude-opus-5,claude-opus-5-5,claude-fable-5, andclaude-fable-5-1: every request with tools has themid-conversation-tool-changes-2026-07-01beta and one placeholder tool, unless a provider tool such aswebSearchTool()takes part. An added tool hasdefer_loading: trueand atool_additionblock in asystemmessage.- Every other model and adapter sends the same request as before.
- The channels are on by default only with the provider's own API. A custom
baseURL, a customfetch, an injected client, or theOPENAI_BASE_URL/ANTHROPIC_BASE_URLenvironment variable turns the default off. SetmidConversationChannels: trueto turn the channels on anyway. Setfalseto turn them off anywhere. - With prompt caching on (the default), the automatic Claude tool cache marker goes on the last start tool, not on the placeholder or an added tool.
- New optional fields:
ModelMessage.midConversationChange,TextOptions.midConversationChanges, andTextAdapter.midConversationChannels, with the typesMidConversationChange,MidConversationChanges, andMidConversationChannels.splitMidConversationChangeshelps adapter authors read the changes.
- Before each model call,
-
#1697
cef1911- Prompt caching is now on by default. Eachchat()call asks the provider to cache the stable start of the request (system prompt, tools, and earlier messages), so repeated requests cost less and answer sooner.- New
chat()optionpromptCache:'none' | 'short' | 'long', or{ retention, key }. The default is'short'. The key ispromptCache.key, else thethreadIdorconversationIdthat you give. AthreadIdthatchat()makes up is never the key. - To turn it off, pass
promptCache: 'none'. Do this for a large prompt that you send to Claude one time only, because Claude bills the cache write. - A middleware can change it for the next model call:
onConfiggetsconfig.promptCacheand can return a new value. - Each adapter sends its own fields:
- Claude on Anthropic, Bedrock Converse, and OpenRouter gets cache markers.
'long'asks for the 1-hour TTL. - OpenAI (Responses and Chat Completions) gets
prompt_cache_key, andprompt_cache_retentionorprompt_cache_optionson'long'. - Mistral gets
prompt_cache_key, and usage now reports cache reads. - OpenRouter gets
sessionId.
- Claude on Anthropic, Bedrock Converse, and OpenRouter gets cache markers.
- A manual
cache_control,cachePoint,prompt_cache_key, orsessionIdwins over the automatic value. - New types:
PromptCacheRetention,PromptCacheOptions, andResolvedPromptCache. Adapters readTextOptions.promptCache.
- New
-
#1692
7532b2b- Set reasoning withchat({ reasoning })onopenaiText,openaiChatCompletions, andazureOpenaiText.openaiTextsends the level asreasoning: { effort, summary }.openaiChatCompletionssendsreasoning_effort.azureOpenaiTextandcreateAzureOpenaiTextread the levels of the OpenAI model name, not of the deployment name, and sendreasoning: { effort, summary }. A name that is not an OpenAI model takes noreasoning.- Each chat model has its reasoning data in
model-meta.ts.OpenAIModelReasoningByNameandOPENAI_MODEL_REASONINGcome from it.
Breaking:
reasoningis no longer inmodelOptionsofopenaiText,openaiChatCompletions,azureOpenaiText, andcreateAzureOpenaiText.OpenAIReasoningOptionsandOpenAIReasoningOptionsWithConciseare removed.// Before chat({ adapter: openaiText('gpt-5.5'), messages, modelOptions: { reasoning: { effort: 'high', summary: 'auto' } }, }) // After chat({ adapter: openaiText('gpt-5.5'), messages, reasoning: 'high' })
Patch Changes
-
#1733
b881627- Chat Completions adapters skip a stream chunk that has nochoicesfield, as some gateways send for the usage trailer. Before, the run failed withCannot read properties of undefined (reading '0'). -
#1698
1bfcee3- Keep a conversation valid when the next request goes to a different model.- Each assistant message records
metadata.tanstack.source({ provider, api, model }), andresponseIdand the resolvedmodelwhen the provider sends them. A failed or aborted answer getsstopReason: 'error'or'aborted'.RUN_FINISHEDhas a newresponseIdfield.TextAdapterhas new optionalproviderandapifields. - When the next request goes to a different source, the adapter removes signatures and redacted thinking, turns readable thinking into text, and rewrites tool call IDs to the shape the target API accepts. Each call stays paired with its result.
- Every request drops failed and aborted assistant batches and adds a
No result providedresult for an unanswered tool call. The saved history does not change. RUN_FINISHEDandRUN_ERRORmetadata now merge onto the assistant messages of that model call inStreamProcessor.- Anthropic: the new
allowEmptySignatureoption (defaultfalse) replays unsigned thinking from the same source, for gateways. The newprovideroption names a gateway. - Azure OpenAI reports the
azure-openai-responsesAPI. - Gemini, Mistral, and Bedrock Converse send same-source thinking back to the model, in block order.
withPersistencewrites the source and the stop reason onto streaming snapshot rows.- Adapter authors get
transformMessagesForReplay()andhashToolCallId()from@tanstack/ai/adapter-internals.
- Each assistant message records
-
#1692
7532b2b- Sendchat({ toolChoice })to each provider.- Anthropic and Bedrock Converse. Claude Fable 5.1, Mythos 5.1, Opus 5.5, and Sonnet 5.5 reject a forced tool, and every Claude model rejects one while thinking is on. On those,
'required'and a named tool fall back toauto. - Bedrock Converse has no
none.'none'sends no tool config. Bedrock refuses tool calls in the history without a tool config, so the history goes out as text. - Gemini maps the choice to
functionCallingConfig(AUTO,NONE,ANY, andallowedFunctionNames). With only provider tools, such as Google Search, it sends no tool config. - OpenAI and Azure OpenAI (Responses), Grok, Mistral, and OpenRouter (Chat Completions and Responses) send their own
tool_choiceshape.
- Anthropic and Bedrock Converse. Claude Fable 5.1, Mythos 5.1, Opus 5.5, and Sonnet 5.5 reject a forced tool, and every Claude model rejects one while thinking is on. On those,
-
Updated dependencies [
1bfcee3,b881627,412b0fe,a0150c2,20954cc,b881627,fac0555,6774e80,5bd27f2,c20f7b0,cef1911,51f72fb,6f1e559,eb4eea0,cef1911,7532b2b,7532b2b,1bfcee3,78edeb2,44e3a0a,7532b2b,ce99a17,7a5c0d6,b881627]:- @tanstack/ai@0.69.0
- @tanstack/openai-base@0.14.0
- @tanstack/ai-utils@0.4.2