0.6.6

OpenAI reasoning blocks, ADK workflow pauses and reducer conformance

A patch to @silverprotocol/core, @silverprotocol/openai-agents and @silverprotocol/google-adk. The wire vocabulary is untouched (AGJSON_VERSION stays 1.0.0-draft.3), no peer versions moved, and @silverprotocol/claude-agent-sdk, @silverprotocol/vercel-ai and @silverprotocol/richtext change only their version number.

Core: two reducer conformance fixes

  • A late delta for a message the Reducer has already sealed no longer attaches to it. A text, reasoning, opaque-reasoning or tool-argument delta whose block belongs to a sealed message now sets needsResync, as block-creating events already did (SPEC.md INV-MSG). A delta for a block the reducer has never seen behaves as before. If your stream delivers deltas after message.end, you will now see a resync instead of a message that grew after it closed.
  • A final tool.done that follows a preliminary one (more: true) now keeps toolMetadata and dynamic. Until now only the first delivery carried them into the folded result.

OpenAI Agents SDK: reasoning as a first-class block

  • Reasoning now folds as a first-class reasoning block. The Agents SDK reports a reasoning item only after the response completes, so until now it reached AgJSON only as ext.openai.late-reasoning. The block now opens where the item appears on the wire, ahead of the function call it precedes, and is filled from the completed response: OpenAI re-encrypts a reasoning item at each stage, and only the final copy is valid to send back when you replay the conversation.
  • message.start.model is filled from response.created, so the folded message records the model that answered.
  • A built-in tool call that OpenAI runs itself now carries providerExecuted: true on tool.start, so a client that relays tool calls knows not to run it again.
  • An assistant message’s phase (for example, commentary versus the final answer) now also rides text.start in providerMetadata, so it is known before the first delta. text.end carries it as before.

Google ADK

  • Streaming block ids no longer repeat within a turn. Each id is now a per-turn count for its kind, not the part’s position in its event, so two thinking events in one invoke no longer both open reasoning:0. The first block of each kind keeps its old id.
  • A workflow’s pause closes its turn as paused. A nested model node’s final answer no longer closes the whole invocation turn, so a later request for input lands on an open turn instead of making the Reducer resync.
  • hitl.ask for an authentication pause fills the spec’s authConfig field: the scheme, and the authorization URL, token URL and scopes where ADK provides them.
  • displayName on inline data and file data is carried: as the filename of a file block, in providerMetadata on image and audio blocks, and alongside a resource link.
  • Events that carry JSON null where the genai types say a field is optional (for example, session payloads serialized from Python) no longer throw or produce output the schema rejects.
  • Hardens how authentication objects from ADK are carried.

The compatibility tables on each npm page are unchanged.