mirror of
https://github.com/meta-llama/llama-stack.git
synced 2025-10-05 04:17:32 +00:00
fix(openai_responses): OpenAIResponsesObject is not complete
This commit is contained in:
parent
27d6becfd0
commit
12f55c68b4
2 changed files with 179 additions and 13 deletions
|
@ -4,17 +4,22 @@
|
|||
# This source code is licensed under the terms described in the LICENSE file in
|
||||
# the root directory of this source tree.
|
||||
|
||||
from typing import Annotated, Any, Literal
|
||||
from typing import Annotated, Any, Literal, Optional, TypeAlias, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from typing_extensions import TypedDict
|
||||
|
||||
from llama_stack.apis.tools.openai_tool_choice import (
|
||||
ToolChoiceAllowed,
|
||||
ToolChoiceCustom,
|
||||
ToolChoiceFunction,
|
||||
ToolChoiceMcp,
|
||||
ToolChoiceTypes
|
||||
)
|
||||
from llama_stack.apis.vector_io import SearchRankingOptions as FileSearchRankingOptions
|
||||
from llama_stack.schema_utils import json_schema_type, register_schema
|
||||
|
||||
# NOTE(ashwin): this file is literally a copy of the OpenAI responses API schema. We should probably
|
||||
# take their YAML and generate this file automatically. Their YAML is available.
|
||||
|
||||
OpenAIResponsesToolChoice: TypeAlias = Union[ToolChoiceTypes, ToolChoiceAllowed, ToolChoiceFunction, ToolChoiceMcp, ToolChoiceCustom]
|
||||
|
||||
@json_schema_type
|
||||
class OpenAIResponseError(BaseModel):
|
||||
|
@ -316,21 +321,90 @@ class OpenAIResponseText(BaseModel):
|
|||
:param format: (Optional) Text format configuration specifying output format requirements
|
||||
"""
|
||||
|
||||
format: OpenAIResponseTextFormat | None = None
|
||||
# Default to text format to avoid breaking the loading of old responses
|
||||
# before the field was added. New responses will have this set always.
|
||||
format: OpenAIResponseTextFormat | None = Field(default_factory=lambda: OpenAIResponseTextFormat(type="text"))
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class OpenAIResponseIncompleteDetails(BaseModel):
|
||||
"""Incomplete details for OpenAI responses.
|
||||
|
||||
:param reason: Reason for the response being incomplete
|
||||
"""
|
||||
|
||||
reason: str
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class OpenAIResponsePrompt(BaseModel):
|
||||
"""Reference to a prompt template and its variables.
|
||||
|
||||
:param id: The unique identifier of the prompt template to use.
|
||||
:param variables: (Optional) Map of values to substitute in for variables in your prompt. The substitution values can either be strings, or other Response input types like images or files.
|
||||
:param version: (Optional) Version of the prompt template.
|
||||
"""
|
||||
|
||||
id: str
|
||||
variables: Optional[dict[str, Any]] = None
|
||||
version: Optional[str] = None
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class OpenAIResponseReasoning(BaseModel):
|
||||
"""Configuration options for reasoning models.
|
||||
|
||||
:param effort: (Optional) The effort level to use for reasoning.
|
||||
:param generate_summary: Deprecated. Use the generate_summary_text field instead. (Optional) Whether to generate a summary of the reasoning process.
|
||||
"""
|
||||
|
||||
effort: Optional[Literal["low", "medium", "high", "minimal"]] = None
|
||||
generate_summary: Optional[str] = None
|
||||
summary: Optional[str] = None
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class OpenAIResponsesTool(BaseModel):
|
||||
description: Optional[str] = None
|
||||
"""
|
||||
The description of the function, including guidance on when and how to call it,
|
||||
and guidance about what to tell the user when calling (if anything).
|
||||
"""
|
||||
|
||||
name: Optional[str] = None
|
||||
"""The name of the function."""
|
||||
|
||||
parameters: Optional[object] = None
|
||||
"""Parameters of the function in JSON Schema."""
|
||||
|
||||
type: Optional[Literal["function"]] = None
|
||||
"""The type of the tool, i.e. `function`."""
|
||||
|
||||
|
||||
@json_schema_type
|
||||
class OpenAIResponseObject(BaseModel):
|
||||
"""Complete OpenAI response object containing generation results and metadata.
|
||||
|
||||
Based on OpenAI Responses API schema: https://github.com/openai/openai-python/blob/34014aedbb8946c03e97e5c8d72e03ad2259cd7c/src/openai/types/responses/response.py#L38
|
||||
|
||||
:param created_at: Unix timestamp when the response was created
|
||||
:param error: (Optional) Error details if the response generation failed
|
||||
:param id: Unique identifier for this response
|
||||
:param incomplete_details: (Optional) Incomplete details if the response is incomplete
|
||||
:param instructions: (Optional) A system (or developer) message inserted into the model's context.
|
||||
:param max_output_tokens: (Optional) An upper bound for the number of tokens that can be generated for a response, including visible output tokens and reasoning tokens.
|
||||
:param max_tool_calls: (Optional) The maximum number of total calls to built-in tools that can be processed in a response.
|
||||
:param metadata: (Optional) Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format, and querying for objects via API or the dashboard.
|
||||
:param model: Model identifier used for generation
|
||||
:param object: Object type identifier, always "response"
|
||||
:param output: List of generated output items (messages, tool calls, etc.)
|
||||
:param parallel_tool_calls: Whether tool calls can be executed in parallel
|
||||
:param previous_response_id: (Optional) ID of the previous response in a conversation
|
||||
:param prompt: (Optional) Reference to a prompt template and its variables.
|
||||
:param prompt_cache_key: (Optional)Used to cache responses for similar requests to optimize your cache hit rates. Replaces the user field.
|
||||
:param reasoning: (Optional) Configuration options for reasoning models.
|
||||
:param safety_identifier: (Optional) A stable identifier used to help detect users of your application that may be violating OpenAI's usage policies.
|
||||
:param service_tier: (Optional) Specifies the processing type used for serving the request.
|
||||
:param status: Current status of the response generation
|
||||
:param temperature: (Optional) Sampling temperature used for generation
|
||||
:param text: Text formatting configuration for the response
|
||||
|
@ -340,21 +414,32 @@ class OpenAIResponseObject(BaseModel):
|
|||
"""
|
||||
|
||||
created_at: int
|
||||
error: OpenAIResponseError | None = None
|
||||
error: Optional[OpenAIResponseError] = None
|
||||
id: str
|
||||
incomplete_details: Optional[OpenAIResponseIncompleteDetails] = None # TODO: unimplemented
|
||||
instructions: Optional[str | list[str]] = None # TODO: unimplemented
|
||||
max_output_tokens: Optional[int] = None # TODO: unimplemented
|
||||
max_tool_calls: Optional[int] = None # TODO: unimplemented
|
||||
metadata: Optional[dict[str, str]] = None # TODO: unimplemented
|
||||
model: str
|
||||
object: Literal["response"] = "response"
|
||||
output: list[OpenAIResponseOutput]
|
||||
parallel_tool_calls: bool = False
|
||||
previous_response_id: str | None = None
|
||||
previous_response_id: Optional[str] = None
|
||||
prompt: Optional[OpenAIResponsePrompt] = None
|
||||
prompt_cache_key: Optional[str] = None
|
||||
reasoning: Optional[OpenAIResponseReasoning] = None
|
||||
safety_identifier: Optional[str] = None
|
||||
service_tier: Optional[str] = None # TODO: unimplemented
|
||||
status: str
|
||||
temperature: float | None = None
|
||||
# Default to text format to avoid breaking the loading of old responses
|
||||
# before the field was added. New responses will have this set always.
|
||||
text: OpenAIResponseText = OpenAIResponseText(format=OpenAIResponseTextFormat(type="text"))
|
||||
top_p: float | None = None
|
||||
truncation: str | None = None
|
||||
user: str | None = None
|
||||
text: Optional[OpenAIResponseText] = None
|
||||
tool_choice: Optional[OpenAIResponsesToolChoice] = None # TODO: unimplemented
|
||||
tools: Optional[list[OpenAIResponsesTool]] = None # TODO: unimplemented
|
||||
top_logprobs: Optional[int] = None # TODO: unimplemented
|
||||
top_p: Optional[float] = None
|
||||
user: Optional[str] = None # Deprecated: This field is being replaced by safety_identifier and prompt_cache_key
|
||||
truncation: Optional[str] = None
|
||||
|
||||
|
||||
@json_schema_type
|
||||
|
|
81
llama_stack/apis/tools/openai_tool_choice.py
Normal file
81
llama_stack/apis/tools/openai_tool_choice.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
from typing import Dict, List, Literal, Optional, TypeAlias
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
ToolChoiceOptions: TypeAlias = Literal["none", "auto", "required"]
|
||||
|
||||
|
||||
class ToolChoiceTypes(BaseModel):
|
||||
type: Literal[
|
||||
"file_search",
|
||||
"web_search_preview",
|
||||
"computer_use_preview",
|
||||
"web_search_preview_2025_03_11",
|
||||
"image_generation",
|
||||
"code_interpreter",
|
||||
]
|
||||
"""The type of hosted tool the model should to use.
|
||||
|
||||
Allowed values are:
|
||||
|
||||
- `file_search`
|
||||
- `web_search_preview`
|
||||
- `computer_use_preview`
|
||||
- `code_interpreter`
|
||||
- `image_generation`
|
||||
"""
|
||||
|
||||
|
||||
class ToolChoiceAllowed(BaseModel):
|
||||
mode: Literal["auto", "required"]
|
||||
"""Constrains the tools available to the model to a pre-defined set.
|
||||
|
||||
`auto` allows the model to pick from among the allowed tools and generate a
|
||||
message.
|
||||
|
||||
`required` requires the model to call one or more of the allowed tools.
|
||||
"""
|
||||
|
||||
tools: List[Dict[str, object]]
|
||||
"""A list of tool definitions that the model should be allowed to call.
|
||||
|
||||
For the Responses API, the list of tool definitions might look like:
|
||||
|
||||
```json
|
||||
[
|
||||
{ "type": "function", "name": "get_weather" },
|
||||
{ "type": "mcp", "server_label": "deepwiki" },
|
||||
{ "type": "image_generation" }
|
||||
]
|
||||
```
|
||||
"""
|
||||
|
||||
type: Literal["allowed_tools"]
|
||||
"""Allowed tool configuration type. Always `allowed_tools`."""
|
||||
|
||||
|
||||
class ToolChoiceFunction(BaseModel):
|
||||
name: str
|
||||
"""The name of the function to call."""
|
||||
|
||||
type: Literal["function"]
|
||||
"""For function calling, the type is always `function`."""
|
||||
|
||||
|
||||
class ToolChoiceMcp(BaseModel):
|
||||
server_label: str
|
||||
"""The label of the MCP server to use."""
|
||||
|
||||
type: Literal["mcp"]
|
||||
"""For MCP tools, the type is always `mcp`."""
|
||||
|
||||
name: Optional[str] = None
|
||||
"""The name of the tool to call on the server."""
|
||||
|
||||
|
||||
class ToolChoiceCustom(BaseModel):
|
||||
name: str
|
||||
"""The name of the custom tool to call."""
|
||||
|
||||
type: Literal["custom"]
|
||||
"""For custom tool calling, the type is always `custom`."""
|
Loading…
Add table
Add a link
Reference in a new issue