ToolkitBuilder/ToolkitConfig pairs. This guide walks through both patterns, explains why you might pick one over the other, and maps out the runtime flow for message-specific tool selection.
Static Toolkits (Always On)
- Construct the toolkit up front (for example
StorageToolkit()or a custom bundle) and pass it in the agent’stoolkitslist. - The toolkit is instantiated exactly once and participates in every LLM turn; no additional configuration is required.
- Choose this when the agent must always provide a capability.
Python
Dynamic Toolkits (Builder Driven)
- Register one or more
ToolkitBuilderinstances so the agent can materialise toolkits from configs at runtime. - The UI (or calling service) requests the builder list via
get_thread_toolkit_builders, lets the user pick tools, then sends atoolsarray where each entry matches a buildernameand config schema. - During the turn,
make_tools(model, providers, tools)validates each config against the builder’sToolkitConfigand instantiates only the requested toolkits. - Perfect for capabilities that should be opt-in or short lived: MCP connectors, local shell access, or storage uploads that only appear when the user adds an attachment.
Python
Message Flow for Dynamic Tools
- Discover providers: the client sends
get_thread_toolkit_builders; the chatbot replies with the builders it supports. - User picks tools: the client shows those builders as toggles and builds a JSON payload that matches the selected configs.
- Agent turn:
ChatBotcollects static thread toolkits, callsmake_toolswith the selected configs, and flattens the combined toolkit list. - LLM execution:
OpenAIResponsesAdapter.nextconverts those toolkits into OpenAI tool definitions for that single request. - Tool call routing: when the LLM calls a tool,
ResponsesToolBundlelooks up the owning toolkit (static or dynamic) and executes it. On the next message, the list resets and the process repeats.
Motivations and Use Cases
- User-selected connectors: Let people opt into specific tools for MCP servers, web search, proprietary APIs, and more on a per-message basis.
- Parity with consumer chat UIs: Deliver a ChatGPT-style experience where tools appear as checkboxes the user can toggle.
- Focused reasoning: Surface only the tools relevant to the current task so the model stays on target instead of exploring unnecessary capabilities.