add deepgram
This commit is contained in:
parent
4d93df09e2
commit
c0cf74273a
78
package-lock.json
generated
78
package-lock.json
generated
@ -11,6 +11,7 @@
|
|||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@anthropic-ai/sdk": "^0.56.0",
|
"@anthropic-ai/sdk": "^0.56.0",
|
||||||
|
"@deepgram/sdk": "^4.9.1",
|
||||||
"@google/genai": "^1.8.0",
|
"@google/genai": "^1.8.0",
|
||||||
"@google/generative-ai": "^0.24.1",
|
"@google/generative-ai": "^0.24.1",
|
||||||
"axios": "^1.10.0",
|
"axios": "^1.10.0",
|
||||||
@ -54,6 +55,50 @@
|
|||||||
"anthropic-ai-sdk": "bin/cli"
|
"anthropic-ai-sdk": "bin/cli"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@deepgram/captions": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@deepgram/captions/-/captions-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-8B1C/oTxTxyHlSFubAhNRgCbQ2SQ5wwvtlByn8sDYZvdDtdn/VE2yEPZ4BvUnrKWmsbTQY6/ooLV+9Ka2qmDSQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"dayjs": "^1.11.10"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@deepgram/sdk": {
|
||||||
|
"version": "4.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@deepgram/sdk/-/sdk-4.9.1.tgz",
|
||||||
|
"integrity": "sha512-a30Sed6OIRldnW1U0Q0Orvhjojq4O/1pMv6ijj+3j8735LBBfAJvlJpRCjrgtzBpnkKlY6v3bV5F8qUUSpz2yg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@deepgram/captions": "^1.1.1",
|
||||||
|
"@types/node": "^18.19.39",
|
||||||
|
"cross-fetch": "^3.1.5",
|
||||||
|
"deepmerge": "^4.3.1",
|
||||||
|
"events": "^3.3.0",
|
||||||
|
"ws": "^8.17.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@deepgram/sdk/node_modules/@types/node": {
|
||||||
|
"version": "18.19.118",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.118.tgz",
|
||||||
|
"integrity": "sha512-hIPK0hSrrcaoAu/gJMzN3QClXE4QdCdFvaenJ0JsjIbExP1JFFVH+RHcBt25c9n8bx5dkIfqKE+uw6BmBns7ug==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~5.26.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@deepgram/sdk/node_modules/undici-types": {
|
||||||
|
"version": "5.26.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@develar/schema-utils": {
|
"node_modules/@develar/schema-utils": {
|
||||||
"version": "2.6.5",
|
"version": "2.6.5",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -2992,6 +3037,15 @@
|
|||||||
"optional": true,
|
"optional": true,
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/cross-fetch": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"node-fetch": "^2.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -3020,6 +3074,12 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dayjs": {
|
||||||
|
"version": "1.11.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
|
||||||
|
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/debounce-fn": {
|
"node_modules/debounce-fn": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -3078,6 +3138,15 @@
|
|||||||
"node": ">=4.0.0"
|
"node": ">=4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/deepmerge": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/defaults": {
|
"node_modules/defaults": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
@ -3735,6 +3804,15 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/events": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.8.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/expand-template": {
|
"node_modules/expand-template": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"license": "(MIT OR WTFPL)",
|
"license": "(MIT OR WTFPL)",
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@anthropic-ai/sdk": "^0.56.0",
|
"@anthropic-ai/sdk": "^0.56.0",
|
||||||
|
"@deepgram/sdk": "^4.9.1",
|
||||||
"@google/genai": "^1.8.0",
|
"@google/genai": "^1.8.0",
|
||||||
"@google/generative-ai": "^0.24.1",
|
"@google/generative-ai": "^0.24.1",
|
||||||
"axios": "^1.10.0",
|
"axios": "^1.10.0",
|
||||||
|
@ -57,6 +57,14 @@ const PROVIDERS = {
|
|||||||
],
|
],
|
||||||
sttModels: [],
|
sttModels: [],
|
||||||
},
|
},
|
||||||
|
'deepgram': {
|
||||||
|
name: 'Deepgram',
|
||||||
|
handler: () => require("./providers/deepgram"),
|
||||||
|
llmModels: [],
|
||||||
|
sttModels: [
|
||||||
|
{ id: 'nova-3', name: 'Nova-3 (General)' },
|
||||||
|
],
|
||||||
|
},
|
||||||
'ollama': {
|
'ollama': {
|
||||||
name: 'Ollama (Local)',
|
name: 'Ollama (Local)',
|
||||||
handler: () => require("./providers/ollama"),
|
handler: () => require("./providers/ollama"),
|
||||||
@ -148,6 +156,7 @@ function getProviderClass(providerId) {
|
|||||||
'openai': 'OpenAIProvider',
|
'openai': 'OpenAIProvider',
|
||||||
'anthropic': 'AnthropicProvider',
|
'anthropic': 'AnthropicProvider',
|
||||||
'gemini': 'GeminiProvider',
|
'gemini': 'GeminiProvider',
|
||||||
|
'deepgram': 'DeepgramProvider',
|
||||||
'ollama': 'OllamaProvider',
|
'ollama': 'OllamaProvider',
|
||||||
'whisper': 'WhisperProvider'
|
'whisper': 'WhisperProvider'
|
||||||
};
|
};
|
||||||
|
111
src/features/common/ai/providers/deepgram.js
Normal file
111
src/features/common/ai/providers/deepgram.js
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// providers/deepgram.js
|
||||||
|
|
||||||
|
const { createClient, LiveTranscriptionEvents } = require('@deepgram/sdk');
|
||||||
|
const WebSocket = require('ws');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deepgram Provider 클래스. API 키 유효성 검사를 담당합니다.
|
||||||
|
*/
|
||||||
|
class DeepgramProvider {
|
||||||
|
/**
|
||||||
|
* Deepgram API 키의 유효성을 검사합니다.
|
||||||
|
* @param {string} key - 검사할 Deepgram API 키
|
||||||
|
* @returns {Promise<{success: boolean, error?: string}>}
|
||||||
|
*/
|
||||||
|
static async validateApiKey(key) {
|
||||||
|
if (!key || typeof key !== 'string') {
|
||||||
|
return { success: false, error: 'Invalid Deepgram API key format.' };
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// ✨ 변경점: SDK 대신 직접 fetch로 API를 호출하여 안정성 확보 (openai.js 방식)
|
||||||
|
const response = await fetch('https://api.deepgram.com/v1/projects', {
|
||||||
|
headers: { 'Authorization': `Token ${key}` }
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
return { success: true };
|
||||||
|
} else {
|
||||||
|
const errorData = await response.json().catch(() => ({}));
|
||||||
|
const message = errorData.err_msg || `Validation failed with status: ${response.status}`;
|
||||||
|
return { success: false, error: message };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`[DeepgramProvider] Network error during key validation:`, error);
|
||||||
|
return { success: false, error: error.message || 'A network error occurred during validation.' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSTT({
|
||||||
|
apiKey,
|
||||||
|
language = 'en-US',
|
||||||
|
sampleRate = 24000,
|
||||||
|
callbacks = {},
|
||||||
|
}) {
|
||||||
|
const qs = new URLSearchParams({
|
||||||
|
model: 'nova-3',
|
||||||
|
encoding: 'linear16',
|
||||||
|
sample_rate: sampleRate.toString(),
|
||||||
|
language,
|
||||||
|
smart_format: 'true',
|
||||||
|
interim_results: 'true',
|
||||||
|
channels: '1',
|
||||||
|
});
|
||||||
|
|
||||||
|
const url = `wss://api.deepgram.com/v1/listen?${qs}`;
|
||||||
|
|
||||||
|
const ws = new WebSocket(url, {
|
||||||
|
headers: { Authorization: `Token ${apiKey}` },
|
||||||
|
});
|
||||||
|
ws.binaryType = 'arraybuffer';
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const to = setTimeout(() => {
|
||||||
|
ws.terminate();
|
||||||
|
reject(new Error('DG open timeout (10 s)'));
|
||||||
|
}, 10_000);
|
||||||
|
|
||||||
|
ws.on('open', () => {
|
||||||
|
clearTimeout(to);
|
||||||
|
resolve({
|
||||||
|
sendRealtimeInput: (buf) => ws.send(buf),
|
||||||
|
close: () => ws.close(1000, 'client'),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.on('message', raw => {
|
||||||
|
let msg;
|
||||||
|
try { msg = JSON.parse(raw.toString()); } catch { return; }
|
||||||
|
if (msg.channel?.alternatives?.[0]?.transcript !== undefined) {
|
||||||
|
callbacks.onmessage?.({ provider: 'deepgram', ...msg });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.on('close', (code, reason) =>
|
||||||
|
callbacks.onclose?.({ code, reason: reason.toString() })
|
||||||
|
);
|
||||||
|
|
||||||
|
ws.on('error', err => {
|
||||||
|
clearTimeout(to);
|
||||||
|
callbacks.onerror?.(err);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... (LLM 관련 Placeholder 함수들은 그대로 유지) ...
|
||||||
|
function createLLM(opts) {
|
||||||
|
console.warn("[Deepgram] LLM not supported.");
|
||||||
|
return { generateContent: async () => { throw new Error("Deepgram does not support LLM functionality."); } };
|
||||||
|
}
|
||||||
|
function createStreamingLLM(opts) {
|
||||||
|
console.warn("[Deepgram] Streaming LLM not supported.");
|
||||||
|
return { streamChat: async () => { throw new Error("Deepgram does not support Streaming LLM functionality."); } };
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
DeepgramProvider,
|
||||||
|
createSTT,
|
||||||
|
createLLM,
|
||||||
|
createStreamingLLM
|
||||||
|
};
|
@ -55,17 +55,6 @@ class SttService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleSendSystemAudioContent(data, mimeType) {
|
|
||||||
try {
|
|
||||||
await this.sendSystemAudioContent(data, mimeType);
|
|
||||||
this.sendToRenderer('system-audio-data', { data });
|
|
||||||
return { success: true };
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error sending system audio:', error);
|
|
||||||
return { success: false, error: error.message };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
flushMyCompletion() {
|
flushMyCompletion() {
|
||||||
const finalText = (this.myCompletionBuffer + this.myCurrentUtterance).trim();
|
const finalText = (this.myCompletionBuffer + this.myCurrentUtterance).trim();
|
||||||
if (!this.modelInfo || !finalText) return;
|
if (!this.modelInfo || !finalText) return;
|
||||||
@ -157,7 +146,7 @@ class SttService {
|
|||||||
console.log('[SttService] Ignoring message - session already closed');
|
console.log('[SttService] Ignoring message - session already closed');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
console.log('[SttService] handleMyMessage', message);
|
// console.log('[SttService] handleMyMessage', message);
|
||||||
|
|
||||||
if (this.modelInfo.provider === 'whisper') {
|
if (this.modelInfo.provider === 'whisper') {
|
||||||
// Whisper STT emits 'transcription' events with different structure
|
// Whisper STT emits 'transcription' events with different structure
|
||||||
@ -178,10 +167,6 @@ class SttService {
|
|||||||
'(NOISE)'
|
'(NOISE)'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const normalizedText = finalText.toLowerCase().trim();
|
|
||||||
|
|
||||||
const isNoise = noisePatterns.some(pattern =>
|
const isNoise = noisePatterns.some(pattern =>
|
||||||
finalText.includes(pattern) || finalText === pattern
|
finalText.includes(pattern) || finalText === pattern
|
||||||
);
|
);
|
||||||
@ -232,6 +217,38 @@ class SttService {
|
|||||||
isFinal: false,
|
isFinal: false,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Deepgram
|
||||||
|
} else if (this.modelInfo.provider === 'deepgram') {
|
||||||
|
const text = message.channel?.alternatives?.[0]?.transcript;
|
||||||
|
if (!text || text.trim().length === 0) return;
|
||||||
|
|
||||||
|
const isFinal = message.is_final;
|
||||||
|
console.log(`[SttService-Me-Deepgram] Received: isFinal=${isFinal}, text="${text}"`);
|
||||||
|
|
||||||
|
if (isFinal) {
|
||||||
|
// 최종 결과가 도착하면, 현재 진행중인 부분 발화는 비우고
|
||||||
|
// 최종 텍스트로 debounce를 실행합니다.
|
||||||
|
this.myCurrentUtterance = '';
|
||||||
|
this.debounceMyCompletion(text);
|
||||||
|
} else {
|
||||||
|
// 부분 결과(interim)인 경우, 화면에 실시간으로 업데이트합니다.
|
||||||
|
if (this.myCompletionTimer) clearTimeout(this.myCompletionTimer);
|
||||||
|
this.myCompletionTimer = null;
|
||||||
|
|
||||||
|
this.myCurrentUtterance = text;
|
||||||
|
|
||||||
|
const continuousText = (this.myCompletionBuffer + ' ' + this.myCurrentUtterance).trim();
|
||||||
|
|
||||||
|
this.sendToRenderer('stt-update', {
|
||||||
|
speaker: 'Me',
|
||||||
|
text: continuousText,
|
||||||
|
isPartial: true,
|
||||||
|
isFinal: false,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const type = message.type;
|
const type = message.type;
|
||||||
const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || '';
|
const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || '';
|
||||||
@ -291,9 +308,6 @@ class SttService {
|
|||||||
'(NOISE)'
|
'(NOISE)'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
const normalizedText = finalText.toLowerCase().trim();
|
|
||||||
|
|
||||||
const isNoise = noisePatterns.some(pattern =>
|
const isNoise = noisePatterns.some(pattern =>
|
||||||
finalText.includes(pattern) || finalText === pattern
|
finalText.includes(pattern) || finalText === pattern
|
||||||
);
|
);
|
||||||
@ -345,6 +359,34 @@ class SttService {
|
|||||||
isFinal: false,
|
isFinal: false,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Deepgram
|
||||||
|
} else if (this.modelInfo.provider === 'deepgram') {
|
||||||
|
const text = message.channel?.alternatives?.[0]?.transcript;
|
||||||
|
if (!text || text.trim().length === 0) return;
|
||||||
|
|
||||||
|
const isFinal = message.is_final;
|
||||||
|
|
||||||
|
if (isFinal) {
|
||||||
|
this.theirCurrentUtterance = '';
|
||||||
|
this.debounceTheirCompletion(text);
|
||||||
|
} else {
|
||||||
|
if (this.theirCompletionTimer) clearTimeout(this.theirCompletionTimer);
|
||||||
|
this.theirCompletionTimer = null;
|
||||||
|
|
||||||
|
this.theirCurrentUtterance = text;
|
||||||
|
|
||||||
|
const continuousText = (this.theirCompletionBuffer + ' ' + this.theirCurrentUtterance).trim();
|
||||||
|
|
||||||
|
this.sendToRenderer('stt-update', {
|
||||||
|
speaker: 'Them',
|
||||||
|
text: continuousText,
|
||||||
|
isPartial: true,
|
||||||
|
isFinal: false,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const type = message.type;
|
const type = message.type;
|
||||||
const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || '';
|
const text = message.transcript || message.delta || (message.alternatives && message.alternatives[0]?.transcript) || '';
|
||||||
@ -431,10 +473,14 @@ class SttService {
|
|||||||
throw new Error('STT model info could not be retrieved.');
|
throw new Error('STT model info could not be retrieved.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const payload = modelInfo.provider === 'gemini'
|
let payload;
|
||||||
? { audio: { data, mimeType: mimeType || 'audio/pcm;rate=24000' } }
|
if (modelInfo.provider === 'gemini') {
|
||||||
: data;
|
payload = { audio: { data, mimeType: mimeType || 'audio/pcm;rate=24000' } };
|
||||||
|
} else if (modelInfo.provider === 'deepgram') {
|
||||||
|
payload = Buffer.from(data, 'base64');
|
||||||
|
} else {
|
||||||
|
payload = data;
|
||||||
|
}
|
||||||
await this.mySttSession.sendRealtimeInput(payload);
|
await this.mySttSession.sendRealtimeInput(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,9 +498,14 @@ class SttService {
|
|||||||
throw new Error('STT model info could not be retrieved.');
|
throw new Error('STT model info could not be retrieved.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const payload = modelInfo.provider === 'gemini'
|
let payload;
|
||||||
? { audio: { data, mimeType: mimeType || 'audio/pcm;rate=24000' } }
|
if (modelInfo.provider === 'gemini') {
|
||||||
: data;
|
payload = { audio: { data, mimeType: mimeType || 'audio/pcm;rate=24000' } };
|
||||||
|
} else if (modelInfo.provider === 'deepgram') {
|
||||||
|
payload = Buffer.from(data, 'base64');
|
||||||
|
} else {
|
||||||
|
payload = data;
|
||||||
|
}
|
||||||
|
|
||||||
await this.theirSttSession.sendRealtimeInput(payload);
|
await this.theirSttSession.sendRealtimeInput(payload);
|
||||||
}
|
}
|
||||||
@ -547,9 +598,15 @@ class SttService {
|
|||||||
|
|
||||||
if (this.theirSttSession) {
|
if (this.theirSttSession) {
|
||||||
try {
|
try {
|
||||||
const payload = modelInfo.provider === 'gemini'
|
let payload;
|
||||||
? { audio: { data: base64Data, mimeType: 'audio/pcm;rate=24000' } }
|
if (modelInfo.provider === 'gemini') {
|
||||||
: base64Data;
|
payload = { audio: { data: base64Data, mimeType: 'audio/pcm;rate=24000' } };
|
||||||
|
} else if (modelInfo.provider === 'deepgram') {
|
||||||
|
payload = Buffer.from(base64Data, 'base64');
|
||||||
|
} else {
|
||||||
|
payload = base64Data;
|
||||||
|
}
|
||||||
|
|
||||||
await this.theirSttSession.sendRealtimeInput(payload);
|
await this.theirSttSession.sendRealtimeInput(payload);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error sending system audio:', err.message);
|
console.error('Error sending system audio:', err.message);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user