8.7 KiB
8.7 KiB
Open Responses mapping (llm_client -> Open Responses)
This document maps the current llm_client event model to Open Responses items
and streaming events. It focuses on output streaming; input items are noted
where they are the closest semantic match.
Legend
- OR item: Open Responses item types used in
response.output. - OR event: Open Responses streaming events (
response.*). - Note: Gaps or required adaptation decisions.
Response lifecycle / meta events
| llm_client | Open Responses | Note |
|---|---|---|
StatusEvent::Started |
response.created, response.queued, response.in_progress |
OR has finer-grained lifecycle states; pick a subset or map Started -> response.in_progress. |
StatusEvent::Completed |
response.completed |
|
StatusEvent::Failed |
response.failed |
|
StatusEvent::Cancelled |
(no direct event) | Could map to response.incomplete or response.failed depending on semantics. |
UsageEvent |
response.completed payload usage |
OR reports usage on the response object, not as a dedicated streaming event. |
ErrorEvent |
error event |
OR has a dedicated error streaming event. |
PingEvent |
(no direct event) | OR does not define a heartbeat event. |
Output block lifecycle
Text block
| llm_client | Open Responses | Note |
|---|---|---|
BlockStart { block_type: Text, metadata: Text } |
response.output_item.added with item type message (assistant) |
OR output items are message/function_call/reasoning. This creates the message item. |
BlockDelta { delta: Text(..) } |
response.output_text.delta |
Text deltas map 1:1 to output text deltas. |
BlockStop { block_type: Text } |
response.output_text.done + response.content_part.done + response.output_item.done |
OR emits separate done events for content parts and items. |
Tool use (function call)
| llm_client | Open Responses | Note |
|---|---|---|
BlockStart { block_type: ToolUse, metadata: ToolUse { id, name } } |
response.output_item.added with item type function_call |
OR uses call_id + name + arguments string. Map id -> call_id. |
BlockDelta { delta: InputJson(..) } |
response.function_call_arguments.delta |
OR spec does not explicitly require argument deltas; treat as OpenAI-compatible extension if adopted. |
BlockStop { block_type: ToolUse } |
response.function_call_arguments.done + response.output_item.done |
Item status can be set to completed or incomplete. |
Tool result (function call output)
| llm_client | Open Responses | Note |
|---|---|---|
BlockStart { block_type: ToolResult, metadata: ToolResult { tool_use_id } } |
Input item function_call_output |
OR treats tool results as input items, not output items. This is a request-side mapping. |
BlockDelta |
(no direct output event) | OR does not stream tool output deltas as response events. |
BlockStop |
(no direct output event) | Tool output lives on the next request as an input item. |
Thinking / reasoning
| llm_client | Open Responses | Note |
|---|---|---|
BlockStart { block_type: Thinking, metadata: Thinking } |
response.output_item.added with item type reasoning |
OR models reasoning as a separate item type. |
BlockDelta { delta: Thinking(..) } |
response.reasoning.delta |
OR has dedicated reasoning delta events. |
BlockStop { block_type: Thinking } |
response.reasoning.done |
OR separates reasoning summary events (response.reasoning_summary_*) from reasoning deltas. Decide whether Thinking maps to full reasoning or summary only. |
Stop reasons
llm_client StopReason |
Open Responses | Note |
|---|---|---|
EndTurn |
response.completed + item status completed |
|
MaxTokens |
response.incomplete + item status incomplete |
|
StopSequence |
response.completed |
|
ToolUse |
response.completed for message item, followed by function_call output item |
OR models tool call as a separate output item. |
Gaps / open decisions
PingEventhas no OR equivalent. If needed, keep as internal only.Cancelledstatus needs a policy: map toresponse.incompleteorresponse.failed.- OR has
response.refusal.delta/response.refusal.done.llm_clienthas no refusal delta type; consider adding a new block or delta variant if needed. - OR splits item and content part lifecycles.
llm_clientcurrently has a single block lifecycle, so mapping should decide whether to synthesizecontent_part.*events or ignore them. - The OR specification does not state how
function_call.argumentsstream deltas;response.function_call_arguments.*should be treated as a compatible extension if required.