From 9a9f8511142c6de8e7daa239ce6a818ac8c1b795 Mon Sep 17 00:00:00 2001 From: ShineKOT <1917095344@qq.com> Date: Wed, 24 Sep 2025 17:40:43 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DAI=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E8=B0=83=E7=94=A8=E6=B6=88=E6=81=AF=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../markdown-message/markdown-message.scss | 6 ++++ .../markdown-message/markdown-message.tsx | 14 ++++++---- .../chat-messages/chat-messages.tsx | 3 +- .../chat-tool-call-item.scss | 25 +++++++++++++++++ .../chat-tool-call-item.tsx | 9 ++++-- src/controller/ai-chat/ai-chat.controller.ts | 13 +++++---- src/entity/chat-message/chat-message.ts | 28 +++++++++++++++---- 7 files changed, 78 insertions(+), 20 deletions(-) diff --git a/src/components/chat-message-item/markdown-message/markdown-message.scss b/src/components/chat-message-item/markdown-message/markdown-message.scss index 494790b..f11fb0f 100644 --- a/src/components/chat-message-item/markdown-message/markdown-message.scss +++ b/src/components/chat-message-item/markdown-message/markdown-message.scss @@ -104,6 +104,12 @@ color: getCssVar(ai-chat, color); background-color: getCssVar('ai-chat', 'background-color-light'); } + + .#{bem(chat-thought-chain)} { + + .#{bem(chat-tool-call)} { + margin-top: 8px; + } + } } @include b(markdown-message-footer) { padding: 10px 0; diff --git a/src/components/chat-message-item/markdown-message/markdown-message.tsx b/src/components/chat-message-item/markdown-message/markdown-message.tsx index 5653c39..49704ac 100644 --- a/src/components/chat-message-item/markdown-message/markdown-message.tsx +++ b/src/components/chat-message-item/markdown-message/markdown-message.tsx @@ -179,9 +179,11 @@ export const MarkdownMessage = (props: MarkdownMessageProps) => { thoughtChain.value.description = thoughtContent || ''; cherry.value.setMarkdown(answerContent || ''); } else if (message.content.indexOf('') !== -1) { - // 存在工具调用则内容显示为空 - const tempContent = ''; - cherry.value.setMarkdown(tempContent || ''); + // 存在工具调用时将工具调用文本信息清除 + const content = message.content + .replace(/\[^]*?\<\/tool_call\>/gs, '') + .trim(); + cherry.value.setMarkdown(content || ''); } else { cherry.value.setMarkdown(message.content || ''); } @@ -213,8 +215,10 @@ export const MarkdownMessage = (props: MarkdownMessageProps) => { content = answerContent; } } else if (message.content.indexOf('') !== -1) { - // 存在工具调用则内容显示为空 - content = ''; + // 存在工具调用时将工具调用文本信息清除 + content = message.content + .replace(/\[^]*?\<\/tool_call\>/gs, '') + .trim(); } else { content = message.content; } diff --git a/src/components/chat-messages/chat-messages.tsx b/src/components/chat-messages/chat-messages.tsx index 1481ec5..0fd1033 100644 --- a/src/components/chat-messages/chat-messages.tsx +++ b/src/components/chat-messages/chat-messages.tsx @@ -90,8 +90,9 @@ export const ChatMessages = (props: ChatMessageProps) => { controller={props.controller} > diff --git a/src/components/chat-tool-call-item/chat-tool-call-item.scss b/src/components/chat-tool-call-item/chat-tool-call-item.scss index c63eefc..588c95b 100644 --- a/src/components/chat-tool-call-item/chat-tool-call-item.scss +++ b/src/components/chat-tool-call-item/chat-tool-call-item.scss @@ -53,10 +53,35 @@ $chat-tool-call-item: ( } } + @include e(header-left) { + gap: 8px; + min-width: 0; + margin-right: 8px; + @include m(caption) { + flex-shrink: 0; + } + + @include m(desc) { + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + + @include e(header-right) { + flex-shrink: 0; + } + @include e(content) { padding: 8px 0; } + @include e(copy) { + display: flex; + align-items: center; + } + .code-line { display: flex; min-height: 18px; diff --git a/src/components/chat-tool-call-item/chat-tool-call-item.tsx b/src/components/chat-tool-call-item/chat-tool-call-item.tsx index e2992d9..da16e83 100644 --- a/src/components/chat-tool-call-item/chat-tool-call-item.tsx +++ b/src/components/chat-tool-call-item/chat-tool-call-item.tsx @@ -171,7 +171,12 @@ export const ChatToolCallItem = (props: ChatToolCallItemProps) => {
onCollapse()}>
-
{props.item.name}
+
+ {props.item.name} +
+
+ {props.item.parameters.desc} +
{props.item.error && 发生错误} @@ -194,7 +199,7 @@ export const ChatToolCallItem = (props: ChatToolCallItemProps) => { )} - + {isCopying.value ? ( item.messageid === data.messageid, ); if (i !== -1) { - this.messages.value[i] = new ChatMessage(data); + this.messages.value[i].replace(data); this.messages.value = [...this.messages.value]; } else { this.messages.value = [...this.messages.value, new ChatMessage(data)]; @@ -317,7 +318,7 @@ export class AiChatController { if (i !== -1) { const chatMsg = this.messages.value[i]; data.content = chatMsg.content; - this.messages.value[i] = new ChatMessage(data); + this.messages.value[i].replace(data); this.messages.value = [...this.messages.value]; } else { this.messages.value = [...this.messages.value, new ChatMessage(data)]; @@ -388,7 +389,7 @@ export class AiChatController { const messageOrigin = item._origin; if (messageOrigin.suggestions) { messageOrigin.suggestions = undefined; - this.messages.value[index] = new ChatMessage(messageOrigin); + this.messages.value[index].replace(messageOrigin); } }); this.messages.value = [...this.messages.value]; @@ -650,7 +651,7 @@ export class AiChatController { if (suggestions && suggestions.length > 0) { data.suggestions = suggestions; if (i !== -1) { - this.messages.value[i] = new ChatMessage(data); + this.messages.value[i].replace(data); this.messages.value = [...this.messages.value]; } else { this.messages.value = [...this.messages.value, new ChatMessage(data)]; @@ -681,7 +682,7 @@ export class AiChatController { if (i !== -1) { const messageOrigin = this.messages.value[i]._origin; messageOrigin.suggestions = undefined; - this.messages.value[i] = new ChatMessage(messageOrigin); + this.messages.value[i].replace(messageOrigin); this.messages.value = [...this.messages.value]; } // 存储到前端缓存 diff --git a/src/entity/chat-message/chat-message.ts b/src/entity/chat-message/chat-message.ts index 29a7e3d..c3df3ee 100644 --- a/src/entity/chat-message/chat-message.ts +++ b/src/entity/chat-message/chat-message.ts @@ -14,6 +14,14 @@ import { ChatToolCallParser } from '../../utils'; export class ChatMessage implements IChatMessage { toolcalls: IChatMessage['toolcalls'] = []; + /** + * @description 消息的所有原始内容 + * - 用于维护工具调用消息数据 + * @type {string} + * @memberof ChatMessage + */ + allcontent: string = ''; + get messageid(): IChatMessage['messageid'] { return this.msg.messageid; } @@ -78,7 +86,8 @@ export class ChatMessage implements IChatMessage { } constructor(protected msg: IChatMessage) { - this.computeToolCalls(); + this.toolcalls = msg.toolcalls || []; + this.allcontent = msg.content; } /** @@ -89,9 +98,8 @@ export class ChatMessage implements IChatMessage { * @param {IChatMessage} msg */ update(msg: IChatMessage): void { - if (!msg.content) { - msg.content = ''; - } + if (!msg.content) msg.content = ''; + this.allcontent += msg.content; // 接收到新的(思考的开始标识)内容后清除前面的所有内容 if (msg.content.indexOf('') !== -1 && this.msg.content) { this.msg.content = ''; @@ -100,6 +108,15 @@ export class ChatMessage implements IChatMessage { this.computeToolCalls(); } + /** + * @description 替换消息 + * @param {IChatMessage} msg + * @memberof ChatMessage + */ + replace(msg: IChatMessage): void { + this.msg = msg; + } + /** * 更新消息完成状态 * @@ -109,7 +126,6 @@ export class ChatMessage implements IChatMessage { */ updateCompleted(completed: boolean): void { this.msg.completed = completed; - this.computeToolCalls(); } /** @@ -117,6 +133,6 @@ export class ChatMessage implements IChatMessage { * @memberof ChatMessage */ computeToolCalls(): void { - this.toolcalls = ChatToolCallParser.parse(this.msg.content); + this.toolcalls = ChatToolCallParser.parse(this.allcontent); } } -- Gitee From 5be94cad05d7dc69a436d5da64b8b4735d935f36 Mon Sep 17 00:00:00 2001 From: ShineKOT <1917095344@qq.com> Date: Fri, 26 Sep 2025 18:39:48 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20AI=E6=96=B0=E5=A2=9EautoQuestion?= =?UTF-8?q?=E5=92=8CautoFill=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../markdown-message/markdown-message.scss | 3 + .../user-message/user-message.scss | 2 +- src/controller/ai-chat/ai-chat.controller.ts | 68 ++++++++++++------- .../i-chat-options/i-chat-options.ts | 16 +++++ 4 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/components/chat-message-item/markdown-message/markdown-message.scss b/src/components/chat-message-item/markdown-message/markdown-message.scss index f11fb0f..dfecda8 100644 --- a/src/components/chat-message-item/markdown-message/markdown-message.scss +++ b/src/components/chat-message-item/markdown-message/markdown-message.scss @@ -100,10 +100,13 @@ background-color: getCssVar('ai-chat', 'background-color-light'); border-radius: getCssVar('ai-chat', 'border-radius'); + .cherry-markdown.theme__dark ul.cherry-list__default, + .cherry.theme__dark.cherry--no-toolbar, .cherry div.cherry-previewer { color: getCssVar(ai-chat, color); background-color: getCssVar('ai-chat', 'background-color-light'); } + .#{bem(chat-thought-chain)} { + .#{bem(chat-tool-call)} { diff --git a/src/components/chat-message-item/user-message/user-message.scss b/src/components/chat-message-item/user-message/user-message.scss index 5d488b7..43214a8 100644 --- a/src/components/chat-message-item/user-message/user-message.scss +++ b/src/components/chat-message-item/user-message/user-message.scss @@ -78,7 +78,7 @@ background-color: getCssVar(ai-chat, background, color); } - .cherry-previewer { + .cherry div.cherry-previewer { padding: 0; color: getCssVar(ai-chat, color); background-color: getCssVar('ai-chat', 'background-color-light'); diff --git a/src/controller/ai-chat/ai-chat.controller.ts b/src/controller/ai-chat/ai-chat.controller.ts index b16de6c..e2496f6 100644 --- a/src/controller/ai-chat/ai-chat.controller.ts +++ b/src/controller/ai-chat/ai-chat.controller.ts @@ -3,17 +3,17 @@ import { Signal, signal } from '@preact/signals'; import { ChatMaterial, ChatMessage } from '../../entity'; import { + ITopic, + IMaterial, IChatMessage, IChatOptions, IChatSuggestion, - IMaterial, - ITopic, } from '../../interface'; import { - ChatSuggestionParser, createUUID, - generateHashWithText, IndexedDBUtil, + ChatSuggestionParser, + generateHashWithText, MaterialResourceParser, } from '../../utils'; import { TextUtil } from '../../utils/util/util'; @@ -116,17 +116,6 @@ export class AiChatController { */ chatSessionid: string = ''; - /** - * 聊天窗触发提问回调 - * - * @author tony001 - * @date 2025-02-24 14:02:51 - * @param {object} context - * @param {object} params - * @param {object} otherParams - * @param {IChatMessage[]} question 提问历史内容(包含当前提问) - * @return {*} {Promise} 等待回答 - /** * Creates an instance of AiChatController. * @@ -184,16 +173,34 @@ export class AiChatController { appendCurData: this.opts.appendCurData, sessionid: this.chatSessionid, }); - // 存在附加内容,在请求历史记录后,需要附加当前编辑内容作为用户消息 - if (result && this.opts.appendCurContent) { - this.addMessage({ - state: 30, - messageid: createUUID(), - role: 'USER', - type: 'DEFAULT', - content: this.opts.appendCurContent, - completed: true, - }); + if (result) { + // 历史数据最后一个项是user时自动提问 + if (this.opts.autoQuestion !== false) { + const message = this.messages.value[this.messages.value.length - 1]; + if (message.role === 'USER') { + // 提问 + await this.opts.question( + this, + this.context, + this.params, + { appDataEntityId: this.appDataEntityId }, + this.getMessages(), + this.chatSessionid, + ); + if (this.opts.action) + await this.opts.action('question', message.content); + } + } + // 存在附加内容,在请求历史记录后,需要附加当前编辑内容作为用户消息 + if (this.opts.appendCurContent) + this.addMessage({ + state: 30, + messageid: createUUID(), + role: 'USER', + type: 'DEFAULT', + content: this.opts.appendCurContent, + completed: true, + }); } return true; } @@ -302,6 +309,17 @@ export class AiChatController { } }); } + // AI回答完成时自动回填 + const message = + i !== -1 + ? this.messages.value[i] + : this.messages.value[this.messages.value.length - 1]; + if ( + this.opts.autoFill === true && + message.role === 'ASSISTANT' && + message.state === 30 + ) + this.backfill(message); } /** diff --git a/src/interface/i-chat-options/i-chat-options.ts b/src/interface/i-chat-options/i-chat-options.ts index 085325a..f301df1 100644 --- a/src/interface/i-chat-options/i-chat-options.ts +++ b/src/interface/i-chat-options/i-chat-options.ts @@ -48,6 +48,22 @@ export interface IChat { */ appDataEntityId: string; + /** + * @description 自动提问 + * - 历史数据最后一个项是user时是否自动提问,默认开启 + * @type {boolean} + * @memberof IChat + */ + autoQuestion?: boolean; + + /** + * @description 是否自动回填 + * - AI回答完成之后是否触发回填,默认关闭 + * @type {boolean} + * @memberof IChat + */ + autoFill?: boolean; + /** * 传入对象参数(如果外部传入,在请求历史记录,需要附加当前参数) * -- Gitee From 194393a858c8c1249a251979423aef677d7e5c39 Mon Sep 17 00:00:00 2001 From: ShineKOT <1917095344@qq.com> Date: Fri, 26 Sep 2025 19:22:19 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/ai-chat/ai-chat.controller.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/controller/ai-chat/ai-chat.controller.ts b/src/controller/ai-chat/ai-chat.controller.ts index e2496f6..1d6b3e7 100644 --- a/src/controller/ai-chat/ai-chat.controller.ts +++ b/src/controller/ai-chat/ai-chat.controller.ts @@ -310,16 +310,14 @@ export class AiChatController { }); } // AI回答完成时自动回填 - const message = - i !== -1 - ? this.messages.value[i] - : this.messages.value[this.messages.value.length - 1]; - if ( - this.opts.autoFill === true && - message.role === 'ASSISTANT' && - message.state === 30 - ) - this.backfill(message); + if (this.opts.autoFill === true) { + const message = + i !== -1 + ? this.messages.value[i] + : this.messages.value[this.messages.value.length - 1]; + if (message.role === 'ASSISTANT' && message.state === 30) + this.backfill(message); + } } /** -- Gitee