* feat: scaffold message, generating, and map pages and align header steps * feat: implement AI bouquet generation flow with Gemini/OpenAI --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
58 lines
1.3 KiB
JavaScript
58 lines
1.3 KiB
JavaScript
import { env } from '$env/dynamic/private';
|
|
import { GoogleGenerativeAI } from '@google/generative-ai';
|
|
|
|
let client = null;
|
|
|
|
export function isGeminiConfigured() {
|
|
return Boolean(env.GEMINI_API_KEY);
|
|
}
|
|
|
|
function getClient() {
|
|
if (!isGeminiConfigured()) {
|
|
throw new Error('GEMINI_API_KEY is not configured');
|
|
}
|
|
|
|
if (!client) {
|
|
client = new GoogleGenerativeAI(env.GEMINI_API_KEY);
|
|
}
|
|
|
|
return client;
|
|
}
|
|
|
|
export function getTextModel() {
|
|
return getClient().getGenerativeModel({
|
|
model: env.GEMINI_TEXT_MODEL || 'gemini-2.5-flash'
|
|
});
|
|
}
|
|
|
|
export function getVisionModel() {
|
|
return getClient().getGenerativeModel({
|
|
model: env.GEMINI_TEXT_MODEL || 'gemini-2.5-flash'
|
|
});
|
|
}
|
|
|
|
export function getImageModel() {
|
|
return getClient().getGenerativeModel({
|
|
model: env.GEMINI_IMAGE_MODEL || 'gemini-3.1-flash-image'
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @param {string} text
|
|
*/
|
|
export function parseJsonFromText(text) {
|
|
const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
const candidate = fenced?.[1]?.trim() ?? text.trim();
|
|
|
|
try {
|
|
return JSON.parse(candidate);
|
|
} catch {
|
|
const start = candidate.indexOf('{');
|
|
const end = candidate.lastIndexOf('}');
|
|
if (start >= 0 && end > start) {
|
|
return JSON.parse(candidate.slice(start, end + 1));
|
|
}
|
|
throw new Error('Failed to parse JSON from model response');
|
|
}
|
|
}
|