From a4249f95c3896bd9c640ac936c3ea431a1266503 Mon Sep 17 00:00:00 2001 From: xjs Date: Thu, 28 May 2026 11:45:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages.config.ts | 6 +- src/pages-ai/ai/index.vue | 75 +- src/pages-ai/components/AgentMessage.vue | 16 + src/pages-ai/components/agent-config.ts | 8 +- src/pages-ai/components/agent-service.ts | 127 +- src/store/ai.ts | 2 + src/wxcomponents/agent-ui/chatFile/index.js | 231 ++ src/wxcomponents/agent-ui/chatFile/index.json | 4 + src/wxcomponents/agent-ui/chatFile/index.wxml | 14 + src/wxcomponents/agent-ui/chatFile/index.wxss | 49 + src/wxcomponents/agent-ui/collapse/index.js | 44 + src/wxcomponents/agent-ui/collapse/index.json | 4 + src/wxcomponents/agent-ui/collapse/index.wxml | 10 + src/wxcomponents/agent-ui/collapse/index.wxss | 14 + src/wxcomponents/agent-ui/customCard/index.js | 18 + .../agent-ui/customCard/index.json | 4 + .../agent-ui/customCard/index.wxml | 27 + .../agent-ui/customCard/index.wxss | 3 + .../agent-ui/feedback/imgs/star-highlight.svg | 2 + .../agent-ui/feedback/imgs/star.svg | 2 + src/wxcomponents/agent-ui/feedback/index.js | 277 ++ src/wxcomponents/agent-ui/feedback/index.json | 4 + src/wxcomponents/agent-ui/feedback/index.wxml | 35 + src/wxcomponents/agent-ui/feedback/index.wxss | 91 + src/wxcomponents/agent-ui/imgs/arrow.svg | 2 + src/wxcomponents/agent-ui/imgs/camera.svg | 2 + .../agent-ui/imgs/cancelSaying.svg | 1 + src/wxcomponents/agent-ui/imgs/chat-add.svg | 2 + .../agent-ui/imgs/chat-bubble-add.svg | 2 + .../agent-ui/imgs/chat-bubble-history.svg | 2 + src/wxcomponents/agent-ui/imgs/check.svg | 2 + src/wxcomponents/agent-ui/imgs/clear.svg | 2 + .../agent-ui/imgs/close-filled.png | Bin 0 -> 400 bytes src/wxcomponents/agent-ui/imgs/close-red.svg | 2 + src/wxcomponents/agent-ui/imgs/close.svg | 2 + src/wxcomponents/agent-ui/imgs/copy.svg | 2 + src/wxcomponents/agent-ui/imgs/edit.svg | 2 + .../agent-ui/imgs/error-circle.svg | 2 + src/wxcomponents/agent-ui/imgs/excel.svg | 1 + src/wxcomponents/agent-ui/imgs/file.svg | 3 + src/wxcomponents/agent-ui/imgs/image.svg | 1 + .../agent-ui/imgs/indent-left.svg | 2 + .../agent-ui/imgs/indent-right.svg | 2 + src/wxcomponents/agent-ui/imgs/internet.svg | 2 + .../agent-ui/imgs/internetUse.svg | 2 + src/wxcomponents/agent-ui/imgs/keyboard.svg | 2 + src/wxcomponents/agent-ui/imgs/loading.svg | 1 + src/wxcomponents/agent-ui/imgs/pause.svg | 2 + src/wxcomponents/agent-ui/imgs/pdf.svg | 1 + src/wxcomponents/agent-ui/imgs/play.svg | 2 + src/wxcomponents/agent-ui/imgs/playing.svg | 1 + src/wxcomponents/agent-ui/imgs/ppt.svg | 1 + src/wxcomponents/agent-ui/imgs/search.svg | 2 + src/wxcomponents/agent-ui/imgs/send.svg | 2 + src/wxcomponents/agent-ui/imgs/sendSaying.svg | 1 + src/wxcomponents/agent-ui/imgs/set.svg | 2 + src/wxcomponents/agent-ui/imgs/share.svg | 2 + src/wxcomponents/agent-ui/imgs/sound.svg | 2 + src/wxcomponents/agent-ui/imgs/stop.svg | 2 + src/wxcomponents/agent-ui/imgs/system-sum.svg | 2 + src/wxcomponents/agent-ui/imgs/thumb-down.svg | 2 + src/wxcomponents/agent-ui/imgs/thumb-up.svg | 2 + src/wxcomponents/agent-ui/imgs/toBottom.svg | 2 + src/wxcomponents/agent-ui/imgs/uploadImg.svg | 2 + src/wxcomponents/agent-ui/imgs/voice.svg | 1 + src/wxcomponents/agent-ui/imgs/wechat.svg | 2 + src/wxcomponents/agent-ui/imgs/word.svg | 1 + src/wxcomponents/agent-ui/index.js | 2517 +++++++++++++++++ src/wxcomponents/agent-ui/index.json | 11 + src/wxcomponents/agent-ui/index.wxml | 391 +++ src/wxcomponents/agent-ui/index.wxss | 730 +++++ src/wxcomponents/agent-ui/md5.js | 2 + src/wxcomponents/agent-ui/tool/index.js | 92 + src/wxcomponents/agent-ui/tool/index.json | 5 + src/wxcomponents/agent-ui/tool/index.wxml | 17 + src/wxcomponents/agent-ui/tool/index.wxss | 45 + src/wxcomponents/agent-ui/tools.js | 141 + .../agent-ui/wd-markdown/copy/index.js | 26 + .../agent-ui/wd-markdown/copy/index.json | 6 + .../agent-ui/wd-markdown/copy/index.wxml | 3 + .../agent-ui/wd-markdown/copy/index.wxss | 9 + .../agent-ui/wd-markdown/index.js | 105 + .../agent-ui/wd-markdown/index.json | 7 + .../agent-ui/wd-markdown/index.wxml | 3 + .../agent-ui/wd-markdown/index.wxss | 235 ++ .../agent-ui/wd-markdown/mp-html/index.js | 8 + .../agent-ui/wd-markdown/mp-html/index.json | 1 + .../agent-ui/wd-markdown/mp-html/index.wxml | 1 + .../agent-ui/wd-markdown/mp-html/index.wxss | 11 + .../agent-ui/wd-markdown/mp-html/node/node.js | 1 + .../wd-markdown/mp-html/node/node.json | 1 + .../wd-markdown/mp-html/node/node.wxml | 43 + .../wd-markdown/mp-html/node/node.wxss | 156 + .../agent-ui/wd-markdown/mp-html/parser.js | 1 + .../wd-markdown/utils/highlight.min.js | 1 + .../wd-markdown/utils/hljs_css.min.js | 1 + .../wd-markdown/utils/hljs_javascript.min.js | 1 + .../wd-markdown/utils/markdown-it.min.js | 3 + .../agent-ui/wd-markdown/utils/plugin.js | 55 + 99 files changed, 5705 insertions(+), 66 deletions(-) create mode 100644 src/wxcomponents/agent-ui/chatFile/index.js create mode 100644 src/wxcomponents/agent-ui/chatFile/index.json create mode 100644 src/wxcomponents/agent-ui/chatFile/index.wxml create mode 100644 src/wxcomponents/agent-ui/chatFile/index.wxss create mode 100644 src/wxcomponents/agent-ui/collapse/index.js create mode 100644 src/wxcomponents/agent-ui/collapse/index.json create mode 100644 src/wxcomponents/agent-ui/collapse/index.wxml create mode 100644 src/wxcomponents/agent-ui/collapse/index.wxss create mode 100644 src/wxcomponents/agent-ui/customCard/index.js create mode 100644 src/wxcomponents/agent-ui/customCard/index.json create mode 100644 src/wxcomponents/agent-ui/customCard/index.wxml create mode 100644 src/wxcomponents/agent-ui/customCard/index.wxss create mode 100644 src/wxcomponents/agent-ui/feedback/imgs/star-highlight.svg create mode 100644 src/wxcomponents/agent-ui/feedback/imgs/star.svg create mode 100644 src/wxcomponents/agent-ui/feedback/index.js create mode 100644 src/wxcomponents/agent-ui/feedback/index.json create mode 100644 src/wxcomponents/agent-ui/feedback/index.wxml create mode 100644 src/wxcomponents/agent-ui/feedback/index.wxss create mode 100644 src/wxcomponents/agent-ui/imgs/arrow.svg create mode 100644 src/wxcomponents/agent-ui/imgs/camera.svg create mode 100644 src/wxcomponents/agent-ui/imgs/cancelSaying.svg create mode 100644 src/wxcomponents/agent-ui/imgs/chat-add.svg create mode 100644 src/wxcomponents/agent-ui/imgs/chat-bubble-add.svg create mode 100644 src/wxcomponents/agent-ui/imgs/chat-bubble-history.svg create mode 100644 src/wxcomponents/agent-ui/imgs/check.svg create mode 100644 src/wxcomponents/agent-ui/imgs/clear.svg create mode 100644 src/wxcomponents/agent-ui/imgs/close-filled.png create mode 100644 src/wxcomponents/agent-ui/imgs/close-red.svg create mode 100644 src/wxcomponents/agent-ui/imgs/close.svg create mode 100644 src/wxcomponents/agent-ui/imgs/copy.svg create mode 100644 src/wxcomponents/agent-ui/imgs/edit.svg create mode 100644 src/wxcomponents/agent-ui/imgs/error-circle.svg create mode 100644 src/wxcomponents/agent-ui/imgs/excel.svg create mode 100644 src/wxcomponents/agent-ui/imgs/file.svg create mode 100644 src/wxcomponents/agent-ui/imgs/image.svg create mode 100644 src/wxcomponents/agent-ui/imgs/indent-left.svg create mode 100644 src/wxcomponents/agent-ui/imgs/indent-right.svg create mode 100644 src/wxcomponents/agent-ui/imgs/internet.svg create mode 100644 src/wxcomponents/agent-ui/imgs/internetUse.svg create mode 100644 src/wxcomponents/agent-ui/imgs/keyboard.svg create mode 100644 src/wxcomponents/agent-ui/imgs/loading.svg create mode 100644 src/wxcomponents/agent-ui/imgs/pause.svg create mode 100644 src/wxcomponents/agent-ui/imgs/pdf.svg create mode 100644 src/wxcomponents/agent-ui/imgs/play.svg create mode 100644 src/wxcomponents/agent-ui/imgs/playing.svg create mode 100644 src/wxcomponents/agent-ui/imgs/ppt.svg create mode 100644 src/wxcomponents/agent-ui/imgs/search.svg create mode 100644 src/wxcomponents/agent-ui/imgs/send.svg create mode 100644 src/wxcomponents/agent-ui/imgs/sendSaying.svg create mode 100644 src/wxcomponents/agent-ui/imgs/set.svg create mode 100644 src/wxcomponents/agent-ui/imgs/share.svg create mode 100644 src/wxcomponents/agent-ui/imgs/sound.svg create mode 100644 src/wxcomponents/agent-ui/imgs/stop.svg create mode 100644 src/wxcomponents/agent-ui/imgs/system-sum.svg create mode 100644 src/wxcomponents/agent-ui/imgs/thumb-down.svg create mode 100644 src/wxcomponents/agent-ui/imgs/thumb-up.svg create mode 100644 src/wxcomponents/agent-ui/imgs/toBottom.svg create mode 100644 src/wxcomponents/agent-ui/imgs/uploadImg.svg create mode 100644 src/wxcomponents/agent-ui/imgs/voice.svg create mode 100644 src/wxcomponents/agent-ui/imgs/wechat.svg create mode 100644 src/wxcomponents/agent-ui/imgs/word.svg create mode 100644 src/wxcomponents/agent-ui/index.js create mode 100644 src/wxcomponents/agent-ui/index.json create mode 100644 src/wxcomponents/agent-ui/index.wxml create mode 100644 src/wxcomponents/agent-ui/index.wxss create mode 100644 src/wxcomponents/agent-ui/md5.js create mode 100644 src/wxcomponents/agent-ui/tool/index.js create mode 100644 src/wxcomponents/agent-ui/tool/index.json create mode 100644 src/wxcomponents/agent-ui/tool/index.wxml create mode 100644 src/wxcomponents/agent-ui/tool/index.wxss create mode 100644 src/wxcomponents/agent-ui/tools.js create mode 100644 src/wxcomponents/agent-ui/wd-markdown/copy/index.js create mode 100644 src/wxcomponents/agent-ui/wd-markdown/copy/index.json create mode 100644 src/wxcomponents/agent-ui/wd-markdown/copy/index.wxml create mode 100644 src/wxcomponents/agent-ui/wd-markdown/copy/index.wxss create mode 100644 src/wxcomponents/agent-ui/wd-markdown/index.js create mode 100644 src/wxcomponents/agent-ui/wd-markdown/index.json create mode 100644 src/wxcomponents/agent-ui/wd-markdown/index.wxml create mode 100644 src/wxcomponents/agent-ui/wd-markdown/index.wxss create mode 100644 src/wxcomponents/agent-ui/wd-markdown/mp-html/index.js create mode 100644 src/wxcomponents/agent-ui/wd-markdown/mp-html/index.json create mode 100644 src/wxcomponents/agent-ui/wd-markdown/mp-html/index.wxml create mode 100644 src/wxcomponents/agent-ui/wd-markdown/mp-html/index.wxss create mode 100644 src/wxcomponents/agent-ui/wd-markdown/mp-html/node/node.js create mode 100644 src/wxcomponents/agent-ui/wd-markdown/mp-html/node/node.json create mode 100644 src/wxcomponents/agent-ui/wd-markdown/mp-html/node/node.wxml create mode 100644 src/wxcomponents/agent-ui/wd-markdown/mp-html/node/node.wxss create mode 100644 src/wxcomponents/agent-ui/wd-markdown/mp-html/parser.js create mode 100644 src/wxcomponents/agent-ui/wd-markdown/utils/highlight.min.js create mode 100644 src/wxcomponents/agent-ui/wd-markdown/utils/hljs_css.min.js create mode 100644 src/wxcomponents/agent-ui/wd-markdown/utils/hljs_javascript.min.js create mode 100644 src/wxcomponents/agent-ui/wd-markdown/utils/markdown-it.min.js create mode 100644 src/wxcomponents/agent-ui/wd-markdown/utils/plugin.js diff --git a/pages.config.ts b/pages.config.ts index 64f0422..a064ee9 100644 --- a/pages.config.ts +++ b/pages.config.ts @@ -8,6 +8,10 @@ export default defineUniPages({ navigationBarBackgroundColor: '#FFFFFF', navigationBarTextStyle: 'black', backgroundColor: '#FFFFFF', + // 全局注册 markdown 渲染组件,自定义聊天 UI 使用 + usingComponents: { + 'markdown-preview': '/wxcomponents/agent-ui/wd-markdown/index', + }, }, easycom: { autoscan: true, @@ -23,7 +27,7 @@ export default defineUniPages({ preloadRule: { 'pages/index/index': { network: 'all', - packages: ['chart-sub'], + packages: ['chart-sub', 'pages-ai'], }, }, }) diff --git a/src/pages-ai/ai/index.vue b/src/pages-ai/ai/index.vue index 702243f..4bc9b97 100644 --- a/src/pages-ai/ai/index.vue +++ b/src/pages-ai/ai/index.vue @@ -18,17 +18,13 @@ definePage({ }) const agentConfig = reactive({ ...defaultAgentConfig }) -// 预留:model 模式下使用,当前 bot 模式不读取 - -const _modelConfig = reactive({ ...defaultModelConfig }) +const modelConfig = reactive({ ...defaultModelConfig }) const aiStore = useAiStore() const paging = ref(null) const messages = ref([]) const loading = ref(false) -/** 当前轮回复结束后由 getRecommendQuestions 返回的追问建议 */ -const recommendQuestions = ref([]) // 用于停止流:在新一轮发送时把上一轮的 controller 标记为 cancelled let cancelFlag = false @@ -44,6 +40,15 @@ onLoad(() => { // #endif aiStore.ensureThreadId() + + wx.cloud.extend.AI.bot.getRecommendQuestions({ + data: { + botId: 'agent-wxai-4gl75um61026324f', + msg: '你是谁', + }, + }).then((resp) => { + console.log(resp) + }) }) // z-paging 聊天模式:第一页直接把 store 里的历史灌给它 @@ -66,8 +71,6 @@ async function handleSend(text: string) { } cancelFlag = false loading.value = true - // 新一轮发送时收起上一轮的追问建议 - recommendQuestions.value = [] const userMsg: AiMessage = { id: generateMessageId(), @@ -84,19 +87,21 @@ async function handleSend(text: string) { createdAt: Date.now() + 1, } - // 同时写入 store 与 z-paging 列表 - // 顺序与首屏 queryList 保持一致:在数组中 user 在前、ai 在后 - // z-paging 聊天模式 addChatRecordData 内部会反转 + 前插, - // 最终 totalData = [aiMsg, userMsg, ...历史],下标 0 = 视觉最底 = aiMsg, - // userMsg 显示在 aiMsg 上方,符合"用户问 → AI 答在下方"的正常顺序 + // store 顺序:旧 → 新;z-paging 聊天模式 addChatRecordData 内部会反转 + 前插, + // 最终 totalData = [aiMsg, userMsg, ...历史],下标 0 = 视觉最底,符合"用户问 → AI 答在下方" aiStore.addMessage(userMsg) aiStore.addMessage(aiMsg) paging.value?.addChatRecordData([userMsg, aiMsg]) try { await streamMessage({ + chatMode: agentConfig.chatMode, + // bot 模式参数 botId: agentConfig.botId, threadId: aiStore.ensureThreadId(), + // model 模式参数 + modelProvider: modelConfig.modelProvider, + quickResponseModel: modelConfig.quickResponseModel, // 倒数第二条之前是历史;当前 aiMsg 是占位,不传 history: aiStore.messages.slice(0, -1), prompt: text, @@ -117,10 +122,11 @@ async function handleSend(text: string) { aiStore.updateMessage(aiMsg.id, { pending: false }) - // 一轮对话结束后,请求大模型给追问建议 - if (!cancelFlag) { - void loadRecommendQuestions(text) - } + // 当前 V2 agent 后端不支持 getRecommendQuestions(端点 404),先关掉这一调用。 + // 等切换到 bot-xxx 旧版 agent 或后端补上对应路由再开启。 + // if (!cancelFlag) { + // void loadRecommendQuestions(aiMsg.id, text) + // } } catch (err) { aiStore.updateMessage(aiMsg.id, { @@ -150,23 +156,20 @@ function handleRetry(id: string) { if (failedIdx <= 0) { return } - // 重试:找到这条 ai 消息对应的上一条用户消息 const userMsg = aiStore.messages[failedIdx - 1] if (!userMsg || userMsg.role !== 'user') { return } - // 移除失败的回复后重新发送 aiStore.removeMessage(id) handleSend(userMsg.content) } function handleClickQuestion(question: string) { - recommendQuestions.value = [] handleSend(question) } -async function loadRecommendQuestions(prompt: string) { - // 取最近一对 user / assistant 用作上下文 +/** 请求追问建议,结果挂到对应 AI 消息的 recommendQuestions */ +async function loadRecommendQuestions(aiMsgId: string, prompt: string) { const last = aiStore.messages.slice(-2).map(m => ({ role: m.role === 'user' ? ('user' as const) : ('assistant' as const), content: m.content, @@ -178,27 +181,25 @@ async function loadRecommendQuestions(prompt: string) { prompt, max: 3, onProgress: (qs) => { - recommendQuestions.value = qs + aiStore.updateMessage(aiMsgId, { recommendQuestions: qs }) }, }) - recommendQuestions.value = questions + aiStore.updateMessage(aiMsgId, { recommendQuestions: questions }) } catch (error) { console.error('[recommend]', error) - recommendQuestions.value = [] } } function handleClear() { aiStore.clear() - recommendQuestions.value = [] paging.value?.reload() }