extract STT provider handling

This commit is contained in:
Daniel 2026-05-08 06:05:39 +02:00
parent d4a3c8fd60
commit 48ee92fc5d
3 changed files with 112 additions and 54 deletions

View file

@ -10,6 +10,7 @@ var PROMPTS = require('../utils/prompts');
var logger = require('../utils/logger');
var { gatewayUrl } = require('../utils/errors');
var { GOOGLE_TTS_VOICES, OPENAI_TTS_VOICES, getTTSEnvProvider, getLiteLLMHeaders, getLiteLLMTTSModels, getTTSProvider, getTTSVoiceLists } = require('../utils/ttsProvider');
var { getSTTDependencies, getSTTModelLists, getSTTProvider } = require('../utils/sttProvider');
router.use(authMiddleware);
@ -626,21 +627,9 @@ router.post('/config/tts/test', async function(req, res) {
// ── GET STT provider status and model list ─────────────────────────────────
router.get('/config/stt', async function(req, res) {
try {
var { isGoogleSTTConfigured } = require('../utils/transcribeGoogle');
var { isAWSTranscribeConfigured } = require('../utils/transcribeAWS');
var { isLocalWhisperConfigured } = require('../utils/transcribeLocal');
var { whisperClient, litellmClient } = require('../utils/ai');
var envProvider = process.env.TRANSCRIBE_PROVIDER || 'auto';
var activeProvider = envProvider;
if (envProvider === 'auto') {
if (isGoogleSTTConfigured()) activeProvider = 'google';
else if (isAWSTranscribeConfigured()) activeProvider = 'aws';
else if (isLocalWhisperConfigured()) activeProvider = 'local';
else if (litellmClient) activeProvider = 'litellm';
else if (whisperClient) activeProvider = 'openai';
else activeProvider = 'none';
}
var configured = getSTTDependencies();
var activeProvider = getSTTProvider(configured);
var dbModel = await db.getSetting('stt.model') || '';
var envModel = process.env.GOOGLE_STT_MODEL || process.env.LITELLM_STT_MODEL || '';
res.json({
@ -650,20 +639,8 @@ router.get('/config/stt', async function(req, res) {
currentModel: dbModel || envModel,
dbModel: dbModel,
envModel: envModel,
configured: {
google: isGoogleSTTConfigured(),
aws: isAWSTranscribeConfigured(),
local: isLocalWhisperConfigured(),
litellm: !!litellmClient,
openai: !!whisperClient
},
models: {
google: ['gemini-2.0-flash', 'gemini-2.5-flash', 'gemini-2.0-flash-lite'],
aws: ['standard', 'medical'],
openai: ['whisper-1'],
litellm: ['whisper-1', 'gemini-2.0-flash', 'gemini-2.5-flash'],
local: ['tiny', 'base', 'small', 'medium', 'large']
}
configured: configured,
models: getSTTModelLists()
});
} catch (e) { res.status(500).json({ error: 'Request failed' }); }
});
@ -673,22 +650,10 @@ router.get('/config/stt/discover', async function(req, res) {
try {
var search = (req.query.q || '').toLowerCase().trim();
var axios = require('axios');
var { isGoogleSTTConfigured } = require('../utils/transcribeGoogle');
var { isAWSTranscribeConfigured } = require('../utils/transcribeAWS');
var { isLocalWhisperConfigured } = require('../utils/transcribeLocal');
var { whisperClient, litellmClient } = require('../utils/ai');
var discovered = [];
var envProvider = process.env.TRANSCRIBE_PROVIDER || 'auto';
var provider = envProvider;
if (envProvider === 'auto') {
if (isGoogleSTTConfigured()) provider = 'google';
else if (isAWSTranscribeConfigured()) provider = 'aws';
else if (isLocalWhisperConfigured()) provider = 'local';
else if (litellmClient) provider = 'litellm';
else if (whisperClient) provider = 'openai';
else provider = 'none';
}
var provider = getSTTProvider();
if (provider === 'google') {
['gemini-2.5-flash','gemini-2.0-flash','gemini-2.0-flash-lite','gemini-1.5-pro','gemini-1.5-flash'].forEach(function(m) {
@ -757,22 +722,14 @@ router.post('/config/stt/test', async function(req, res) {
var audioBuffer = Buffer.from(audioBase64, 'base64');
var mime = mimeType || 'audio/webm';
var { isGoogleSTTConfigured, transcribeWithGemini } = require('../utils/transcribeGoogle');
var { isAWSTranscribeConfigured, transcribeWithAWS } = require('../utils/transcribeAWS');
var { isLocalWhisperConfigured, transcribeWithLocal } = require('../utils/transcribeLocal');
var { transcribeWithGemini } = require('../utils/transcribeGoogle');
var { transcribeWithAWS } = require('../utils/transcribeAWS');
var { transcribeWithLocal } = require('../utils/transcribeLocal');
var { whisperClient, litellmClient } = require('../utils/ai');
var axios = require('axios');
var envProvider = process.env.TRANSCRIBE_PROVIDER || 'auto';
var provider = envProvider;
if (envProvider === 'auto') {
if (isGoogleSTTConfigured()) provider = 'google';
else if (isAWSTranscribeConfigured()) provider = 'aws';
else if (isLocalWhisperConfigured()) provider = 'local';
else if (litellmClient) provider = 'litellm';
else if (whisperClient) provider = 'openai';
else return res.json({ success: false, error: 'No STT provider configured' });
}
var provider = getSTTProvider();
if (provider === 'none') return res.json({ success: false, error: 'No STT provider configured' });
var start = Date.now();
var text = '';

53
src/utils/sttProvider.js Normal file
View file

@ -0,0 +1,53 @@
const GOOGLE_STT_MODELS = ['gemini-2.0-flash', 'gemini-2.5-flash', 'gemini-2.0-flash-lite'];
const AWS_STT_MODES = ['standard', 'medical'];
const OPENAI_STT_MODELS = ['whisper-1'];
const LITELLM_STT_MODELS = ['whisper-1', 'gemini-2.0-flash', 'gemini-2.5-flash'];
const LOCAL_WHISPER_MODELS = ['tiny', 'base', 'small', 'medium', 'large'];
function getSTTDependencies() {
var { isGoogleSTTConfigured } = require('./transcribeGoogle');
var { isAWSTranscribeConfigured } = require('./transcribeAWS');
var { isLocalWhisperConfigured } = require('./transcribeLocal');
var { whisperClient, litellmClient } = require('./ai');
return {
google: isGoogleSTTConfigured(),
aws: isAWSTranscribeConfigured(),
local: isLocalWhisperConfigured(),
litellm: !!litellmClient,
openai: !!whisperClient
};
}
function getSTTProvider(deps) {
var env = process.env.TRANSCRIBE_PROVIDER || 'auto';
if (env !== 'auto') return env;
var configured = deps || getSTTDependencies();
if (configured.google) return 'google';
if (configured.aws) return 'aws';
if (configured.local) return 'local';
if (configured.litellm) return 'litellm';
if (configured.openai) return 'openai';
return 'none';
}
function getSTTModelLists() {
return {
google: GOOGLE_STT_MODELS,
aws: AWS_STT_MODES,
openai: OPENAI_STT_MODELS,
litellm: LITELLM_STT_MODELS,
local: LOCAL_WHISPER_MODELS
};
}
module.exports = {
AWS_STT_MODES,
GOOGLE_STT_MODELS,
LITELLM_STT_MODELS,
LOCAL_WHISPER_MODELS,
OPENAI_STT_MODELS,
getSTTDependencies,
getSTTModelLists,
getSTTProvider
};

48
test/stt-provider.test.js Normal file
View file

@ -0,0 +1,48 @@
const { test } = require('node:test');
const assert = require('node:assert/strict');
const ENV_KEYS = ['TRANSCRIBE_PROVIDER'];
function withEnv(overrides, fn) {
const previous = {};
ENV_KEYS.forEach((key) => { previous[key] = process.env[key]; delete process.env[key]; });
Object.entries(overrides).forEach(([key, value]) => { process.env[key] = value; });
try {
return fn();
} finally {
ENV_KEYS.forEach((key) => {
if (previous[key] === undefined) delete process.env[key];
else process.env[key] = previous[key];
});
}
}
test('STT provider respects explicit provider override', () => {
const sttProvider = require('../src/utils/sttProvider');
withEnv({ TRANSCRIBE_PROVIDER: 'litellm' }, () => {
assert.equal(sttProvider.getSTTProvider({ google: true }), 'litellm');
});
});
test('STT provider auto-detects in existing priority order', () => {
const sttProvider = require('../src/utils/sttProvider');
withEnv({}, () => {
assert.equal(sttProvider.getSTTProvider({ google: true, aws: true, local: true, litellm: true, openai: true }), 'google');
assert.equal(sttProvider.getSTTProvider({ aws: true, local: true, litellm: true, openai: true }), 'aws');
assert.equal(sttProvider.getSTTProvider({ local: true, litellm: true, openai: true }), 'local');
assert.equal(sttProvider.getSTTProvider({ litellm: true, openai: true }), 'litellm');
assert.equal(sttProvider.getSTTProvider({ openai: true }), 'openai');
assert.equal(sttProvider.getSTTProvider({}), 'none');
});
});
test('STT model lists preserve admin defaults', () => {
const sttProvider = require('../src/utils/sttProvider');
assert.deepEqual(sttProvider.getSTTModelLists(), {
google: ['gemini-2.0-flash', 'gemini-2.5-flash', 'gemini-2.0-flash-lite'],
aws: ['standard', 'medical'],
openai: ['whisper-1'],
litellm: ['whisper-1', 'gemini-2.0-flash', 'gemini-2.5-flash'],
local: ['tiny', 'base', 'small', 'medium', 'large']
});
});