feat: OpenResponses
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
# 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
|
||||
|
||||
- `PingEvent` has no OR equivalent. If needed, keep as internal only.
|
||||
- `Cancelled` status needs a policy: map to `response.incomplete` or
|
||||
`response.failed`.
|
||||
- OR has `response.refusal.delta` / `response.refusal.done`. `llm_client` has no
|
||||
refusal delta type; consider adding a new block or delta variant if needed.
|
||||
- OR splits _item_ and _content part_ lifecycles. `llm_client` currently has a
|
||||
single block lifecycle, so mapping should decide whether to synthesize
|
||||
`content_part.*` events or ignore them.
|
||||
- The OR specification does not state how `function_call.arguments` stream
|
||||
deltas; `response.function_call_arguments.*` should be treated as a compatible
|
||||
extension if required.
|
||||
Reference in New Issue
Block a user