The unified AI client provides a simple interface for interacting with OpenAI and Anthropic models.
Overview
The AI client (src/lib/ai/client.ts) abstracts away provider-specific details, allowing you to switch between OpenAI and Anthropic with minimal code changes.
Setup
1. Environment Variables
Add your API keys to .env.local:
# Required for OpenAI
OPENAI_API_KEY=sk-...
# Optional for Anthropic
ANTHROPIC_API_KEY=sk-ant-...
2. Basic Usage
import { generateChatCompletion } from "@/lib/ai/client";
const response = await generateChatCompletion({
messages: [
{ role: "user", content: "What is TypeScript?" }
],
});
console.log(response.content); // AI response text
console.log(response.provider); // "openai" or "anthropic"
console.log(response.model); // Model used (e.g., "gpt-4")
API Reference
generateChatCompletion(options)
Generate a chat completion from an AI provider.
Parameters:
-
messages(required) - Array of chat messagestype ChatMessage = { role: "user" | "assistant" | "system"; content: string; }; -
model(optional) - Model to use (defaults based on provider)- OpenAI:
"gpt-4","gpt-3.5-turbo" - Anthropic:
"claude-3-opus-20240229","claude-3-sonnet-20240229"
- OpenAI:
-
temperature(optional) - Randomness (0-2, default: 0.7) -
maxTokens(optional) - Maximum tokens in response (default: 1000) -
provider(optional) - Force a specific provider:"openai"or"anthropic"
Returns:
interface ChatCompletionResult {
content: string;
provider: AIProvider;
model: string;
usage?: {
promptTokens: number;
completionTokens: number;
totalTokens: number;
};
}
Examples
Simple Chat
const response = await generateChatCompletion({
messages: [
{ role: "user", content: "Explain React hooks in one sentence." }
],
});
With System Prompt
const response = await generateChatCompletion({
messages: [
{ role: "system", content: "You are a helpful coding assistant." },
{ role: "user", content: "How do I use useEffect?" }
],
});
Conversation History
const messages = [
{ role: "user", content: "What is React?" },
{ role: "assistant", content: "React is a JavaScript library..." },
{ role: "user", content: "How does it differ from Vue?" }
];
const response = await generateChatCompletion({ messages });
Custom Model and Temperature
const response = await generateChatCompletion({
messages: [{ role: "user", content: "Write a creative story." }],
model: "gpt-4",
temperature: 0.9, // More creative
maxTokens: 2000,
});
Force Provider
// Use Anthropic even if OpenAI is default
const response = await generateChatCompletion({
messages: [{ role: "user", content: "Hello!" }],
provider: "anthropic",
});
Provider Selection
The client automatically selects a provider based on:
- Explicit
providerparameter (if provided) - Environment variables - Uses provider with available API key
- Default - Falls back to OpenAI if both are available
Error Handling
The client handles common errors:
- Missing API keys - Throws clear error message
- Rate limits - Returns error with retry information
- Invalid requests - Validates input and returns helpful errors
- Timeouts - Configurable timeout (default: 120 seconds)
try {
const response = await generateChatCompletion({ messages });
} catch (error) {
if (error.message.includes("API key")) {
// Handle missing API key
} else if (error.message.includes("rate limit")) {
// Handle rate limit
} else {
// Handle other errors
}
}
Best Practices
- Always check subscription before making requests
- Use system prompts for consistent behavior
- Set appropriate
maxTokensto control costs - Handle errors gracefully with try/catch
- Use streaming for better UX (see Streaming)
Next Steps
- Learn about Streaming Responses
- Explore Prompt Templates
- Set up Content Moderation