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 494790b9dc202092f4978701599ae1900eec3a63..dfecda8c1524408d9c834c07c00e7e0aa84ab4dc 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,19 @@ 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)} { + 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 5653c39014ab9b706794835cd09f1f585c63525e..49704accafff999fa685538766d8a11b0973e0eb 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-message-item/user-message/user-message.scss b/src/components/chat-message-item/user-message/user-message.scss index 5d488b7587c0a870e5c7f1e1883925b96b7f832a..43214a8b7e05ffa533eb82b0c23d52874fc477f7 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/components/chat-messages/chat-messages.tsx b/src/components/chat-messages/chat-messages.tsx index 1481ec55ab394849e20c9e9904227403b54c01dc..0fd1033f4d6a687a92f5d9895727b8b4af43984f 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 c63eefc10fef57b2e3a7ba97df210e9d2a56af21..588c95b3e93c98246cf2f04d1b357c97d76458cc 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 e2992d9c8166d042c97653fb9f6eeae70e6af937..da16e838f7996712e9206ec69d4da3f74f05c92c 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 ? ( } 等待回答 - /** * Creates an instance of AiChatController. * @@ -172,7 +161,8 @@ export class AiChatController { content: item.content, suggestions: item.suggestions, completed: true, - } as const; + toolcalls: item.toolcalls, + }; this.addMessage(msg); }); return true; @@ -183,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; } @@ -282,7 +290,7 @@ export class AiChatController { item => 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)]; @@ -301,6 +309,15 @@ export class AiChatController { } }); } + // AI回答完成时自动回填 + 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); + } } /** @@ -317,7 +334,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 +405,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 +667,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 +698,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 29a7e3d6968d5d254861af0e196e3b153655fe06..c3df3ee4ae89c19e81608e8dadf613a36a9e34fa 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); } } diff --git a/src/interface/i-chat-options/i-chat-options.ts b/src/interface/i-chat-options/i-chat-options.ts index 085325a658788a5d5957ce9bd27bbda15c58d21c..f301df161eaf5c3ab26cdb6e86ffa50cd967878b 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; + /** * 传入对象参数(如果外部传入,在请求历史记录,需要附加当前参数) *