UNPKG

component-genie-mcp

Version:

A simplified Model Context Protocol server for querying React components with complete content access

296 lines (268 loc) 11.2 kB
/** * 向Agent聊天SSE接口发起请求 * @param {Object} config - 配置参数 * @param {string} config.baseUrl - 基础URL,例如 'https://gateway-boss.zacz.cn' * @param {string} config.query - 用户问句 * @param {string} config.agentInstanceId - agent编码 * @param {string} config.tenantId - 租户ID * @param {string} config.userId - 用户ID * @param {string} config.bizInvokeFrom - 业务调用来源,默认"ROBOT" */ async function sendAgentChatRequest(config) { const { baseUrl = "https://gateway-boss.zacz.cn", query, agentInstanceId, tenantId, userId, bizInvokeFrom = "ROBOT", isStream = true, confirm = false, deep_plan = false, } = config; // 构建请求数据 const requestData = { query, agentInstanceId, tenantId, userId, bizInvokeFrom, isStream, confirm, deep_plan, }; const url = `${baseUrl}/quick/agent/chat/sse`; // 添加调试信息 console.log("发起请求:"); console.log(`URL: ${url}`); console.log(`Method: POST`); console.log(`请求数据:`, JSON.stringify(requestData, null, 2)); console.log(`请求体长度:`, JSON.stringify(requestData).length); console.log(`请求体内容:`, JSON.stringify(requestData)); try { const response = await fetch(url, { method: "POST", headers: { Accept: "text/event-stream", "Accept-Encoding": "gzip, deflate, br, zstd", "Accept-Language": "zh-CN,zh;q=0.9", Authorization: "Basic T3dnWEJWMU44WDJDY1ViN21qbTMycG5MeE4wZ2cxaWpXQVJzcEw5eE0xODpieTZvaEhqVG4xMjZ5Nkh2bnltTHpEYjNsMWQ1bjZqbg==", Connection: "keep-alive", "Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36", "sec-ch-ua": '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"', "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": '"macOS"', "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "none", "Sec-Fetch-Storage-Access": "active", // 如果需要的话,可以添加Cookie // "Cookie": "cna=wRorIfwBTVUCAYzNZlBEXjsl; xlly_s=1; ..." }, body: JSON.stringify(requestData), }); console.log(`状态码: ${response.status}`); console.log(`响应头:`, Object.fromEntries(response.headers.entries())); if (!response.ok) { console.log(`====== 请求失败 =====`); console.log(`状态码: ${response.status} ${response.statusText}`); console.log(`URL: ${url}`); console.log(`请求数据:`, JSON.stringify(requestData, null, 2)); // 尝试读取错误响应体 try { const errorText = await response.text(); console.log(`错误响应体:`, errorText); } catch (err) { console.log(`无法读取错误响应体:`, err.message); } throw new Error( `请求失败,状态码: ${response.status} ${response.statusText}` ); } if (!response.body) { throw new Error("响应体为空"); } // 获取ReadableStream读取器 const reader = response.body.getReader(); const decoder = new TextDecoder(); let buffer = ""; try { while (true) { const { done, value } = await reader.read(); if (done) { console.log("SSE连接结束"); break; } // 解码数据块 const chunk = decoder.decode(value, { stream: true }); buffer += chunk; // 处理SSE数据流 const lines = buffer.split("\n"); buffer = lines.pop() || ""; // 保留最后一个不完整的行 lines.forEach((line) => { if (line.startsWith("data: ")) { const data = line.slice(6); // 移除 'data: ' 前缀 if (data === "[DONE]") { console.log("流式输出结束"); return; } if (data.trim() === "") { return; // 跳过空数据行 } try { const jsonData = JSON.parse(data); handleSSEMessage(jsonData); } catch (error) { console.error("解析JSON数据失败:", error.message); console.error("原始数据:", data); } } }); } } finally { reader.releaseLock(); } } catch (error) { console.error("请求错误:", error); throw error; } } /** * 处理SSE消息 * @param {Object} data - 解析后的JSON数据 */ function handleSSEMessage(data) { console.log("\n=== 收到新消息 ==="); console.log(`消息ID: ${data.msgId}`); console.log(`消息类型: ${data.msgType}`); console.log(`对话ID: ${data.chatId}`); console.log(`会话ID: ${data.conversationId}`); console.log(`是否结束: ${data.isEnd}`); console.log(`是否首次消息: ${data.firstMessageFlag}`); console.log(`消耗Token: ${data.totalTokens}`); console.log(`耗时: ${data.spendTime}ms`); if (data.content) { console.log(`消息完结: ${data.content.messageEnd}`); console.log(`内容: ${data.content.docAskContent || data.content.sentence}`); console.log(`内容类型: ${data.content.type}`); // 处理文档引用信息 if (data.content.docInfoList && data.content.docInfoList.length > 0) { console.log("引用文档:"); data.content.docInfoList.forEach((doc, index) => { console.log(` ${index + 1}. ${doc.docName} (ID: ${doc.docId})`); console.log(` 摘要: ${doc.summary}`); console.log(` URL: ${doc.docUrl}`); }); } // 处理分片信息 if ( data.content.segmentInfoList && data.content.segmentInfoList.length > 0 ) { console.log("相关分片:"); data.content.segmentInfoList.forEach((segment, index) => { console.log( ` ${index + 1}. 文档ID: ${segment.documentId}, 分片ID: ${ segment.segmentId }, 分数: ${segment.score}` ); }); } } // 处理思维链信息 if ( data.thoughtChainContentInfo && data.thoughtChainContentInfo.thoughtChainList ) { console.log("思维链信息:"); data.thoughtChainContentInfo.thoughtChainList.forEach((chain, index) => { console.log(` ${index + 1}. ${chain.title} (${chain.thoughtChainType})`); console.log(` 状态: ${chain.status}`); if (chain.failMessage) { console.log(` 失败原因: ${chain.failMessage}`); } }); } console.log("==================\n"); } // 使用示例 async function main() { const query = `# 智能生成任务列表 **1** **标题**:*~智能生成~* * 标题后展示提示文案:*~保留最近90天的智能生成任务记录~* **2** **搜索**:支持按任务名称模糊搜索,大小写不敏感 **3** **筛选**: * ~资产类型~:本期仅支持表、指标;指标是否展示取决于当前 user 是否支持指标资产管理 * ~创建人~:下拉多选搜索框,可选范围为当前租户下“正常”状态的用户;可快捷筛选“我创建的” * ~生成进度~:多选 CheckBox,支持:*~已完成、生成中、已终止、执行异常~* **4** **列表项**:列表高度根据当前行的明细行动态调整高度,展示 2 行或 3 行 * ~任务名称/资产类型~:第一行展示任务名称,超长...hover 展示全部;第二行展示资产类型 * ~生成属性~:按“资产类型”分开展示,仅展示配置了的类型对应的属性,最多 3 行 * 所有属性名称平铺展示,无需缩进为等 n 个 * 自动识别指标的配置无需在此处展示 * ~资产总数~:展示按照当前任务配置,真正需要进行智能生成的资产数@扶至钦(扶犁) * 暂未返回结果的时候展示为-;拿到全部数值后再返回 * 标题后展示 info icon,hover 提示:*~表资产仅统计表个数,不统计指标个数~* * ~生成进度~:第一行展示总体状态、第二行起展示明细状态 * ~全部完成~:无继续生成中、待生成的资产,可能包含“成功”和“失败” 1 第一行灰色文字展示 2 第二行起展示“成功、失败”的个数,仅展示有对应资产的状态行;失败的数值红色 highlight,如果为 0 则展示为黑色无需标红[2025-06-10 更新] 3 “已终止”的算"失败" * ~生成中~:存在“生成中、待生成”的资产 1 第一行灰色文字:*~生成中~*; 2 第二行起展示“已完成、生成中”的个数,其中 * 已完成:包含“成功”和“失败” * 生成中:包含“生成中”和“待生成” * ~已终止~:手动终止过的生成任务 1 第一行红色文字展示 2 第二行起展示“已完成、待生成”的个数 * 其中正在生成中被手动终止的,视为“待生成”;继续生成/重新生成时,该部分也需要继续生成/重新生成 * ~执行异常~:失败 icon+“执行异常”文案,以及“查看执行日志”的 icon 1 整体执行异常视为该状态 2 点击 icon 右侧呼出异常日志的抽屉,支持复制和全屏展示,样式参见下图 * ~审核状态~:仅展示有对应资产的状态行,仅”全部成功、已终止”生成状态的展示,其余展示为- * ~已应用~:手动确认“应用”过的资产;如果应用后重新生成,视为待审核 * ~已弃用~:手动确认“启用”过的资产;如果启用后重新生成,视为待审核 * ~待审核~:其余视为“待审核” * ~创建人/创建时间~: * 第一行展示创建人名称 * 第二行展示创建时间 * ~操作~: * ~查看详情~:点击当前页面跳转至该任务的详情页;更多其他操作本期仅在在任务详情页支持 * [2025-06-04 新增]~删除~: 1 除“生成中”状态不展示该操作 icon,其他均展示 2 点击弹出二次确认弹框: * 标题:*~删除智能生成任务:{任务名}~* * 提示:*~删除后,已生成的内容将被清理,删除操作不可恢复~* * 操作校验: * 是否有【上架管理-管理】权限 * 如果在确定前该任务已经被删除,无需报错,提示操作成功即可 * 排序:按照创建时间倒序 * 分页:支持分页;底部分页条不展示批量操作入口(本期不支持批量操作)[2025-05-14 更新] `; try { // 配置请求参数 const config = { baseUrl: "https://gateway-boss.zacz.cn", agentInstanceId: "5be564ab-2b61-4aed-93c4-12729e4034d6", bizInvokeFrom: "ROBOT", query, tenantId: "25073022381050", userId: 283360, confirm: false, deep_plan: false, isStream: true, }; console.log("开始发送请求..."); await sendAgentChatRequest(config); console.log("请求完成"); } catch (error) { console.error("执行失败:", error.message); } } // 如果直接运行此文件,则执行main函数 main();