packagist prism-php/prism v0.102.0

6 hours ago

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\StreamCollector is removed. Use StreamedMessages::fromEvents($events) inside an asEventStreamResponse, asDataStreamResponse or asBroadcast callback.
  • OpenAI models Prism doesn't recognise, including custom names on OpenAI-compatible servers, get json_schema structured output instead of json_object. Use ->usingStructuredMode(StructuredMode::Json) for servers that can't handle it. gpt-3.5-turbo*, gpt-4, gpt-4-* and gpt-4o-2024-05-13 stay on json_object.
  • Reported token usage changes wherever a provider deviated from the usage contract (below).

Usage

  • promptTokens is uncached input. cacheReadInputTokens and cacheWriteInputTokens never overlap with it.
  • completionTokens includes reasoning. thoughtTokens is the reasoning portion.
  • Optional fields are null when the provider doesn't report them, 0 when it reports zero.
  • Gemini no longer excludes thinking from completionTokens or 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 null usage plus usage_seconds.
  • Prism Server's prompt_tokens and total_tokens include 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 thinking and thinking_signature are 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's ErrorEvent reports recoverable: false. OpenRouter's sync finish_reason: "error" maps to Error.
  • Stream callback messages are grouped one assistant message per step.
  • PrismFake multi-step streams split at every step. Fake tool steps need ->withFinishReason(FinishReason::ToolCalls) for StreamedMessages to 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_content reasoning and store: false conversations.
  • Anthropic fallbacks provider option, with beta headers added automatically and per-attempt usage in additionalContent['usage_iterations'].
  • Anthropic thinking.type passes through (adaptive, enabled, disabled, between_tools) with display and block_binding.
  • Anthropic pause_turn resumes automatically in text, structured and streaming requests within maxSteps.
  • Anthropic stop_reason and stop_details in additionalContent.
  • step_finish event payloads include finish_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_exceeded maps to Length.
  • OpenAI streams handle response.incomplete and response.failed.
  • DeepSeek, xAI, Z, Gemini and Ollama no longer run tool calls after a length, safety or error finish.
  • Every stream ends with a StepFinishEvent and exactly one StreamEndEvent. Exhausted maxSteps on a tool step reports ToolCalls.
  • Every TextStart / ThinkingStart gets exactly one matching Complete. DeepSeek emitted duplicate ThinkingComplete events.
  • 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 length and emits step events.
  • PrismFake streams emit the same step events as real providers.

Deprecations

  • OllamaStreamState token counters.

What's Changed

  • OpenAI and Anthropic Latest Model Support & Standardization by @sixlive in #1043

Full Changelog: v0.101.0...v0.102.0

Don't miss a new prism release

NewReleases is sending notifications on new releases.