Skip to content

Commit 48c2ee4

Browse files
authored
docs: clarify capability visibility and authorization (#4642)
1 parent f265bae commit 48c2ee4

3 files changed

Lines changed: 17 additions & 1 deletion

File tree

docs/context.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ You can use the context for things like:
2929

3030
Within a single run, derived wrappers share the same underlying app context, approval state, and usage tracking. Nested [`Agent.as_tool()`][agents.agent.Agent.as_tool] runs may attach a different `tool_input`, but they do not get an isolated copy of your app state by default.
3131

32+
### Use local context for capability visibility
33+
34+
When function tools, MCP tools, and handoffs depend on the same request policy, keep the policy inputs or helper on your application context. Each SDK surface exposes the current run context through its own callback:
35+
36+
- [`FunctionTool.is_enabled`][agents.tool.FunctionTool.is_enabled] receives a `RunContextWrapper`.
37+
- [`Handoff.is_enabled`][agents.handoffs.Handoff.is_enabled] receives a `RunContextWrapper`.
38+
- An MCP [`tool_filter`](mcp.md#dynamic-tool-filtering) receives a [`ToolFilterContext`][agents.mcp.ToolFilterContext], whose `run_context` property contains the current `RunContextWrapper`.
39+
40+
Adapt the shared application policy to these callbacks instead of maintaining separate capability lists. The callbacks control which capabilities the SDK exposes for the current run; they cannot authorize a model-generated argument or resource selection. For function tools, enforce those decisions inside the tool implementation or with [tool input guardrails](guardrails.md#tool-guardrails) and [approvals](human_in_the_loop.md) when appropriate. MCP servers must authorize their own protected operations. For a handoff with `input_type`, check the parsed input at the start of `on_handoff`, before application side effects, and raise instead of returning when authorization fails. Tool input guardrails do not run for handoffs. See [handoff inputs](handoffs.md#handoff-inputs) for the callback lifecycle.
41+
3242
### What `RunContextWrapper` exposes
3343

3444
[`RunContextWrapper`][agents.run_context.RunContextWrapper] is a wrapper around your app-defined context object. In practice you will most often use:

docs/handoffs.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ handoff_obj = handoff(
8585

8686
`input_type` describes the arguments for the handoff tool call itself. The SDK exposes that schema to the model as the handoff tool's `parameters`, validates the returned JSON locally, and passes the parsed value to `on_handoff`.
8787

88+
`is_enabled` is evaluated while the SDK prepares the available handoffs, before the model returns handoff arguments, so it cannot authorize values inside an argument-bearing handoff. When authorization depends on the parsed fields, perform the check at the start of `on_handoff`, before any application side effects. If authorization fails, raise instead of returning; the SDK continues the transfer after `on_handoff` returns successfully. Tool input guardrails apply to function tools, not handoffs.
89+
8890
It does not replace the next agent's main input, and it does not choose a different destination. The [`handoff()`][agents.handoffs.handoff] helper still transfers to the specific agent you wrapped, and the receiving agent still sees the conversation history unless you change it with an [`input_filter`][agents.handoffs.Handoff.input_filter] or nested handoff history settings.
8991

9092
`input_type` is also separate from [`RunContextWrapper.context`][agents.run_context.RunContextWrapper.context]. Use `input_type` for metadata the model decides at handoff time, not for application state or dependencies you already have locally.

docs/tools.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,11 +833,15 @@ The `is_enabled` parameter accepts:
833833

834834
Disabled tools are completely hidden from the LLM at runtime, making this useful for:
835835

836-
- Feature gating based on user permissions
836+
- Request-scoped capability visibility
837837
- Environment-specific tool availability (dev vs prod)
838838
- A/B testing different tool configurations
839839
- Dynamic tool filtering based on runtime state
840840

841+
For locally configured function tools, the runner also reevaluates `is_enabled` before invocation. However, `is_enabled` controls visibility and dispatch; it does not replace authorization that depends on the tool arguments or the resource being accessed. Enforce those checks inside the tool implementation, or use [tool input guardrails](guardrails.md#tool-guardrails) and [approvals](human_in_the_loop.md) when appropriate. MCP servers must authorize their own protected operations.
842+
843+
See [context management](context.md#use-local-context-for-capability-visibility) for a pattern that applies one application policy across function tools, MCP tools, and handoffs.
844+
841845
## Experimental: Codex tool
842846

843847
The `codex_tool` wraps the Codex CLI so an agent can run workspace-scoped tasks (shell, file edits, MCP tools) during a tool call. This surface is experimental and may change.

0 commit comments

Comments
 (0)