feat: reuse previous mcp tool listings where possible (#3710)

# What does this PR do?
This PR checks whether, if a previous response is linked, there are
mcp_list_tools objects that can be reused instead of listing the tools
explicitly every time.

 Closes #3106 

## Test Plan
Tested manually.
Added unit tests to cover new behaviour.

---------

Signed-off-by: Gordon Sim <gsim@redhat.com>
Co-authored-by: Ashwin Bharambe <ashwin.bharambe@gmail.com>
This commit is contained in:
grs 2025-10-10 17:28:25 +01:00 committed by GitHub
parent 0066d986c5
commit 8bf07f91cb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 1835 additions and 983 deletions

View file

@ -8975,6 +8975,168 @@
"title": "OpenAIResponseInputMessageContentText",
"description": "Text content for input messages in OpenAI response format."
},
"OpenAIResponseInputToolFileSearch": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "file_search",
"default": "file_search",
"description": "Tool type identifier, always \"file_search\""
},
"vector_store_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of vector store identifiers to search within"
},
"filters": {
"type": "object",
"additionalProperties": {
"oneOf": [
{
"type": "null"
},
{
"type": "boolean"
},
{
"type": "number"
},
{
"type": "string"
},
{
"type": "array"
},
{
"type": "object"
}
]
},
"description": "(Optional) Additional filters to apply to the search"
},
"max_num_results": {
"type": "integer",
"default": 10,
"description": "(Optional) Maximum number of search results to return (1-50)"
},
"ranking_options": {
"type": "object",
"properties": {
"ranker": {
"type": "string",
"description": "(Optional) Name of the ranking algorithm to use"
},
"score_threshold": {
"type": "number",
"default": 0.0,
"description": "(Optional) Minimum relevance score threshold for results"
}
},
"additionalProperties": false,
"description": "(Optional) Options for ranking and scoring search results"
}
},
"additionalProperties": false,
"required": [
"type",
"vector_store_ids"
],
"title": "OpenAIResponseInputToolFileSearch",
"description": "File search tool configuration for OpenAI response inputs."
},
"OpenAIResponseInputToolFunction": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "function",
"default": "function",
"description": "Tool type identifier, always \"function\""
},
"name": {
"type": "string",
"description": "Name of the function that can be called"
},
"description": {
"type": "string",
"description": "(Optional) Description of what the function does"
},
"parameters": {
"type": "object",
"additionalProperties": {
"oneOf": [
{
"type": "null"
},
{
"type": "boolean"
},
{
"type": "number"
},
{
"type": "string"
},
{
"type": "array"
},
{
"type": "object"
}
]
},
"description": "(Optional) JSON schema defining the function's parameters"
},
"strict": {
"type": "boolean",
"description": "(Optional) Whether to enforce strict parameter validation"
}
},
"additionalProperties": false,
"required": [
"type",
"name"
],
"title": "OpenAIResponseInputToolFunction",
"description": "Function tool configuration for OpenAI response inputs."
},
"OpenAIResponseInputToolWebSearch": {
"type": "object",
"properties": {
"type": {
"oneOf": [
{
"type": "string",
"const": "web_search"
},
{
"type": "string",
"const": "web_search_preview"
},
{
"type": "string",
"const": "web_search_preview_2025_03_11"
}
],
"default": "web_search",
"description": "Web search tool type variant to use"
},
"search_context_size": {
"type": "string",
"default": "medium",
"description": "(Optional) Size of search context, must be \"low\", \"medium\", or \"high\""
}
},
"additionalProperties": false,
"required": [
"type"
],
"title": "OpenAIResponseInputToolWebSearch",
"description": "Web search tool configuration for OpenAI response inputs."
},
"OpenAIResponseMCPApprovalRequest": {
"type": "object",
"properties": {
@ -9157,6 +9319,13 @@
"type": "number",
"description": "(Optional) Nucleus sampling parameter used for generation"
},
"tools": {
"type": "array",
"items": {
"$ref": "#/components/schemas/OpenAIResponseTool"
},
"description": "(Optional) An array of tools the model may call while generating a response."
},
"truncation": {
"type": "string",
"description": "(Optional) Truncation strategy applied to the response"
@ -9610,6 +9779,79 @@
"title": "OpenAIResponseText",
"description": "Text response configuration for OpenAI responses."
},
"OpenAIResponseTool": {
"oneOf": [
{
"$ref": "#/components/schemas/OpenAIResponseInputToolWebSearch"
},
{
"$ref": "#/components/schemas/OpenAIResponseInputToolFileSearch"
},
{
"$ref": "#/components/schemas/OpenAIResponseInputToolFunction"
},
{
"$ref": "#/components/schemas/OpenAIResponseToolMCP"
}
],
"discriminator": {
"propertyName": "type",
"mapping": {
"web_search": "#/components/schemas/OpenAIResponseInputToolWebSearch",
"file_search": "#/components/schemas/OpenAIResponseInputToolFileSearch",
"function": "#/components/schemas/OpenAIResponseInputToolFunction",
"mcp": "#/components/schemas/OpenAIResponseToolMCP"
}
}
},
"OpenAIResponseToolMCP": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "mcp",
"default": "mcp",
"description": "Tool type identifier, always \"mcp\""
},
"server_label": {
"type": "string",
"description": "Label to identify this MCP server"
},
"allowed_tools": {
"oneOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "object",
"properties": {
"tool_names": {
"type": "array",
"items": {
"type": "string"
},
"description": "(Optional) List of specific tool names that are allowed"
}
},
"additionalProperties": false,
"title": "AllowedToolsFilter",
"description": "Filter configuration for restricting which MCP tools can be used."
}
],
"description": "(Optional) Restriction on which tools can be used from this server"
}
},
"additionalProperties": false,
"required": [
"type",
"server_label"
],
"title": "OpenAIResponseToolMCP",
"description": "Model Context Protocol (MCP) tool configuration for OpenAI response object."
},
"OpenAIResponseUsage": {
"type": "object",
"properties": {
@ -9697,134 +9939,6 @@
}
}
},
"OpenAIResponseInputToolFileSearch": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "file_search",
"default": "file_search",
"description": "Tool type identifier, always \"file_search\""
},
"vector_store_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of vector store identifiers to search within"
},
"filters": {
"type": "object",
"additionalProperties": {
"oneOf": [
{
"type": "null"
},
{
"type": "boolean"
},
{
"type": "number"
},
{
"type": "string"
},
{
"type": "array"
},
{
"type": "object"
}
]
},
"description": "(Optional) Additional filters to apply to the search"
},
"max_num_results": {
"type": "integer",
"default": 10,
"description": "(Optional) Maximum number of search results to return (1-50)"
},
"ranking_options": {
"type": "object",
"properties": {
"ranker": {
"type": "string",
"description": "(Optional) Name of the ranking algorithm to use"
},
"score_threshold": {
"type": "number",
"default": 0.0,
"description": "(Optional) Minimum relevance score threshold for results"
}
},
"additionalProperties": false,
"description": "(Optional) Options for ranking and scoring search results"
}
},
"additionalProperties": false,
"required": [
"type",
"vector_store_ids"
],
"title": "OpenAIResponseInputToolFileSearch",
"description": "File search tool configuration for OpenAI response inputs."
},
"OpenAIResponseInputToolFunction": {
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "function",
"default": "function",
"description": "Tool type identifier, always \"function\""
},
"name": {
"type": "string",
"description": "Name of the function that can be called"
},
"description": {
"type": "string",
"description": "(Optional) Description of what the function does"
},
"parameters": {
"type": "object",
"additionalProperties": {
"oneOf": [
{
"type": "null"
},
{
"type": "boolean"
},
{
"type": "number"
},
{
"type": "string"
},
{
"type": "array"
},
{
"type": "object"
}
]
},
"description": "(Optional) JSON schema defining the function's parameters"
},
"strict": {
"type": "boolean",
"description": "(Optional) Whether to enforce strict parameter validation"
}
},
"additionalProperties": false,
"required": [
"type",
"name"
],
"title": "OpenAIResponseInputToolFunction",
"description": "Function tool configuration for OpenAI response inputs."
},
"OpenAIResponseInputToolMCP": {
"type": "object",
"properties": {
@ -9941,40 +10055,6 @@
"title": "OpenAIResponseInputToolMCP",
"description": "Model Context Protocol (MCP) tool configuration for OpenAI response inputs."
},
"OpenAIResponseInputToolWebSearch": {
"type": "object",
"properties": {
"type": {
"oneOf": [
{
"type": "string",
"const": "web_search"
},
{
"type": "string",
"const": "web_search_preview"
},
{
"type": "string",
"const": "web_search_preview_2025_03_11"
}
],
"default": "web_search",
"description": "Web search tool type variant to use"
},
"search_context_size": {
"type": "string",
"default": "medium",
"description": "(Optional) Size of search context, must be \"low\", \"medium\", or \"high\""
}
},
"additionalProperties": false,
"required": [
"type"
],
"title": "OpenAIResponseInputToolWebSearch",
"description": "Web search tool configuration for OpenAI response inputs."
},
"CreateOpenaiResponseRequest": {
"type": "object",
"properties": {
@ -10096,6 +10176,13 @@
"type": "number",
"description": "(Optional) Nucleus sampling parameter used for generation"
},
"tools": {
"type": "array",
"items": {
"$ref": "#/components/schemas/OpenAIResponseTool"
},
"description": "(Optional) An array of tools the model may call while generating a response."
},
"truncation": {
"type": "string",
"description": "(Optional) Truncation strategy applied to the response"