module.exports = { main: async (event) => { let { data = {}, userInfo } = event; const COZE_TOKEN = 'sat_OiXlI4Da5Q99fxmul6pNfExmA6hR898UbxBDwrvjZ638APxRSlFnXbz6zyFedKNG'; // 从前端传入 bot_id,不同项目用不同智能体 const BOT_ID = data.bot_id || '7680345813062680618'; const res = await uniCloud.httpclient.request('https://api.coze.cn/v3/chat', { method: 'POST', dataType: 'text', contentType: 'json', timeout: 120000, headers: { 'Authorization': 'Bearer ' + COZE_TOKEN }, data: { bot_id: BOT_ID, user_id: (userInfo && userInfo.uid) || 'anonymous', stream: true, auto_save_history: true, additional_messages: [{ role: 'user', content: data.message, content_type: 'text' }] } }); // 扣子 v3 流式事件说明: // conversation.message.delta —— 增量片段(应当拼接) // conversation.message.completed —— 该条消息的「完整内容」(不能再次拼接,否则重复) // 因此必须按事件类型区分,只累加 delta;completed 仅用于兜底。 let conversationId = ''; const msgMap = new Map(); // messageId -> { text } let curEvent = ''; const text = res.data || ''; const lines = text.split('\n'); for (const line of lines) { if (line.startsWith('event:')) { curEvent = line.slice(6).trim(); continue; } if (!line.startsWith('data:')) continue; const d = line.slice(5).trim(); if (d === '[DONE]' || d === '"[DONE]"') continue; try { const p = JSON.parse(d); if (p.conversation_id) conversationId = p.conversation_id; // 只取正文,忽略 verbose(工具调用日志)等其他类型 if (p.type !== 'answer' || typeof p.content !== 'string') continue; const key = p.id || '__default__'; const rec = msgMap.get(key) || { text: '' }; if (curEvent === 'conversation.message.delta') { // 防御:万一上游发的是累计内容而非增量,用长度+前缀判断避免重复 if (p.content.length > rec.text.length && p.content.indexOf(rec.text) === 0) { rec.text = p.content; } else { rec.text += p.content; } msgMap.set(key, rec); } else if (curEvent === 'conversation.message.completed') { // 已有 delta 拼出的内容就丢掉 completed,避免重复;没有则用它兜底 if (!rec.text && p.content) { rec.text = p.content; msgMap.set(key, rec); } } } catch (e) { /* 跳过 */ } } // 按消息首次出现顺序拼接(多段消息之间自带换行,直接相连) let answer = ''; for (const rec of msgMap.values()) answer += rec.text; if (!answer) answer = '暂时无法回复,请拨打 400-686-5559 咨询'; return { code: 0, msg: 'ok', data: { answer, conversation_id: conversationId } }; } };