Skip to content

Commit 47d6adf

Browse files
authored
Merge pull request #1412 from asimurka/responses_implement_allowed_tools_filtering
LCORE-1262: Resolve allowed tools filters in LCS
2 parents f7b0104 + 00c9ad1 commit 47d6adf

4 files changed

Lines changed: 924 additions & 54 deletions

File tree

docs/responses.md

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ JSON schema with optional name, description, and strict mode:
270270

271271
#### `tool_choice`
272272

273-
Optional. **Tool selection strategy** that controls whether and how the model uses tools.
273+
Optional. **Tool selection strategy** that controls whether and how the model uses tools. Does not affect inline RAG selection.
274274

275275
**What it does:** When tools are supplied by `tools` attribute, `tool_choice` decides if the model may call them, must call at least one, or must not use any. You can pass a **simple mode string** or a **specific tool-config object** to force a particular tool (e.g. always use file search or a given function). Omitted or `null` behaves like `"auto"`. Typical use: disable tools for a plain-Q&A turn (`"none"`), force RAG-only (`file_search`), or constrain to a subset of tools (`allowed_tools`).
276276

@@ -282,9 +282,9 @@ Optional. **Tool selection strategy** that controls whether and how the model us
282282

283283
**Specific tool objects (object with `type`):**
284284

285-
- `allowed_tools`: Restrict to a list of tool definitions; `mode` is `"auto"` or `"required"`, `tools` is a list of tool objects (same shapes as in [tools](#tools)).
286-
- `file_search`: Force the model to use file search.
287-
- `web_search`: Force the model to use web search (optionally with a variant such as `web_search_preview`).
285+
- `allowed_tools`: Restrict to a list of tool definitions; `mode` is `"auto"` or `"required"`, `tools` is a list of key-valued filters for tools configured by `tools` attribute.
286+
- `file_search`: Force the model to use file-only search.
287+
- `web_search`: Force the model to use only web search.
288288
- `function`: Force a specific function; `name` (required) is the function name.
289289
- `mcp`: Force a tool on an MCP server; `server_label` (required), `name` (optional) tool name.
290290
- `custom`: Force a custom tool; `name` (required).
@@ -299,16 +299,25 @@ Simple modes (string): use one of `"auto"`, `"required"`, or `"none"`.
299299
{ "tool_choice": "none" }
300300
```
301301

302-
Restrict to specific tools with `allowed_tools` (mode `"auto"` or `"required"`, plus `tools` array):
302+
Restrict tool usage to a specific subset using `allowed_tools`. You can control behavior with the `mode` field (`"auto"` or `"required"`) and explicitly list permitted tools in the `tools` array.
303+
304+
The `tools` array acts as a **key-value filter**: each object specifies matching criteria (such as `type`, `server_label`, or `name`), and only tools that satisfy all provided attributes are allowed.
305+
306+
The example below limits tool usage to:
307+
- the `file_search` tool
308+
- a specific MCP tools (`tool_1` and `tool_2`) available on `server_1` (for multiple `name`s act as union)
309+
310+
If the `name` field is omitted for an MCP tool, the filter applies to all tools available on the specified server.
303311

304312
```json
305313
{
306314
"tool_choice": {
307315
"type": "allowed_tools",
308316
"mode": "required",
309317
"tools": [
310-
{ "type": "file_search", "vector_store_ids": ["vs_123"] },
311-
{ "type": "web_search" }
318+
{ "type": "file_search"},
319+
{ "type": "mcp", "server_label": "server_1", "name": "tool_1" },
320+
{ "type": "mcp", "server_label": "server_1", "name": "tool_2" }
312321
]
313322
}
314323
}
@@ -398,8 +407,8 @@ The following response attributes are inherited directly from the LLS OpenAPI sp
398407
| `temperature` | float | Temperature parameter used for generation |
399408
| `text` | object | Text response configuration object used |
400409
| `top_p` | float | Top-p sampling used |
401-
| `tools` | array[object] | Tools available during generation |
402-
| `tool_choice` | string or object | Tool selection used |
410+
| `tools` | array[object] | Internally resolved tools available during generation |
411+
| `tool_choice` | string or object | Internally resolved tool selection used |
403412
| `truncation` | string | Truncation strategy applied (`"auto"` or `"disabled"`) |
404413
| `usage` | object | Token usage (input_tokens, output_tokens, total_tokens) |
405414
| `instructions` | string | System instructions used |
@@ -519,6 +528,10 @@ Vector store IDs are configured within the `tools` as `file_search` tools rather
519528

520529
**Vector store IDs:** Accepts **LCORE format** in requests and also outputs it in responses; LCORE translates to/from Llama Stack format internally.
521530

531+
The response includes `tools` and `tool_choice` fields that reflect the internally resolved configuration. More specifically, the final set of tools and selection constraints after internal resolution and filtering.
532+
533+
`tool_choice` only constrains how the model may use tools (including RAG via the `file_search` tool). It does **not** change inline RAG: vector store IDs you list under `tools` for file search are still used to build inline RAG context even if you set `tool_choice` to `none` or use an allowlist that omits `file_search`.
534+
522535
### LCORE-Specific Extensions
523536

524537
The API introduces extensions that are not part of the OpenResponses specification:

src/app/endpoints/responses.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,14 @@ async def responses_endpoint_handler(
232232
responses_request.shield_ids,
233233
)
234234

235-
(
236-
responses_request.tools,
237-
responses_request.tool_choice,
238-
vector_store_ids,
239-
) = await resolve_tool_choice(
235+
# Extract vector store IDs for Inline RAG context before resolving tool choice.
236+
vector_store_ids: Optional[list[str]] = (
237+
extract_vector_store_ids_from_tools(responses_request.tools)
238+
if responses_request.tools is not None
239+
else None
240+
)
241+
242+
responses_request.tools, responses_request.tool_choice = await resolve_tool_choice(
240243
responses_request.tools,
241244
responses_request.tool_choice,
242245
auth[1],

0 commit comments

Comments
 (0)