mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-08-15 14:08:00 +00:00
feat(responses): add MCP argument streaming and content part events (#3136)
# What does this PR do? Adds content part streaming events to the OpenAI-compatible Responses API to support more granular streaming of response content. This introduces: 1. New schema types for content parts: `OpenAIResponseContentPart` with variants for text output and refusals 2. New streaming event types: - `OpenAIResponseObjectStreamResponseContentPartAdded` for when content parts begin - `OpenAIResponseObjectStreamResponseContentPartDone` for when content parts complete 3. Implementation in the reference provider to emit these events during streaming responses. Also emits MCP arguments just like function call ones. ## Test Plan Updated existing streaming tests to verify content part events are properly emitted
This commit is contained in:
parent
8638537d14
commit
e1e161553c
6 changed files with 480 additions and 35 deletions
137
docs/_static/llama-stack-spec.html
vendored
137
docs/_static/llama-stack-spec.html
vendored
|
@ -8821,6 +8821,61 @@
|
|||
"title": "OpenAIResponseOutputMessageMCPListTools",
|
||||
"description": "MCP list tools output message containing available tools from an MCP server."
|
||||
},
|
||||
"OpenAIResponseContentPart": {
|
||||
"oneOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/OpenAIResponseContentPartOutputText"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OpenAIResponseContentPartRefusal"
|
||||
}
|
||||
],
|
||||
"discriminator": {
|
||||
"propertyName": "type",
|
||||
"mapping": {
|
||||
"output_text": "#/components/schemas/OpenAIResponseContentPartOutputText",
|
||||
"refusal": "#/components/schemas/OpenAIResponseContentPartRefusal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"OpenAIResponseContentPartOutputText": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "output_text",
|
||||
"default": "output_text"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"type",
|
||||
"text"
|
||||
],
|
||||
"title": "OpenAIResponseContentPartOutputText"
|
||||
},
|
||||
"OpenAIResponseContentPartRefusal": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "refusal",
|
||||
"default": "refusal"
|
||||
},
|
||||
"refusal": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"type",
|
||||
"refusal"
|
||||
],
|
||||
"title": "OpenAIResponseContentPartRefusal"
|
||||
},
|
||||
"OpenAIResponseObjectStream": {
|
||||
"oneOf": [
|
||||
{
|
||||
|
@ -8877,6 +8932,12 @@
|
|||
{
|
||||
"$ref": "#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallCompleted"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OpenAIResponseObjectStreamResponseContentPartAdded"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OpenAIResponseObjectStreamResponseContentPartDone"
|
||||
},
|
||||
{
|
||||
"$ref": "#/components/schemas/OpenAIResponseObjectStreamResponseCompleted"
|
||||
}
|
||||
|
@ -8902,6 +8963,8 @@
|
|||
"response.mcp_call.in_progress": "#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallInProgress",
|
||||
"response.mcp_call.failed": "#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallFailed",
|
||||
"response.mcp_call.completed": "#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallCompleted",
|
||||
"response.content_part.added": "#/components/schemas/OpenAIResponseObjectStreamResponseContentPartAdded",
|
||||
"response.content_part.done": "#/components/schemas/OpenAIResponseObjectStreamResponseContentPartDone",
|
||||
"response.completed": "#/components/schemas/OpenAIResponseObjectStreamResponseCompleted"
|
||||
}
|
||||
}
|
||||
|
@ -8928,6 +8991,80 @@
|
|||
"title": "OpenAIResponseObjectStreamResponseCompleted",
|
||||
"description": "Streaming event indicating a response has been completed."
|
||||
},
|
||||
"OpenAIResponseObjectStreamResponseContentPartAdded": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"response_id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the response containing this content"
|
||||
},
|
||||
"item_id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the output item containing this content part"
|
||||
},
|
||||
"part": {
|
||||
"$ref": "#/components/schemas/OpenAIResponseContentPart",
|
||||
"description": "The content part that was added"
|
||||
},
|
||||
"sequence_number": {
|
||||
"type": "integer",
|
||||
"description": "Sequential number for ordering streaming events"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "response.content_part.added",
|
||||
"default": "response.content_part.added",
|
||||
"description": "Event type identifier, always \"response.content_part.added\""
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"response_id",
|
||||
"item_id",
|
||||
"part",
|
||||
"sequence_number",
|
||||
"type"
|
||||
],
|
||||
"title": "OpenAIResponseObjectStreamResponseContentPartAdded",
|
||||
"description": "Streaming event for when a new content part is added to a response item."
|
||||
},
|
||||
"OpenAIResponseObjectStreamResponseContentPartDone": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"response_id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the response containing this content"
|
||||
},
|
||||
"item_id": {
|
||||
"type": "string",
|
||||
"description": "Unique identifier of the output item containing this content part"
|
||||
},
|
||||
"part": {
|
||||
"$ref": "#/components/schemas/OpenAIResponseContentPart",
|
||||
"description": "The completed content part"
|
||||
},
|
||||
"sequence_number": {
|
||||
"type": "integer",
|
||||
"description": "Sequential number for ordering streaming events"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "response.content_part.done",
|
||||
"default": "response.content_part.done",
|
||||
"description": "Event type identifier, always \"response.content_part.done\""
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"response_id",
|
||||
"item_id",
|
||||
"part",
|
||||
"sequence_number",
|
||||
"type"
|
||||
],
|
||||
"title": "OpenAIResponseObjectStreamResponseContentPartDone",
|
||||
"description": "Streaming event for when a content part is completed."
|
||||
},
|
||||
"OpenAIResponseObjectStreamResponseCreated": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
|
111
docs/_static/llama-stack-spec.yaml
vendored
111
docs/_static/llama-stack-spec.yaml
vendored
|
@ -6441,6 +6441,43 @@ components:
|
|||
title: OpenAIResponseOutputMessageMCPListTools
|
||||
description: >-
|
||||
MCP list tools output message containing available tools from an MCP server.
|
||||
OpenAIResponseContentPart:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/OpenAIResponseContentPartOutputText'
|
||||
- $ref: '#/components/schemas/OpenAIResponseContentPartRefusal'
|
||||
discriminator:
|
||||
propertyName: type
|
||||
mapping:
|
||||
output_text: '#/components/schemas/OpenAIResponseContentPartOutputText'
|
||||
refusal: '#/components/schemas/OpenAIResponseContentPartRefusal'
|
||||
OpenAIResponseContentPartOutputText:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
const: output_text
|
||||
default: output_text
|
||||
text:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
required:
|
||||
- type
|
||||
- text
|
||||
title: OpenAIResponseContentPartOutputText
|
||||
OpenAIResponseContentPartRefusal:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
const: refusal
|
||||
default: refusal
|
||||
refusal:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
required:
|
||||
- type
|
||||
- refusal
|
||||
title: OpenAIResponseContentPartRefusal
|
||||
OpenAIResponseObjectStream:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseCreated'
|
||||
|
@ -6461,6 +6498,8 @@ components:
|
|||
- $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallInProgress'
|
||||
- $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallFailed'
|
||||
- $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallCompleted'
|
||||
- $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseContentPartAdded'
|
||||
- $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseContentPartDone'
|
||||
- $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseCompleted'
|
||||
discriminator:
|
||||
propertyName: type
|
||||
|
@ -6483,6 +6522,8 @@ components:
|
|||
response.mcp_call.in_progress: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallInProgress'
|
||||
response.mcp_call.failed: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallFailed'
|
||||
response.mcp_call.completed: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallCompleted'
|
||||
response.content_part.added: '#/components/schemas/OpenAIResponseObjectStreamResponseContentPartAdded'
|
||||
response.content_part.done: '#/components/schemas/OpenAIResponseObjectStreamResponseContentPartDone'
|
||||
response.completed: '#/components/schemas/OpenAIResponseObjectStreamResponseCompleted'
|
||||
"OpenAIResponseObjectStreamResponseCompleted":
|
||||
type: object
|
||||
|
@ -6504,6 +6545,76 @@ components:
|
|||
OpenAIResponseObjectStreamResponseCompleted
|
||||
description: >-
|
||||
Streaming event indicating a response has been completed.
|
||||
"OpenAIResponseObjectStreamResponseContentPartAdded":
|
||||
type: object
|
||||
properties:
|
||||
response_id:
|
||||
type: string
|
||||
description: >-
|
||||
Unique identifier of the response containing this content
|
||||
item_id:
|
||||
type: string
|
||||
description: >-
|
||||
Unique identifier of the output item containing this content part
|
||||
part:
|
||||
$ref: '#/components/schemas/OpenAIResponseContentPart'
|
||||
description: The content part that was added
|
||||
sequence_number:
|
||||
type: integer
|
||||
description: >-
|
||||
Sequential number for ordering streaming events
|
||||
type:
|
||||
type: string
|
||||
const: response.content_part.added
|
||||
default: response.content_part.added
|
||||
description: >-
|
||||
Event type identifier, always "response.content_part.added"
|
||||
additionalProperties: false
|
||||
required:
|
||||
- response_id
|
||||
- item_id
|
||||
- part
|
||||
- sequence_number
|
||||
- type
|
||||
title: >-
|
||||
OpenAIResponseObjectStreamResponseContentPartAdded
|
||||
description: >-
|
||||
Streaming event for when a new content part is added to a response item.
|
||||
"OpenAIResponseObjectStreamResponseContentPartDone":
|
||||
type: object
|
||||
properties:
|
||||
response_id:
|
||||
type: string
|
||||
description: >-
|
||||
Unique identifier of the response containing this content
|
||||
item_id:
|
||||
type: string
|
||||
description: >-
|
||||
Unique identifier of the output item containing this content part
|
||||
part:
|
||||
$ref: '#/components/schemas/OpenAIResponseContentPart'
|
||||
description: The completed content part
|
||||
sequence_number:
|
||||
type: integer
|
||||
description: >-
|
||||
Sequential number for ordering streaming events
|
||||
type:
|
||||
type: string
|
||||
const: response.content_part.done
|
||||
default: response.content_part.done
|
||||
description: >-
|
||||
Event type identifier, always "response.content_part.done"
|
||||
additionalProperties: false
|
||||
required:
|
||||
- response_id
|
||||
- item_id
|
||||
- part
|
||||
- sequence_number
|
||||
- type
|
||||
title: >-
|
||||
OpenAIResponseObjectStreamResponseContentPartDone
|
||||
description: >-
|
||||
Streaming event for when a content part is completed.
|
||||
"OpenAIResponseObjectStreamResponseCreated":
|
||||
type: object
|
||||
properties:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue