UNPKG

esp-ai

Version:

Provide a complete set of AI dialogue solutions for your development board, including but not limited to the IAT+LLM+TTS integration solution for the ESP32 series development board. | 为你的开发板提供全套的AI对话方案,包括但不限于 `ESP32` 系列开发板的 `IAT+LLM+TTS` 集成方案。

225 lines (200 loc) 9.4 kB
/** * Copyright (c) 2024 小明IO * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Commercial use of this software requires prior written authorization from the Licensor. * 请注意:将 ESP-AI 代码用于商业用途需要事先获得许可方的授权。 * 删除与修改版权属于侵权行为,请尊重作者版权,避免产生不必要的纠纷。 * * @author 小明IO * @email 1746809408@qq.com * @github https://github.com/wangzongming/esp-ai * @websit https://espai.fun */ const log = require("../../utils/log"); const isOutTimeErr = require("../../utils/isOutTimeErr"); const gen_intention_prompt = require("../../utils/gen_intention_prompt"); const du_cache = require("../../audio_temp/du_cache"); const play_audio = require("../../audio_temp/play_audio"); /** * 客户端连接成功 */ async function fn({ device_id }) { try { const { devLog, gen_client_config, auth } = G_config; const { ws, client_params = {}, client_version, error_catch } = G_devices.get(device_id); const { LITTLE_ROM } = client_params; if (auth) { const { success: auth_success, message: auth_message, code: auth_code } = await auth({ ws, client_params: client_params, type: "connect", send_error_to_client: (code, message) => { ws.send(JSON.stringify({ type: "error", message: message, code: code })); } }); if (!auth_success) { G_devices.set(device_id, { ...G_devices.get(device_id), authed: false }) ws.send(JSON.stringify({ type: "auth_fail", message: `${auth_message || "-"}`, code: isOutTimeErr(auth_message) ? "007" : auth_code, })); // 防止大量失效用户重复请求 setTimeout(() => { ws.close(); G_devices.delete(device_id); }, 5000) return; } else { G_devices.set(device_id, { ...G_devices.get(device_id), authed: true }) }; } const user_config = await gen_client_config({ client_params, ws, send_error_to_client: (code, message) => { ws.send(JSON.stringify({ type: "error", message: message, code: code })); } }) || {}; if (user_config?.success === false) { // 服务报错 ws && ws.send(JSON.stringify({ type: "error", at: "auth", code: isOutTimeErr(user_config.message) ? "007" : (user_config.code || "006"), message: `获取服务配置失败:${user_config.message}` })); setTimeout(() => { ws.close(); }, 5000) return; } if (!user_config.iat_server || !user_config.iat_config) { error_catch("IAT", "100", `请配置 iat_server、iat_config 参数。`); return log.error(`请配置 iat_server、iat_config 参数。`); } if (!user_config.llm_server || !user_config.llm_config) { error_catch("LLM", "200", `请配置 llm_server、llm_config 参数。`); return log.error(`请配置 llm_server、llm_config 参数。`); } if (!user_config.tts_server || !user_config.tts_config) { error_catch("TTS", "300", `请配置 tts_server、tts_config 参数。`); return log.error(`请配置 tts_server、tts_config 参数。`) } devLog && log.info(`---------------------------------------------------`); devLog && log.t_info(`客户端连接成功:${device_id}`); devLog && log.t_info(`客户端版本号:v${client_version}`); devLog && log.t_info(`用户配置 iat_server:${user_config.iat_server}`); devLog && log.t_info(`用户配置 iat_config:${JSON.stringify(user_config.iat_config)}`); devLog && log.t_info(`用户配置 llm_server:${user_config.llm_server}`); devLog && log.t_info(`用户配置 llm_config:${JSON.stringify(user_config.llm_config)}`); devLog && log.t_info(`用户配置 tts_server:${user_config.tts_server}`); devLog && log.t_info(`用户配置 tts_config:${JSON.stringify(user_config.tts_config)}`); devLog && log.info(`---------------------------------------------------`); const _user_config = { f_reply: "您好", sleep_reply: "我先休息了哦,有需要再叫我。", connected_reply: "后台服务连接成功", ...user_config, } G_devices.set(device_id, { ...G_devices.get(device_id), user_config: _user_config, intention_prompt: gen_intention_prompt(_user_config.intention) }) const TTS_FN = require(`../tts`); const { user_config: { connected_reply, intention = [] } } = G_devices.get(device_id); ws && ws.send(JSON.stringify({ type: "stc_time", stc_time: +new Date() + "" })); intention.forEach(({ instruct, pin, target_device_id, channel, freq, resolution }) => { if (!target_device_id && (instruct === "__io_high__" || instruct === "__io_low__" || instruct === "__pwm__")) { !pin && log.error(`${instruct} 指令必须配置引脚号:pin`); G_Instance.pinMode(device_id, pin, "OUTPUT"); } if (!target_device_id && (instruct === "__LEDC__")) { !pin && log.error(`${instruct} 指令必须配置引脚号:pin`); G_Instance.LEDCInit(device_id, { pin, channel, freq, resolution }); } }) // setTimeout(async () => { // // 播放音频测试 // const session_id = await G_Instance.newSession(device_id); // play_audio( // "https://xiaomingio.top/music.mp3" // // "https://xiaomingio.top/music2.mp3" // // "http://192.168.3.16:8000/ad.opus" // // "http://192.168.3.16:8000/ad_16.mp3" // , ws, "play_music", session_id, device_id, 0, () => { // console.log("音乐播放完毕") // }) // }, 2000) // return; // await TTS_FN(device_id, { // session_id: "0010", // // text: "好的好的,连接成功了。", // text: "小米从创立之初就非常重视与用户的互动。我们有一个专门的论坛,用户可以在那里提出建议和反馈。有一次,一位米粉在论坛上发帖,哈哈哈哈。", // // text: `<speak>一匹马受了惊吓<soundEvent src="http://nls.alicdn.com/sound-event/horse-neigh.wav"/>人们四散躲避</speak>`, // text_is_over: true, // }) // return; // await TTS_FN(device_id, { // session_id: "0010", // text: "听起来不太好受。记得多穿衣服保暖。东方财富最新的股价为13.74元/股。", // // text: `<speak>一匹马受了惊吓<soundEvent src="http://nls.alicdn.com/sound-event/horse-neigh.wav"/>人们四散躲避</speak>`, // text_is_over: true, // }) // return; // 缓存提示音 if (user_config.iatDu !== false && LITTLE_ROM !== "1") { du_cache(ws); } // 缓存问候语 const f_reply = _user_config.f_reply; if (f_reply !== false && LITTLE_ROM !== "1") { await TTS_FN(device_id, { text: f_reply, text_is_over: true, session_id: G_session_ids.cache_hello, is_create_cache: true, }) } // 播放ws连接成功语音 if (connected_reply) { await TTS_FN(device_id, { text: connected_reply, text_is_over: true, tts_task_id: "connected_reply", session_id: G_session_ids.cache_connected, }) } } catch (err) { console.log(err); log.error(`[${device_id}] play_audio_ws_conntceed 消息错误: ${err}`) } } module.exports = fn