57 lines
1.7 KiB
TypeScript
57 lines
1.7 KiB
TypeScript
import { GoogleGenAI } from '@google/genai';
|
|
import { ChatMessage, PersonaMode } from '@/types/chat';
|
|
import { SYSTEM_PROMPT, MODE_MODIFIERS } from './prompts';
|
|
|
|
const apiKey = process.env.GEMINI_API_KEY;
|
|
|
|
export function getGeminiClient() {
|
|
if (!apiKey) {
|
|
throw new Error('GEMINI_API_KEY is not defined in your environment variables.');
|
|
}
|
|
return new GoogleGenAI({ apiKey });
|
|
}
|
|
|
|
export async function streamSchopenhauerReply(
|
|
messages: ChatMessage[],
|
|
mode: PersonaMode
|
|
) {
|
|
const ai = getGeminiClient();
|
|
const systemInstruction = `${SYSTEM_PROMPT}\n\n${MODE_MODIFIERS[mode]}`;
|
|
|
|
// Map our messages to Gemini API format.
|
|
// Gemini expects: { role: 'user' | 'model', parts: [{ text: string }] }
|
|
// We limit the history to the last 16 messages for performance.
|
|
const historyLimit = 16;
|
|
const recentMessages = messages.slice(-historyLimit);
|
|
|
|
const contents = recentMessages.map((msg) => ({
|
|
role: msg.role === 'assistant' ? 'model' : 'user',
|
|
parts: [{ text: msg.content }],
|
|
}));
|
|
|
|
const modelCandidates = [
|
|
process.env.GEMINI_MODEL || 'gemini-3.1-flash',
|
|
'gemini-2.5-flash',
|
|
'gemini-1.5-flash',
|
|
];
|
|
|
|
let lastError: any = null;
|
|
for (const modelName of modelCandidates) {
|
|
try {
|
|
const responseStream = await ai.models.generateContentStream({
|
|
model: modelName,
|
|
contents,
|
|
config: {
|
|
systemInstruction,
|
|
temperature: 0.7,
|
|
},
|
|
});
|
|
return { responseStream, modelUsed: modelName };
|
|
} catch (err) {
|
|
console.warn(`Failed to start stream with model ${modelName}:`, err);
|
|
lastError = err;
|
|
}
|
|
}
|
|
throw lastError || new Error('All Gemini model candidates failed to initialize.');
|
|
}
|