Unified Claude SDK with multi-provider failover for The Whatever App
npm install @thewhateverapp/aiUnified Claude SDK with multi-provider failover for YOLO Labs services.
``bash`
pnpm add @thewhateverapp/ai
`typescript
import { AI } from '@thewhateverapp/ai';
const ai = new AI({
providers: {
anthropic: { apiKey: process.env.ANTHROPIC_API_KEY },
vertex: { projectId: process.env.GCP_PROJECT_ID },
openrouter: { apiKey: process.env.OPENROUTER_API_KEY },
},
});
const response = await ai.chat({
messages: [{ role: 'user', content: 'Hello!' }],
});
console.log(response.content);
`
- Multi-provider failover: Anthropic → Vertex AI → OpenRouter
- Rate limit tracking: Preemptive provider rotation
- Streaming support: Real-time response streaming
- Tool/function calling: Full tool use support
- Type-safe: Complete TypeScript types
`typescript`
const response = await ai.chat({
messages: [{ role: 'user', content: 'Hello!' }],
system: 'You are a helpful assistant.',
model: 'claude-sonnet-4-20250514', // optional, defaults to claude-sonnet-4
maxTokens: 4096,
temperature: 0.7,
});
`typescript`
for await (const event of ai.chatStream({ messages })) {
if (event.type === 'content_block_delta' && event.delta.text) {
process.stdout.write(event.delta.text);
}
}
`typescript
const response = await ai.chat({
messages: [{ role: 'user', content: 'What is the weather in Tokyo?' }],
tools: [
{
name: 'get_weather',
description: 'Get current weather for a location',
input_schema: {
type: 'object',
properties: {
location: { type: 'string', description: 'City name' },
},
required: ['location'],
},
},
],
});
if (response.stop_reason === 'tool_use') {
const toolUse = response.content.find(c => c.type === 'tool_use');
// Handle tool call...
}
`
`typescript`
const response = await ai.chat({
messages,
provider: 'vertex', // bypass failover
});
| Provider | Auth | Model Format |
|----------|------|--------------|
| Anthropic | API key | claude-sonnet-4-20250514 |claude-sonnet-4@20250514
| Vertex AI | GCP ADC | |anthropic/claude-sonnet-4-20250514
| OpenRouter | API key | |
Model names are automatically converted between formats.
`typescript
import { RateLimitError, AllProvidersFailedError } from '@thewhateverapp/ai';
try {
await ai.chat({ messages });
} catch (error) {
if (error instanceof RateLimitError) {
console.log(Rate limited by ${error.provider}, retry after ${error.retryAfter}ms);`
} else if (error instanceof AllProvidersFailedError) {
console.log('All providers failed:', error.errors);
}
}
`typescript``
const ai = new AI({
providers: {
anthropic: { apiKey: '...' },
vertex: { projectId: '...', region: 'us-east5' },
openrouter: { apiKey: '...' },
},
defaultModel: 'claude-sonnet-4-20250514',
fallbackChain: ['anthropic', 'vertex', 'openrouter'],
timeout: 60000,
});