| name | ai-sdk-patterns |
| description | Vercel AI SDK tool patterns for dx-toolkit - input schemas for smart queries, API key handling, raw response returns |
Vercel AI SDK Tool Patterns
Package-specific patterns for @youdotcom-oss/ai-sdk-plugin. Use these patterns when creating AI SDK tools.
Tool Function Structure
Each tool function follows this pattern:
export const youToolName = (config: YouToolsConfig = {}) => {
const apiKey = config.apiKey ?? process.env.YDC_API_KEY;
return tool({
description: 'Tool description for AI model',
inputSchema: ZodSchema,
execute: async (params) => {
if (!apiKey) {
throw new Error('YDC_API_KEY is required');
}
const response = await callApiUtility({
params,
YDC_API_KEY: apiKey,
getUserAgent,
});
// Return raw API response for maximum flexibility
return response;
},
});
};
Key Components
config- Optional configuration with API keytool()- AI SDK tool wrapperinputSchema- Zod schema that enables AI to construct intelligent queriesexecute()- Async function that calls You.com API- Returns raw API response for maximum flexibility
Input Schemas Enable Smart Queries
The most critical pattern is providing comprehensive input schemas. These schemas allow AI agents to construct intelligent, well-formed queries with all available parameters.
Always use schemas from @youdotcom-oss/mcp
// ✅ Import from @youdotcom-oss/mcp
import { SearchQuerySchema } from '@youdotcom-oss/mcp';
export const youSearch = (config: YouToolsConfig = {}) => {
return tool({
description: '...',
inputSchema: SearchQuerySchema, // Enables AI to use all search parameters
execute: async (params) => { ... },
});
};
// ❌ Don't duplicate or simplify schemas
const MySearchSchema = z.object({ query: z.string() }); // Missing filters!
inputSchema: MySearchSchema
Why this matters:
- Rich schemas enable AI to use advanced query parameters (filters, freshness, country, etc.)
- AI can construct more intelligent queries based on user intent
- Prevents duplicating schema definitions across packages
- Ensures consistency with MCP server schemas
Schema Examples
SearchQuerySchema - Enables AI to use search filters:
// AI can automatically add filters based on user intent:
// "Latest news about AI" → { query: "AI", freshness: "day" }
// "Python tutorials" → { query: "Python tutorials" }
ExpressAgentInputSchema - Enables AI to control agent behavior:
// AI can enable/disable web search based on query type:
// "What is 2+2?" → { input: "What is 2+2?", tools: [] } // No web needed
// "Latest GDP data" → { input: "Latest GDP data", tools: ["search"] }
ContentsQuerySchema - Enables AI to extract from multiple URLs:
// AI can extract from multiple pages and choose format:
// { urls: ["url1", "url2"], format: "markdown" }
API Key Handling
Always provide environment variable fallback
// ✅ Automatic environment variable fallback
const apiKey = config.apiKey ?? process.env.YDC_API_KEY;
// Usage - no explicit apiKey needed if YDC_API_KEY is set
const search = youSearch();
// Or override with explicit config
const search = youSearch({ apiKey: 'custom-key' });
Always validate API key before API calls
// ✅ Check API key in execute function
execute: async (params) => {
if (!apiKey) {
throw new Error('YDC_API_KEY is required');
}
const response = await callApi(...);
}
// ❌ Don't skip validation
execute: async (params) => {
const response = await callApi(...); // May fail with unclear error
}
Why this pattern?
- Provides clear error message when API key is missing
- Fails fast before making API calls
- Helps users identify configuration issues quickly
Response Format
Always return raw API response
// ✅ Return raw API response
execute: async (params) => {
const response = await fetchSearchResults({
searchQuery: params,
YDC_API_KEY: apiKey,
getUserAgent,
});
return response; // Raw response for maximum flexibility
}
// ❌ Don't format or transform responses
return {
text: formatResponse(response),
data: response,
};
Why raw responses?
- Maximum flexibility for AI SDK to process results
- No information loss from formatting
- AI SDK handles presentation layer
- Easier to debug (see actual API response)
Tool Descriptions
Write descriptions that guide AI behavior and explain when to use the tool:
// ✅ Clear guidance for AI model
description: 'Search the web for current information, news, articles, and content using You.com. Returns web results with snippets and news articles. Use this when you need up-to-date information or facts from the internet.'
// ✅ Explains tool purpose and use case
description: 'Fast AI agent powered by You.com that provides quick answers with optional web search. Use this for straightforward queries that benefit from real-time web information.'
// ❌ Too brief
description: 'Search the web'
// ❌ For humans instead of AI
description: 'This tool allows you to search'
Best Practices
- Use comprehensive input schemas - Enable AI to construct intelligent queries with all available parameters
- Always use schemas from @youdotcom-oss/mcp - Don't duplicate, import from shared package
- Return raw API responses - Maximum flexibility, no information loss
- Validate API keys - Fail fast with clear error messages
- Use environment variable fallback - Automatic YDC_API_KEY detection
- Write clear tool descriptions - Guide AI on when and how to use tools
Related Resources
- Vercel AI SDK Documentation: https://sdk.vercel.ai/docs
- Package AGENTS.md:
packages/ai-sdk-plugin/AGENTS.md - MCP Package (schemas):
packages/mcp/ - API Documentation:
packages/ai-sdk-plugin/docs/API.md