import type { Context } from 'hono'; import { createRouter } from '../../create-router'; import { readSttConfig } from '../server-settings/stt'; import { listPiModels } from './list-models'; import { logger } from './logger'; import { transcribeAudio } from '../stt/transcribe'; import { getUserSettings } from 'officerdb'; export const piRestRouter = createRouter(); /** * GET /api/pi/models — Claude tiers only. */ piRestRouter.get('/pi/models', async (ctx: Context) => { try { const models = await listPiModels(); const providerNames: Record = { 'claude-code': 'Claude Code' }; return ctx.json({ models, providerNames, hostHome: process.env.HOME ?? '' }); } catch (err) { logger.error('Failed to list models', { error: String(err) }); return ctx.json({ models: [], providerNames: {} }); } }); /** * POST /api/pi/stt */ piRestRouter.post('/pi/stt', async (ctx: Context) => { const sttConfig = await readSttConfig(); if (!sttConfig?.url) { return ctx.json({ error: 'Whisper not configured — set it up in Settings → Speech to Text' }, 400); } const user = ctx.get('user'); const body = await ctx.req.parseBody(); const file = body['file']; if (!file || !(file instanceof File)) { return ctx.json({ error: 'file is required' }, 400); } const settings = (await getUserSettings(user.id)) as { languages?: { spoken?: string[] } }; const spokenLanguages = settings.languages?.spoken ?? []; try { const result = await transcribeAudio({ file, whisperUrl: sttConfig.url, spokenLanguages }); return ctx.json(result); } catch (err) { logger.error('STT proxy failed', { error: String(err) }); return ctx.json({ error: err instanceof Error ? err.message : 'Failed to reach Whisper server' }, 502); } });