This commit is contained in:
juanmaldini7 committed 2026-09-28 11:42:07 -03:00
commit ca253f1b16
11 files changed
+2416

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
import { GoogleGenAI, FileState, createPartFromUri, createUserContent, type File } from '@google/genai';
import type { AudioTrack } from './recorder.js';
import { buildPrompt } from './prompt.js';
const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const MODEL = process.env.GEMINI_MODEL || 'gemini-2.5-flash';
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
async function upload(track: AudioTrack): Promise<File> {
let file = await ai.files.upload({ file: track.file, config: { mimeType: 'audio/ogg', displayName: track.name } });
while (file.state === FileState.PROCESSING) {
await sleep(2000);
file = await ai.files.get({ name: file.name! });
}
if (file.state === FileState.FAILED) throw new Error(`Gemini no pudo procesar el audio de ${track.name}`);
return file;
}
export async function generateNotes(tracks: AudioTrack[], startedAt: Date): Promise<string> {
const files: File[] = [];
try {
for (const track of tracks) files.push(await upload(track));
const parts = tracks.flatMap((track, i) => [
`Pista ${i + 1}: ${track.name}`,
createPartFromUri(files[i].uri!, files[i].mimeType!),
]);
const res = await ai.models.generateContent({
model: MODEL,
contents: createUserContent([buildPrompt(tracks.map((t) => t.name), startedAt), ...parts]),
});
const text = res.text?.trim();
if (!text) throw new Error('Gemini devolvió una respuesta vacía');
return text.replace(/^```(?:markdown|md)?\n([\s\S]*)\n```$/, '$1');
} finally {
await Promise.allSettled(files.map((f) => ai.files.delete({ name: f.name! })));
}
}