Support for the latest Anthropic models (Claude Opus 5.5, Sonnet 5.5, Haiku 5.5, Fable 5.1) and OpenAI models (GPT-6.1 Sol, GPT-6 Astra/Luna, GPT-5.6, GPT-5.5), plus one usage contract and one stream shape across every provider.
Token usage numbers change on most providers. If you store usage for billing or analytics, read the Usage section before upgrading.
Breaking Changes
Prism\Prism\Streaming\StreamCollectoris removed. UseStreamedMessages::fromEvents($events)inside anasEventStreamResponse,asDataStreamResponseorasBroadcastcallback.- OpenAI models Prism doesn't recognise, including custom names on OpenAI-compatible servers, get
json_schemastructured output instead ofjson_object. Use->usingStructuredMode(StructuredMode::Json)for servers that can't handle it.gpt-3.5-turbo*,gpt-4,gpt-4-*andgpt-4o-2024-05-13stay onjson_object. - Reported token usage changes wherever a provider deviated from the usage contract (below).
Usage
promptTokensis uncached input.cacheReadInputTokensandcacheWriteInputTokensnever overlap with it.completionTokensincludes reasoning.thoughtTokensis the reasoning portion.- Optional fields are
nullwhen the provider doesn't report them,0when it reports zero. - Gemini no longer excludes thinking from
completionTokensor double counts implicit cache hits. - Mistral, Groq, Z, xAI and OpenRouter no longer count cached input in
promptTokens. - Multi-step streams sum every step. Gemini, Groq and OpenRouter reported only the last one.
- Duration-billed transcriptions (OpenAI whisper-1, Groq) return
nullusage plususage_seconds. - Prism Server's
prompt_tokensandtotal_tokensinclude cached input, matching OpenAI's response shape.
| Provider | Before | After |
|---|---|---|
| Gemini thinking budget | completion 492 | completion 1701 |
| Mistral cache hit | prompt 2471 | prompt 23, cache read 2448 |
| DeepSeek structured | prompt 187 | prompt 59, cache read 128 |
| OpenRouter two-step stream | 75 / 15 | 125 / 158, thought 128 |
| OpenAI whisper-1 | Usage(0, 0)
| null, usage_seconds 317
|
Full table in #1043.
Behavior Changes
- OpenAI refusals return
FinishReason::Refusal. Structured refusals used to throw. - OpenAI tool steps can include the model's commentary text.
- OpenAI streaming sends
store. - Anthropic
thinkingandthinking_signatureare populated whenever the model returns thinking. In streams they hold the final step's first thinking block. - Tools only run when a step ends with tool calls. Text responses no longer list tool calls that weren't executed.
- Stream finish reasons reflect the real stop reason on every provider. Anthropic and Ollama streams always reported
Stop. - In-stream errors end the stream with
Error. Anthropic'sErrorEventreportsrecoverable: false. OpenRouter's syncfinish_reason: "error"maps toError. - Stream callback messages are grouped one assistant message per step.
PrismFakemulti-step streams split at every step. Fake tool steps need->withFinishReason(FinishReason::ToolCalls)forStreamedMessagesto keep their tool calls.- After a client disconnect, the persistence callback can receive the rest of a tool step whose tools already ran.
Features
StreamedMessages::fromEvents()builds replay-ready messages from stream callback events.- Anthropic and OpenAI replay each step's content blocks / output items as returned (
content_blocks,output_items), including thinking signatures, redacted thinking,encrypted_contentreasoning andstore: falseconversations. - Anthropic
fallbacksprovider option, with beta headers added automatically and per-attempt usage inadditionalContent['usage_iterations']. - Anthropic
thinking.typepasses through (adaptive,enabled,disabled,between_tools) withdisplayandblock_binding. - Anthropic
pause_turnresumes automatically in text, structured and streaming requests withinmaxSteps. - Anthropic
stop_reasonandstop_detailsinadditionalContent. step_finishevent payloads includefinish_reason.
Fixes
- Anthropic structured output no longer exceeds the cache breakpoint limit on the fourth step.
- Anthropic structured tool mode honours an explicit
toolChoice. - Anthropic streams report the real finish reason.
model_context_window_exceededmaps toLength. - OpenAI streams handle
response.incompleteandresponse.failed. - DeepSeek, xAI, Z, Gemini and Ollama no longer run tool calls after a length, safety or error finish.
- Every stream ends with a
StepFinishEventand exactly oneStreamEndEvent. ExhaustedmaxStepson a tool step reportsToolCalls. - Every
TextStart/ThinkingStartgets exactly one matchingComplete. DeepSeek emitted duplicateThinkingCompleteevents. - Text and reasoning in the same chunk as a tool call are kept (Gemini, DeepSeek, Z, Groq, Mistral, OpenRouter, xAI, Ollama).
- OpenRouter and Ollama handle in-stream error chunks.
- Client disconnects keep the finished step's tool results and replay data.
- Content and deltas that are exactly
"0"are kept.withPrompt('0')sends a user message. - Z replays assistant tool calls.
- xAI's "Thinking..." placeholder dedup is scoped to the current stream step.
- Perplexity maps
lengthand emits step events. PrismFakestreams emit the same step events as real providers.
Deprecations
OllamaStreamStatetoken counters.
What's Changed
Full Changelog: v0.101.0...v0.102.0