File size: 2,807 Bytes
ea81969
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

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;
}