LLM connection

This commit is contained in:
2026-06-18 21:16:28 +02:00
parent 9a23863320
commit 5086743a11
13 changed files with 393 additions and 26 deletions

View File

@@ -1,15 +1,14 @@
import { Router } from 'express';
import multer from 'multer';
import { execFile } from 'child_process';
import { tmpdir } from 'os';
import { join } from 'path';
import { tmpdir } from 'os';
import { rm, writeFile } from 'fs';
import { promisify } from 'util';
import { writeFile, unlink } from 'fs';
import { whisperService } from '../services/whisper.service.js';
import { raspiService } from '../services/raspi.service.js';
const execFileAsync = promisify(execFile);
import { llamacppService } from '../services/llama.service.js';
const unlinkAsync = promisify(rm);
const writeFileAsync = promisify(writeFile);
const unlinkAsync = promisify(unlink);
const router = Router();
@@ -69,11 +68,9 @@ router.post('/process/:filename', async (req, res) => {
}
});
const whisperModel = process.env.WHISPER_MODEL ?? 'base';
const whisperLanguage = process.env.WHISPER_LANGUAGE ?? 'ca';
router.post('/upload', upload.single('file'), async (req, res) => {
let tmpFile: string | undefined;
let tmpTxt: string | undefined;
try {
if (!req.file) {
return res.status(400).json({ error: 'No audio file provided' });
@@ -83,23 +80,24 @@ router.post('/upload', upload.single('file'), async (req, res) => {
tmpFile = join(tmpdir(), `quibot-audio-${Date.now()}.${ext}`);
await writeFileAsync(tmpFile, req.file.buffer);
console.log(`[whisper] Model: ${whisperModel}, Language: ${whisperLanguage}, File: ${tmpFile}`);
const transcription = await whisperService.transcribe(tmpFile);
console.log(transcription);
const { stdout, stderr } = await execFileAsync('whisper', [
tmpFile,
'--model', whisperModel,
'--language', whisperLanguage,
'--output_format', 'txt',
], { maxBuffer: 50 * 1024 * 1024 });
const txtPath = join(tmpdir(), `quibot-audio-${Date.now()}.txt`);
tmpTxt = txtPath;
await writeFileAsync(txtPath, transcription);
if (stderr) {
console.log(`[whisper] stderr: ${stderr}`);
}
const transcription = stdout.trim();
const llmResponse = await llamacppService.chatWithPreamble(transcription).catch(
(err: unknown) => {
const msg = err instanceof Error ? err.message : String(err);
console.error(`[audio] llama.cpp failed: ${msg}`);
return undefined;
},
);
res.json({
transcription,
llmResponse,
originalFilename: req.file.originalname,
});
} catch (err: unknown) {
@@ -113,6 +111,13 @@ router.post('/upload', upload.single('file'), async (req, res) => {
// ignore cleanup errors
}
}
if (tmpTxt) {
try {
await unlinkAsync(tmpTxt);
} catch {
// ignore cleanup errors
}
}
}
});