feature/05-exercise-encyclopedia #4
@@ -1,15 +1,15 @@
|
|||||||
/**
|
/**
|
||||||
* Gemini API with Multi-Tier Fallback
|
* Gemini API with Multi-Tier Fallback
|
||||||
* Tries: Gemini → OpenCode → OpenRouter
|
* Tries: Gemini → OpenRouter → OpenCode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fetch = require('node-fetch');
|
const fetch = require('node-fetch');
|
||||||
|
|
||||||
const GEMINI_API_KEY = process.env.GOOGLE_API_KEY;
|
const GEMINI_API_KEY = process.env.GOOGLE_API_KEY;
|
||||||
const OPENCODE_API_KEY = process.env.OPENCODE_API_KEY;
|
|
||||||
const OPENCODE_BASE_URL = process.env.OPENCODE_BASE_URL || 'https://api.opencode.com/v1';
|
|
||||||
const OPENROUTER_API_KEY = process.env.OPENROUTER_API_KEY;
|
const OPENROUTER_API_KEY = process.env.OPENROUTER_API_KEY;
|
||||||
const OPENROUTER_BASE_URL = process.env.OPENROUTER_BASE_URL || 'https://openrouter.ai/api/v1';
|
const OPENROUTER_BASE_URL = process.env.OPENROUTER_BASE_URL || 'https://openrouter.ai/api/v1';
|
||||||
|
const OPENCODE_API_KEY = process.env.OPENCODE_API_KEY;
|
||||||
|
const OPENCODE_BASE_URL = process.env.OPENCODE_BASE_URL || 'https://api.opencode.com/v1';
|
||||||
|
|
||||||
async function generateWithFallback(prompt, options = {}) {
|
async function generateWithFallback(prompt, options = {}) {
|
||||||
console.log('🤖 Generating content...');
|
console.log('🤖 Generating content...');
|
||||||
@@ -46,40 +46,10 @@ async function generateWithFallback(prompt, options = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tier 2: Fallback to OpenCode
|
// Tier 2: Fallback to OpenRouter (billigare, mer flexibel)
|
||||||
if (OPENCODE_API_KEY) {
|
|
||||||
try {
|
|
||||||
console.log('📍 Tier 2: Attempting OpenCode API...');
|
|
||||||
const response = await fetch(`${OPENCODE_BASE_URL}/chat/completions`, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Authorization': `Bearer ${OPENCODE_API_KEY}`,
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
|
||||||
model: options.model || 'gpt-4',
|
|
||||||
messages: [{ role: 'user', content: prompt }],
|
|
||||||
temperature: options.temperature || 0.7,
|
|
||||||
max_tokens: options.maxTokens || 2048
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
const data = await response.json();
|
|
||||||
console.log('✅ OpenCode API success');
|
|
||||||
return { success: true, provider: 'opencode', data };
|
|
||||||
}
|
|
||||||
|
|
||||||
console.warn(`OpenCode error: ${response.status}, trying next fallback...`);
|
|
||||||
} catch (err) {
|
|
||||||
console.warn(`OpenCode failed: ${err.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tier 3: Fallback to OpenRouter
|
|
||||||
if (OPENROUTER_API_KEY) {
|
if (OPENROUTER_API_KEY) {
|
||||||
try {
|
try {
|
||||||
console.log('📍 Tier 3: Attempting OpenRouter API...');
|
console.log('📍 Tier 2: Attempting OpenRouter API...');
|
||||||
const response = await fetch(`${OPENROUTER_BASE_URL}/chat/completions`, {
|
const response = await fetch(`${OPENROUTER_BASE_URL}/chat/completions`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -101,20 +71,50 @@ async function generateWithFallback(prompt, options = {}) {
|
|||||||
return { success: true, provider: 'openrouter', data };
|
return { success: true, provider: 'openrouter', data };
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`OpenRouter error: ${response.status}`);
|
console.warn(`OpenRouter error: ${response.status}, trying next fallback...`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`OpenRouter failed: ${err.message}`);
|
console.warn(`OpenRouter failed: ${err.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error('All generation APIs failed (Gemini → OpenCode → OpenRouter)');
|
// Tier 3: Fallback to OpenCode (sista försöket)
|
||||||
|
if (OPENCODE_API_KEY) {
|
||||||
|
try {
|
||||||
|
console.log('📍 Tier 3: Attempting OpenCode API...');
|
||||||
|
const response = await fetch(`${OPENCODE_BASE_URL}/chat/completions`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${OPENCODE_API_KEY}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
model: options.model || 'gpt-4',
|
||||||
|
messages: [{ role: 'user', content: prompt }],
|
||||||
|
temperature: options.temperature || 0.7,
|
||||||
|
max_tokens: options.maxTokens || 2048
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const data = await response.json();
|
||||||
|
console.log('✅ OpenCode API success');
|
||||||
|
return { success: true, provider: 'opencode', data };
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`OpenCode error: ${response.status}`);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`OpenCode failed: ${err.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('All generation APIs failed (Gemini → OpenRouter → OpenCode)');
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
generateWithFallback,
|
generateWithFallback,
|
||||||
getAvailableProviders: () => ({
|
getAvailableProviders: () => ({
|
||||||
gemini: !!GEMINI_API_KEY,
|
gemini: !!GEMINI_API_KEY,
|
||||||
opencode: !!OPENCODE_API_KEY,
|
openrouter: !!OPENROUTER_API_KEY,
|
||||||
openrouter: !!OPENROUTER_API_KEY
|
opencode: !!OPENCODE_API_KEY
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user