Fix LiteLLM STT: use chat/completions with Gemini audio instead of broken /audio/transcriptions
LiteLLM /audio/transcriptions gives 'Unmapped provider' for Vertex AI Chirp. The correct approach: use /v1/chat/completions with a Gemini model and send audio as base64 input_audio content block — Gemini natively understands audio. Set LITELLM_STT_MODEL to your Gemini model name (e.g. gemini-2.5-flash).
This commit is contained in:
parent
28fe1f520e
commit
f78f25e42f
1 changed files with 35 additions and 18 deletions
|
|
@ -78,24 +78,41 @@ router.post('/transcribe', authMiddleware, upload.single('audio'), async (req, r
|
||||||
|
|
||||||
if (provider === 'litellm') {
|
if (provider === 'litellm') {
|
||||||
if (!process.env.LITELLM_API_BASE) return res.status(400).json({ error: 'LITELLM_API_BASE not set.' });
|
if (!process.env.LITELLM_API_BASE) return res.status(400).json({ error: 'LITELLM_API_BASE not set.' });
|
||||||
// Default to whisper-1 — vertex_ai/chirp does NOT work via LiteLLM audio proxy.
|
// LiteLLM /audio/transcriptions does NOT support Vertex AI Chirp (Unmapped provider error).
|
||||||
// User should set LITELLM_STT_MODEL to their configured whisper alias, or
|
// Instead, use /v1/chat/completions with a Gemini model — Gemini understands audio natively
|
||||||
// use TRANSCRIBE_PROVIDER=google for Vertex AI / Gemini transcription instead.
|
// via base64 inline data. Set LITELLM_STT_MODEL to your Gemini model name in LiteLLM.
|
||||||
var sttModel = process.env.LITELLM_STT_MODEL || 'whisper-1';
|
var sttModel = process.env.LITELLM_STT_MODEL || 'gemini-2.0-flash';
|
||||||
var FormData = require('form-data');
|
var axios = require('axios');
|
||||||
var axios = require('axios');
|
var base64audio = req.file.buffer.toString('base64');
|
||||||
var form = new FormData();
|
var mimeType = req.file.mimetype || 'audio/webm';
|
||||||
form.append('file', req.file.buffer, { filename: 'audio.webm', contentType: req.file.mimetype || 'audio/webm' });
|
var base = process.env.LITELLM_API_BASE.replace(/\/+$/, '');
|
||||||
form.append('model', sttModel);
|
var headers = { 'Content-Type': 'application/json' };
|
||||||
var sttHeaders = Object.assign({}, form.getHeaders());
|
if (process.env.LITELLM_API_KEY) headers['Authorization'] = 'Bearer ' + process.env.LITELLM_API_KEY;
|
||||||
if (process.env.LITELLM_API_KEY) sttHeaders['Authorization'] = 'Bearer ' + process.env.LITELLM_API_KEY;
|
|
||||||
var sttResp = await require('axios').post(
|
var sttResp = await axios.post(base + '/v1/chat/completions', {
|
||||||
process.env.LITELLM_API_BASE.replace(/\/+$/, '') + '/v1/audio/transcriptions',
|
model: sttModel,
|
||||||
form, { headers: sttHeaders, timeout: 120000 }
|
messages: [{
|
||||||
);
|
role: 'user',
|
||||||
var text = (sttResp.data && sttResp.data.text) ? sttResp.data.text : String(sttResp.data || '');
|
content: [
|
||||||
console.log('[Transcribe] LiteLLM (' + sttModel + ') done in ' + (Date.now() - startTime) + 'ms');
|
{
|
||||||
return res.json({ success: true, text: text, provider: 'litellm-stt', duration: Date.now() - startTime });
|
type: 'input_audio',
|
||||||
|
input_audio: { data: base64audio, format: mimeType.split('/')[1] || 'webm' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
text: 'Transcribe this audio of a medical encounter. Output the spoken words only, exactly as heard. No commentary, no formatting.'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}, { headers: headers, timeout: 120000 });
|
||||||
|
|
||||||
|
var text = '';
|
||||||
|
if (sttResp.data && sttResp.data.choices && sttResp.data.choices[0]) {
|
||||||
|
var msg = sttResp.data.choices[0].message;
|
||||||
|
text = (msg && msg.content) ? msg.content : '';
|
||||||
|
}
|
||||||
|
console.log('[Transcribe] LiteLLM/' + sttModel + ' done in ' + (Date.now() - startTime) + 'ms');
|
||||||
|
return res.json({ success: true, text: text.trim(), provider: 'litellm-gemini', duration: Date.now() - startTime });
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenAI Whisper (direct)
|
// OpenAI Whisper (direct)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue