83 lines
3.0 KiB
JavaScript
83 lines
3.0 KiB
JavaScript
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 }
|
|
};
|
|
}
|
|
};
|