Session 8· 02· 15 min
Static vs Dynamic Tools
What you'll learn
- ▸Filter available tools based on agent state (auth level)
- ▸Use @wrap_model_call middleware to adjust tools at runtime
- ▸See the difference between static (fixed) and dynamic (state-driven) tools
What you will build
An agent where basic users can only search public docs, but admin users can also search internal docs. The middleware reads auth_level from state and filters the tool list dynamically.
Static tools
lesson 00
- •tools=[a, b, c] at creation
- •Same tools every call
- •Simple, predictable
Dynamic tools
this lesson
- •Middleware filters tools per call
- •Based on state (auth, step, flags)
- •Fine-grained access control
02_dynamic_tools.py (middleware)
@wrap_model_call
def filter_tools_by_auth(
request: ModelRequest, ①
handler: Callable[[ModelRequest], ModelResponse],
) -> ModelResponse:
auth = request.state.get("auth_level", "basic") ②
if auth == "admin":
tools = [search_public, search_internal]
else:
tools = [search_public]
request = request.override(tools=tools) ③
return handler(request)①ModelRequest gives you access to the current state and tools.
②Read state to decide which tools the model should see.
③request.override returns a new request with the filtered tool list.
$ python 02_dynamic_tools.py
Knowledge Check
Why would you hide tools from the model instead of just checking permissions in the tool function?
Recap — what you just learned
- ✓@wrap_model_call middleware runs before every LLM call
- ✓request.state lets you read agent state (auth, step, flags)
- ✓request.override(tools=...) swaps the tool list dynamically