feat: add OpenAI provider integration and examples

This commit is contained in:
2025-05-28 12:04:10 +02:00
parent 42902445fb
commit aa2fd98cc1
9 changed files with 1061 additions and 17 deletions

169
README.md
View File

@ -1,6 +1,6 @@
# Simple AI Provider
A professional, extensible TypeScript package for integrating multiple AI providers into your applications with a unified interface. Currently supports Claude (Anthropic) with plans to add more providers.
A professional, extensible TypeScript package for integrating multiple AI providers into your applications with a unified interface. Currently supports **Claude (Anthropic)** and **OpenAI (GPT)** with plans to add more providers.
## Features
@ -11,6 +11,7 @@ A professional, extensible TypeScript package for integrating multiple AI provid
- 🛡️ **Error Handling**: Robust error handling with categorized error types
- 🔧 **Extensible**: Easy to add new AI providers
- 📦 **Modern**: Built with ES modules and modern JavaScript features
- 🌐 **Multi-Provider**: Switch between Claude and OpenAI seamlessly
## Installation
@ -47,16 +48,62 @@ const response = await claude.complete({
console.log(response.content);
```
### Basic Usage with OpenAI
```typescript
import { createOpenAIProvider } from 'simple-ai-provider';
// Create an OpenAI provider
const openai = createOpenAIProvider('your-openai-api-key');
// Initialize the provider
await openai.initialize();
// Generate a completion
const response = await openai.complete({
messages: [
{ role: 'user', content: 'Hello! How are you today?' }
],
maxTokens: 100,
temperature: 0.7
});
console.log(response.content);
```
### Multi-Provider Usage
```typescript
import { createProvider, createClaudeProvider, createOpenAIProvider } from 'simple-ai-provider';
// Method 1: Using specific factory functions
const claude = createClaudeProvider('your-anthropic-api-key');
const openai = createOpenAIProvider('your-openai-api-key');
// Method 2: Using generic factory
const claude2 = createProvider('claude', { apiKey: 'your-anthropic-api-key' });
const openai2 = createProvider('openai', { apiKey: 'your-openai-api-key' });
// Initialize both
await Promise.all([claude.initialize(), openai.initialize()]);
// Use the same interface for both providers
const prompt = { messages: [{ role: 'user', content: 'Explain AI' }] };
const claudeResponse = await claude.complete(prompt);
const openaiResponse = await openai.complete(prompt);
```
### Streaming Responses
```typescript
import { createClaudeProvider } from 'simple-ai-provider';
import { createOpenAIProvider } from 'simple-ai-provider';
const claude = createClaudeProvider('your-anthropic-api-key');
await claude.initialize();
const openai = createOpenAIProvider('your-openai-api-key');
await openai.initialize();
// Stream a completion
for await (const chunk of claude.stream({
for await (const chunk of openai.stream({
messages: [
{ role: 'user', content: 'Write a short story about a robot.' }
],
@ -73,8 +120,9 @@ for await (const chunk of claude.stream({
### Advanced Configuration
```typescript
import { ClaudeProvider } from 'simple-ai-provider';
import { ClaudeProvider, OpenAIProvider } from 'simple-ai-provider';
// Claude with custom configuration
const claude = new ClaudeProvider({
apiKey: 'your-anthropic-api-key',
defaultModel: 'claude-3-5-sonnet-20241022',
@ -83,14 +131,24 @@ const claude = new ClaudeProvider({
baseUrl: 'https://api.anthropic.com' // optional custom endpoint
});
await claude.initialize();
// OpenAI with organization and project
const openai = new OpenAIProvider({
apiKey: 'your-openai-api-key',
defaultModel: 'gpt-4',
organization: 'org-your-org-id',
project: 'proj-your-project-id',
timeout: 60000,
maxRetries: 5
});
const response = await claude.complete({
await Promise.all([claude.initialize(), openai.initialize()]);
const response = await openai.complete({
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: 'Explain quantum computing in simple terms.' }
],
model: 'claude-3-5-haiku-20241022',
model: 'gpt-4-turbo',
maxTokens: 300,
temperature: 0.5,
topP: 0.9,
@ -147,6 +205,17 @@ const claude = createClaudeProvider('your-api-key', {
});
```
#### `createOpenAIProvider(apiKey, options?)`
Creates an OpenAI provider with simplified configuration.
```typescript
const openai = createOpenAIProvider('your-api-key', {
defaultModel: 'gpt-4',
organization: 'org-123',
timeout: 60000
});
```
#### `createProvider(type, config)`
Generic factory function for creating any provider type.
@ -155,6 +224,11 @@ const claude = createProvider('claude', {
apiKey: 'your-api-key',
defaultModel: 'claude-3-5-sonnet-20241022'
});
const openai = createProvider('openai', {
apiKey: 'your-api-key',
defaultModel: 'gpt-4'
});
```
### Provider Methods
@ -182,7 +256,7 @@ The package provides comprehensive error handling with categorized error types:
import { AIProviderError, AIErrorType } from 'simple-ai-provider';
try {
const response = await claude.complete({
const response = await openai.complete({
messages: [{ role: 'user', content: 'Hello!' }]
});
} catch (error) {
@ -213,26 +287,91 @@ try {
- `claude-3-sonnet-20240229`
- `claude-3-haiku-20240307`
### OpenAI (GPT)
- `gpt-4` (default)
- `gpt-4-turbo`
- `gpt-4-turbo-preview`
- `gpt-4-0125-preview`
- `gpt-4-1106-preview`
- `gpt-3.5-turbo`
- `gpt-3.5-turbo-0125`
- `gpt-3.5-turbo-1106`
## Environment Variables
You can set your API keys as environment variables:
```bash
export ANTHROPIC_API_KEY="your-anthropic-api-key"
export OPENAI_API_KEY="your-openai-api-key"
```
```typescript
const claude = createClaudeProvider(process.env.ANTHROPIC_API_KEY!);
const openai = createOpenAIProvider(process.env.OPENAI_API_KEY!);
```
## Provider Comparison
| Feature | Claude | OpenAI |
|---------|--------|--------|
| **Models** | 5 models | 8+ models |
| **Max Context** | 200K tokens | 128K tokens |
| **Streaming** | ✅ | ✅ |
| **Vision** | ✅ | ✅ |
| **Function Calling** | ✅ | ✅ |
| **JSON Mode** | ❌ | ✅ |
| **System Messages** | ✅ (separate) | ✅ (inline) |
## Best Practices
1. **Always initialize providers** before using them
2. **Handle errors gracefully** with proper error types
3. **Use appropriate models** for your use case
3. **Use appropriate models** for your use case (speed vs. capability)
4. **Set reasonable timeouts** for your application
5. **Implement retry logic** for production applications
6. **Monitor token usage** to control costs
7. **Use environment variables** for API keys
8. **Consider provider-specific features** when choosing
## Advanced Usage
### Provider Registry
```typescript
import { ProviderRegistry } from 'simple-ai-provider';
// List all registered providers
console.log(ProviderRegistry.getRegisteredProviders()); // ['claude', 'openai']
// Create provider by name
const provider = ProviderRegistry.create('openai', {
apiKey: 'your-api-key'
});
// Check if provider is registered
if (ProviderRegistry.isRegistered('claude')) {
console.log('Claude is available!');
}
```
### Custom Error Handling
```typescript
function handleAIError(error: unknown, providerName: string) {
if (error instanceof AIProviderError) {
console.error(`${providerName} Error (${error.type}):`, error.message);
if (error.statusCode) {
console.error('HTTP Status:', error.statusCode);
}
if (error.originalError) {
console.error('Original Error:', error.originalError.message);
}
}
}
```
## Extending the Package
@ -264,6 +403,9 @@ class MyCustomProvider extends BaseAIProvider {
};
}
}
// Register your provider
ProviderRegistry.register('mycustom', MyCustomProvider);
```
## Contributing
@ -279,6 +421,9 @@ MIT
### 1.0.0
- Initial release
- Claude provider implementation
- Streaming support
- OpenAI provider implementation
- Streaming support for both providers
- Comprehensive error handling
- TypeScript support
- Provider registry system
- Multi-provider examples