|
|
| import { GoogleGenAI } from '@google/genai'; |
| import fs from 'fs'; |
| import path from 'path'; |
| import { fileURLToPath } from 'url'; |
|
|
| const __dirname = path.dirname(fileURLToPath(import.meta.url)); |
|
|
| export const getPrompt = (filename) => { |
| try { |
| const filePath = path.resolve(__dirname, '..', '..', 'prompts', filename); |
| if (fs.existsSync(filePath)) { |
| return fs.readFileSync(filePath, 'utf8'); |
| } else { |
| const internalPath = path.resolve(__dirname, '..', '..', '..', 'prompts', filename); |
| return fs.existsSync(internalPath) ? fs.readFileSync(internalPath, 'utf8') : ""; |
| } |
| } catch (e) { |
| console.error(`[AI-ENGINE] Prompt Load Error (${filename}):`, e.message); |
| return ""; |
| } |
| }; |
|
|
| export function cleanJson(raw) { |
| if (!raw) return ""; |
| return raw.replace(/```json/gi, '').replace(/```/gi, '').trim(); |
| } |
|
|
| export function cleanSRTOutput(text) { |
| if (!text) return ""; |
| let cleaned = text.replace(/```srt/gi, '').replace(/```/gi, '').trim(); |
| const firstIndex = cleaned.search(/^\d+\s*\r?\n\d{2}:\d{2}:\d{2},\d{3}/m); |
| if (firstIndex !== -1) { |
| cleaned = cleaned.substring(firstIndex); |
| } |
| return cleaned; |
| } |
|
|
| export const DEFAULT_SAFETY_SETTINGS = [ |
| { category: 'HARM_CATEGORY_HARASSMENT', threshold: 'BLOCK_ONLY_HIGH' }, |
| { category: 'HARM_CATEGORY_HATE_SPEECH', threshold: 'BLOCK_ONLY_HIGH' }, |
| { category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', threshold: 'BLOCK_ONLY_HIGH' }, |
| { category: 'HARM_CATEGORY_DANGEROUS_CONTENT', threshold: 'BLOCK_ONLY_HIGH' }, |
| { category: 'HARM_CATEGORY_CIVIC_INTEGRITY', threshold: 'BLOCK_ONLY_HIGH' } |
| ]; |
|
|
| export async function tryModels(apiKey, modelList, taskFn) { |
| let lastError = null; |
| const ai = new GoogleGenAI({ apiKey }); |
| const MAX_RETRIES_PER_MODEL = 2; |
|
|
| for (const modelName of modelList) { |
| for (let attempt = 0; attempt <= MAX_RETRIES_PER_MODEL; attempt++) { |
| try { |
| return await taskFn(ai, modelName); |
| } catch (e) { |
| const rawError = (e.message || "Unknown error").toLowerCase(); |
| const isRateLimit = rawError.includes('429') || rawError.includes('quota') || rawError.includes('limit'); |
| |
| if (isRateLimit && attempt < MAX_RETRIES_PER_MODEL) { |
| const waitTime = (attempt + 1) * 5000; |
| console.warn(`[AI-ENGINE] Rate limit on ${modelName}. Retry in ${waitTime}ms...`); |
| await new Promise(r => setTimeout(r, waitTime)); |
| continue; |
| } |
| console.error(`[AI-ENGINE] Error on ${modelName}:`, rawError); |
| lastError = e; |
| break; |
| } |
| } |
| } |
| throw lastError; |
| } |
|
|