--- C:\kefu\wechat_rpa\backups\review-assistant-20260917\assets\ui\console-app.js +++ C:\kefu\wechat_rpa\assets\ui\console-app.js @@ -469,11 +469,32 @@ return `
${head("AI 设置","配置模型、客服人格、知识库与工具能力",`${configLabel}`)}
${tabs}

客服人格

AI
服务风格:温和专业简洁
✧ 实时预览

您好!我是甄养堂${esc(ai.name || "贴心管家")},
很高兴为您服务 😊

请问有什么可以帮您的吗?

✣ 模型编排

由后台决定,本机只执行
答题模型:${esc(plan.answer || "后台未配置")}
裁判模型:${esc(plan.judge || "未启用")}
裁判模式:${esc(plan.mode || "—")}
编排版本:${plan.version ? "v" + esc(plan.version) : "—"}
上下文轮数:${esc(ai.context || 8)} 轮
网关:${esc(plan.gateway || "未下发——模型调用会失败,请去「系统设置 → 后台连接」")}
最后同步:${esc(plan.syncedAt || "尚未同步")}
模型接口、密钥、温度、最大 tokens 现在统一在后台的「AI 模型 → 模型清单 / 角色编排」里配。
上下文轮数和 MCP 在「桌面端 → 客户端配置」里配,随配置下发——在这台机器上改会被下一次同步覆盖。

▰ 企业知识库

${esc(knowledgeCount)}个知识片段
● ${esc(syncLabel)}✓ ${connectedKnowledge?"已连接":"未连接"}

◇ MCP 工具

单次最多调用 ${esc(ai.mcpRounds || 5)} 轮 · 由后台下发
${names.map((name,index)=>`
${toolTokens[index]}
${name}
${toolsOn[index]?"已启用":"未启用"}
`).join("")}
工具清单和调用轮数在后台的「桌面端 → 客户端配置 → MCP 服务器」里配,随配置下发。
在这台机器上改会被下一次同步覆盖,所以这里只展示不修改。

${icon("shield")} 选择性审核规则

由后台决定,本机只执行
${reviewRulesHtml}
命中任意一条,这一条回复才会停下来等人工确认;其余照常自动发送。模型裁判判定为高风险时同样会转人工,那一条不在这份清单里、关不掉。
在后台的「桌面端 → 客户端配置 → 审核规则」里配置,随配置下发。

发送模式

${icon("shield")}${blanketReview?"全部审核后发送":"自动发送(命中规则单独审核)"}
在「自动化设置」页顶部切换;这个总开关和上面的选择性规则是 OR 的关系,任一个成立都会拦下。

配置状态

${statusCells([["cloud",STATE.aiOk===false?"AI 服务异常":"云端模型正常","最后检查:刚刚"],["folder",knowledgeStatus,`${esc(knowledgeCount)} 个知识片段`],["folder",`${toolCount} 个工具可用`,toolStatus],["shield","安全策略已生效","严格模式"]])}
`; }; +function reviewAssistantPanel(a){ + const r = a.reviewAssistant || {}; + const recipient = r.recipient || {}; + const busy = Boolean(r.busy); + const canChoose = r.ready && !busy; + const canToggle = canChoose && (recipient.id || r.enabled); + return `

医疗助理审核提醒

${r.enabled ? "当前账号已开启" : "当前账号未开启"}
+

客户会话进入待审核时,由当前托管企业微信账号向指定助理的私人微信发送客户咨询、待发送回复和审核原因。

+
托管企微账号(最近核验)${esc(r.accountName || "尚未核验")}${r.accountId ? `${esc(r.accountId)}` : ""}
+
助理私人微信
${esc(recipient.name || "尚未选择")}${recipient.label ? `
${esc(recipient.label)}
` : ""}
+
+ + 开启审核提醒
+ ${r.reason ? `

${esc(r.reason)}

` : ""} + ${r.message ? `

${esc(r.message)}

` : ""} + ${r.notification && r.notification.message ? `

最近提醒(读取账号时刷新):${esc(r.notification.message)}

` : ""} +

设置按企微账号分别保存。选择或更换联系人后默认关闭,确认收件人后再开启;同名联系人按列表中的联系编号区分。

+

人工用同一企业微信账号直接回复客户后结束本次审核;后续自动回复仍逐条风控。此识别以账号发出的消息为准,不区分手机或电脑。在助理私人微信回复提醒,不会解除客户审核。

+
提醒内容示例(只读,不会发送)
${esc(r.preview || "请先读取当前账号")}
`; +} + automationView = function(){ if (STATE.demo) return _automationView(); const a = STATE.automation || {}; const autoOn = (STATE.sendMode || "auto") === "auto"; - return `
${head("自动化设置","配置企业微信监听、消息合并与自动发送规则",`${esc(a.wecom || "企业微信未识别")}规则已生效`)}

监听与发送策略

${icon("activity")} ● 规则运行中
${[["activity","扫描未读"],["log","提取消息"],["folder","合并消息"],["brain","请求 AI"],["send","回填发送"]].map(x=>`
${icon(x[0])}
${x[1]}
`).join("")}
${icon("clock")}扫描间隔  秒
${icon("hourglass")} 连续消息等待  秒
${icon("clock")}发送前等待  秒

企业微信窗口

✓
${icon("clipboard")} 主窗口:● ${esc(a.wecom || "未识别")}
${icon("user")} 当前账号:${esc(a.account || "—")}
${icon("globe")} DPI:${esc(STATE.dpi || "—")}
${icon("monitor")} 最小化恢复:● 已开启

人机共存

启用人工操作保护
鼠标静止  秒 后恢复
草稿超时直发
输入框里有人工草稿  0 ? "" : "disabled"}> 分钟后直接发出
关闭时只跳过该会话、绝不动别人写的字;命中审核规则的仍会等人确认
${icon("bot")}
AI 运行中
${icon("cursor")}
${icon("pause")}
检测到人工操作
AI 暂停

消息处理

✓ 同一客户连续消息自动合并
✓ 保留最近 轮上下文${esc(a.context || 8)} 轮
✓ 一次只处理 1 个会话1 个

异常与兜底

${icon("clock")}AI 超时:${esc(a.timeout || 120)} 秒后重试2 次
${icon("alert")}发送失败:自动重试已开启
${icon("message")}固定回复:${esc(a.reply || "在的,请稍等")}

高风险转人工

● 已开启
${icon("shield")} 诊断${icon("package")} 用药调整${icon("coins")} 投诉退款

启动前检查

${statusCells([["check","企业微信已登录", STATE.wecomConnected ? "检查完成" : "等待连接"],["cloud","AI 服务正常","检查完成"],["activity","窗口坐标已校准", STATE.wecomConnected ? "检查完成" : "待校准"],["shield","规则配置有效","检查完成"]])}
`; + return `
${head("自动化设置","配置企业微信监听、消息合并与自动发送规则",`${esc(a.wecom || "企业微信未识别")}规则已生效`)}
${reviewAssistantPanel(a)}

监听与发送策略

${icon("activity")} ● 规则运行中
${[["activity","扫描未读"],["log","提取消息"],["folder","合并消息"],["brain","请求 AI"],["send","回填发送"]].map(x=>`
${icon(x[0])}
${x[1]}
`).join("")}
${icon("clock")}扫描间隔  秒
${icon("hourglass")} 连续消息等待  秒
${icon("clock")}发送前等待  秒

企业微信窗口

✓
${icon("clipboard")} 主窗口:● ${esc(a.wecom || "未识别")}
${icon("user")} 当前账号:${esc(a.account || "—")}
${icon("globe")} DPI:${esc(STATE.dpi || "—")}
${icon("monitor")} 最小化恢复:● 已开启

人机共存

启用人工操作保护
鼠标静止  秒 后恢复
草稿超时直发
输入框里有人工草稿  0 ? "" : "disabled"}> 分钟后直接发出
关闭时只跳过该会话、绝不动别人写的字;命中审核规则的仍会等人确认
${icon("bot")}
AI 运行中
${icon("cursor")}
${icon("pause")}
检测到人工操作
AI 暂停

消息处理

✓ 同一客户连续消息自动合并
✓ 保留最近 轮上下文${esc(a.context || 8)} 轮
✓ 一次只处理 1 个会话1 个

异常与兜底

${icon("clock")}AI 超时:${esc(a.timeout || 120)} 秒后重试2 次
${icon("alert")}发送失败:自动重试已开启
${icon("message")}固定回复:${esc(a.reply || "在的,请稍等")}

高风险转人工

● 已开启
${icon("shield")} 诊断${icon("package")} 用药调整${icon("coins")} 投诉退款

启动前检查

${statusCells([["check","企业微信已登录", STATE.wecomConnected ? "检查完成" : "等待连接"],["cloud","AI 服务正常","检查完成"],["activity","窗口坐标已校准", STATE.wecomConnected ? "检查完成" : "待校准"],["shield","规则配置有效","检查完成"]])}
`; }; logsView = function(){ @@ -1181,6 +1202,15 @@ "edit-knowledge": () => callBridge("editKnowledge"), "sync-knowledge": () => callBridge("syncKnowledge"), "open-data": () => callBridge("openDataDir"), + "review-assistant-refresh": () => callBridge("refreshReviewAssistant"), + "review-assistant-choose": () => callBridge("chooseReviewAssistant"), + "review-assistant-toggle": () => { + const r = (STATE.automation || {}).reviewAssistant || {}; + if (!r.ready || r.busy) return; + callBridgeWithFeedback("setReviewAssistantEnabled", [JSON.stringify({expected_account: r.accountId, enabled: !r.enabled})], { + pending: "正在核对当前账号与助理联系人…", + }); + }, "save-automation": () => callBridgeWithFeedback( "saveAutomationSettings", [collectAutomationPayload()], { button: action, busyLabel: "保存中…",