feat: add Google Gemini provider integration and docs

This commit is contained in:
2025-05-28 12:13:29 +02:00
parent aa2fd98cc1
commit 5da37f388f
9 changed files with 1015 additions and 87 deletions

View File

@ -1,11 +1,12 @@
/**
* Multi-provider example for Simple AI Provider
* Demonstrates how to use both Claude and OpenAI providers
* Demonstrates how to use Claude, OpenAI, and Gemini providers
*/
import {
createClaudeProvider,
createOpenAIProvider,
createGeminiProvider,
createProvider,
ProviderRegistry,
AIProviderError,
@ -18,6 +19,7 @@ async function multiProviderExample() {
// Get API keys from environment
const claudeApiKey = process.env.ANTHROPIC_API_KEY || 'your-claude-api-key';
const openaiApiKey = process.env.OPENAI_API_KEY || 'your-openai-api-key';
const geminiApiKey = process.env.GOOGLE_AI_API_KEY || 'your-gemini-api-key';
try {
// Method 1: Using factory functions
@ -31,6 +33,10 @@ async function multiProviderExample() {
defaultModel: 'gpt-3.5-turbo'
});
const gemini = createGeminiProvider(geminiApiKey, {
defaultModel: 'gemini-1.5-flash'
});
console.log('✓ Providers created\n');
// Method 2: Using generic createProvider function
@ -46,6 +52,11 @@ async function multiProviderExample() {
defaultModel: 'gpt-3.5-turbo'
});
const gemini2 = createProvider('gemini', {
apiKey: geminiApiKey,
defaultModel: 'gemini-1.5-flash'
});
console.log('✓ Generic providers created\n');
// Method 3: Using Provider Registry
@ -63,7 +74,8 @@ async function multiProviderExample() {
console.log('4. Initializing providers...');
await Promise.all([
claude.initialize(),
openai.initialize()
openai.initialize(),
gemini.initialize()
]);
console.log('✓ All providers initialized\n');
@ -71,12 +83,13 @@ async function multiProviderExample() {
console.log('5. Provider Information:');
console.log('Claude Info:', claude.getInfo());
console.log('OpenAI Info:', openai.getInfo());
console.log('Gemini Info:', gemini.getInfo());
console.log();
// Test the same prompt with both providers
// Test the same prompt with all providers
const testPrompt = 'Explain the concept of recursion in programming in one sentence.';
console.log('6. Testing same prompt with both providers...');
console.log('6. Testing same prompt with all providers...');
console.log(`Prompt: "${testPrompt}"\n`);
// Claude response
@ -111,6 +124,22 @@ async function multiProviderExample() {
console.log('Model:', openaiResponse.model);
console.log();
// Gemini response
console.log('--- Gemini Response ---');
const geminiResponse = await gemini.complete({
messages: [
{ role: 'system', content: 'You are a concise programming tutor.' },
{ role: 'user', content: testPrompt }
],
maxTokens: 100,
temperature: 0.7
});
console.log('Response:', geminiResponse.content);
console.log('Usage:', geminiResponse.usage);
console.log('Model:', geminiResponse.model);
console.log();
// Streaming comparison
console.log('7. Streaming comparison...');
console.log('Streaming from Claude:');
@ -139,6 +168,19 @@ async function multiProviderExample() {
}
}
console.log('Streaming from Gemini:');
for await (const chunk of gemini.stream({
messages: [{ role: 'user', content: 'Count from 1 to 5.' }],
maxTokens: 50
})) {
if (!chunk.isComplete) {
process.stdout.write(chunk.content);
} else {
console.log('\n✓ Gemini streaming complete\n');
}
}
// Provider-specific features demo
console.log('8. Provider-specific features...');
@ -158,6 +200,18 @@ async function multiProviderExample() {
});
console.log('✓ Created Claude provider with custom settings');
// Gemini with safety settings
const geminiCustom = createGeminiProvider(geminiApiKey, {
defaultModel: 'gemini-1.5-pro',
safetySettings: [],
generationConfig: {
temperature: 0.9,
topP: 0.8,
topK: 40
}
});
console.log('✓ Created Gemini provider with safety and generation settings');
console.log('\n🎉 Multi-provider example completed successfully!');
} catch (error) {
@ -169,7 +223,7 @@ async function multiProviderExample() {
switch (error.type) {
case AIErrorType.AUTHENTICATION:
console.error('💡 Hint: Check your API keys in environment variables');
console.error(' Set ANTHROPIC_API_KEY and OPENAI_API_KEY');
console.error(' Set ANTHROPIC_API_KEY, OPENAI_API_KEY, and GOOGLE_AI_API_KEY');
break;
case AIErrorType.RATE_LIMIT:
console.error('💡 Hint: You are being rate limited. Wait and try again.');
@ -192,18 +246,44 @@ async function compareProviders() {
const providers = [
{ name: 'Claude', factory: () => createClaudeProvider('dummy-key') },
{ name: 'OpenAI', factory: () => createOpenAIProvider('dummy-key') }
{ name: 'OpenAI', factory: () => createOpenAIProvider('dummy-key') },
{ name: 'Gemini', factory: () => createGeminiProvider('dummy-key') }
];
console.log('\nProvider Capabilities:');
console.log('| Provider | Models | Context | Streaming | Vision | Functions |');
console.log('|----------|--------|---------|-----------|--------|-----------|');
console.log('| Provider | Models | Context | Streaming | Vision | Functions | Multimodal |');
console.log('|----------|--------|---------|-----------|--------|-----------|------------|');
for (const { name, factory } of providers) {
const provider = factory();
const info = provider.getInfo();
console.log(`| ${name.padEnd(8)} | ${info.models.length.toString().padEnd(6)} | ${info.maxContextLength.toLocaleString().padEnd(7)} | ${info.supportsStreaming ? '✓' : '✗'.padEnd(9)} | ${info.capabilities?.vision ? '✓' : '✗'.padEnd(6)} | ${info.capabilities?.functionCalling ? '✓' : '✗'.padEnd(9)} |`);
const contextStr = info.maxContextLength >= 1000000
? `${(info.maxContextLength / 1000000).toFixed(1)}M`
: `${(info.maxContextLength / 1000).toFixed(0)}K`;
console.log(`| ${name.padEnd(8)} | ${info.models.length.toString().padEnd(6)} | ${contextStr.padEnd(7)} | ${info.supportsStreaming ? '✓' : '✗'.padEnd(9)} | ${info.capabilities?.vision ? '✓' : '✗'.padEnd(6)} | ${info.capabilities?.functionCalling ? '✓' : '✗'.padEnd(9)} | ${info.capabilities?.multimodal ? '✓' : '✗'.padEnd(10)} |`);
}
console.log();
}
// Feature comparison
async function featureComparison() {
console.log('\n=== Feature Comparison ===');
const features = [
['Provider', 'Context Window', 'Streaming', 'Vision', 'Function Calling', 'System Messages', 'Special Features'],
['Claude', '200K tokens', '✅', '✅', '✅', '✅ (separate)', 'Advanced reasoning'],
['OpenAI', '128K tokens', '✅', '✅', '✅', '✅ (inline)', 'JSON mode, plugins'],
['Gemini', '1M tokens', '✅', '✅', '✅', '✅ (separate)', 'Largest context, multimodal']
];
for (const row of features) {
console.log('| ' + row.map(cell => cell.padEnd(15)).join(' | ') + ' |');
if (row[0] === 'Provider') {
console.log('|' + ''.padEnd(row.length * 17 + row.length - 1, '-') + '|');
}
}
console.log();
@ -213,4 +293,5 @@ async function compareProviders() {
if (import.meta.main) {
await multiProviderExample();
await compareProviders();
await featureComparison();
}