Allow users to explicitly request tools like Canvas, Web Search, or Image Generation from the UI.
Problem
Users want to control which AI capabilities are used for their request. Without explicit selection, the AI decides autonomously which tools to invoke based on the message content.Solution
Add a tool selector in the chat input that:- Shows available tools based on model capabilities
- Stores the selection in message metadata
- Expands UI selections to actual tool names
- Appends a prompt to the message requesting those tools
How it works
- UI Selection: User picks a tool (e.g., “Canvas”) from the dropdown
- Metadata Storage: Selection stored as
selectedToolin message metadata - Tool Expansion: Single UI choice expands to multiple related tools
- Prompt Injection: Text appended to message requesting those tools
Flow
1. Define UI Tool Options
components/chat-features-definitions.ts
2. Map UI Selection to Tool Names
A single UI selection can map to multiple actual tools. For example, “Canvas” enables all document creation and editing tools.lib/ai/determine-explicitly-requested-tools.ts
3. Append Tool Request to Message
When tools are explicitly requested, append a text part to the user’s message instructing the model.app/(chat)/api/chat/add-explicit-tool-request-to-messages.ts
4. Wire It Together in the API Route
app/(chat)/api/chat/route.ts
lib/ai/core-chat-agent.ts
5. Build the UI Component
components/responsive-tools.tsx
Key files
| File | Purpose |
|---|---|
components/chat-features-definitions.ts | UI tool definitions (name, icon, shortName) |
components/responsive-tools.tsx | Tool selector dropdown component |
lib/ai/determine-explicitly-requested-tools.ts | Maps UI selection to actual tool names |
app/(chat)/api/chat/add-explicit-tool-request-to-messages.ts | Appends tool request prompt to message |
lib/ai/core-chat-agent.ts | Calls the prompt injection function |
Extending
To add a new tool option:- Add the tool definition to
toolDefinitionsinchat-features-definitions.ts - Add the key to
enabledToolsarray if it should appear in the selector - Add a mapping case in
determineExplicitlyRequestedTools