claw-subagent-service 0.0.176 → 0.0.177
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -285,7 +285,7 @@ class RongyunMessageHandler {
|
|
|
285
285
|
const roomId = data.room_id;
|
|
286
286
|
const sessionId = data.gateway_session_id || data.session_id;
|
|
287
287
|
// 使用解析后的 content(聊天内容),如果没有则使用原始 content
|
|
288
|
-
|
|
288
|
+
let content = data.content || data._raw_content;
|
|
289
289
|
const requestId = data.request_id;
|
|
290
290
|
const sourceId = data.source_im_id;
|
|
291
291
|
|
|
@@ -301,6 +301,16 @@ class RongyunMessageHandler {
|
|
|
301
301
|
return;
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
+
// 语音消息:先进行语音识别
|
|
305
|
+
if (data.voiceUrl) {
|
|
306
|
+
const voiceText = await this._recognizeVoice(data.voiceUrl, data.voiceDuration);
|
|
307
|
+
if (voiceText !== null) {
|
|
308
|
+
content = `[语音转文字] ${voiceText}`;
|
|
309
|
+
} else {
|
|
310
|
+
content = `[语音消息,转文字失败] ${content}`;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
304
314
|
let fullResponse = '';
|
|
305
315
|
const chatTimeoutMs = (this.config.chatTimeout || 600) * 1000;
|
|
306
316
|
|
|
@@ -766,6 +776,53 @@ class RongyunMessageHandler {
|
|
|
766
776
|
this.logError(`发送响应失败: ${msg}`);
|
|
767
777
|
}
|
|
768
778
|
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* 语音识别:调用后端百度语音 API 将语音转为文字
|
|
782
|
+
*/
|
|
783
|
+
async _recognizeVoice(voiceUrl, voiceDuration) {
|
|
784
|
+
try {
|
|
785
|
+
if (!voiceUrl) {
|
|
786
|
+
this.logWarn('[_recognizeVoice] 语音 URL 为空,跳过识别');
|
|
787
|
+
return null;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// 从 URL 提取扩展名并映射为百度支持的格式
|
|
791
|
+
const urlPath = voiceUrl.split('?')[0];
|
|
792
|
+
const ext = urlPath.split('.').pop()?.toLowerCase() || '';
|
|
793
|
+
const fmtMap = { aac: 'm4a', ogg: 'mp3', oga: 'mp3', opus: 'mp3' };
|
|
794
|
+
let format = fmtMap[ext] || ext;
|
|
795
|
+
if (!['pcm', 'wav', 'amr', 'm4a', 'mp3'].includes(format)) {
|
|
796
|
+
format = 'mp3';
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
// 采样率修正:amr 强制 8000,其余兜底 16000
|
|
800
|
+
let sampleRate = 16000;
|
|
801
|
+
if (format === 'amr') sampleRate = 8000;
|
|
802
|
+
|
|
803
|
+
const axios = require('axios');
|
|
804
|
+
const apiUrl = `${this.config.apiBaseUrl}/im/api/voice/recognize`;
|
|
805
|
+
this.logInfo(`[_recognizeVoice] 调用语音识别 API: ${apiUrl}, format=${format}, sampleRate=${sampleRate}`);
|
|
806
|
+
|
|
807
|
+
const response = await axios.post(apiUrl, {
|
|
808
|
+
audioUrl: voiceUrl,
|
|
809
|
+
format,
|
|
810
|
+
sampleRate,
|
|
811
|
+
}, { timeout: 30000 });
|
|
812
|
+
|
|
813
|
+
if (response.data?.code === 200 && response.data?.data?.text !== undefined) {
|
|
814
|
+
const text = response.data.data.text;
|
|
815
|
+
this.logInfo(`[_recognizeVoice] 语音识别成功: "${text.substring(0, 50)}${text.length > 50 ? '...' : ''}"`);
|
|
816
|
+
return text;
|
|
817
|
+
} else {
|
|
818
|
+
this.logWarn(`[_recognizeVoice] 语音识别失败: ${JSON.stringify(response.data)}`);
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
} catch (err) {
|
|
822
|
+
this.logError(`[_recognizeVoice] 语音识别异常: ${err.message}`);
|
|
823
|
+
return null;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
769
826
|
}
|
|
770
827
|
|
|
771
828
|
module.exports = {
|