feat(dross): voice Phase 2a — local whisper transcribe + mic (2.12.0)

faster-whisper (small.en, GPU+CPU fallback) on CT 102 → POST
/api/voice/transcribe (multer→whisper client) → mic in the bubble
records (MediaRecorder), uploads, drops the transcript into the input
to review-and-send. Infra scripts in deploy/whisper/. Retention (P2b)
next. NOTE: mic needs a secure context (the https domain), not the LAN IP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-10 01:00:10 +10:00
parent fc1e93a58f
commit e29bacbda1
10 changed files with 196 additions and 3 deletions

View File

@@ -0,0 +1,24 @@
import { describe, it, expect, beforeAll } from 'vitest';
import request from 'supertest';
import { createApp } from '../../server.js';
import { resetDb } from '../helpers/db.js';
import { migrateUp } from '../../lib/db/migrate.js';
let app;
const owner = { Authorization: 'Bearer test-token' };
beforeAll(async () => {
await resetDb(); await migrateUp();
process.env.OWNER_TOKEN = 'test-token';
app = createApp();
});
describe('voice transcribe route', () => {
it('401 without a token', async () => {
const res = await request(app).post('/api/voice/transcribe');
expect(res.status).toBe(401);
});
it('400 when no audio supplied', async () => {
const res = await request(app).post('/api/voice/transcribe').set(owner);
expect(res.status).toBe(400);
});
});