@siact/sime-x-vue 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sime-x-vue.mjs +85 -12
- package/dist/sime-x-vue.mjs.map +1 -1
- package/dist/sime-x-vue.umd.js +85 -12
- package/dist/sime-x-vue.umd.js.map +1 -1
- package/dist/style.css +109 -109
- package/package.json +1 -1
- package/types/components/voice-assistant.vue.d.ts +5 -1
- package/types/composables/use-tts.d.ts +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sime-x-vue.umd.js","sources":["../src/lib/agent-chat-transport.ts","../src/components/ai-chat.vue","../src/lib/data-stream-parser.ts","../src/composables/use-agent-invoke.ts","../src/composables/use-bubble.ts","../src/injection-key.ts","../src/components/command-test.vue","../src/utils/command-manager.ts","../src/components/sime-provider.vue","../src/composables/use-tts.ts","../src/lib/utils.ts","../src/composables/use-voice-recognition.ts","../src/components/voice-assistant.vue","../src/types.ts"],"sourcesContent":["import type { UIMessage } from 'ai';\r\nimport { DefaultChatTransport } from 'ai';\r\nimport type { DiscoveredCommand } from '../utils/command-types';\r\n\r\nexport interface AgentChatTransportOptions {\r\n /** streamInvoke endpoint URL, e.g. http://host/agent/{id}/stream-invoke */\r\n api: string;\r\n /** 项目 ID */\r\n projectId?: string;\r\n /** 动态获取宿主命令 */\r\n getCommands?: () => Promise<DiscoveredCommand[]>;\r\n /** 额外 headers */\r\n headers?: Record<string, string> | (() => Record<string, string>);\r\n /** 额外 body 字段 */\r\n body?: Record<string, unknown> | (() => Record<string, unknown>);\r\n}\r\n\r\n/**\r\n * 基于 DefaultChatTransport 的自定义 Transport,\r\n * 通过 prepareSendMessagesRequest 将 AI SDK 标准 messages 转换为 streamInvoke 接口格式。\r\n *\r\n * streamInvoke 期望:{ input, projectId, commands, messages }\r\n * - input: 最后一条 user 消息的文本\r\n * - messages: 历史对话(不含最后一条 user 消息)\r\n * - commands: 宿主命令列表\r\n * - projectId: 项目 ID\r\n */\r\nexport function createAgentChatTransport(options: AgentChatTransportOptions) {\r\n const { api, projectId, getCommands, headers: extraHeaders, body: extraBody } = options;\r\n\r\n return new DefaultChatTransport({\r\n api,\r\n headers: extraHeaders,\r\n prepareSendMessagesRequest({ messages }) {\r\n // 提取最后一条 user 消息作为 input\r\n const lastUserMessage = findLastUserMessage(messages);\r\n const input = lastUserMessage\r\n ? lastUserMessage.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('')\r\n : '';\r\n\r\n // 将历史消息转换为 streamInvoke 的简单 messages 格式\r\n const historyMessages = buildHistoryMessages(messages, lastUserMessage?.id);\r\n\r\n const resolvedExtraBody = typeof extraBody === 'function' ? extraBody() : extraBody || {};\r\n\r\n return {\r\n body: {\r\n input,\r\n projectId: projectId || '',\r\n messages: historyMessages.length > 0 ? historyMessages : undefined,\r\n ...resolvedExtraBody,\r\n },\r\n };\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * 带命令注入的 AgentChatTransport 工厂函数\r\n * 在每次发送前异步获取宿主命令并注入 body\r\n */\r\nexport class AgentChatTransport extends DefaultChatTransport<UIMessage> {\r\n private agentOptions: AgentChatTransportOptions;\r\n\r\n constructor(options: AgentChatTransportOptions) {\r\n const { api, headers: extraHeaders, body: extraBody, projectId } = options;\r\n\r\n super({\r\n api,\r\n headers: extraHeaders,\r\n prepareSendMessagesRequest({ messages }) {\r\n const lastUserMessage = findLastUserMessage(messages);\r\n const input = lastUserMessage\r\n ? lastUserMessage.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('')\r\n : '';\r\n\r\n const historyMessages = buildHistoryMessages(messages, lastUserMessage?.id);\r\n\r\n const resolvedExtraBody = typeof extraBody === 'function' ? extraBody() : extraBody || {};\r\n\r\n return {\r\n body: {\r\n input,\r\n projectId: projectId || '',\r\n messages: historyMessages.length > 0 ? historyMessages : undefined,\r\n ...resolvedExtraBody,\r\n },\r\n };\r\n },\r\n });\r\n\r\n this.agentOptions = options;\r\n }\r\n\r\n async sendMessages(options: Parameters<DefaultChatTransport<UIMessage>['sendMessages']>[0]) {\r\n // 如果配置了 getCommands,在发送前获取宿主命令并注入 body\r\n if (this.agentOptions.getCommands) {\r\n try {\r\n const commands = await this.agentOptions.getCommands();\r\n if (commands && commands.length > 0) {\r\n options.body = {\r\n ...((options.body as Record<string, unknown>) || {}),\r\n commands,\r\n };\r\n }\r\n } catch {\r\n // 获取命令失败,静默忽略\r\n }\r\n }\r\n\r\n return super.sendMessages(options);\r\n }\r\n}\r\n\r\n// ── 辅助函数 ──\r\n\r\nfunction findLastUserMessage(messages: UIMessage[]): UIMessage | undefined {\r\n for (let i = messages.length - 1; i >= 0; i--) {\r\n if (messages[i].role === 'user') {\r\n return messages[i];\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction buildHistoryMessages(\r\n messages: UIMessage[],\r\n excludeId?: string,\r\n): Array<{ role: 'user' | 'assistant'; content: string }> {\r\n const history: Array<{ role: 'user' | 'assistant'; content: string }> = [];\r\n\r\n for (const msg of messages) {\r\n if (msg.id === excludeId) continue;\r\n if (msg.role !== 'user' && msg.role !== 'assistant') continue;\r\n\r\n const textContent = msg.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('');\r\n\r\n if (textContent.trim()) {\r\n history.push({\r\n role: msg.role as 'user' | 'assistant',\r\n content: textContent,\r\n });\r\n }\r\n }\r\n\r\n return history;\r\n}\r\n","<template>\r\n <div class=\"ai-chat\" :class=\"{ 'ai-chat--full-width': fullWidth }\">\r\n <!-- 空消息:欢迎页 -->\r\n <div v-if=\"isEmpty\" class=\"ai-chat__welcome\">\r\n <div class=\"ai-chat__welcome-header\">\r\n <h1 class=\"ai-chat__welcome-title\">{{ welcomeTitle }}</h1>\r\n <p class=\"ai-chat__welcome-desc\">{{ welcomeDescription }}</p>\r\n </div>\r\n\r\n <div class=\"ai-chat__input-area\">\r\n <form class=\"ai-chat__form\" @submit.prevent=\"handleSubmit\">\r\n <div class=\"ai-chat__input-wrapper\">\r\n <textarea\r\n ref=\"textareaRef\"\r\n v-model=\"inputText\"\r\n class=\"ai-chat__textarea\"\r\n placeholder=\"发送消息...\"\r\n rows=\"1\"\r\n @keydown=\"handleKeydown\"\r\n @input=\"autoResize\"\r\n />\r\n <button\r\n type=\"submit\"\r\n class=\"ai-chat__send-btn\"\r\n :disabled=\"!inputText.trim() || isLoading\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </form>\r\n\r\n <div v-if=\"suggestions.length > 0\" class=\"ai-chat__suggestions\">\r\n <button\r\n v-for=\"suggestion in suggestions\"\r\n :key=\"suggestion\"\r\n class=\"ai-chat__suggestion\"\r\n @click=\"handleSuggestionClick(suggestion)\"\r\n >\r\n {{ suggestion }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- 消息列表 -->\r\n <template v-else>\r\n <div ref=\"messagesContainerRef\" class=\"ai-chat__messages\" @scroll=\"handleScroll\">\r\n <div class=\"ai-chat__messages-inner\">\r\n <div\r\n v-for=\"message in chat.messages\"\r\n :key=\"message.id\"\r\n class=\"ai-chat__message-group\"\r\n >\r\n <template v-for=\"(part, partIndex) in message.parts\" :key=\"`${message.id}-${partIndex}`\">\r\n <!-- 文本消息 -->\r\n <div v-if=\"part.type === 'text'\" class=\"ai-chat__message\" :class=\"`ai-chat__message--${message.role}`\">\r\n <div class=\"ai-chat__message-content\">\r\n <div class=\"ai-chat__message-text\" v-html=\"renderMarkdown(part.text)\" />\r\n </div>\r\n </div>\r\n\r\n <!-- 推理/思考过程 -->\r\n <div v-else-if=\"part.type === 'reasoning'\" class=\"ai-chat__reasoning\">\r\n <button class=\"ai-chat__reasoning-trigger\" @click=\"toggleReasoning(message.id)\">\r\n <svg\r\n class=\"ai-chat__reasoning-icon\"\r\n :class=\"{ 'ai-chat__reasoning-icon--open': reasoningOpen[message.id] }\"\r\n width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n >\r\n <polyline points=\"9 18 15 12 9 6\" />\r\n </svg>\r\n <span>思考过程</span>\r\n <span\r\n v-if=\"isStreamingMessage(message.id) && partIndex === message.parts.length - 1\"\r\n class=\"ai-chat__reasoning-streaming\"\r\n />\r\n </button>\r\n <div v-if=\"reasoningOpen[message.id]\" class=\"ai-chat__reasoning-content\">\r\n {{ part.text }}\r\n </div>\r\n </div>\r\n\r\n <!-- 工具调用/结果 -->\r\n <div v-else-if=\"isToolPart(part)\" class=\"ai-chat__tool\">\r\n <div\r\n class=\"ai-chat__tool-step\"\r\n :class=\"{\r\n 'ai-chat__tool-step--loading': isToolLoading(part),\r\n 'ai-chat__tool-step--done': isToolDone(part),\r\n 'ai-chat__tool-step--error': isToolError(part),\r\n }\"\r\n >\r\n <!-- 状态图标 -->\r\n <span class=\"ai-chat__tool-icon\">\r\n <svg v-if=\"isToolLoading(part)\" class=\"ai-chat__tool-spinner\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-dasharray=\"31.4 31.4\" />\r\n </svg>\r\n <svg v-else-if=\"isToolDone(part)\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M20 6L9 17l-5-5\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <svg v-else-if=\"isToolError(part)\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <path d=\"M15 9l-6 6M9 9l6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n </span>\r\n <span class=\"ai-chat__tool-name\">{{ getToolDisplayName(getToolName(part)) }}</span>\r\n </div>\r\n </div>\r\n </template>\r\n\r\n <!-- 助手消息操作(非流式时显示) -->\r\n <div\r\n v-if=\"message.role === 'assistant' && !isStreamingMessage(message.id)\"\r\n class=\"ai-chat__message-actions\"\r\n >\r\n <button class=\"ai-chat__action-btn\" title=\"重新生成\" @click=\"handleRegenerate(message.id)\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"23 4 23 10 17 10\" /><polyline points=\"1 20 1 14 7 14\" />\r\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\" />\r\n </svg>\r\n </button>\r\n <button class=\"ai-chat__action-btn\" title=\"复制\" @click=\"handleCopy(message)\">\r\n <svg v-if=\"!copiedId || copiedId !== message.id\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" /><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\r\n </svg>\r\n <svg v-else width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- 流式加载指示器 -->\r\n <div v-if=\"chat.status === 'submitted'\" class=\"ai-chat__thinking\">\r\n <div class=\"ai-chat__thinking-dots\">\r\n <span /><span /><span />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- 滚动到底部按钮 -->\r\n <transition name=\"fade\">\r\n <button\r\n v-if=\"showScrollButton\"\r\n class=\"ai-chat__scroll-btn\"\r\n @click=\"scrollToBottom\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\" />\r\n </svg>\r\n </button>\r\n </transition>\r\n\r\n <!-- 输入区域 -->\r\n <div v-if=\"!isReadonly\" class=\"ai-chat__input-area ai-chat__input-area--bottom\">\r\n <form class=\"ai-chat__form\" @submit.prevent=\"handleSubmit\">\r\n <div class=\"ai-chat__input-wrapper\">\r\n <textarea\r\n ref=\"textareaRef\"\r\n v-model=\"inputText\"\r\n class=\"ai-chat__textarea\"\r\n placeholder=\"发送消息...\"\r\n rows=\"1\"\r\n @keydown=\"handleKeydown\"\r\n @input=\"autoResize\"\r\n />\r\n <button\r\n v-if=\"chat.status === 'streaming' || chat.status === 'submitted'\"\r\n type=\"button\"\r\n class=\"ai-chat__stop-btn\"\r\n @click=\"handleStop\"\r\n >\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" />\r\n </svg>\r\n </button>\r\n <button\r\n v-else\r\n type=\"submit\"\r\n class=\"ai-chat__send-btn\"\r\n :disabled=\"!inputText.trim()\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n </template>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { ref, computed, watch, nextTick, onMounted, reactive } from 'vue';\r\nimport { Chat } from '@ai-sdk/vue';\r\nimport type { UIMessage } from 'ai';\r\nimport { AgentChatTransport } from '../lib/agent-chat-transport';\r\nimport type { AgentChatTransportOptions } from '../lib/agent-chat-transport';\r\n\r\n// ── 工具名称映射 ──\r\nconst toolDisplayNames: Record<string, string> = {\r\n generateReport: '生成报告',\r\n searchKnowledge: '知识库检索',\r\n resolveInstanceTargets: '解析实例目标',\r\n getHistoryMetrics: '历史数据查询',\r\n getRealtimeMetrics: '实时数据查询',\r\n queryBitableData: '多维表格查询',\r\n searchUser: '搜索用户',\r\n createBitableRecord: '创建表格记录',\r\n timeTool: '时间工具',\r\n loadSkill: '加载技能',\r\n executeCommand: '执行命令',\r\n dataAnalyzer: '数据分析',\r\n dataPredictor: '数据预测',\r\n};\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** streamInvoke endpoint URL */\r\n api: string;\r\n /** 项目 ID */\r\n projectId?: string;\r\n /** 是否只读 */\r\n isReadonly?: boolean;\r\n /** 欢迎标题 */\r\n welcomeTitle?: string;\r\n /** 欢迎描述 */\r\n welcomeDescription?: string;\r\n /** 快捷建议 */\r\n suggestions?: string[];\r\n /** 是否全宽 */\r\n fullWidth?: boolean;\r\n /** 自定义工具名称映射 */\r\n toolNames?: Record<string, string>;\r\n /** 额外 transport 配置 */\r\n transportOptions?: Partial<AgentChatTransportOptions>;\r\n /** 额外 headers */\r\n headers?: Record<string, string>;\r\n /** 额外 body */\r\n body?: Record<string, unknown>;\r\n }>(),\r\n {\r\n isReadonly: false,\r\n welcomeTitle: '你好,有什么可以帮助你的吗?',\r\n welcomeDescription: '我可以帮你回答问题、分析数据、生成报告等。',\r\n suggestions: () => [],\r\n fullWidth: false,\r\n toolNames: () => ({}),\r\n },\r\n);\r\n\r\nconst emit = defineEmits<{\r\n (e: 'error', error: Error): void;\r\n (e: 'finish', message: UIMessage): void;\r\n}>();\r\n\r\n// ── Chat 实例 ──\r\nconst transport = new AgentChatTransport({\r\n api: props.api,\r\n projectId: props.projectId,\r\n headers: props.headers,\r\n body: props.body,\r\n ...props.transportOptions,\r\n});\r\n\r\nconst chat = new Chat({\r\n transport,\r\n onError: (error) => {\r\n console.error('[AiChat] error:', error);\r\n emit('error', error instanceof Error ? error : new Error(String(error)));\r\n },\r\n onFinish: ({ message }) => {\r\n emit('finish', message);\r\n },\r\n});\r\n\r\n// ── 输入状态 ──\r\nconst inputText = ref('');\r\nconst textareaRef = ref<HTMLTextAreaElement | null>(null);\r\nconst messagesContainerRef = ref<HTMLElement | null>(null);\r\nconst showScrollButton = ref(false);\r\nconst copiedId = ref<string | null>(null);\r\nconst reasoningOpen = reactive<Record<string, boolean>>({});\r\n\r\nconst isEmpty = computed(() => chat.messages.length === 0);\r\nconst isLoading = computed(() => chat.status === 'streaming' || chat.status === 'submitted');\r\n\r\n// ── 自动滚动 ──\r\nconst scrollToBottom = () => {\r\n nextTick(() => {\r\n const el = messagesContainerRef.value;\r\n if (el) {\r\n el.scrollTop = el.scrollHeight;\r\n }\r\n });\r\n};\r\n\r\nconst handleScroll = () => {\r\n const el = messagesContainerRef.value;\r\n if (!el) return;\r\n const threshold = 100;\r\n showScrollButton.value = el.scrollHeight - el.scrollTop - el.clientHeight > threshold;\r\n};\r\n\r\n// 消息变化时自动滚动\r\nwatch(\r\n () => chat.messages.length,\r\n () => {\r\n if (!showScrollButton.value) {\r\n scrollToBottom();\r\n }\r\n },\r\n);\r\n\r\n// 流式输出时自动滚动\r\nwatch(\r\n () => {\r\n const msgs = chat.messages;\r\n if (msgs.length === 0) return '';\r\n const last = msgs[msgs.length - 1];\r\n return last.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('');\r\n },\r\n () => {\r\n if (!showScrollButton.value) {\r\n scrollToBottom();\r\n }\r\n },\r\n);\r\n\r\n// ── 输入处理 ──\r\nconst autoResize = () => {\r\n const el = textareaRef.value;\r\n if (!el) return;\r\n el.style.height = 'auto';\r\n el.style.height = `${Math.min(el.scrollHeight, 200)}px`;\r\n};\r\n\r\nconst handleKeydown = (e: KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSubmit();\r\n }\r\n};\r\n\r\nconst handleSubmit = () => {\r\n const text = inputText.value.trim();\r\n if (!text || isLoading.value) return;\r\n\r\n chat.sendMessage({ text });\r\n inputText.value = '';\r\n\r\n nextTick(() => {\r\n if (textareaRef.value) {\r\n textareaRef.value.style.height = 'auto';\r\n }\r\n });\r\n};\r\n\r\nconst handleSuggestionClick = (suggestion: string) => {\r\n chat.sendMessage({ text: suggestion });\r\n};\r\n\r\nconst handleStop = () => {\r\n chat.stop();\r\n};\r\n\r\n// ── 重新生成 ──\r\nconst handleRegenerate = (assistantMessageId: string) => {\r\n const msgs = chat.messages;\r\n const index = msgs.findIndex((m: UIMessage) => m.id === assistantMessageId);\r\n if (index <= 0) return;\r\n\r\n // 找到前一条 user 消息\r\n let userMsg: UIMessage | null = null;\r\n for (let i = index - 1; i >= 0; i--) {\r\n if (msgs[i].role === 'user') {\r\n userMsg = msgs[i];\r\n break;\r\n }\r\n }\r\n if (!userMsg) return;\r\n\r\n const userText = userMsg.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('');\r\n\r\n // 截断消息到 user 消息之前,然后重新发送\r\n chat.messages = msgs.slice(0, msgs.indexOf(userMsg));\r\n\r\n nextTick(() => {\r\n chat.sendMessage({ text: userText });\r\n });\r\n};\r\n\r\n// ── 复制 ──\r\nconst handleCopy = async (message: UIMessage) => {\r\n const text = message.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('');\r\n\r\n try {\r\n await navigator.clipboard.writeText(text);\r\n copiedId.value = message.id;\r\n setTimeout(() => {\r\n copiedId.value = null;\r\n }, 2000);\r\n } catch {\r\n console.error('Failed to copy');\r\n }\r\n};\r\n\r\n// ── 工具状态判断 ──\r\nconst isToolPart = (part: any): boolean => {\r\n return typeof part.type === 'string' && part.type.startsWith('tool-');\r\n};\r\n\r\nconst isToolLoading = (part: any): boolean => {\r\n return part.state === 'partial-call' || part.state === 'call' ||\r\n part.state === 'input-streaming' || part.state === 'input-available';\r\n};\r\n\r\nconst isToolDone = (part: any): boolean => {\r\n return part.state === 'result' || part.state === 'output-available';\r\n};\r\n\r\nconst isToolError = (part: any): boolean => {\r\n return part.state === 'error' || part.state === 'output-error';\r\n};\r\n\r\nconst getToolName = (part: any): string => {\r\n return part.toolName || part.type?.replace('tool-', '') || 'unknown';\r\n};\r\n\r\nconst getToolDisplayName = (name: string): string => {\r\n return props.toolNames?.[name] || toolDisplayNames[name] || name;\r\n};\r\n\r\n// ── 流式判断 ──\r\nconst isStreamingMessage = (messageId: string): boolean => {\r\n if (chat.status !== 'streaming' && chat.status !== 'submitted') return false;\r\n const msgs = chat.messages;\r\n return msgs.length > 0 && msgs[msgs.length - 1].id === messageId;\r\n};\r\n\r\n// ── 推理折叠 ──\r\nconst toggleReasoning = (messageId: string) => {\r\n reasoningOpen[messageId] = !reasoningOpen[messageId];\r\n};\r\n\r\n// ── Markdown 简单渲染 ──\r\nconst renderMarkdown = (text: string): string => {\r\n if (!text) return '';\r\n return text\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')\r\n .replace(/\\*(.*?)\\*/g, '<em>$1</em>')\r\n .replace(/`([^`]+)`/g, '<code>$1</code>')\r\n .replace(/```(\\w*)\\n([\\s\\S]*?)```/g, '<pre><code class=\"language-$1\">$2</code></pre>')\r\n .replace(/\\n/g, '<br/>');\r\n};\r\n\r\n// ── 初始化 ──\r\nonMounted(() => {\r\n autoResize();\r\n});\r\n\r\n// ── 暴露 chat 实例给父组件 ──\r\ndefineExpose({\r\n chat,\r\n sendMessage: (text: string) => chat.sendMessage({ text }),\r\n clearMessages: () => { chat.messages = []; },\r\n stop: () => chat.stop(),\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.ai-chat {\r\n --chat-bg: #ffffff;\r\n --chat-text: #1a1a1a;\r\n --chat-text-secondary: #6b7280;\r\n --chat-border: #e5e7eb;\r\n --chat-user-bg: #f3f4f6;\r\n --chat-assistant-bg: transparent;\r\n --chat-input-bg: #f9fafb;\r\n --chat-input-border: #d1d5db;\r\n --chat-input-focus: #3b82f6;\r\n --chat-btn-bg: #3b82f6;\r\n --chat-btn-text: #ffffff;\r\n --chat-suggestion-bg: #f3f4f6;\r\n --chat-suggestion-hover: #e5e7eb;\r\n --chat-tool-accent: #6366f1;\r\n --chat-tool-success: #10b981;\r\n --chat-tool-error: #ef4444;\r\n --chat-code-bg: #f3f4f6;\r\n --chat-scroll-btn-bg: #ffffff;\r\n\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n min-width: 0;\r\n overflow: hidden;\r\n background: var(--chat-bg);\r\n color: var(--chat-text);\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n font-size: 14px;\r\n line-height: 1.6;\r\n position: relative;\r\n}\r\n\r\n// ── 欢迎页 ──\r\n.ai-chat__welcome {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n flex: 1;\r\n padding: 24px;\r\n overflow-y: auto;\r\n}\r\n\r\n.ai-chat__welcome-header {\r\n text-align: center;\r\n margin-bottom: 32px;\r\n}\r\n\r\n.ai-chat__welcome-title {\r\n font-size: 24px;\r\n font-weight: 700;\r\n margin: 0 0 8px;\r\n}\r\n\r\n.ai-chat__welcome-desc {\r\n color: var(--chat-text-secondary);\r\n margin: 0;\r\n max-width: 480px;\r\n}\r\n\r\n// ── 消息区域 ──\r\n.ai-chat__messages {\r\n flex: 1;\r\n overflow-y: auto;\r\n scroll-behavior: smooth;\r\n\r\n &::-webkit-scrollbar {\r\n width: 6px;\r\n }\r\n &::-webkit-scrollbar-thumb {\r\n background: rgba(0, 0, 0, 0.15);\r\n border-radius: 3px;\r\n }\r\n}\r\n\r\n.ai-chat__messages-inner {\r\n max-width: 768px;\r\n margin: 0 auto;\r\n padding: 16px 16px 8px;\r\n\r\n .ai-chat--full-width & {\r\n max-width: 100%;\r\n padding: 16px 48px 8px;\r\n }\r\n}\r\n\r\n// ── 消息 ──\r\n.ai-chat__message-group {\r\n margin-bottom: 16px;\r\n}\r\n\r\n.ai-chat__message {\r\n display: flex;\r\n margin-bottom: 4px;\r\n\r\n &--user {\r\n justify-content: flex-end;\r\n\r\n .ai-chat__message-content {\r\n background: var(--chat-user-bg);\r\n border-radius: 16px 16px 4px 16px;\r\n max-width: 85%;\r\n }\r\n }\r\n\r\n &--assistant {\r\n justify-content: flex-start;\r\n\r\n .ai-chat__message-content {\r\n background: var(--chat-assistant-bg);\r\n max-width: 100%;\r\n }\r\n }\r\n}\r\n\r\n.ai-chat__message-content {\r\n padding: 10px 14px;\r\n border-radius: 16px;\r\n word-break: break-word;\r\n}\r\n\r\n.ai-chat__message-text {\r\n :deep(code) {\r\n background: var(--chat-code-bg);\r\n padding: 1px 4px;\r\n border-radius: 3px;\r\n font-size: 13px;\r\n font-family: 'SF Mono', Monaco, Consolas, monospace;\r\n }\r\n\r\n :deep(pre) {\r\n background: var(--chat-code-bg);\r\n padding: 12px;\r\n border-radius: 8px;\r\n overflow-x: auto;\r\n margin: 8px 0;\r\n\r\n code {\r\n background: transparent;\r\n padding: 0;\r\n }\r\n }\r\n\r\n :deep(strong) {\r\n font-weight: 600;\r\n }\r\n}\r\n\r\n// ── 推理/思考 ──\r\n.ai-chat__reasoning {\r\n margin: 4px 0;\r\n}\r\n\r\n.ai-chat__reasoning-trigger {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n background: none;\r\n border: none;\r\n color: var(--chat-text-secondary);\r\n font-size: 12px;\r\n cursor: pointer;\r\n padding: 4px 8px;\r\n border-radius: 6px;\r\n transition: background 0.15s;\r\n\r\n &:hover {\r\n background: var(--chat-suggestion-bg);\r\n }\r\n}\r\n\r\n.ai-chat__reasoning-icon {\r\n transition: transform 0.2s;\r\n &--open {\r\n transform: rotate(90deg);\r\n }\r\n}\r\n\r\n.ai-chat__reasoning-streaming {\r\n width: 6px;\r\n height: 6px;\r\n border-radius: 50%;\r\n background: var(--chat-tool-accent);\r\n animation: pulse 1s infinite;\r\n}\r\n\r\n.ai-chat__reasoning-content {\r\n margin: 4px 0 4px 20px;\r\n padding: 8px 12px;\r\n border-left: 2px solid var(--chat-border);\r\n color: var(--chat-text-secondary);\r\n font-size: 13px;\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n// ── 工具 ──\r\n.ai-chat__tool {\r\n margin: 2px 0;\r\n}\r\n\r\n.ai-chat__tool-step {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n padding: 4px 10px;\r\n border-radius: 8px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n animation: slide-in 0.25s ease;\r\n\r\n &--loading {\r\n .ai-chat__tool-icon { color: var(--chat-tool-accent); }\r\n .ai-chat__tool-name { color: var(--chat-text-secondary); }\r\n }\r\n\r\n &--done {\r\n .ai-chat__tool-icon { color: var(--chat-tool-success); }\r\n .ai-chat__tool-name { color: var(--chat-text-secondary); opacity: 0.7; }\r\n }\r\n\r\n &--error {\r\n .ai-chat__tool-icon { color: var(--chat-tool-error); }\r\n .ai-chat__tool-name { color: var(--chat-tool-error); }\r\n }\r\n}\r\n\r\n.ai-chat__tool-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 18px;\r\n height: 18px;\r\n flex-shrink: 0;\r\n}\r\n\r\n.ai-chat__tool-spinner {\r\n animation: spin 0.8s linear infinite;\r\n}\r\n\r\n.ai-chat__tool-name {\r\n white-space: nowrap;\r\n}\r\n\r\n// ── 消息操作 ──\r\n.ai-chat__message-actions {\r\n display: flex;\r\n gap: 4px;\r\n margin-top: 4px;\r\n opacity: 0;\r\n transition: opacity 0.2s;\r\n\r\n .ai-chat__message-group:hover & {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n.ai-chat__action-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 28px;\r\n height: 28px;\r\n border-radius: 6px;\r\n border: 1px solid var(--chat-border);\r\n background: var(--chat-bg);\r\n color: var(--chat-text-secondary);\r\n cursor: pointer;\r\n transition: all 0.15s;\r\n\r\n &:hover {\r\n background: var(--chat-suggestion-bg);\r\n color: var(--chat-text);\r\n }\r\n}\r\n\r\n// ── 思考中 ──\r\n.ai-chat__thinking {\r\n padding: 8px 0;\r\n}\r\n\r\n.ai-chat__thinking-dots {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n\r\n span {\r\n width: 6px;\r\n height: 6px;\r\n border-radius: 50%;\r\n background: var(--chat-text-secondary);\r\n animation: thinking-bounce 1s infinite ease-in-out;\r\n\r\n &:nth-child(2) { animation-delay: 0.15s; }\r\n &:nth-child(3) { animation-delay: 0.3s; }\r\n }\r\n}\r\n\r\n// ── 滚动按钮 ──\r\n.ai-chat__scroll-btn {\r\n position: absolute;\r\n bottom: 80px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n width: 36px;\r\n height: 36px;\r\n border-radius: 50%;\r\n border: 1px solid var(--chat-border);\r\n background: var(--chat-scroll-btn-bg);\r\n color: var(--chat-text-secondary);\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\r\n transition: all 0.15s;\r\n z-index: 10;\r\n\r\n &:hover {\r\n background: var(--chat-suggestion-bg);\r\n color: var(--chat-text);\r\n }\r\n}\r\n\r\n// ── 输入区域 ──\r\n.ai-chat__input-area {\r\n width: 100%;\r\n max-width: 768px;\r\n margin: 0 auto;\r\n padding: 0 16px;\r\n\r\n .ai-chat--full-width & {\r\n max-width: 100%;\r\n padding: 0 48px;\r\n }\r\n\r\n &--bottom {\r\n padding-bottom: 16px;\r\n flex-shrink: 0;\r\n }\r\n}\r\n\r\n.ai-chat__form {\r\n width: 100%;\r\n}\r\n\r\n.ai-chat__input-wrapper {\r\n display: flex;\r\n align-items: flex-end;\r\n gap: 8px;\r\n border: 1px solid var(--chat-input-border);\r\n border-radius: 12px;\r\n padding: 8px 12px;\r\n background: var(--chat-input-bg);\r\n transition: border-color 0.2s, box-shadow 0.2s;\r\n\r\n &:focus-within {\r\n border-color: var(--chat-input-focus);\r\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);\r\n }\r\n}\r\n\r\n.ai-chat__textarea {\r\n flex: 1;\r\n border: none;\r\n outline: none;\r\n resize: none;\r\n background: transparent;\r\n color: var(--chat-text);\r\n font-size: 14px;\r\n line-height: 1.5;\r\n font-family: inherit;\r\n min-height: 24px;\r\n max-height: 200px;\r\n\r\n &::placeholder {\r\n color: var(--chat-text-secondary);\r\n }\r\n}\r\n\r\n.ai-chat__send-btn,\r\n.ai-chat__stop-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 8px;\r\n border: none;\r\n cursor: pointer;\r\n flex-shrink: 0;\r\n transition: all 0.15s;\r\n}\r\n\r\n.ai-chat__send-btn {\r\n background: var(--chat-btn-bg);\r\n color: var(--chat-btn-text);\r\n\r\n &:hover:not(:disabled) {\r\n opacity: 0.9;\r\n }\r\n\r\n &:disabled {\r\n opacity: 0.4;\r\n cursor: not-allowed;\r\n }\r\n}\r\n\r\n.ai-chat__stop-btn {\r\n background: var(--chat-tool-error);\r\n color: white;\r\n\r\n &:hover {\r\n opacity: 0.9;\r\n }\r\n}\r\n\r\n// ── 建议 ──\r\n.ai-chat__suggestions {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n margin-top: 12px;\r\n}\r\n\r\n.ai-chat__suggestion {\r\n padding: 8px 14px;\r\n border-radius: 12px;\r\n border: 1px solid var(--chat-border);\r\n background: var(--chat-suggestion-bg);\r\n color: var(--chat-text);\r\n font-size: 13px;\r\n cursor: pointer;\r\n transition: all 0.15s;\r\n text-align: left;\r\n line-height: 1.4;\r\n\r\n &:hover {\r\n background: var(--chat-suggestion-hover);\r\n border-color: var(--chat-input-border);\r\n }\r\n}\r\n\r\n// ── 动画 ──\r\n@keyframes spin {\r\n from { transform: rotate(0deg); }\r\n to { transform: rotate(360deg); }\r\n}\r\n\r\n@keyframes pulse {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.4; }\r\n}\r\n\r\n@keyframes thinking-bounce {\r\n 0%, 100% { transform: translateY(0); opacity: 0.3; }\r\n 50% { transform: translateY(-3px); opacity: 1; }\r\n}\r\n\r\n@keyframes slide-in {\r\n from { opacity: 0; transform: translateX(-6px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n\r\n.fade-enter-active,\r\n.fade-leave-active {\r\n transition: opacity 0.2s;\r\n}\r\n.fade-enter-from,\r\n.fade-leave-to {\r\n opacity: 0;\r\n}\r\n</style>\r\n","/**\r\n * AI SDK Stream Protocol Parser for Vue\r\n *\r\n * Handles THREE possible response formats from the agent/chat service:\r\n *\r\n * Format A – UI Message Stream Protocol (pipeUIMessageStreamToResponse) ★ PRIMARY\r\n * SSE format with JSON objects containing a \"type\" field:\r\n * data: {\"type\":\"start\",\"messageId\":\"...\"}\r\n * data: {\"type\":\"text-delta\",\"id\":\"...\",\"delta\":\"Hello\"}\r\n * data: {\"type\":\"tool-input-start\",\"toolCallId\":\"...\",\"toolName\":\"...\"}\r\n * data: {\"type\":\"tool-input-delta\",\"toolCallId\":\"...\",\"inputTextDelta\":\"...\"}\r\n * data: {\"type\":\"tool-input-available\",\"toolCallId\":\"...\",\"toolName\":\"...\",\"input\":{...}}\r\n * data: {\"type\":\"tool-output-available\",\"toolCallId\":\"...\",\"output\":{...}}\r\n * data: {\"type\":\"finish-step\"}\r\n * data: {\"type\":\"finish\"}\r\n * data: [DONE]\r\n *\r\n * Format B – Legacy Data Stream Protocol (pipeDataStreamToResponse)\r\n * Each line: CODE:JSON_VALUE\\n\r\n * 0:\"text\" 9:{toolCallId,toolName} c:{toolCallId,toolName,args} a:{toolCallId,result}\r\n *\r\n * Format C – Plain text stream (pipeTextStreamToResponse fallback)\r\n * Raw UTF-8 text chunks with no protocol framing.\r\n *\r\n * The parser auto-detects the format from the first chunk.\r\n */\r\n\r\n// ── Part types (mirrors AI SDK UIMessage.parts) ──────────────────────\r\n\r\nexport type ToolState =\r\n | 'partial-call' // streaming tool call args\r\n | 'call' // tool call complete, waiting for result\r\n | 'result' // tool result received\r\n | 'error'; // tool call errored\r\n\r\nexport interface TextPart {\r\n type: 'text';\r\n text: string;\r\n}\r\n\r\nexport interface ToolCallPart {\r\n type: 'tool-call';\r\n toolCallId: string;\r\n toolName: string;\r\n args: any;\r\n state: ToolState;\r\n}\r\n\r\nexport interface ToolResultPart {\r\n type: 'tool-result';\r\n toolCallId: string;\r\n toolName: string;\r\n args: any;\r\n result: any;\r\n state: ToolState;\r\n}\r\n\r\nexport type MessagePart = TextPart | ToolCallPart | ToolResultPart;\r\n\r\nexport interface StreamMessage {\r\n id: string;\r\n role: 'user' | 'assistant';\r\n parts: MessagePart[];\r\n createdAt: number;\r\n}\r\n\r\n// ── Internal tracking for tool calls ─────────────────────────────────\r\n\r\ninterface ToolCallTracker {\r\n toolCallId: string;\r\n toolName: string;\r\n argsText: string;\r\n args: any;\r\n result?: any;\r\n state: ToolState;\r\n}\r\n\r\n// ── Stream event types ───────────────────────────────────────────────\r\n\r\nexport type StreamEventType =\r\n | 'text-delta'\r\n | 'tool-call-start'\r\n | 'tool-call-delta'\r\n | 'tool-call-complete'\r\n | 'tool-result'\r\n | 'step-finish'\r\n | 'finish'\r\n | 'error';\r\n\r\nexport interface StreamEvent {\r\n type: StreamEventType;\r\n data: any;\r\n}\r\n\r\n// ── Parser callbacks ─────────────────────────────────────────────────\r\n\r\nexport interface DataStreamCallbacks {\r\n onTextDelta?: (text: string) => void;\r\n onToolCallStart?: (toolCallId: string, toolName: string) => void;\r\n onToolCallDelta?: (toolCallId: string, argsTextDelta: string) => void;\r\n onToolCallComplete?: (toolCallId: string, toolName: string, args: any) => void;\r\n onToolResult?: (toolCallId: string, result: any) => void;\r\n onStepFinish?: (data: any) => void;\r\n onFinish?: (data: any) => void;\r\n onError?: (error: string, data?: any) => void;\r\n}\r\n\r\n// ── Format detection ─────────────────────────────────────────────────\r\n\r\ntype StreamFormat = 'ui-message-stream' | 'data-stream' | 'plain-text';\r\n\r\nconst DATA_STREAM_LINE_RE = /^[0-9a-f]:/;\r\n\r\nfunction detectFormat(firstChunk: string): StreamFormat {\r\n const trimmed = firstChunk.trimStart();\r\n\r\n // UI Message Stream (SSE with JSON type objects) — this is the primary format\r\n // from pipeUIMessageStreamToResponse\r\n if (trimmed.startsWith('data:')) {\r\n // Try to parse the first data line to check if it's UI Message Stream\r\n const firstLine = trimmed.split('\\n')[0];\r\n const payload = firstLine.slice(5).trim();\r\n try {\r\n const parsed = JSON.parse(payload);\r\n if (parsed && typeof parsed.type === 'string') {\r\n return 'ui-message-stream';\r\n }\r\n } catch {\r\n // Not JSON with type → could be old data stream inside SSE, or [DONE]\r\n }\r\n // SSE with old data stream lines inside (e.g., data: 0:\"text\")\r\n if (DATA_STREAM_LINE_RE.test(payload)) {\r\n return 'data-stream';\r\n }\r\n // SSE but unknown content — treat as UI message stream (most likely)\r\n return 'ui-message-stream';\r\n }\r\n\r\n // Legacy data stream protocol: lines like 0:\"text\"\\n\r\n if (DATA_STREAM_LINE_RE.test(trimmed)) {\r\n return 'data-stream';\r\n }\r\n\r\n // Fallback: plain text\r\n return 'plain-text';\r\n}\r\n\r\n// ── UI Message Stream Protocol parser ────────────────────────────────\r\n\r\nfunction processUIMessageStreamEvent(payload: string, callbacks: DataStreamCallbacks): void {\r\n const trimmed = payload.trim();\r\n if (!trimmed || trimmed === '[DONE]') {\r\n callbacks.onFinish?.({});\r\n return;\r\n }\r\n\r\n let parsed: any;\r\n try {\r\n parsed = JSON.parse(trimmed);\r\n } catch {\r\n // Not valid JSON — ignore\r\n console.warn('[DataStreamParser] failed to parse UI message stream event:', trimmed.slice(0, 100));\r\n return;\r\n }\r\n\r\n const type = parsed?.type;\r\n if (!type) return;\r\n\r\n switch (type) {\r\n case 'text-delta':\r\n // {\"type\":\"text-delta\",\"id\":\"...\",\"delta\":\"Hello\"}\r\n if (typeof parsed.delta === 'string') {\r\n callbacks.onTextDelta?.(parsed.delta);\r\n }\r\n break;\r\n\r\n case 'tool-input-start':\r\n // {\"type\":\"tool-input-start\",\"toolCallId\":\"...\",\"toolName\":\"...\"}\r\n callbacks.onToolCallStart?.(parsed.toolCallId, parsed.toolName);\r\n break;\r\n\r\n case 'tool-input-delta':\r\n // {\"type\":\"tool-input-delta\",\"toolCallId\":\"...\",\"inputTextDelta\":\"...\"}\r\n callbacks.onToolCallDelta?.(parsed.toolCallId, parsed.inputTextDelta);\r\n break;\r\n\r\n case 'tool-input-available':\r\n // {\"type\":\"tool-input-available\",\"toolCallId\":\"...\",\"toolName\":\"...\",\"input\":{...}}\r\n callbacks.onToolCallComplete?.(parsed.toolCallId, parsed.toolName, parsed.input);\r\n break;\r\n\r\n case 'tool-output-available':\r\n // {\"type\":\"tool-output-available\",\"toolCallId\":\"...\",\"output\":{...}}\r\n callbacks.onToolResult?.(parsed.toolCallId, parsed.output);\r\n break;\r\n\r\n case 'finish-step':\r\n callbacks.onStepFinish?.(parsed);\r\n break;\r\n\r\n case 'finish':\r\n callbacks.onFinish?.(parsed);\r\n break;\r\n\r\n case 'error':\r\n case 'tool-output-error':\r\n callbacks.onError?.(parsed.errorText || parsed.error || 'Unknown error', parsed);\r\n break;\r\n\r\n // Parts we acknowledge but don't need to act on:\r\n case 'start':\r\n case 'text-start':\r\n case 'text-end':\r\n case 'start-step':\r\n case 'reasoning-start':\r\n case 'reasoning-delta':\r\n case 'reasoning-end':\r\n case 'source-url':\r\n case 'source-document':\r\n case 'file':\r\n case 'abort':\r\n // No-op for voice assistant\r\n break;\r\n\r\n default:\r\n // Unknown type — log and ignore\r\n if (type.startsWith('data-')) {\r\n // Custom data parts — ignore\r\n } else {\r\n console.log('[DataStreamParser] unhandled UI message stream type:', type);\r\n }\r\n break;\r\n }\r\n}\r\n\r\n// ── Legacy Data Stream Protocol parser ───────────────────────────────\r\n\r\nfunction parseLegacyProtocolLine(line: string, callbacks: DataStreamCallbacks): void {\r\n if (!line || !DATA_STREAM_LINE_RE.test(line)) return;\r\n\r\n const code = line[0];\r\n const rawValue = line.slice(2);\r\n\r\n let value: any;\r\n try {\r\n value = JSON.parse(rawValue);\r\n } catch {\r\n value = rawValue;\r\n }\r\n\r\n switch (code) {\r\n case '0':\r\n callbacks.onTextDelta?.(value);\r\n break;\r\n case '9':\r\n callbacks.onToolCallStart?.(value.toolCallId, value.toolName);\r\n break;\r\n case 'b':\r\n callbacks.onToolCallDelta?.(value.toolCallId, value.argsTextDelta);\r\n break;\r\n case 'c':\r\n callbacks.onToolCallComplete?.(value.toolCallId, value.toolName, value.args);\r\n break;\r\n case 'a':\r\n callbacks.onToolResult?.(value.toolCallId, value.result);\r\n break;\r\n case 'e':\r\n callbacks.onStepFinish?.(value);\r\n break;\r\n case 'd':\r\n callbacks.onFinish?.(value);\r\n break;\r\n case '3':\r\n callbacks.onError?.(value);\r\n break;\r\n }\r\n}\r\n\r\n// ── Read and parse a stream response (auto-detecting format) ─────────\r\n\r\nexport async function readDataStream(response: Response, callbacks: DataStreamCallbacks): Promise<void> {\r\n if (!response.body) return;\r\n\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n let format: StreamFormat | null = null;\r\n\r\n while (true) {\r\n const { value, done } = await reader.read();\r\n if (done) break;\r\n\r\n const chunk = decoder.decode(value, { stream: true });\r\n buffer += chunk;\r\n\r\n // Auto-detect format from the first meaningful content\r\n if (format === null && buffer.trim().length > 0) {\r\n format = detectFormat(buffer);\r\n console.log('[DataStreamParser] detected format:', format, '| first 200 chars:', buffer.slice(0, 200));\r\n }\r\n\r\n if (format === 'plain-text') {\r\n const text = buffer;\r\n buffer = '';\r\n if (text) callbacks.onTextDelta?.(text);\r\n continue;\r\n }\r\n\r\n if (format === 'ui-message-stream') {\r\n // SSE format: events separated by \\n\\n\r\n while (true) {\r\n const eventEnd = buffer.indexOf('\\n\\n');\r\n if (eventEnd === -1) break;\r\n\r\n const eventBlock = buffer.slice(0, eventEnd);\r\n buffer = buffer.slice(eventEnd + 2);\r\n\r\n // Extract data lines from SSE event block\r\n const dataLines = eventBlock\r\n .split(/\\r?\\n/)\r\n .filter((l) => l.startsWith('data:'))\r\n .map((l) => l.slice(5).trimStart());\r\n\r\n for (const dataLine of dataLines) {\r\n processUIMessageStreamEvent(dataLine, callbacks);\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (format === 'data-stream') {\r\n // Legacy data stream or SSE-wrapped legacy\r\n // Check if it looks like SSE (data: prefix)\r\n const isSSEWrapped = buffer.trimStart().startsWith('data:');\r\n\r\n if (isSSEWrapped) {\r\n while (true) {\r\n const eventEnd = buffer.indexOf('\\n\\n');\r\n if (eventEnd === -1) break;\r\n\r\n const eventBlock = buffer.slice(0, eventEnd);\r\n buffer = buffer.slice(eventEnd + 2);\r\n\r\n const dataLines = eventBlock\r\n .split(/\\r?\\n/)\r\n .filter((l) => l.startsWith('data:'))\r\n .map((l) => l.slice(5).trimStart());\r\n\r\n for (const dl of dataLines) {\r\n const t = dl.trim();\r\n if (!t || t === '[DONE]') {\r\n if (t === '[DONE]') callbacks.onFinish?.({});\r\n continue;\r\n }\r\n parseLegacyProtocolLine(t, callbacks);\r\n }\r\n }\r\n } else {\r\n // Raw data stream lines separated by \\n\r\n while (true) {\r\n const newlineIdx = buffer.indexOf('\\n');\r\n if (newlineIdx === -1) break;\r\n\r\n const line = buffer.slice(0, newlineIdx).trim();\r\n buffer = buffer.slice(newlineIdx + 1);\r\n\r\n if (line) parseLegacyProtocolLine(line, callbacks);\r\n }\r\n }\r\n continue;\r\n }\r\n }\r\n\r\n // Process remaining buffer\r\n const tail = decoder.decode();\r\n if (tail) buffer += tail;\r\n\r\n if (buffer.trim()) {\r\n if (format === 'plain-text') {\r\n callbacks.onTextDelta?.(buffer);\r\n } else if (format === 'ui-message-stream') {\r\n const dataLines = buffer\r\n .split(/\\r?\\n/)\r\n .filter((l) => l.startsWith('data:'))\r\n .map((l) => l.slice(5).trimStart());\r\n for (const dl of dataLines) {\r\n processUIMessageStreamEvent(dl, callbacks);\r\n }\r\n } else if (format === 'data-stream') {\r\n parseLegacyProtocolLine(buffer.trim(), callbacks);\r\n }\r\n }\r\n\r\n callbacks.onFinish?.({});\r\n}\r\n\r\n// ── High-level: parse stream into MessageParts ───────────────────────\r\n\r\nexport interface StreamParseResult {\r\n textContent: string;\r\n parts: MessagePart[];\r\n toolCalls: Map<string, ToolCallTracker>;\r\n}\r\n\r\nexport async function parseDataStreamToMessage(\r\n response: Response,\r\n onUpdate: (result: StreamParseResult) => void,\r\n): Promise<StreamParseResult> {\r\n let textContent = '';\r\n const parts: MessagePart[] = [];\r\n const toolCalls = new Map<string, ToolCallTracker>();\r\n\r\n const ensureTextPart = (): TextPart => {\r\n for (let i = parts.length - 1; i >= 0; i--) {\r\n if (parts[i].type === 'text') {\r\n return parts[i] as TextPart;\r\n }\r\n }\r\n const textPart: TextPart = { type: 'text', text: '' };\r\n parts.push(textPart);\r\n return textPart;\r\n };\r\n\r\n const findToolPartIndex = (toolCallId: string): number => {\r\n return parts.findIndex((p) => (p.type === 'tool-call' || p.type === 'tool-result') && p.toolCallId === toolCallId);\r\n };\r\n\r\n const emitUpdate = () => {\r\n onUpdate({ textContent, parts: [...parts], toolCalls: new Map(toolCalls) });\r\n };\r\n\r\n await readDataStream(response, {\r\n onTextDelta(text) {\r\n textContent += text;\r\n const textPart = ensureTextPart();\r\n textPart.text = textContent;\r\n emitUpdate();\r\n },\r\n\r\n onToolCallStart(toolCallId, toolName) {\r\n const tracker: ToolCallTracker = {\r\n toolCallId,\r\n toolName,\r\n argsText: '',\r\n args: undefined,\r\n state: 'partial-call',\r\n };\r\n toolCalls.set(toolCallId, tracker);\r\n\r\n const part: ToolCallPart = {\r\n type: 'tool-call',\r\n toolCallId,\r\n toolName,\r\n args: undefined,\r\n state: 'partial-call',\r\n };\r\n parts.push(part);\r\n emitUpdate();\r\n },\r\n\r\n onToolCallDelta(toolCallId, argsTextDelta) {\r\n const tracker = toolCalls.get(toolCallId);\r\n if (tracker) {\r\n tracker.argsText += argsTextDelta;\r\n try {\r\n tracker.args = JSON.parse(tracker.argsText);\r\n } catch {\r\n // Not valid JSON yet\r\n }\r\n const idx = findToolPartIndex(toolCallId);\r\n if (idx !== -1 && parts[idx].type === 'tool-call') {\r\n (parts[idx] as ToolCallPart).args = tracker.args;\r\n }\r\n emitUpdate();\r\n }\r\n },\r\n\r\n onToolCallComplete(toolCallId, toolName, args) {\r\n const tracker = toolCalls.get(toolCallId);\r\n if (tracker) {\r\n tracker.state = 'call';\r\n tracker.args = typeof args === 'string' ? safeJsonParse(args) : args;\r\n } else {\r\n toolCalls.set(toolCallId, {\r\n toolCallId,\r\n toolName,\r\n argsText: typeof args === 'string' ? args : JSON.stringify(args),\r\n args: typeof args === 'string' ? safeJsonParse(args) : args,\r\n state: 'call',\r\n });\r\n }\r\n\r\n const idx = findToolPartIndex(toolCallId);\r\n if (idx !== -1) {\r\n (parts[idx] as ToolCallPart).state = 'call';\r\n (parts[idx] as ToolCallPart).toolName = toolName;\r\n (parts[idx] as ToolCallPart).args = toolCalls.get(toolCallId)!.args;\r\n } else {\r\n parts.push({\r\n type: 'tool-call',\r\n toolCallId,\r\n toolName,\r\n args: toolCalls.get(toolCallId)!.args,\r\n state: 'call',\r\n });\r\n }\r\n emitUpdate();\r\n },\r\n\r\n onToolResult(toolCallId, result) {\r\n const tracker = toolCalls.get(toolCallId);\r\n if (tracker) {\r\n tracker.result = result;\r\n tracker.state = 'result';\r\n }\r\n\r\n const idx = findToolPartIndex(toolCallId);\r\n if (idx !== -1) {\r\n const existing = parts[idx] as ToolCallPart;\r\n const resultPart: ToolResultPart = {\r\n type: 'tool-result',\r\n toolCallId,\r\n toolName: existing.toolName,\r\n args: existing.args,\r\n result,\r\n state: 'result',\r\n };\r\n parts[idx] = resultPart;\r\n } else {\r\n parts.push({\r\n type: 'tool-result',\r\n toolCallId,\r\n toolName: tracker?.toolName || 'unknown',\r\n args: tracker?.args,\r\n result,\r\n state: 'result',\r\n });\r\n }\r\n emitUpdate();\r\n },\r\n\r\n onError(error, data) {\r\n const toolCallId = data?.toolCallId;\r\n if (toolCallId) {\r\n toolCalls.delete(toolCallId);\r\n const idx = findToolPartIndex(toolCallId);\r\n if (idx !== -1) {\r\n parts.splice(idx, 1);\r\n emitUpdate();\r\n }\r\n }\r\n console.error('[DataStreamParser] stream error:', error);\r\n },\r\n\r\n onStepFinish(_data) {\r\n emitUpdate();\r\n },\r\n\r\n onFinish(_data) {\r\n emitUpdate();\r\n },\r\n });\r\n\r\n return { textContent, parts, toolCalls };\r\n}\r\n\r\n// ── Utilities ────────────────────────────────────────────────────────\r\n\r\nfunction safeJsonParse(str: string): any {\r\n try {\r\n return JSON.parse(str);\r\n } catch {\r\n return str;\r\n }\r\n}\r\n","import { computed, ref } from 'vue';\r\nimport {\r\n parseDataStreamToMessage,\r\n type StreamParseResult,\r\n type ToolCallPart,\r\n type ToolResultPart,\r\n} from '../lib/data-stream-parser';\r\nimport type { AiChatbotXContext } from '../types';\r\nimport type { DiscoveredCommand } from '../utils/command-types';\r\n\r\nexport interface UseAgentInvokeOptions {\r\n endpoint: string;\r\n projectId?: string;\r\n appToken?: string;\r\n aiChatbotX: AiChatbotXContext;\r\n /** TTS 控制 */\r\n tts: {\r\n speak: (text: string) => void;\r\n feed: (delta: string) => void;\r\n flush: () => void;\r\n stop: () => void;\r\n };\r\n /** 气泡控制 */\r\n bubble: {\r\n open: () => void;\r\n scheduleDismiss: () => void;\r\n scrollToBottom: () => void;\r\n };\r\n /** 会话记忆超时(ms),超过此时间未发起新对话则自动清空历史,默认 120000(2分钟) */\r\n sessionTimeoutMs?: number;\r\n /** 最大保留历史轮数(一轮 = user + assistant),默认 10 */\r\n maxHistoryTurns?: number;\r\n}\r\n\r\n// ── 工具名称映射 ──\r\nconst toolDisplayNames: Record<string, string> = {\r\n generateReport: '生成报告',\r\n searchKnowledge: '知识库检索',\r\n resolveInstanceTargets: '解析实例目标',\r\n getHistoryMetrics: '历史数据查询',\r\n getRealtimeMetrics: '实时数据查询',\r\n queryBitableData: '多维表格查询',\r\n searchUser: '搜索用户',\r\n createBitableRecord: '创建表格记录',\r\n timeTool: '时间工具',\r\n loadSkill: '加载技能',\r\n executeCommand: '执行命令',\r\n dataAnalyzer: '数据分析',\r\n dataPredictor: '数据预测',\r\n};\r\n\r\n/**\r\n * Agent 调用 composable\r\n *\r\n * 管理 Agent 调用、流式解析、工具执行、文本/工具状态。\r\n * 支持中断(abort)以便在唤醒时取消正在进行的调用。\r\n */\r\nexport function useAgentInvoke(options: UseAgentInvokeOptions) {\r\n const { aiChatbotX, tts, bubble } = options;\r\n\r\n const sessionTimeoutMs = options.sessionTimeoutMs ?? 120_000;\r\n const maxHistoryTurns = options.maxHistoryTurns ?? 10;\r\n\r\n const isInvoking = ref(false);\r\n const currentTextContent = ref('');\r\n const currentToolParts = ref<(ToolCallPart | ToolResultPart)[]>([]);\r\n const executingTools = ref<Set<string>>(new Set());\r\n\r\n // ── 对话历史 ──\r\n type HistoryMessage = { role: 'user' | 'assistant'; content: string };\r\n const conversationHistory = ref<HistoryMessage[]>([]);\r\n let lastInteractionTime = 0;\r\n\r\n /** 检查会话是否超时,超时则自动清空历史 */\r\n const checkSessionTimeout = () => {\r\n if (lastInteractionTime > 0 && Date.now() - lastInteractionTime > sessionTimeoutMs) {\r\n conversationHistory.value = [];\r\n }\r\n };\r\n\r\n /** 追加消息到历史(自动裁剪超出 maxHistoryTurns 的旧记录) */\r\n const appendToHistory = (role: 'user' | 'assistant', content: string) => {\r\n conversationHistory.value.push({ role, content });\r\n // 一轮 = 2 条消息(user + assistant),裁剪到 maxHistoryTurns * 2\r\n const maxLen = maxHistoryTurns * 2;\r\n if (conversationHistory.value.length > maxLen) {\r\n conversationHistory.value = conversationHistory.value.slice(-maxLen);\r\n }\r\n };\r\n\r\n /** 手动清空对话历史 */\r\n const clearHistory = () => {\r\n conversationHistory.value = [];\r\n };\r\n\r\n // AbortController 用于中断正在进行的请求\r\n let abortController: AbortController | null = null;\r\n\r\n const hasAnyContent = computed(() => {\r\n return !!(currentTextContent.value || currentToolParts.value.length > 0);\r\n });\r\n\r\n const toolDisplayName = (name: string) => toolDisplayNames[name] || name;\r\n\r\n // ── 重置状态 ──\r\n\r\n const resetState = () => {\r\n currentTextContent.value = '';\r\n currentToolParts.value = [];\r\n executingTools.value = new Set();\r\n };\r\n\r\n // ── 宿主命令执行 ──\r\n\r\n const extractExecutableCommands = (payload: any): { name: string; args: any[] }[] => {\r\n if (!payload || typeof payload !== 'object') return [];\r\n const commands = payload.commands;\r\n if (!Array.isArray(commands) || commands.length === 0) return [];\r\n\r\n return commands\r\n .filter((cmd) => cmd && typeof cmd === 'object' && typeof cmd.name === 'string' && cmd.name.trim())\r\n .map((cmd) => ({\r\n name: cmd.name,\r\n args: Array.isArray(cmd.args) ? cmd.args : [],\r\n }));\r\n };\r\n\r\n const buildCommandDefinitionMap = (commands: DiscoveredCommand[]) => {\r\n return new Map(commands.map((command) => [command.name, command]));\r\n };\r\n\r\n const toExecutableCommand = (\r\n toolName: string,\r\n payload: any,\r\n commandDefinitions: Map<string, DiscoveredCommand>,\r\n ): { name: string; args: any[] } | null => {\r\n const commandDefinition = commandDefinitions.get(toolName);\r\n if (!commandDefinition) {\r\n return null;\r\n }\r\n\r\n const parameters = commandDefinition.parameters || [];\r\n\r\n if (Array.isArray(payload)) {\r\n return {\r\n name: toolName,\r\n args: payload,\r\n };\r\n }\r\n\r\n if (!payload || typeof payload !== 'object') {\r\n return {\r\n name: toolName,\r\n args: [],\r\n };\r\n }\r\n\r\n const payloadRecord = payload as Record<string, any>;\r\n\r\n return {\r\n name: toolName,\r\n args: parameters.map((parameter) => payloadRecord[parameter.name]),\r\n };\r\n };\r\n\r\n const resolveExecutableCommands = (\r\n toolName: string,\r\n payload: any,\r\n commandDefinitions: Map<string, DiscoveredCommand>,\r\n ): { name: string; args: any[] }[] => {\r\n const extractedCommands = extractExecutableCommands(payload);\r\n if (extractedCommands.length > 0) {\r\n return extractedCommands;\r\n }\r\n\r\n const directCommand = toExecutableCommand(toolName, payload, commandDefinitions);\r\n return directCommand ? [directCommand] : [];\r\n };\r\n\r\n const executeHostCommands = async (\r\n toolCallId: string,\r\n toolName: string,\r\n payload: any,\r\n commandDefinitions: Map<string, DiscoveredCommand>,\r\n ) => {\r\n const commands = resolveExecutableCommands(toolName, payload, commandDefinitions);\r\n if (commands.length === 0) return false;\r\n\r\n try {\r\n executingTools.value = new Set([...executingTools.value, toolCallId]);\r\n for (const cmd of commands) {\r\n try {\r\n await aiChatbotX.executeCommand(cmd.name, cmd.args);\r\n } catch (cmdErr) {\r\n console.error(`[AgentInvoke] 执行命令 ${cmd.name} 失败:`, cmdErr);\r\n }\r\n }\r\n return true;\r\n } finally {\r\n const next = new Set(executingTools.value);\r\n next.delete(toolCallId);\r\n executingTools.value = next;\r\n }\r\n };\r\n\r\n // ── JSON 响应解析 ──\r\n\r\n const parseAssistantText = (payload: unknown): string => {\r\n if (!payload) return '';\r\n if (typeof payload === 'string') return payload;\r\n if (typeof payload === 'object') {\r\n const data = payload as Record<string, any>;\r\n const directText = data.output || data.answer || data.message || data.result;\r\n if (typeof directText === 'string' && directText.trim()) return directText;\r\n if (data.data && typeof data.data === 'object') {\r\n const nested = data.data as Record<string, any>;\r\n const nestedText = nested.output || nested.answer || nested.message || nested.result;\r\n if (typeof nestedText === 'string' && nestedText.trim()) return nestedText;\r\n }\r\n return JSON.stringify(payload);\r\n }\r\n return String(payload);\r\n };\r\n\r\n // ── 核心调用 ──\r\n\r\n const invoke = async (question: string) => {\r\n const content = question.trim();\r\n if (!content) return;\r\n\r\n // 如果有正在进行的调用,先中断\r\n abort();\r\n\r\n // 检查会话超时,必要时清空历史\r\n checkSessionTimeout();\r\n\r\n resetState();\r\n tts.stop();\r\n isInvoking.value = true;\r\n bubble.open();\r\n\r\n let prevTextLength = 0;\r\n const processedToolResults = new Set<string>();\r\n const processingToolResults = new Set<string>();\r\n abortController = new AbortController();\r\n\r\n const commands = await aiChatbotX.getCommads();\r\n const commandDefinitions = buildCommandDefinitionMap(commands);\r\n\r\n // 构造请求体:包含历史消息\r\n const historyToSend = conversationHistory.value.length > 0 ? [...conversationHistory.value] : undefined;\r\n\r\n try {\r\n const response = await fetch(options.endpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${options.appToken || ''}` },\r\n body: JSON.stringify({\r\n input: content,\r\n projectId: options.projectId || '',\r\n commands: commands.length > 0 ? commands : undefined,\r\n // messages: historyToSend,\r\n }),\r\n signal: abortController.signal,\r\n });\r\n\r\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\r\n\r\n const contentType = response.headers.get('content-type') || '';\r\n const isJsonResponse = contentType.includes('application/json');\r\n\r\n if (isJsonResponse) {\r\n const data = await response.json();\r\n const reply = parseAssistantText(data) || '已收到,但没有返回可展示的文本内容。';\r\n currentTextContent.value = reply;\r\n tts.speak(reply);\r\n\r\n // 追加到对话历史\r\n appendToHistory('user', content);\r\n appendToHistory('assistant', reply);\r\n\r\n if (data.toolResults && Array.isArray(data.toolResults)) {\r\n for (const tr of data.toolResults) {\r\n const toolPart: ToolResultPart = {\r\n type: 'tool-result',\r\n toolCallId: `invoke-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\r\n toolName: tr.toolName,\r\n args: tr.args,\r\n result: tr.result,\r\n state: 'result',\r\n };\r\n currentToolParts.value = [...currentToolParts.value, toolPart];\r\n if (commandDefinitions.has(tr.toolName)) {\r\n void executeHostCommands(toolPart.toolCallId, tr.toolName, tr.result, commandDefinitions);\r\n }\r\n }\r\n }\r\n } else {\r\n await parseDataStreamToMessage(response, (result: StreamParseResult) => {\r\n currentTextContent.value = result.textContent;\r\n\r\n if (result.textContent.length > prevTextLength) {\r\n const delta = result.textContent.slice(prevTextLength);\r\n prevTextLength = result.textContent.length;\r\n tts.feed(delta);\r\n }\r\n\r\n const toolParts: (ToolCallPart | ToolResultPart)[] = result.parts.filter(\r\n (p): p is ToolCallPart | ToolResultPart => p.type === 'tool-call' || p.type === 'tool-result',\r\n );\r\n currentToolParts.value = toolParts;\r\n\r\n for (const part of toolParts) {\r\n if (\r\n commandDefinitions.has(part.toolName) &&\r\n !processedToolResults.has(part.toolCallId) &&\r\n !processingToolResults.has(part.toolCallId)\r\n ) {\r\n if (part.type === 'tool-call' && part.state === 'call' && part.args) {\r\n processingToolResults.add(part.toolCallId);\r\n void executeHostCommands(part.toolCallId, part.toolName, part.args, commandDefinitions).then(\r\n (executed) => {\r\n if (executed) {\r\n processedToolResults.add(part.toolCallId);\r\n }\r\n processingToolResults.delete(part.toolCallId);\r\n },\r\n );\r\n } else if (part.type === 'tool-result' && part.result) {\r\n processingToolResults.add(part.toolCallId);\r\n void executeHostCommands(part.toolCallId, part.toolName, part.result, commandDefinitions).then(\r\n (executed) => {\r\n if (executed) {\r\n processedToolResults.add(part.toolCallId);\r\n }\r\n processingToolResults.delete(part.toolCallId);\r\n },\r\n );\r\n }\r\n }\r\n }\r\n\r\n bubble.scrollToBottom();\r\n });\r\n\r\n tts.flush();\r\n\r\n // 流式响应完成后,追加到对话历史\r\n const assistantReply = currentTextContent.value.trim();\r\n appendToHistory('user', content);\r\n if (assistantReply) {\r\n appendToHistory('assistant', assistantReply);\r\n }\r\n\r\n if (!assistantReply && currentToolParts.value.length === 0) {\r\n currentTextContent.value = '已收到,但没有返回可展示的文本内容。';\r\n }\r\n }\r\n } catch (error: any) {\r\n if (error.name === 'AbortError') {\r\n // 被中断,静默处理\r\n return;\r\n }\r\n console.error('[AgentInvoke] invoke failed:', error);\r\n tts.stop();\r\n currentTextContent.value = '请求失败,请检查服务地址或稍后重试。';\r\n } finally {\r\n isInvoking.value = false;\r\n abortController = null;\r\n lastInteractionTime = Date.now();\r\n bubble.scheduleDismiss();\r\n }\r\n };\r\n\r\n // ── 中断当前调用 ──\r\n\r\n const abort = () => {\r\n if (abortController) {\r\n abortController.abort();\r\n abortController = null;\r\n }\r\n tts.stop();\r\n isInvoking.value = false;\r\n };\r\n\r\n return {\r\n isInvoking,\r\n currentTextContent,\r\n currentToolParts,\r\n executingTools,\r\n hasAnyContent,\r\n conversationHistory,\r\n toolDisplayName,\r\n invoke,\r\n abort,\r\n resetState,\r\n clearHistory,\r\n };\r\n}\r\n","import type { Ref } from 'vue';\r\nimport { computed, nextTick, ref, watch } from 'vue';\r\n\r\nexport interface BubbleSize {\r\n /** 气泡最大宽度,如 '380px' 或 '86vw' */\r\n width?: string;\r\n /** 气泡最大高度,如 '520px' 或 '58vh' */\r\n maxHeight?: string;\r\n}\r\n\r\nexport interface UseBubbleOptions {\r\n /** 自动消失延迟 (ms),默认 4000 */\r\n dismissDelay?: number;\r\n /** 外部 isSpeaking 引用,TTS 播报期间阻止消失 */\r\n isSpeaking?: Ref<boolean>;\r\n /** 外部 hasPendingAudio 引用,TTS 已提交内容但尚未开始播放(覆盖异步窗口期) */\r\n hasPendingAudio?: Ref<boolean>;\r\n /** 外部 isInvoking 引用,调用期间阻止消失 */\r\n isInvoking?: Ref<boolean>;\r\n /** 气泡尺寸 */\r\n bubbleSize?: BubbleSize;\r\n}\r\n\r\n/**\r\n * 气泡生命周期 composable\r\n *\r\n * 管理气泡显示/隐藏、自动消失倒计时、滚动。\r\n * 核心保证:TTS 播报期间(含异步等待 WebSocket 的窗口期)气泡绝不消失。\r\n */\r\nexport function useBubble(options: UseBubbleOptions = {}) {\r\n const visible = ref(false);\r\n const fadingOut = ref(false);\r\n const stackRef = ref<HTMLElement | null>(null);\r\n let dismissTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n // 气泡是否被打开过(防止 TTS 状态单独触发空气泡)\r\n const hasOpened = ref(false);\r\n\r\n /** TTS 是否活跃:正在播报 OR 有待播放内容(覆盖异步初始化窗口) */\r\n const isTTSActive = () => !!(options.isSpeaking?.value || options.hasPendingAudio?.value);\r\n\r\n /** 任何阻止气泡消失的条件 */\r\n const isBusy = () => !!(options.isInvoking?.value || isTTSActive());\r\n\r\n // 核心 show:只要 hasOpened 且(visible 或 TTS 活跃),气泡就必须可见\r\n const show = computed(() => {\r\n if (!hasOpened.value) return false;\r\n if (isTTSActive()) return true;\r\n return visible.value && !fadingOut.value;\r\n });\r\n\r\n const style = computed(() => ({\r\n width: options.bubbleSize?.width || undefined,\r\n maxHeight: options.bubbleSize?.maxHeight || undefined,\r\n }));\r\n\r\n // ── 打开气泡(取消任何挂起的消失计时器) ──\r\n\r\n const open = () => {\r\n cancelDismiss();\r\n fadingOut.value = false;\r\n visible.value = true;\r\n hasOpened.value = true;\r\n };\r\n\r\n // ── 取消消失计时器 ──\r\n\r\n const cancelDismiss = () => {\r\n if (dismissTimer) {\r\n clearTimeout(dismissTimer);\r\n dismissTimer = null;\r\n }\r\n };\r\n\r\n // ── 安排消失(严格检查所有阻止条件) ──\r\n\r\n const scheduleDismiss = () => {\r\n cancelDismiss();\r\n\r\n if (isBusy()) return;\r\n\r\n const delay = options.dismissDelay ?? 4000;\r\n dismissTimer = setTimeout(() => {\r\n // 再次检查:等待期间 TTS 可能已经异步启动\r\n if (isBusy()) return;\r\n\r\n fadingOut.value = true;\r\n setTimeout(() => {\r\n // 最终检查:淡出动画期间 TTS 也可能启动\r\n if (isBusy()) {\r\n fadingOut.value = false;\r\n return;\r\n }\r\n visible.value = false;\r\n fadingOut.value = false;\r\n hasOpened.value = false;\r\n }, 400);\r\n }, delay);\r\n };\r\n\r\n // ── 监听 TTS 状态变化 ──\r\n\r\n const watchTTSRef = (ttsRef: Ref<boolean>) => {\r\n watch(ttsRef, (active) => {\r\n if (active && hasOpened.value) {\r\n // TTS 变为活跃 → 取消消失计时器,撤销淡出\r\n cancelDismiss();\r\n if (fadingOut.value) fadingOut.value = false;\r\n } else if (!active && hasOpened.value && !isBusy()) {\r\n // TTS 变为非活跃且无其他阻止条件 → 安排消失\r\n scheduleDismiss();\r\n }\r\n });\r\n };\r\n\r\n if (options.isSpeaking) watchTTSRef(options.isSpeaking);\r\n if (options.hasPendingAudio) watchTTSRef(options.hasPendingAudio);\r\n\r\n // ── 立即隐藏(中断场景) ──\r\n\r\n const hide = () => {\r\n cancelDismiss();\r\n fadingOut.value = false;\r\n visible.value = false;\r\n hasOpened.value = false;\r\n };\r\n\r\n // ── 滚动到底部 ──\r\n\r\n const scrollToBottom = () => {\r\n nextTick(() => {\r\n if (stackRef.value) {\r\n stackRef.value.scrollTop = stackRef.value.scrollHeight;\r\n }\r\n });\r\n };\r\n\r\n // ── 清理 ──\r\n\r\n const destroy = () => {\r\n cancelDismiss();\r\n };\r\n\r\n return {\r\n visible,\r\n fadingOut,\r\n show,\r\n style,\r\n stackRef,\r\n open,\r\n hide,\r\n cancelDismiss,\r\n scheduleDismiss,\r\n scrollToBottom,\r\n destroy,\r\n };\r\n}\r\n","import type { InjectionKey } from 'vue'\r\nimport type { AiChatbotXContext } from './types'\r\nimport { inject } from 'vue'\r\n\r\nexport const AiChatbotXKey: InjectionKey<AiChatbotXContext> = Symbol('sime-x')\r\n\r\nexport function injectStrict<T>(key: InjectionKey<T>): T\r\nexport function injectStrict<T>(key: InjectionKey<T>, defaultValue: T, treatDefaultAsFactory?: false): T\r\nexport function injectStrict<T>(key: InjectionKey<T>, defaultValue: T | (() => T), treatDefaultAsFactory: true): T\r\nexport function injectStrict<T>(key: InjectionKey<T>, defaultValue?: T | (() => T), treatDefaultAsFactory?: boolean): T {\r\n let result: T | undefined\r\n\r\n if (defaultValue === undefined) {\r\n result = inject(key) as T | undefined\r\n }\r\n else if (treatDefaultAsFactory === true) {\r\n result = inject(key, defaultValue as T | (() => T), true)\r\n }\r\n else {\r\n result = inject(key, defaultValue as T, false)\r\n }\r\n\r\n if (!result) {\r\n throw new Error(`Could not resolve ${key.description}`)\r\n }\r\n return result\r\n}\r\n","<template>\r\n <div class=\"command-test\" :data-theme=\"currentTheme\">\r\n <button @click=\"test\">测试</button>\r\n <button @click=\"test1\">测试1</button>\r\n <!-- ── 气泡区域:agent 回复 ── -->\r\n <transition name=\"bubble-fade\">\r\n <div class=\"bubble-stack\" v-if=\"showBubble\" ref=\"bubbleStackRef\" :style=\"bubbleStyle\">\r\n <div class=\"agent-bubble\">\r\n <!-- 工具执行步骤 -->\r\n <div v-if=\"currentToolParts.length > 0\" class=\"tool-steps\">\r\n <div\r\n v-for=\"toolPart in currentToolParts\"\r\n :key=\"toolPart.toolCallId\"\r\n class=\"tool-step\"\r\n :class=\"{\r\n 'tool-step--loading': toolPart.state === 'partial-call' || toolPart.state === 'call',\r\n 'tool-step--done': toolPart.state === 'result',\r\n 'tool-step--error': toolPart.state === 'error',\r\n 'tool-step--executing': executingTools.has(toolPart.toolCallId),\r\n }\"\r\n >\r\n <span class=\"tool-step__icon\">\r\n <svg\r\n v-if=\"toolPart.state === 'partial-call' || toolPart.state === 'call'\"\r\n class=\"tool-step__spinner\"\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n >\r\n <circle\r\n cx=\"12\"\r\n cy=\"12\"\r\n r=\"10\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"31.4 31.4\"\r\n />\r\n </svg>\r\n <svg v-else-if=\"toolPart.state === 'result'\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M20 6L9 17l-5-5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n <svg v-else-if=\"toolPart.state === 'error'\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <path d=\"M15 9l-6 6M9 9l6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n </span>\r\n <span class=\"tool-step__name\">{{ toolDisplayName(toolPart.toolName) }}</span>\r\n <span v-if=\"executingTools.has(toolPart.toolCallId)\" class=\"tool-step__tag tool-step__tag--exec\"\r\n >命令执行中</span\r\n >\r\n </div>\r\n </div>\r\n\r\n <!-- 思考中动画 -->\r\n <div v-if=\"isInvoking && !hasAnyContent\" class=\"thinking-dots\">\r\n <span></span>\r\n <span></span>\r\n <span></span>\r\n </div>\r\n\r\n <!-- 文本内容 -->\r\n <div v-if=\"currentTextContent\" class=\"agent-text\">{{ currentTextContent }}</div>\r\n </div>\r\n </div>\r\n </transition>\r\n\r\n <!-- ── 输入区域 ── -->\r\n <div class=\"input-bar\">\r\n <input\r\n v-model=\"inputText\"\r\n type=\"text\"\r\n class=\"input-field\"\r\n placeholder=\"输入指令...\"\r\n :disabled=\"isInvoking\"\r\n @keydown.enter=\"handleSubmit\"\r\n />\r\n <button class=\"submit-btn\" :disabled=\"isInvoking || !inputText.trim()\" @click=\"handleSubmit\">\r\n <svg v-if=\"isInvoking\" class=\"btn-spinner\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle\r\n cx=\"12\"\r\n cy=\"12\"\r\n r=\"10\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"31.4 31.4\"\r\n />\r\n </svg>\r\n <svg v-else width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M22 2L11 13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M22 2L15 22l-4-9-9-4 20-7z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { onBeforeUnmount, ref } from 'vue';\r\nimport { useAgentInvoke } from '../composables/use-agent-invoke';\r\nimport { useBubble } from '../composables/use-bubble';\r\nimport { AiChatbotXKey, injectStrict } from '../injection-key';\r\n\r\ninterface BubbleSize {\r\n width?: string;\r\n maxHeight?: string;\r\n}\r\n\r\nconst props = defineProps<{\r\n agentId?: string;\r\n projectId?: string;\r\n bubbleSize?: BubbleSize;\r\n bubbleDismissDelay?: number;\r\n}>();\r\n\r\nconst aiChatbotX = injectStrict(AiChatbotXKey);\r\n\r\nconst currentTheme = 'dark' as const;\r\nconst inputText = ref('');\r\n\r\n// ── TTS no-op(文本测试组件不需要语音播报) ──\r\n\r\nconst noopTts = {\r\n speak: (_text: string) => {},\r\n feed: (_delta: string) => {},\r\n flush: () => {},\r\n stop: () => {},\r\n};\r\n\r\n// ── Bubble bridge(与 voice-assistant 相同模式) ──\r\n\r\nconst bubbleBridge = {\r\n open: () => {},\r\n scheduleDismiss: () => {},\r\n scrollToBottom: () => {},\r\n};\r\n\r\nconst test = () => {\r\n aiChatbotX.speakText('你好,世界,今天是想起五天气横扫的缺点');\r\n};\r\n\r\nconst test1 = () => {\r\n aiChatbotX.abortInvoke();\r\n};\r\n\r\n// ── Agent invoke ──\r\n\r\nconst endpoint = `/sime/proxy/organizations/${aiChatbotX.organizationId()}/agents/${props.agentId}/stream-invoke`;\r\n\r\nconst agent = useAgentInvoke({\r\n endpoint,\r\n appToken: aiChatbotX.appToken(),\r\n projectId: props.projectId,\r\n aiChatbotX,\r\n tts: noopTts,\r\n bubble: {\r\n open: () => bubbleBridge.open(),\r\n scheduleDismiss: () => bubbleBridge.scheduleDismiss(),\r\n scrollToBottom: () => bubbleBridge.scrollToBottom(),\r\n },\r\n});\r\n\r\n// ── Bubble ──\r\n\r\nconst bubble = useBubble({\r\n dismissDelay: props.bubbleDismissDelay ?? 8000,\r\n isInvoking: agent.isInvoking,\r\n bubbleSize: props.bubbleSize,\r\n});\r\n\r\nbubbleBridge.open = bubble.open;\r\nbubbleBridge.scheduleDismiss = bubble.scheduleDismiss;\r\nbubbleBridge.scrollToBottom = bubble.scrollToBottom;\r\n\r\nconst { show: showBubble, style: bubbleStyle, stackRef: bubbleStackRef } = bubble;\r\n\r\n// ── 提交 ──\r\n\r\nconst handleSubmit = () => {\r\n const text = inputText.value.trim();\r\n if (!text || agent.isInvoking.value) return;\r\n inputText.value = '';\r\n agent.invoke(text);\r\n};\r\n\r\n// ── 模板暴露 ──\r\n\r\nconst { isInvoking, currentTextContent, currentToolParts, executingTools, hasAnyContent, toolDisplayName } = agent;\r\n\r\n// ── 清理 ──\r\n\r\nonBeforeUnmount(() => {\r\n bubble.destroy();\r\n agent.abort();\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.command-test {\r\n --text-primary: #e6edf7;\r\n --text-secondary: #95a8c8;\r\n --glass-bg: rgba(8, 16, 32, 0.72);\r\n --glass-border: rgba(125, 160, 220, 0.28);\r\n --shadow-md: 0 18px 36px rgba(1, 6, 20, 0.56);\r\n --color-success: #4ade80;\r\n --color-error: #f87171;\r\n --color-accent: #818cf8;\r\n\r\n position: relative;\r\n display: inline-flex;\r\n flex-direction: column;\r\n align-items: flex-end;\r\n gap: 12px;\r\n}\r\n\r\n/* ── 输入栏 ── */\r\n.input-bar {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n width: 100%;\r\n min-width: 320px;\r\n}\r\n\r\n.input-field {\r\n flex: 1;\r\n padding: 10px 14px;\r\n border-radius: 12px;\r\n border: 1px solid var(--glass-border);\r\n background: var(--glass-bg);\r\n color: var(--text-primary);\r\n font-size: 14px;\r\n outline: none;\r\n backdrop-filter: blur(10px);\r\n transition: border-color 0.2s ease;\r\n\r\n &::placeholder {\r\n color: var(--text-secondary);\r\n }\r\n\r\n &:focus {\r\n border-color: var(--color-accent);\r\n }\r\n\r\n &:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n}\r\n\r\n.submit-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 12px;\r\n border: 1px solid var(--glass-border);\r\n background: var(--glass-bg);\r\n color: var(--color-accent);\r\n cursor: pointer;\r\n backdrop-filter: blur(10px);\r\n transition:\r\n background 0.2s ease,\r\n transform 0.15s ease,\r\n opacity 0.2s ease;\r\n\r\n &:hover:not(:disabled) {\r\n background: rgba(129, 140, 248, 0.12);\r\n transform: scale(1.05);\r\n }\r\n\r\n &:disabled {\r\n opacity: 0.4;\r\n cursor: not-allowed;\r\n }\r\n}\r\n\r\n.btn-spinner {\r\n animation: tool-spin 0.8s linear infinite;\r\n}\r\n\r\n/* ── 气泡容器 ── */\r\n.bubble-stack {\r\n position: absolute;\r\n right: 0;\r\n bottom: calc(100% + 12px);\r\n width: min(380px, 86vw);\r\n max-height: min(58vh, 520px);\r\n overflow: auto;\r\n\r\n &::-webkit-scrollbar {\r\n width: 4px;\r\n }\r\n\r\n &::-webkit-scrollbar-thumb {\r\n background: rgba(126, 155, 204, 0.3);\r\n border-radius: 999px;\r\n }\r\n}\r\n\r\n/* ── Agent 气泡 ── */\r\n.agent-bubble {\r\n border-radius: 16px;\r\n padding: 12px 14px;\r\n background:\r\n radial-gradient(circle at 12% 10%, rgba(80, 122, 255, 0.14), transparent 50%),\r\n linear-gradient(155deg, rgba(24, 42, 72, 0.96), rgba(14, 24, 46, 0.97));\r\n border: 1px solid rgba(108, 141, 204, 0.2);\r\n box-shadow:\r\n 0 12px 32px rgba(1, 6, 20, 0.5),\r\n inset 0 1px 0 rgba(255, 255, 255, 0.04);\r\n backdrop-filter: blur(16px);\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n animation: bubble-appear 0.3s cubic-bezier(0.16, 1, 0.3, 1);\r\n}\r\n\r\n@keyframes bubble-appear {\r\n from {\r\n opacity: 0;\r\n transform: translateY(8px) scale(0.97);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0) scale(1);\r\n }\r\n}\r\n\r\n/* ── 工具执行步骤 ── */\r\n.tool-steps {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n margin-bottom: 6px;\r\n padding-bottom: 8px;\r\n border-bottom: 1px solid rgba(125, 160, 220, 0.1);\r\n}\r\n\r\n.tool-step {\r\n display: flex;\r\n align-items: center;\r\n gap: 7px;\r\n padding: 4px 6px;\r\n border-radius: 8px;\r\n transition: background 0.2s ease;\r\n animation: step-in 0.25s cubic-bezier(0.16, 1, 0.3, 1);\r\n\r\n &--loading {\r\n .tool-step__icon {\r\n color: var(--color-accent);\r\n }\r\n .tool-step__name {\r\n color: rgba(200, 215, 240, 0.85);\r\n }\r\n }\r\n\r\n &--done {\r\n .tool-step__icon {\r\n color: var(--color-success);\r\n }\r\n .tool-step__name {\r\n color: rgba(200, 215, 240, 0.55);\r\n }\r\n }\r\n\r\n &--error {\r\n .tool-step__icon {\r\n color: var(--color-error);\r\n }\r\n .tool-step__name {\r\n color: rgba(248, 113, 113, 0.8);\r\n }\r\n }\r\n\r\n &--executing {\r\n background: rgba(129, 140, 248, 0.06);\r\n .tool-step__icon {\r\n color: var(--color-accent);\r\n }\r\n }\r\n}\r\n\r\n@keyframes step-in {\r\n from {\r\n opacity: 0;\r\n transform: translateX(-6px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateX(0);\r\n }\r\n}\r\n\r\n.tool-step__icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 18px;\r\n height: 18px;\r\n flex-shrink: 0;\r\n}\r\n\r\n.tool-step__spinner {\r\n animation: tool-spin 0.8s linear infinite;\r\n}\r\n\r\n@keyframes tool-spin {\r\n from {\r\n transform: rotate(0deg);\r\n }\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n.tool-step__name {\r\n font-size: 12px;\r\n font-weight: 500;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n transition: color 0.2s ease;\r\n}\r\n\r\n.tool-step__tag {\r\n font-size: 10px;\r\n font-weight: 500;\r\n padding: 1px 6px;\r\n border-radius: 4px;\r\n white-space: nowrap;\r\n flex-shrink: 0;\r\n\r\n &--exec {\r\n background: rgba(129, 140, 248, 0.12);\r\n color: var(--color-accent);\r\n }\r\n}\r\n\r\n/* ── 思考中动画 ── */\r\n.thinking-dots {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 5px;\r\n padding: 2px 0;\r\n\r\n span {\r\n width: 5px;\r\n height: 5px;\r\n border-radius: 50%;\r\n background: var(--text-secondary);\r\n animation: thinking-bounce 1s infinite ease-in-out;\r\n }\r\n\r\n span:nth-child(2) {\r\n animation-delay: 0.15s;\r\n }\r\n\r\n span:nth-child(3) {\r\n animation-delay: 0.3s;\r\n }\r\n}\r\n\r\n@keyframes thinking-bounce {\r\n 0%,\r\n 100% {\r\n transform: translateY(0);\r\n opacity: 0.3;\r\n }\r\n 50% {\r\n transform: translateY(-3px);\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* ── 文本内容 ── */\r\n.agent-text {\r\n font-size: 14px;\r\n line-height: 1.55;\r\n color: var(--text-primary);\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n/* ── 气泡过渡 ── */\r\n.bubble-fade-enter-active {\r\n transition: all 0.35s cubic-bezier(0.16, 1, 0.3, 1);\r\n}\r\n\r\n.bubble-fade-leave-active {\r\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n}\r\n\r\n.bubble-fade-enter-from {\r\n opacity: 0;\r\n transform: translateY(12px) scale(0.95);\r\n}\r\n\r\n.bubble-fade-leave-to {\r\n opacity: 0;\r\n transform: translateY(8px) scale(0.97);\r\n}\r\n\r\n@media (max-width: 768px) {\r\n .bubble-stack {\r\n width: min(320px, 88vw);\r\n max-height: min(54vh, 420px);\r\n }\r\n\r\n .input-bar {\r\n min-width: 260px;\r\n }\r\n}\r\n</style>\r\n","import type { CommandDefinition, DiscoveredCommand } from './command-types';\r\n\r\nexport interface CommandManagerOptions {\r\n debug?: boolean;\r\n}\r\n\r\nexport class CommandManager {\r\n private commands: Map<string, CommandDefinition> = new Map();\r\n private debug: boolean;\r\n\r\n constructor(options: CommandManagerOptions = {}) {\r\n this.debug = options.debug ?? false;\r\n }\r\n\r\n public registerCommand(command: CommandDefinition): void {\r\n this.commands.set(command.name, command);\r\n this.log('注册命令', `${command.name}: ${command.description}`);\r\n }\r\n\r\n public unregisterCommand(name: string): void {\r\n const deleted = this.commands.delete(name);\r\n if (deleted) {\r\n this.log('命令已注销', name);\r\n }\r\n }\r\n\r\n public async executeCommand(command: string, args: any[] = []): Promise<any> {\r\n const commandDef = this.commands.get(command);\r\n if (!commandDef) {\r\n throw new Error(`命令 \"${command}\" 未找到`);\r\n }\r\n\r\n this.log('执行命令', command, args);\r\n return await commandDef.handler(...args);\r\n }\r\n\r\n public getCommands(): DiscoveredCommand[] {\r\n return Array.from(this.commands.values()).map((cmd) => ({\r\n name: cmd.name,\r\n description: cmd.description,\r\n parameters: cmd.parameters,\r\n }));\r\n }\r\n\r\n public hasCommand(name: string): boolean {\r\n return this.commands.has(name);\r\n }\r\n\r\n public clear(): void {\r\n this.commands.clear();\r\n this.log('', '所有命令已清空');\r\n }\r\n\r\n private log(prefix: string, msg: string, ...args: any[]): void {\r\n const time = new Date().toLocaleTimeString([], {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n second: '2-digit',\r\n });\r\n\r\n console.log(\r\n `%c ${prefix}`,\r\n 'background:#7c3aed;color:white;padding:2px 6px;border-radius:3px 0 0 3px;font-weight:bold;',\r\n `${msg}`,\r\n );\r\n\r\n if (args.length > 0) {\r\n console.log(...args);\r\n }\r\n }\r\n}\r\n","<template>\r\n <slot></slot>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { provide, shallowRef } from 'vue';\r\nimport { AiChatbotXKey } from '../injection-key';\r\nimport { CommandManager } from '../utils/command-manager';\r\nimport type { CommandDefinition } from '../utils/command-types';\r\n\r\nconst props = defineProps<{\r\n /** appToken */\r\n appToken: string;\r\n /** organizationId */\r\n organizationId: string;\r\n /** projectId for stream-invoke (used by voice-assistant) */\r\n projectId?: string;\r\n}>();\r\n\r\nconst commandManager = shallowRef<CommandManager>(new CommandManager({ debug: false }));\r\n\r\nconst startListeningRef = shallowRef<() => Promise<void>>(async () => {});\r\nconst stopListeningRef = shallowRef<() => Promise<void>>(async () => {});\r\nconst stopBroadcastRef = shallowRef<() => Promise<void>>(async () => {});\r\n\r\nconst voiceAssistantRef = shallowRef<{\r\n agentInvoke: (text: string) => Promise<void>;\r\n agentAbort: () => void;\r\n speakText: (text: string) => void;\r\n stopSpeak: () => void;\r\n} | null>(null);\r\n\r\nprovide(AiChatbotXKey, {\r\n appToken: () => props.appToken,\r\n organizationId: () => props.organizationId,\r\n startListening: () => startListeningRef.value(),\r\n stopListening: () => stopListeningRef.value(),\r\n stopBroadcast: () => stopBroadcastRef.value(),\r\n registerVoiceMethods: (methods: {\r\n stopBroadcast?: () => Promise<void>;\r\n start: () => Promise<void>;\r\n stop: () => Promise<void>;\r\n }) => {\r\n if (methods.stopBroadcast) stopBroadcastRef.value = methods.stopBroadcast;\r\n if (methods.start) startListeningRef.value = methods.start;\r\n if (methods.stop) stopListeningRef.value = methods.stop;\r\n },\r\n registerVoiceAssistant: (methods: {\r\n agentInvoke: (text: string) => Promise<void>;\r\n agentAbort: () => void;\r\n speakText: (text: string) => void;\r\n stopSpeak: () => void;\r\n }) => {\r\n voiceAssistantRef.value = methods;\r\n },\r\n getCommads: async () => commandManager.value.getCommands(),\r\n registerCommand: (cmd: CommandDefinition) => {\r\n commandManager.value.registerCommand(cmd);\r\n },\r\n unregisterCommand: (name) => {\r\n commandManager.value.unregisterCommand(name);\r\n },\r\n async executeCommand(commandName, args = []) {\r\n return await commandManager.value.executeCommand(commandName, args);\r\n },\r\n sendMessage: async (text: string) => {\r\n voiceAssistantRef.value?.agentInvoke(text);\r\n },\r\n speakText: (text: string) => {\r\n voiceAssistantRef.value?.speakText(text);\r\n },\r\n stopSpeak: () => {\r\n voiceAssistantRef.value?.stopSpeak();\r\n },\r\n abortInvoke: () => {\r\n voiceAssistantRef.value?.agentAbort();\r\n },\r\n});\r\n</script>\r\n","import { ref } from 'vue';\r\nimport { SpeechSynthesizerStandalone } from 'web-voice-kit';\r\nimport type { VoiceConfig } from '../types';\r\n\r\n/**\r\n * TTS 语音播报 composable\r\n *\r\n * 管理讯飞 SpeechSynthesizerStandalone 的生命周期、\r\n * 句子级缓冲、Markdown 清理、AudioContext 预热。\r\n */\r\nexport function useTTS(getVoiceConfig: () => VoiceConfig | null) {\r\n const isSpeaking = ref(false);\r\n // hasPendingAudio: true 从 speak/feed 被调用开始,直到 onQueueEmpty。\r\n // 覆盖了 speak 异步等待 ensureInstance 的窗口期,此时 isSpeaking 尚为 false。\r\n const hasPendingAudio = ref(false);\r\n\r\n let instance: SpeechSynthesizerStandalone | null = null;\r\n let initPromise: Promise<SpeechSynthesizerStandalone | null> | null = null;\r\n let audioCtx: AudioContext | null = null;\r\n\r\n // 句子缓冲\r\n let sentenceBuffer = '';\r\n const SENTENCE_DELIMITERS = /[。!?;\\n!?;]/;\r\n const LEADING_WEAK_PUNCTUATION = /^[\\s,、;:,.!?。]+/;\r\n const TRAILING_SENTENCE_PUNCTUATION = /[。!?.!?;;]$/;\r\n\r\n const findSentenceBoundary = (text: string): number => {\r\n for (let i = 0; i < text.length; i++) {\r\n const char = text[i];\r\n if (SENTENCE_DELIMITERS.test(char)) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n };\r\n\r\n // ── helpers ──\r\n\r\n const normalizeNumbers = (text: string): string => {\r\n return text\r\n .replace(/(-?\\d[\\d,]*\\.?\\d*)\\s*%/g, (_, num) => {\r\n const cleanNum = num.replace(/,/g, '');\r\n const n = parseFloat(cleanNum);\r\n const spoken = cleanNum.replace('.', '点');\r\n if (n < 0) return `负百分之${spoken.replace('-', '')}`;\r\n return `百分之${spoken}`;\r\n })\r\n .replace(/(-?\\d[\\d,]*)\\.(\\d+)/g, (_, intPart, decPart) => {\r\n const cleanInt = intPart.replace(/,/g, '');\r\n if (cleanInt.startsWith('-')) {\r\n return `负${cleanInt.slice(1)}点${decPart}`;\r\n }\r\n return `${cleanInt}点${decPart}`;\r\n })\r\n .replace(/-(\\d)/g, '负$1');\r\n };\r\n\r\n const stripMarkdown = (text: string): string => {\r\n let result = text\r\n .replace(/```[\\s\\S]*?```/g, '')\r\n .replace(/\\|[^\\n]*\\|/g, '')\r\n .replace(/#{1,6}\\s*/g, '')\r\n .replace(/\\*\\*(.*?)\\*\\*/g, '$1')\r\n .replace(/\\*(.*?)\\*/g, '$1')\r\n .replace(/`([^`]*)`/g, '$1')\r\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\r\n .replace(/^[-*+]\\s+/gm, '')\r\n .replace(/^>\\s+/gm, '');\r\n result = normalizeNumbers(result);\r\n result = result\r\n .replace(/\\s*\\+\\s*(?=\\d)/g, '加')\r\n .replace(/\\s*\\+\\s*/g, '加')\r\n .replace(/\\s*-\\s*(?=\\d)/g, '减')\r\n .replace(/\\s*-\\s*/g, '减')\r\n .replace(/\\s*×\\s*/g, '乘')\r\n .replace(/\\s*÷\\s*/g, '除')\r\n .replace(/\\s*=\\s*/g, '等于')\r\n .replace(/\\n{2,}/g, '。')\r\n .replace(/\\n/g, ',')\r\n .trim();\r\n return result;\r\n };\r\n\r\n const normalizeSpeakText = (text: string, options?: { isFinalChunk?: boolean }): string => {\r\n const clean = stripMarkdown(text).replace(LEADING_WEAK_PUNCTUATION, '').trim();\r\n if (!clean) return '';\r\n if (options?.isFinalChunk && !TRAILING_SENTENCE_PUNCTUATION.test(clean)) {\r\n return `${clean}。`;\r\n }\r\n return clean;\r\n };\r\n\r\n // ── AudioContext 预热 ──\r\n\r\n const warmUpAudio = () => {\r\n if (!audioCtx || audioCtx.state === 'closed') {\r\n try {\r\n audioCtx = new AudioContext();\r\n } catch {\r\n return;\r\n }\r\n }\r\n if (audioCtx.state === 'suspended') {\r\n audioCtx.resume();\r\n }\r\n };\r\n\r\n // ── 懒初始化 ──\r\n\r\n /** 回调:TTS 队列清空时触发(外部可监听) */\r\n let onQueueEmptyCb: (() => void) | null = null;\r\n\r\n const ensureInstance = async (): Promise<SpeechSynthesizerStandalone | null> => {\r\n if (instance) return instance;\r\n if (initPromise) return initPromise;\r\n\r\n const vc = getVoiceConfig();\r\n if (!vc || !vc.apiSecret) {\r\n console.warn('[TTS] 缺少 voiceConfig 或 apiSecret,语音播报已禁用');\r\n return null;\r\n }\r\n\r\n initPromise = (async () => {\r\n try {\r\n const tts = new SpeechSynthesizerStandalone({\r\n appId: vc.appId,\r\n apiKey: vc.ttsApiKey || vc.apiKey,\r\n apiSecret: vc.apiSecret!,\r\n websocketUrl: vc.ttsWebsocketUrl || 'wss://tts-api.xfyun.cn/v2/tts',\r\n vcn: vc.ttsVcn || 'xiaoyan',\r\n speed: vc.speed || 55,\r\n volume: vc.volume || 90,\r\n pitch: vc.pitch || 50,\r\n aue: 'raw',\r\n auf: 'audio/L16;rate=16000',\r\n tte: 'UTF8',\r\n autoPlay: true,\r\n });\r\n\r\n tts.onStart(() => {\r\n isSpeaking.value = true;\r\n });\r\n\r\n tts.onEnd(() => {\r\n // 每段文本结束,队列可能还有后续\r\n });\r\n\r\n tts.onQueueEmpty(() => {\r\n isSpeaking.value = false;\r\n hasPendingAudio.value = false;\r\n onQueueEmptyCb?.();\r\n });\r\n\r\n tts.onError((err: any) => {\r\n console.error('[TTS] Error:', err);\r\n isSpeaking.value = false;\r\n });\r\n\r\n // 注入预热的 AudioContext\r\n if (audioCtx && audioCtx.state === 'running') {\r\n (tts as any).audioContext = audioCtx;\r\n (tts as any).gainNode = audioCtx.createGain();\r\n (tts as any).gainNode.connect(audioCtx.destination);\r\n }\r\n\r\n instance = tts;\r\n initPromise = null;\r\n return tts;\r\n } catch (err) {\r\n console.error('[TTS] 初始化失败:', err);\r\n initPromise = null;\r\n return null;\r\n }\r\n })();\r\n\r\n return initPromise;\r\n };\r\n\r\n // ── 公开方法 ──\r\n\r\n const speak = async (text: string) => {\r\n const clean = normalizeSpeakText(text);\r\n if (!clean.trim()) return;\r\n hasPendingAudio.value = true;\r\n const tts = await ensureInstance();\r\n if (!tts) return;\r\n try {\r\n tts.speak(clean);\r\n } catch (err) {\r\n console.error('[TTS] speak 失败:', err);\r\n }\r\n };\r\n\r\n const feed = (delta: string) => {\r\n sentenceBuffer += delta;\r\n while (true) {\r\n const boundaryIndex = findSentenceBoundary(sentenceBuffer);\r\n if (boundaryIndex === -1) break;\r\n const sentence = sentenceBuffer.slice(0, boundaryIndex + 1).trim();\r\n sentenceBuffer = sentenceBuffer.slice(boundaryIndex + 1);\r\n if (sentence.length > 0) speak(sentence);\r\n }\r\n };\r\n\r\n const flush = () => {\r\n const remaining = sentenceBuffer.trim();\r\n sentenceBuffer = '';\r\n if (remaining.length > 0) {\r\n const clean = normalizeSpeakText(remaining, { isFinalChunk: true });\r\n if (clean) void speak(clean);\r\n }\r\n };\r\n\r\n const stop = () => {\r\n sentenceBuffer = '';\r\n isSpeaking.value = false;\r\n hasPendingAudio.value = false;\r\n if (instance) {\r\n try {\r\n instance.stop();\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n };\r\n\r\n const setOnQueueEmpty = (cb: () => void) => {\r\n onQueueEmptyCb = cb;\r\n };\r\n\r\n const destroy = () => {\r\n stop();\r\n if (instance) {\r\n try {\r\n instance.destroy();\r\n } catch {\r\n // ignore\r\n }\r\n instance = null;\r\n }\r\n if (audioCtx) {\r\n try {\r\n audioCtx.close();\r\n } catch {\r\n // ignore\r\n }\r\n audioCtx = null;\r\n }\r\n };\r\n\r\n return {\r\n isSpeaking,\r\n hasPendingAudio,\r\n warmUpAudio,\r\n speak,\r\n feed,\r\n flush,\r\n stop,\r\n destroy,\r\n setOnQueueEmpty,\r\n };\r\n}\r\n","import { DiscoveredCommand } from '../utils/command-types';\r\n\r\nexport const ensureMicrophonePermission = async () => {\r\n // 检查浏览器环境\r\n if (typeof navigator === 'undefined' || typeof window === 'undefined') {\r\n console.log('当前环境不支持麦克风访问');\r\n return false;\r\n }\r\n\r\n // 检查 MediaDevices API 支持\r\n if (!navigator.mediaDevices?.getUserMedia || !navigator.mediaDevices?.enumerateDevices) {\r\n console.log('当前环境不支持麦克风访问');\r\n return false;\r\n }\r\n\r\n try {\r\n // 1. 首先枚举设备,检查是否有音频输入设备\r\n const devices = await navigator.mediaDevices.enumerateDevices();\r\n const audioInputDevices = devices.filter((device) => device.kind === 'audioinput');\r\n\r\n if (audioInputDevices.length === 0) {\r\n console.log('未检测到麦克风设备,请连接麦克风后重试。');\r\n return false;\r\n }\r\n\r\n // 2. 检查权限状态(如果浏览器支持)\r\n if ('permissions' in navigator && navigator.permissions?.query) {\r\n try {\r\n const status = await navigator.permissions.query({ name: 'microphone' as PermissionName });\r\n\r\n if (status.state === 'denied') {\r\n console.log('麦克风权限被禁用,请在浏览器设置中开启。');\r\n return false;\r\n }\r\n } catch (e) {\r\n // 某些浏览器可能不支持 microphone 权限查询,继续执行\r\n console.warn('Permission query not supported:', e);\r\n }\r\n }\r\n\r\n // 3. 尝试获取麦克风流以确认权限和设备可用性\r\n let stream: MediaStream | null = null;\r\n try {\r\n stream = await navigator.mediaDevices.getUserMedia({\r\n audio: {\r\n echoCancellation: true,\r\n noiseSuppression: true,\r\n autoGainControl: true,\r\n },\r\n });\r\n\r\n // 检查流是否有活动的音频轨道\r\n const audioTracks = stream.getAudioTracks();\r\n if (audioTracks.length === 0) {\r\n console.log('无法获取麦克风音频轨道。');\r\n return false;\r\n }\r\n\r\n // 检查音频轨道是否启用且可读\r\n const activeTrack = audioTracks[0];\r\n if (!activeTrack.enabled || activeTrack.readyState !== 'live') {\r\n console.log('麦克风设备不可用,请检查设备连接。');\r\n return false;\r\n }\r\n\r\n return true;\r\n } finally {\r\n // 确保释放流资源\r\n if (stream) {\r\n stream.getTracks().forEach((track) => track.stop());\r\n }\r\n }\r\n } catch (error: any) {\r\n console.error('Microphone permission check failed', error);\r\n\r\n // 根据错误类型提供更具体的提示\r\n if (error.name === 'NotFoundError' || error.name === 'DevicesNotFoundError') {\r\n console.log('未检测到麦克风设备,请连接麦克风后重试。');\r\n } else if (error.name === 'NotAllowedError' || error.name === 'PermissionDeniedError') {\r\n console.log('麦克风权限被拒绝,请在浏览器设置中允许访问。');\r\n } else if (error.name === 'NotReadableError' || error.name === 'TrackStartError') {\r\n console.log('麦克风被其他应用占用或无法访问。');\r\n } else {\r\n console.log('无法访问麦克风,请检查设备连接和浏览器权限。');\r\n }\r\n\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * 语音命令匹配函数\r\n * @param {string} userInput - 用户输入的原始语音文本\r\n * @param {Array} commandList - 命令列表对象数组\r\n * @param {number} threshold - 相似度阈值 (0-1),默认 0.5\r\n */\r\nexport function matchVoiceCommand(userInput: string, commandList: DiscoveredCommand[], threshold = 0.5) {\r\n if (!userInput || typeof userInput !== 'string') return null;\r\n\r\n // 1. 预处理:转小写、去空格、去标点、去语气词\r\n const cleanInput = userInput\r\n .trim()\r\n .toLowerCase()\r\n // 1. 去除所有标点符号及特殊字符\r\n .replace(/[,。?!;:、“”()()<>《》\\s\\.\\,\\?\\!]/g, '')\r\n // 2. 去除常见的前缀 (增加“给我”、“能不能”等)\r\n .replace(/^(请帮我|我想|帮我|麻烦|我要|你好|您好|帮我把|给我|能不能帮我|请问|那个)/g, '')\r\n // 3. 去除中间的动作虚词 (如“把...给...”)\r\n .replace(/给(?=(打开|开启|关闭|停止))/g, '')\r\n // 4. 去除常见的后缀 (增加“就可以了”、“就行”、“模式”)\r\n .replace(/(一下|了|吧|输出|就可以了|就行|模式|操作|功能)$/g, '');\r\n\r\n let bestMatch = null;\r\n let maxScore = 0;\r\n\r\n // 编辑距离算法 (Levenshtein Distance)\r\n const getSimilarity = (s1: string, s2: string) => {\r\n const [l1, l2] = [s1.length, s2.length];\r\n const matrix = Array.from({ length: l1 + 1 }, () => Array(l2 + 1).fill(0));\r\n for (let i = 0; i <= l1; i++) matrix[i][0] = i;\r\n for (let j = 0; j <= l2; j++) matrix[0][j] = j;\r\n\r\n for (let i = 1; i <= l1; i++) {\r\n for (let j = 1; j <= l2; j++) {\r\n const cost = s1[i - 1] === s2[j - 1] ? 0 : 1;\r\n matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + cost);\r\n }\r\n }\r\n return 1 - matrix[l1][l2] / Math.max(l1, l2);\r\n };\r\n\r\n // 2. 遍历命令列表进行比对\r\n for (const cmd of commandList) {\r\n const target = cmd.description.toLowerCase();\r\n let currentScore = 0;\r\n\r\n // 策略 A:直接包含 (如输入“帮我开启漫游吧”,描述是“开启漫游”)\r\n if (cleanInput.includes(target) || target.includes(cleanInput)) {\r\n // 计算包含关系的得分,越接近 1 分越高\r\n currentScore = Math.min(target.length, cleanInput.length) / Math.max(target.length, cleanInput.length);\r\n // 给予包含匹配更高的基础权重\r\n currentScore = 0.8 + currentScore * 0.2;\r\n }\r\n // 策略 B:模糊匹配 (处理同音字错误,如“开启慢游”)\r\n else {\r\n currentScore = getSimilarity(cleanInput, target);\r\n }\r\n\r\n // 更新最高分项\r\n if (currentScore > maxScore) {\r\n maxScore = currentScore;\r\n bestMatch = { ...cmd, confidence: maxScore };\r\n }\r\n }\r\n\r\n // 3. 结果过滤\r\n return maxScore >= threshold ? bestMatch : null;\r\n}\r\n","import { ref } from 'vue';\r\nimport { SpeechTranscriberStandalone, WakeWordDetectorStandalone } from 'web-voice-kit';\r\nimport type { VoiceConfig } from '../types';\r\nimport { ensureMicrophonePermission } from '../lib/utils';\r\n\r\nexport type VoiceStatus = 'standby' | 'listening';\r\n\r\nexport interface UseVoiceRecognitionOptions {\r\n modelPath?: string;\r\n wakeWords?: string[];\r\n getVoiceConfig: () => VoiceConfig | null;\r\n /** 唤醒时回调 */\r\n onWake?: () => void;\r\n /** 转写完成(autoStop)时回调 */\r\n onTranscriptionDone?: (text: string) => void;\r\n}\r\n\r\n/**\r\n * 语音识别 composable\r\n *\r\n * 管理唤醒词检测器 + 语音转写器的生命周期。\r\n */\r\nexport function useVoiceRecognition(options: UseVoiceRecognitionOptions) {\r\n const voiceStatus = ref<VoiceStatus>('standby');\r\n const isTranscribing = ref(false);\r\n const isInitializing = ref(false);\r\n const transcriptionText = ref('');\r\n const wakeAnimating = ref(false);\r\n\r\n let detector: WakeWordDetectorStandalone | null = null;\r\n let transcriber: SpeechTranscriberStandalone | null = null;\r\n\r\n // ── 转写器 ──\r\n\r\n const initTranscriber = () => {\r\n if (transcriber) return;\r\n\r\n const vc = options.getVoiceConfig();\r\n if (!vc || !vc.appId || !vc.apiKey || !vc.websocketUrl) {\r\n console.error('[VoiceRecognition] 缺少 voiceConfig,无法初始化转写器');\r\n return;\r\n }\r\n\r\n transcriber = new SpeechTranscriberStandalone({\r\n appId: vc.appId,\r\n apiKey: vc.apiKey,\r\n websocketUrl: vc.websocketUrl,\r\n autoStop: {\r\n enabled: true,\r\n silenceTimeoutMs: 2000,\r\n noSpeechTimeoutMs: 5000,\r\n maxDurationMs: 45000,\r\n },\r\n });\r\n\r\n transcriber.onResult((result) => {\r\n transcriptionText.value = result.transcript || '';\r\n });\r\n\r\n transcriber.onAutoStop(async () => {\r\n const finalText = transcriptionText.value;\r\n await stopTranscribing();\r\n transcriptionText.value = '';\r\n if (finalText.trim()) {\r\n options.onTranscriptionDone?.(finalText);\r\n }\r\n });\r\n\r\n transcriber.onError((error: any) => {\r\n console.error('[VoiceRecognition] 转写错误:', error);\r\n stopTranscribing();\r\n transcriptionText.value = '';\r\n });\r\n };\r\n\r\n const startTranscribing = async () => {\r\n if (isTranscribing.value) return;\r\n if (!transcriber) initTranscriber();\r\n if (!transcriber) return;\r\n\r\n try {\r\n await transcriber.start();\r\n isTranscribing.value = true;\r\n transcriptionText.value = '';\r\n } catch (error) {\r\n console.error('[VoiceRecognition] 启动转写失败:', error);\r\n }\r\n };\r\n\r\n const stopTranscribing = async () => {\r\n if (!transcriber || !transcriber.isActive()) {\r\n isTranscribing.value = false;\r\n return;\r\n }\r\n try {\r\n await transcriber.stop();\r\n } catch (error) {\r\n console.error('[VoiceRecognition] 停止转写失败:', error);\r\n } finally {\r\n isTranscribing.value = false;\r\n }\r\n };\r\n\r\n // ── 唤醒词检测器 ──\r\n\r\n const initDetector = () => {\r\n if (detector || isInitializing.value) return;\r\n if (!options.modelPath) {\r\n console.error('[VoiceRecognition] 未传入 modelPath,无法启用唤醒词');\r\n return;\r\n }\r\n\r\n isInitializing.value = true;\r\n try {\r\n detector = new WakeWordDetectorStandalone({\r\n modelPath: options.modelPath,\r\n sampleRate: 16000,\r\n usePartial: true,\r\n autoReset: {\r\n enabled: true,\r\n resetDelayMs: 4000,\r\n },\r\n });\r\n\r\n detector.setWakeWords(options.wakeWords || ['你好', '您好']);\r\n detector.onWake(async () => {\r\n wakeAnimating.value = true;\r\n options.onWake?.();\r\n await startTranscribing();\r\n setTimeout(() => {\r\n wakeAnimating.value = false;\r\n }, 1200);\r\n });\r\n\r\n detector.onError((error: any) => {\r\n console.error('[VoiceRecognition] 唤醒监听错误:', error);\r\n voiceStatus.value = 'standby';\r\n stopTranscribing();\r\n });\r\n } finally {\r\n isInitializing.value = false;\r\n }\r\n };\r\n\r\n // ── 切换语音模式 ──\r\n\r\n const toggleVoiceMode = async (targetState?: boolean) => {\r\n const permission = await ensureMicrophonePermission();\r\n if (!permission || isInitializing.value) return;\r\n\r\n if (!detector) {\r\n initDetector();\r\n if (!detector) return;\r\n }\r\n\r\n const isListening = voiceStatus.value === 'listening';\r\n const shouldStart = targetState !== undefined ? targetState : !isListening;\r\n if (isListening === shouldStart) return;\r\n\r\n try {\r\n if (shouldStart) {\r\n await detector.start();\r\n voiceStatus.value = 'listening';\r\n } else {\r\n await detector.stop();\r\n voiceStatus.value = 'standby';\r\n transcriptionText.value = '';\r\n await stopTranscribing();\r\n }\r\n } catch (error) {\r\n console.error('[VoiceRecognition] 监听切换失败:', error);\r\n voiceStatus.value = 'standby';\r\n }\r\n };\r\n\r\n // ── 中断当前转写(唤醒中断场景) ──\r\n\r\n const abortTranscription = async () => {\r\n transcriptionText.value = '';\r\n await stopTranscribing();\r\n };\r\n\r\n // ── 清理 ──\r\n\r\n const destroy = async () => {\r\n if (detector) {\r\n try {\r\n if (detector.isActive()) await detector.stop();\r\n } catch {\r\n // ignore\r\n }\r\n detector = null;\r\n }\r\n if (transcriber) {\r\n try {\r\n if (transcriber.isActive()) await transcriber.stop();\r\n } catch {\r\n // ignore\r\n }\r\n transcriber = null;\r\n }\r\n };\r\n\r\n return {\r\n voiceStatus,\r\n isTranscribing,\r\n isInitializing,\r\n transcriptionText,\r\n wakeAnimating,\r\n startTranscribing,\r\n stopTranscribing,\r\n abortTranscription,\r\n toggleVoiceMode,\r\n destroy,\r\n };\r\n}\r\n","<template>\r\n <div class=\"voice-assistant\" :data-theme=\"currentTheme\">\r\n <!-- ── 气泡区域:仅渲染 agent 回复 ── -->\r\n <transition name=\"bubble-fade\">\r\n <div class=\"bubble-stack\" v-if=\"showBubble\" ref=\"bubbleStackRef\" :style=\"bubbleStyle\">\r\n <div class=\"agent-bubble\">\r\n <!-- 工具执行步骤(内联紧凑样式) -->\r\n <div v-if=\"currentToolParts.length > 0\" class=\"tool-steps\">\r\n <div\r\n v-for=\"toolPart in currentToolParts\"\r\n :key=\"toolPart.toolCallId\"\r\n class=\"tool-step\"\r\n :class=\"{\r\n 'tool-step--loading': toolPart.state === 'partial-call' || toolPart.state === 'call',\r\n 'tool-step--done': toolPart.state === 'result',\r\n 'tool-step--error': toolPart.state === 'error',\r\n 'tool-step--executing': executingTools.has(toolPart.toolCallId),\r\n }\"\r\n >\r\n <!-- 状态图标 -->\r\n <span class=\"tool-step__icon\">\r\n <svg\r\n v-if=\"toolPart.state === 'partial-call' || toolPart.state === 'call'\"\r\n class=\"tool-step__spinner\"\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n >\r\n <circle\r\n cx=\"12\"\r\n cy=\"12\"\r\n r=\"10\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"31.4 31.4\"\r\n />\r\n </svg>\r\n <svg v-else-if=\"toolPart.state === 'result'\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M20 6L9 17l-5-5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n <svg v-else-if=\"toolPart.state === 'error'\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <path d=\"M15 9l-6 6M9 9l6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n </span>\r\n <span class=\"tool-step__name\">{{ toolDisplayName(toolPart.toolName) }}</span>\r\n <span v-if=\"executingTools.has(toolPart.toolCallId)\" class=\"tool-step__tag tool-step__tag--exec\"\r\n >命令执行中</span\r\n >\r\n </div>\r\n </div>\r\n\r\n <!-- 思考中动画(无工具、无文本时显示) -->\r\n <div v-if=\"isInvoking && !hasAnyContent\" class=\"thinking-dots\">\r\n <span></span>\r\n <span></span>\r\n <span></span>\r\n </div>\r\n\r\n <!-- 文本内容 -->\r\n <div v-if=\"currentTextContent\" class=\"agent-text\">{{ currentTextContent }}</div>\r\n </div>\r\n </div>\r\n </transition>\r\n\r\n <!-- ── FAB 按钮 ── -->\r\n <div class=\"assistant-fab\" @click=\"toggleVoiceMode()\">\r\n <div v-if=\"transcriptionText || isInvoking\" class=\"status-pill\">\r\n {{ isInvoking ? '正在思考中...' : transcriptionText }}\r\n </div>\r\n <div class=\"fab-avatar-wrapper\">\r\n <img\r\n :src=\"xLogo ? xLogo : '/x.png'\"\r\n alt=\"voice assistant\"\r\n :style=\"{\r\n width: `${xSize?.width || 88}px`,\r\n }\"\r\n />\r\n\r\n <transition name=\"indicator-fade\">\r\n <div\r\n v-if=\"voiceStatus === 'listening'\"\r\n class=\"listening-badge\"\r\n :class=\"{ 'wake-active': wakeAnimating || isTranscribing || isInvoking }\"\r\n >\r\n <div class=\"listening-waves\">\r\n <div class=\"wave wave-1\"></div>\r\n <div class=\"wave wave-2\"></div>\r\n <div class=\"wave wave-3\"></div>\r\n </div>\r\n <div class=\"listening-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z\"\r\n fill=\"currentColor\"\r\n />\r\n <path\r\n d=\"M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n </div>\r\n </transition>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { computed, onBeforeUnmount } from 'vue';\r\nimport { useAgentInvoke } from '../composables/use-agent-invoke';\r\nimport { useBubble } from '../composables/use-bubble';\r\nimport { useTTS } from '../composables/use-tts';\r\nimport { useVoiceRecognition } from '../composables/use-voice-recognition';\r\nimport { AiChatbotXKey, injectStrict } from '../injection-key';\r\nimport type { VoiceConfig } from '../types';\r\n\r\ninterface XSize {\r\n width: number;\r\n height: number;\r\n}\r\n\r\ninterface BubbleSize {\r\n width?: string;\r\n maxHeight?: string;\r\n}\r\n\r\nconst props = defineProps<{\r\n xLogo?: string;\r\n xTitle?: string;\r\n xSize?: XSize;\r\n xTheme?: 'light' | 'dark' | 'system';\r\n wakeWords?: string[];\r\n wakeResponses?: string[];\r\n modelPath?: string;\r\n agentId?: string;\r\n projectId?: string;\r\n voiceConfig?: VoiceConfig;\r\n bubbleSize?: BubbleSize;\r\n bubbleDismissDelay?: number;\r\n}>();\r\n\r\nconst aiChatbotX = injectStrict(AiChatbotXKey);\r\n\r\nconst getVoiceConfig = (): VoiceConfig | null => {\r\n if (props.voiceConfig) return props.voiceConfig;\r\n return null;\r\n};\r\n\r\nconst currentTheme = 'dark' as const;\r\n\r\nconst wakeResponses = computed(() => props.wakeResponses || ['在呢']);\r\nconst agentId = computed(() => props.agentId);\r\n\r\n// ── 1. TTS ──\r\n\r\nconst tts = useTTS(getVoiceConfig);\r\n\r\n// ── 2. Agent 调用(先创建,以获取 isInvoking ref) ──\r\n\r\n// 先声明 bubble 方法引用,后面绑定到真实 bubble 实例\r\nconst bubbleBridge = {\r\n open: () => {},\r\n scheduleDismiss: () => {},\r\n scrollToBottom: () => {},\r\n};\r\n\r\nconst endpoint = `/sime/proxy/organizations/${aiChatbotX.organizationId()}/agents/${agentId.value}/stream-invoke`;\r\n\r\nconst agent = useAgentInvoke({\r\n endpoint,\r\n appToken: aiChatbotX.appToken(),\r\n projectId: props.projectId,\r\n aiChatbotX,\r\n tts: {\r\n speak: tts.speak,\r\n feed: tts.feed,\r\n flush: tts.flush,\r\n stop: tts.stop,\r\n },\r\n bubble: {\r\n open: () => bubbleBridge.open(),\r\n scheduleDismiss: () => bubbleBridge.scheduleDismiss(),\r\n scrollToBottom: () => bubbleBridge.scrollToBottom(),\r\n },\r\n});\r\n\r\n// ── 3. 气泡(用 agent.isInvoking + tts.isSpeaking 保证气泡不会提前消失) ──\r\n\r\nconst bubble = useBubble({\r\n dismissDelay: props.bubbleDismissDelay,\r\n isSpeaking: tts.isSpeaking,\r\n hasPendingAudio: tts.hasPendingAudio,\r\n isInvoking: agent.isInvoking,\r\n bubbleSize: props.bubbleSize,\r\n});\r\n\r\n// 绑定真实 bubble 方法\r\nbubbleBridge.open = bubble.open;\r\nbubbleBridge.scheduleDismiss = bubble.scheduleDismiss;\r\nbubbleBridge.scrollToBottom = bubble.scrollToBottom;\r\n\r\nconst { show: showBubble, style: bubbleStyle, stackRef: bubbleStackRef } = bubble;\r\n\r\n// TTS 播报结束后的气泡消失由 useBubble 内部 watch(isSpeaking) 自动处理,无需额外回调\r\n\r\n// ── 4. 中断回复:唤醒时中断当前播报和调用 ──\r\n\r\nconst interruptCurrentResponse = () => {\r\n agent.abort();\r\n agent.resetState();\r\n tts.stop();\r\n bubble.hide();\r\n};\r\n\r\n// ── 4.5 TTS 纯播报(带气泡,与 sendMessage 展示一致) ──\r\n\r\nconst speakTextWithBubble = async (text: string) => {\r\n bubble.open();\r\n agent.currentTextContent.value = text;\r\n try {\r\n await tts.speak(text);\r\n } finally {\r\n bubble.scheduleDismiss();\r\n }\r\n};\r\n\r\n// ── 5. 语音识别 ──\r\n\r\nconst voice = useVoiceRecognition({\r\n modelPath: props.modelPath,\r\n wakeWords: props.wakeWords,\r\n getVoiceConfig,\r\n onWake: () => {\r\n interruptCurrentResponse();\r\n tts.warmUpAudio();\r\n const text = wakeResponses.value[Math.floor(Math.random() * wakeResponses.value.length)];\r\n tts.speak(text);\r\n },\r\n onTranscriptionDone: (text) => {\r\n agent.invoke(text);\r\n },\r\n});\r\n\r\n// ── 切换语音模式(点击 FAB) ──\r\n\r\nconst toggleVoiceMode = async (targetState?: boolean) => {\r\n tts.warmUpAudio();\r\n await voice.toggleVoiceMode(targetState);\r\n};\r\n\r\n// ── 模板暴露 ──\r\n\r\nconst { voiceStatus, transcriptionText, wakeAnimating, isTranscribing } = voice;\r\nconst { isInvoking, currentTextContent, currentToolParts, executingTools, hasAnyContent, toolDisplayName } = agent;\r\n\r\n// ── 外部方法注册 ──\r\n\r\naiChatbotX?.registerVoiceMethods({\r\n stopBroadcast: async () => interruptCurrentResponse(),\r\n start: () => toggleVoiceMode(true),\r\n stop: () => toggleVoiceMode(false),\r\n});\r\n\r\naiChatbotX?.registerVoiceAssistant({\r\n agentInvoke: agent.invoke,\r\n agentAbort: agent.abort,\r\n speakText: speakTextWithBubble,\r\n stopSpeak: tts.stop,\r\n});\r\n\r\n// ── 清理 ──\r\n\r\nonBeforeUnmount(async () => {\r\n bubble.destroy();\r\n agent.abort();\r\n tts.destroy();\r\n await voice.destroy();\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.voice-assistant {\r\n --text-primary: #e6edf7;\r\n --text-secondary: #95a8c8;\r\n --glass-bg: rgba(8, 16, 32, 0.72);\r\n --glass-border: rgba(125, 160, 220, 0.28);\r\n --shadow-md: 0 18px 36px rgba(1, 6, 20, 0.56);\r\n --color-success: #4ade80;\r\n --color-error: #f87171;\r\n --color-accent: #818cf8;\r\n\r\n position: relative;\r\n display: inline-flex;\r\n flex-direction: column;\r\n align-items: flex-end;\r\n gap: 12px;\r\n}\r\n\r\n/* ── FAB 按钮 ── */\r\n.assistant-fab {\r\n position: relative;\r\n cursor: pointer;\r\n transition:\r\n transform 0.2s ease,\r\n filter 0.2s ease;\r\n\r\n &:hover {\r\n transform: translateY(-1px) scale(1.03);\r\n filter: brightness(1.06);\r\n }\r\n}\r\n\r\n.status-pill {\r\n position: absolute;\r\n right: calc(100% + 12px);\r\n top: 50%;\r\n transform: translateY(-50%);\r\n max-width: 280px;\r\n background: var(--glass-bg);\r\n color: var(--text-primary);\r\n font-size: 12px;\r\n line-height: 1.45;\r\n padding: 8px 13px;\r\n border-radius: 999px;\r\n border: 1px solid var(--glass-border);\r\n backdrop-filter: blur(10px);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n box-shadow: 0 10px 20px rgba(2, 8, 24, 0.38);\r\n}\r\n\r\n.fab-avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n img {\r\n display: block;\r\n height: auto;\r\n object-fit: contain;\r\n filter: drop-shadow(var(--shadow-md)) saturate(1.05);\r\n }\r\n}\r\n\r\n/* ── 气泡容器 ── */\r\n.bubble-stack {\r\n position: absolute;\r\n right: 0;\r\n bottom: calc(100% + 16px);\r\n width: min(380px, 86vw);\r\n max-height: min(58vh, 520px);\r\n overflow: auto;\r\n\r\n &::-webkit-scrollbar {\r\n width: 4px;\r\n }\r\n\r\n &::-webkit-scrollbar-thumb {\r\n background: rgba(126, 155, 204, 0.3);\r\n border-radius: 999px;\r\n }\r\n}\r\n\r\n/* ── 统一 agent 气泡 ── */\r\n.agent-bubble {\r\n border-radius: 16px;\r\n padding: 12px 14px;\r\n background:\r\n radial-gradient(circle at 12% 10%, rgba(80, 122, 255, 0.14), transparent 50%),\r\n linear-gradient(155deg, rgba(24, 42, 72, 0.96), rgba(14, 24, 46, 0.97));\r\n border: 1px solid rgba(108, 141, 204, 0.2);\r\n box-shadow:\r\n 0 12px 32px rgba(1, 6, 20, 0.5),\r\n inset 0 1px 0 rgba(255, 255, 255, 0.04);\r\n backdrop-filter: blur(16px);\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n animation: bubble-appear 0.3s cubic-bezier(0.16, 1, 0.3, 1);\r\n}\r\n\r\n@keyframes bubble-appear {\r\n from {\r\n opacity: 0;\r\n transform: translateY(8px) scale(0.97);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0) scale(1);\r\n }\r\n}\r\n\r\n/* ── 工具执行步骤(内联紧凑) ── */\r\n.tool-steps {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n margin-bottom: 6px;\r\n padding-bottom: 8px;\r\n border-bottom: 1px solid rgba(125, 160, 220, 0.1);\r\n}\r\n\r\n.tool-step {\r\n display: flex;\r\n align-items: center;\r\n gap: 7px;\r\n padding: 4px 6px;\r\n border-radius: 8px;\r\n transition: background 0.2s ease;\r\n animation: step-in 0.25s cubic-bezier(0.16, 1, 0.3, 1);\r\n\r\n &--loading {\r\n .tool-step__icon {\r\n color: var(--color-accent);\r\n }\r\n .tool-step__name {\r\n color: rgba(200, 215, 240, 0.85);\r\n }\r\n }\r\n\r\n &--done {\r\n .tool-step__icon {\r\n color: var(--color-success);\r\n }\r\n .tool-step__name {\r\n color: rgba(200, 215, 240, 0.55);\r\n }\r\n }\r\n\r\n &--error {\r\n .tool-step__icon {\r\n color: var(--color-error);\r\n }\r\n .tool-step__name {\r\n color: rgba(248, 113, 113, 0.8);\r\n }\r\n }\r\n\r\n &--executing {\r\n background: rgba(129, 140, 248, 0.06);\r\n .tool-step__icon {\r\n color: var(--color-accent);\r\n }\r\n }\r\n}\r\n\r\n@keyframes step-in {\r\n from {\r\n opacity: 0;\r\n transform: translateX(-6px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateX(0);\r\n }\r\n}\r\n\r\n.tool-step__icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 18px;\r\n height: 18px;\r\n flex-shrink: 0;\r\n}\r\n\r\n.tool-step__spinner {\r\n animation: tool-spin 0.8s linear infinite;\r\n}\r\n\r\n@keyframes tool-spin {\r\n from {\r\n transform: rotate(0deg);\r\n }\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n.tool-step__name {\r\n font-size: 12px;\r\n font-weight: 500;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n transition: color 0.2s ease;\r\n}\r\n\r\n.tool-step__tag {\r\n font-size: 10px;\r\n font-weight: 500;\r\n padding: 1px 6px;\r\n border-radius: 4px;\r\n white-space: nowrap;\r\n flex-shrink: 0;\r\n\r\n &--exec {\r\n background: rgba(129, 140, 248, 0.12);\r\n color: var(--color-accent);\r\n }\r\n}\r\n\r\n/* ── 思考中动画 ── */\r\n.thinking-dots {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 5px;\r\n padding: 2px 0;\r\n\r\n span {\r\n width: 5px;\r\n height: 5px;\r\n border-radius: 50%;\r\n background: var(--text-secondary);\r\n animation: thinking-bounce 1s infinite ease-in-out;\r\n }\r\n\r\n span:nth-child(2) {\r\n animation-delay: 0.15s;\r\n }\r\n\r\n span:nth-child(3) {\r\n animation-delay: 0.3s;\r\n }\r\n}\r\n\r\n@keyframes thinking-bounce {\r\n 0%,\r\n 100% {\r\n transform: translateY(0);\r\n opacity: 0.3;\r\n }\r\n 50% {\r\n transform: translateY(-3px);\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* ── 文本内容 ── */\r\n.agent-text {\r\n font-size: 14px;\r\n line-height: 1.55;\r\n color: var(--text-primary);\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n/* ── 气泡淡入淡出过渡 ── */\r\n.bubble-fade-enter-active {\r\n transition: all 0.35s cubic-bezier(0.16, 1, 0.3, 1);\r\n}\r\n\r\n.bubble-fade-leave-active {\r\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n}\r\n\r\n.bubble-fade-enter-from {\r\n opacity: 0;\r\n transform: translateY(12px) scale(0.95);\r\n}\r\n\r\n.bubble-fade-leave-to {\r\n opacity: 0;\r\n transform: translateY(8px) scale(0.97);\r\n}\r\n\r\n/* ── 监听状态指示器 ── */\r\n.listening-badge {\r\n position: absolute;\r\n top: -8px;\r\n right: -8px;\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n background-color: rgba(0, 0, 0, 0.72);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.listening-waves {\r\n position: absolute;\r\n inset: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.wave {\r\n position: absolute;\r\n width: 100%;\r\n height: 100%;\r\n border-radius: 50%;\r\n border: 2px solid rgba(255, 255, 255, 0.65);\r\n animation: wave-expand 3s ease-out infinite;\r\n}\r\n\r\n.wave-1 {\r\n animation-delay: 0s;\r\n}\r\n\r\n.wave-2 {\r\n animation-delay: 0.6s;\r\n}\r\n\r\n.wave-3 {\r\n animation-delay: 1.2s;\r\n}\r\n\r\n.listening-icon {\r\n position: relative;\r\n color: #fff;\r\n}\r\n\r\n.listening-badge.wake-active {\r\n background-color: rgba(34, 197, 94, 0.9);\r\n animation: wake-badge-pop 0.35s ease;\r\n}\r\n\r\n.indicator-fade-enter-active,\r\n.indicator-fade-leave-active {\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.indicator-fade-enter-from,\r\n.indicator-fade-leave-to {\r\n opacity: 0;\r\n transform: translateY(6px);\r\n}\r\n\r\n@media (max-width: 768px) {\r\n .bubble-stack {\r\n width: min(320px, 88vw);\r\n max-height: min(54vh, 420px);\r\n }\r\n\r\n .status-pill {\r\n max-width: 220px;\r\n }\r\n}\r\n\r\n@keyframes wave-expand {\r\n 0% {\r\n transform: scale(0.8);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: scale(1.2);\r\n opacity: 0;\r\n }\r\n}\r\n\r\n@keyframes wake-badge-pop {\r\n 0% {\r\n transform: scale(1);\r\n }\r\n 50% {\r\n transform: scale(1.35);\r\n }\r\n 100% {\r\n transform: scale(1);\r\n }\r\n}\r\n</style>\r\n","import type { CommandDefinition, DiscoveredCommand } from './utils/command-types';\r\n\r\nexport enum clientCommandKey {\r\n SET_THEME = 'SiMeAgent_setTheme',\r\n APPEND_MESSAGE = 'SiMeAgent_appendMessage',\r\n WAKE = 'SiMeAgent_wake',\r\n TRANSITION = 'SiMeAgent_transition',\r\n TRANSITION_END = 'SiMeAgent_transition_end',\r\n START_NEW_CONVERSATION = 'SiMeAgent_startNewConversation',\r\n RECOGNITION = 'SiMeAgent_recognition',\r\n}\r\n\r\nexport interface VoiceConfig {\r\n appId: string;\r\n /** STT(语音转写)apiKey */\r\n apiKey: string;\r\n /** apiSecret,TTS 鉴权必需 */\r\n apiSecret?: string;\r\n /** STT(语音转写)WebSocket 地址 */\r\n websocketUrl: string;\r\n /** TTS apiKey(可选,不填则复用 apiKey) */\r\n ttsApiKey?: string;\r\n /** TTS(语音合成)WebSocket 地址 */\r\n ttsWebsocketUrl?: string;\r\n /** TTS 发音人,默认 xiaoyan */\r\n ttsVcn?: string;\r\n /** TTS 发音速度 */\r\n speed?: number;\r\n /** TTS 发音音量 */\r\n volume?: number;\r\n /** TTS 发音音调 */\r\n pitch?: number;\r\n}\r\n\r\nexport interface AiChatbotXContext {\r\n appToken: () => string;\r\n organizationId: () => string;\r\n registerCommand: (cmd: CommandDefinition) => void;\r\n unregisterCommand: (name: string) => void;\r\n getCommads: () => Promise<DiscoveredCommand[]>;\r\n /** 中止当前语音播报并关闭气泡 */\r\n stopBroadcast: () => Promise<void>;\r\n startListening: () => Promise<void>;\r\n stopListening: () => Promise<void>;\r\n registerVoiceMethods: (methods: {\r\n stopBroadcast?: () => Promise<void>;\r\n start: () => Promise<void>;\r\n stop: () => Promise<void>;\r\n }) => void;\r\n registerVoiceAssistant: (methods: {\r\n agentInvoke: (text: string) => Promise<void>;\r\n agentAbort: () => void;\r\n speakText: (text: string) => void;\r\n stopSpeak: () => void;\r\n }) => void;\r\n executeCommand: (commandName: string, args?: any[]) => Promise<any>;\r\n sendMessage: (text: string) => Promise<void>;\r\n speakText: (text: string) => void;\r\n stopSpeak: () => void;\r\n abortInvoke: () => void;\r\n}\r\n"],"names":["DefaultChatTransport","Chat","ref","reactive","computed","nextTick","watch","onMounted","_createElementBlock","_normalizeClass","_openBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_8","_Fragment","_renderList","_hoisted_9","_hoisted_10","_unref","_hoisted_11","_hoisted_13","_hoisted_15","_createVNode","_Transition","inject","currentTheme","onBeforeUnmount","_hoisted_7","shallowRef","provide","_renderSlot","SpeechSynthesizerStandalone","SpeechTranscriberStandalone","WakeWordDetectorStandalone","_normalizeStyle","clientCommandKey"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sime-x-vue.umd.js","sources":["../src/lib/agent-chat-transport.ts","../src/components/ai-chat.vue","../src/lib/data-stream-parser.ts","../src/composables/use-agent-invoke.ts","../src/composables/use-bubble.ts","../src/injection-key.ts","../src/components/command-test.vue","../src/utils/command-manager.ts","../src/components/sime-provider.vue","../src/composables/use-tts.ts","../src/lib/utils.ts","../src/composables/use-voice-recognition.ts","../src/components/voice-assistant.vue","../src/types.ts"],"sourcesContent":["import type { UIMessage } from 'ai';\r\nimport { DefaultChatTransport } from 'ai';\r\nimport type { DiscoveredCommand } from '../utils/command-types';\r\n\r\nexport interface AgentChatTransportOptions {\r\n /** streamInvoke endpoint URL, e.g. http://host/agent/{id}/stream-invoke */\r\n api: string;\r\n /** 项目 ID */\r\n projectId?: string;\r\n /** 动态获取宿主命令 */\r\n getCommands?: () => Promise<DiscoveredCommand[]>;\r\n /** 额外 headers */\r\n headers?: Record<string, string> | (() => Record<string, string>);\r\n /** 额外 body 字段 */\r\n body?: Record<string, unknown> | (() => Record<string, unknown>);\r\n}\r\n\r\n/**\r\n * 基于 DefaultChatTransport 的自定义 Transport,\r\n * 通过 prepareSendMessagesRequest 将 AI SDK 标准 messages 转换为 streamInvoke 接口格式。\r\n *\r\n * streamInvoke 期望:{ input, projectId, commands, messages }\r\n * - input: 最后一条 user 消息的文本\r\n * - messages: 历史对话(不含最后一条 user 消息)\r\n * - commands: 宿主命令列表\r\n * - projectId: 项目 ID\r\n */\r\nexport function createAgentChatTransport(options: AgentChatTransportOptions) {\r\n const { api, projectId, getCommands, headers: extraHeaders, body: extraBody } = options;\r\n\r\n return new DefaultChatTransport({\r\n api,\r\n headers: extraHeaders,\r\n prepareSendMessagesRequest({ messages }) {\r\n // 提取最后一条 user 消息作为 input\r\n const lastUserMessage = findLastUserMessage(messages);\r\n const input = lastUserMessage\r\n ? lastUserMessage.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('')\r\n : '';\r\n\r\n // 将历史消息转换为 streamInvoke 的简单 messages 格式\r\n const historyMessages = buildHistoryMessages(messages, lastUserMessage?.id);\r\n\r\n const resolvedExtraBody = typeof extraBody === 'function' ? extraBody() : extraBody || {};\r\n\r\n return {\r\n body: {\r\n input,\r\n projectId: projectId || '',\r\n messages: historyMessages.length > 0 ? historyMessages : undefined,\r\n ...resolvedExtraBody,\r\n },\r\n };\r\n },\r\n });\r\n}\r\n\r\n/**\r\n * 带命令注入的 AgentChatTransport 工厂函数\r\n * 在每次发送前异步获取宿主命令并注入 body\r\n */\r\nexport class AgentChatTransport extends DefaultChatTransport<UIMessage> {\r\n private agentOptions: AgentChatTransportOptions;\r\n\r\n constructor(options: AgentChatTransportOptions) {\r\n const { api, headers: extraHeaders, body: extraBody, projectId } = options;\r\n\r\n super({\r\n api,\r\n headers: extraHeaders,\r\n prepareSendMessagesRequest({ messages }) {\r\n const lastUserMessage = findLastUserMessage(messages);\r\n const input = lastUserMessage\r\n ? lastUserMessage.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('')\r\n : '';\r\n\r\n const historyMessages = buildHistoryMessages(messages, lastUserMessage?.id);\r\n\r\n const resolvedExtraBody = typeof extraBody === 'function' ? extraBody() : extraBody || {};\r\n\r\n return {\r\n body: {\r\n input,\r\n projectId: projectId || '',\r\n messages: historyMessages.length > 0 ? historyMessages : undefined,\r\n ...resolvedExtraBody,\r\n },\r\n };\r\n },\r\n });\r\n\r\n this.agentOptions = options;\r\n }\r\n\r\n async sendMessages(options: Parameters<DefaultChatTransport<UIMessage>['sendMessages']>[0]) {\r\n // 如果配置了 getCommands,在发送前获取宿主命令并注入 body\r\n if (this.agentOptions.getCommands) {\r\n try {\r\n const commands = await this.agentOptions.getCommands();\r\n if (commands && commands.length > 0) {\r\n options.body = {\r\n ...((options.body as Record<string, unknown>) || {}),\r\n commands,\r\n };\r\n }\r\n } catch {\r\n // 获取命令失败,静默忽略\r\n }\r\n }\r\n\r\n return super.sendMessages(options);\r\n }\r\n}\r\n\r\n// ── 辅助函数 ──\r\n\r\nfunction findLastUserMessage(messages: UIMessage[]): UIMessage | undefined {\r\n for (let i = messages.length - 1; i >= 0; i--) {\r\n if (messages[i].role === 'user') {\r\n return messages[i];\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction buildHistoryMessages(\r\n messages: UIMessage[],\r\n excludeId?: string,\r\n): Array<{ role: 'user' | 'assistant'; content: string }> {\r\n const history: Array<{ role: 'user' | 'assistant'; content: string }> = [];\r\n\r\n for (const msg of messages) {\r\n if (msg.id === excludeId) continue;\r\n if (msg.role !== 'user' && msg.role !== 'assistant') continue;\r\n\r\n const textContent = msg.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('');\r\n\r\n if (textContent.trim()) {\r\n history.push({\r\n role: msg.role as 'user' | 'assistant',\r\n content: textContent,\r\n });\r\n }\r\n }\r\n\r\n return history;\r\n}\r\n","<template>\r\n <div class=\"ai-chat\" :class=\"{ 'ai-chat--full-width': fullWidth }\">\r\n <!-- 空消息:欢迎页 -->\r\n <div v-if=\"isEmpty\" class=\"ai-chat__welcome\">\r\n <div class=\"ai-chat__welcome-header\">\r\n <h1 class=\"ai-chat__welcome-title\">{{ welcomeTitle }}</h1>\r\n <p class=\"ai-chat__welcome-desc\">{{ welcomeDescription }}</p>\r\n </div>\r\n\r\n <div class=\"ai-chat__input-area\">\r\n <form class=\"ai-chat__form\" @submit.prevent=\"handleSubmit\">\r\n <div class=\"ai-chat__input-wrapper\">\r\n <textarea\r\n ref=\"textareaRef\"\r\n v-model=\"inputText\"\r\n class=\"ai-chat__textarea\"\r\n placeholder=\"发送消息...\"\r\n rows=\"1\"\r\n @keydown=\"handleKeydown\"\r\n @input=\"autoResize\"\r\n />\r\n <button\r\n type=\"submit\"\r\n class=\"ai-chat__send-btn\"\r\n :disabled=\"!inputText.trim() || isLoading\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </form>\r\n\r\n <div v-if=\"suggestions.length > 0\" class=\"ai-chat__suggestions\">\r\n <button\r\n v-for=\"suggestion in suggestions\"\r\n :key=\"suggestion\"\r\n class=\"ai-chat__suggestion\"\r\n @click=\"handleSuggestionClick(suggestion)\"\r\n >\r\n {{ suggestion }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- 消息列表 -->\r\n <template v-else>\r\n <div ref=\"messagesContainerRef\" class=\"ai-chat__messages\" @scroll=\"handleScroll\">\r\n <div class=\"ai-chat__messages-inner\">\r\n <div\r\n v-for=\"message in chat.messages\"\r\n :key=\"message.id\"\r\n class=\"ai-chat__message-group\"\r\n >\r\n <template v-for=\"(part, partIndex) in message.parts\" :key=\"`${message.id}-${partIndex}`\">\r\n <!-- 文本消息 -->\r\n <div v-if=\"part.type === 'text'\" class=\"ai-chat__message\" :class=\"`ai-chat__message--${message.role}`\">\r\n <div class=\"ai-chat__message-content\">\r\n <div class=\"ai-chat__message-text\" v-html=\"renderMarkdown(part.text)\" />\r\n </div>\r\n </div>\r\n\r\n <!-- 推理/思考过程 -->\r\n <div v-else-if=\"part.type === 'reasoning'\" class=\"ai-chat__reasoning\">\r\n <button class=\"ai-chat__reasoning-trigger\" @click=\"toggleReasoning(message.id)\">\r\n <svg\r\n class=\"ai-chat__reasoning-icon\"\r\n :class=\"{ 'ai-chat__reasoning-icon--open': reasoningOpen[message.id] }\"\r\n width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"\r\n >\r\n <polyline points=\"9 18 15 12 9 6\" />\r\n </svg>\r\n <span>思考过程</span>\r\n <span\r\n v-if=\"isStreamingMessage(message.id) && partIndex === message.parts.length - 1\"\r\n class=\"ai-chat__reasoning-streaming\"\r\n />\r\n </button>\r\n <div v-if=\"reasoningOpen[message.id]\" class=\"ai-chat__reasoning-content\">\r\n {{ part.text }}\r\n </div>\r\n </div>\r\n\r\n <!-- 工具调用/结果 -->\r\n <div v-else-if=\"isToolPart(part)\" class=\"ai-chat__tool\">\r\n <div\r\n class=\"ai-chat__tool-step\"\r\n :class=\"{\r\n 'ai-chat__tool-step--loading': isToolLoading(part),\r\n 'ai-chat__tool-step--done': isToolDone(part),\r\n 'ai-chat__tool-step--error': isToolError(part),\r\n }\"\r\n >\r\n <!-- 状态图标 -->\r\n <span class=\"ai-chat__tool-icon\">\r\n <svg v-if=\"isToolLoading(part)\" class=\"ai-chat__tool-spinner\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-dasharray=\"31.4 31.4\" />\r\n </svg>\r\n <svg v-else-if=\"isToolDone(part)\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M20 6L9 17l-5-5\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <svg v-else-if=\"isToolError(part)\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <path d=\"M15 9l-6 6M9 9l6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n </span>\r\n <span class=\"ai-chat__tool-name\">{{ getToolDisplayName(getToolName(part)) }}</span>\r\n </div>\r\n </div>\r\n </template>\r\n\r\n <!-- 助手消息操作(非流式时显示) -->\r\n <div\r\n v-if=\"message.role === 'assistant' && !isStreamingMessage(message.id)\"\r\n class=\"ai-chat__message-actions\"\r\n >\r\n <button class=\"ai-chat__action-btn\" title=\"重新生成\" @click=\"handleRegenerate(message.id)\">\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"23 4 23 10 17 10\" /><polyline points=\"1 20 1 14 7 14\" />\r\n <path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\" />\r\n </svg>\r\n </button>\r\n <button class=\"ai-chat__action-btn\" title=\"复制\" @click=\"handleCopy(message)\">\r\n <svg v-if=\"!copiedId || copiedId !== message.id\" width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" /><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\r\n </svg>\r\n <svg v-else width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"20 6 9 17 4 12\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <!-- 流式加载指示器 -->\r\n <div v-if=\"chat.status === 'submitted'\" class=\"ai-chat__thinking\">\r\n <div class=\"ai-chat__thinking-dots\">\r\n <span /><span /><span />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- 滚动到底部按钮 -->\r\n <transition name=\"fade\">\r\n <button\r\n v-if=\"showScrollButton\"\r\n class=\"ai-chat__scroll-btn\"\r\n @click=\"scrollToBottom\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <polyline points=\"6 9 12 15 18 9\" />\r\n </svg>\r\n </button>\r\n </transition>\r\n\r\n <!-- 输入区域 -->\r\n <div v-if=\"!isReadonly\" class=\"ai-chat__input-area ai-chat__input-area--bottom\">\r\n <form class=\"ai-chat__form\" @submit.prevent=\"handleSubmit\">\r\n <div class=\"ai-chat__input-wrapper\">\r\n <textarea\r\n ref=\"textareaRef\"\r\n v-model=\"inputText\"\r\n class=\"ai-chat__textarea\"\r\n placeholder=\"发送消息...\"\r\n rows=\"1\"\r\n @keydown=\"handleKeydown\"\r\n @input=\"autoResize\"\r\n />\r\n <button\r\n v-if=\"chat.status === 'streaming' || chat.status === 'submitted'\"\r\n type=\"button\"\r\n class=\"ai-chat__stop-btn\"\r\n @click=\"handleStop\"\r\n >\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" />\r\n </svg>\r\n </button>\r\n <button\r\n v-else\r\n type=\"submit\"\r\n class=\"ai-chat__send-btn\"\r\n :disabled=\"!inputText.trim()\"\r\n >\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\r\n </svg>\r\n </button>\r\n </div>\r\n </form>\r\n </div>\r\n </template>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { ref, computed, watch, nextTick, onMounted, reactive } from 'vue';\r\nimport { Chat } from '@ai-sdk/vue';\r\nimport type { UIMessage } from 'ai';\r\nimport { AgentChatTransport } from '../lib/agent-chat-transport';\r\nimport type { AgentChatTransportOptions } from '../lib/agent-chat-transport';\r\n\r\n// ── 工具名称映射 ──\r\nconst toolDisplayNames: Record<string, string> = {\r\n generateReport: '生成报告',\r\n searchKnowledge: '知识库检索',\r\n resolveInstanceTargets: '解析实例目标',\r\n getHistoryMetrics: '历史数据查询',\r\n getRealtimeMetrics: '实时数据查询',\r\n queryBitableData: '多维表格查询',\r\n searchUser: '搜索用户',\r\n createBitableRecord: '创建表格记录',\r\n timeTool: '时间工具',\r\n loadSkill: '加载技能',\r\n executeCommand: '执行命令',\r\n dataAnalyzer: '数据分析',\r\n dataPredictor: '数据预测',\r\n};\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n /** streamInvoke endpoint URL */\r\n api: string;\r\n /** 项目 ID */\r\n projectId?: string;\r\n /** 是否只读 */\r\n isReadonly?: boolean;\r\n /** 欢迎标题 */\r\n welcomeTitle?: string;\r\n /** 欢迎描述 */\r\n welcomeDescription?: string;\r\n /** 快捷建议 */\r\n suggestions?: string[];\r\n /** 是否全宽 */\r\n fullWidth?: boolean;\r\n /** 自定义工具名称映射 */\r\n toolNames?: Record<string, string>;\r\n /** 额外 transport 配置 */\r\n transportOptions?: Partial<AgentChatTransportOptions>;\r\n /** 额外 headers */\r\n headers?: Record<string, string>;\r\n /** 额外 body */\r\n body?: Record<string, unknown>;\r\n }>(),\r\n {\r\n isReadonly: false,\r\n welcomeTitle: '你好,有什么可以帮助你的吗?',\r\n welcomeDescription: '我可以帮你回答问题、分析数据、生成报告等。',\r\n suggestions: () => [],\r\n fullWidth: false,\r\n toolNames: () => ({}),\r\n },\r\n);\r\n\r\nconst emit = defineEmits<{\r\n (e: 'error', error: Error): void;\r\n (e: 'finish', message: UIMessage): void;\r\n}>();\r\n\r\n// ── Chat 实例 ──\r\nconst transport = new AgentChatTransport({\r\n api: props.api,\r\n projectId: props.projectId,\r\n headers: props.headers,\r\n body: props.body,\r\n ...props.transportOptions,\r\n});\r\n\r\nconst chat = new Chat({\r\n transport,\r\n onError: (error) => {\r\n console.error('[AiChat] error:', error);\r\n emit('error', error instanceof Error ? error : new Error(String(error)));\r\n },\r\n onFinish: ({ message }) => {\r\n emit('finish', message);\r\n },\r\n});\r\n\r\n// ── 输入状态 ──\r\nconst inputText = ref('');\r\nconst textareaRef = ref<HTMLTextAreaElement | null>(null);\r\nconst messagesContainerRef = ref<HTMLElement | null>(null);\r\nconst showScrollButton = ref(false);\r\nconst copiedId = ref<string | null>(null);\r\nconst reasoningOpen = reactive<Record<string, boolean>>({});\r\n\r\nconst isEmpty = computed(() => chat.messages.length === 0);\r\nconst isLoading = computed(() => chat.status === 'streaming' || chat.status === 'submitted');\r\n\r\n// ── 自动滚动 ──\r\nconst scrollToBottom = () => {\r\n nextTick(() => {\r\n const el = messagesContainerRef.value;\r\n if (el) {\r\n el.scrollTop = el.scrollHeight;\r\n }\r\n });\r\n};\r\n\r\nconst handleScroll = () => {\r\n const el = messagesContainerRef.value;\r\n if (!el) return;\r\n const threshold = 100;\r\n showScrollButton.value = el.scrollHeight - el.scrollTop - el.clientHeight > threshold;\r\n};\r\n\r\n// 消息变化时自动滚动\r\nwatch(\r\n () => chat.messages.length,\r\n () => {\r\n if (!showScrollButton.value) {\r\n scrollToBottom();\r\n }\r\n },\r\n);\r\n\r\n// 流式输出时自动滚动\r\nwatch(\r\n () => {\r\n const msgs = chat.messages;\r\n if (msgs.length === 0) return '';\r\n const last = msgs[msgs.length - 1];\r\n return last.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('');\r\n },\r\n () => {\r\n if (!showScrollButton.value) {\r\n scrollToBottom();\r\n }\r\n },\r\n);\r\n\r\n// ── 输入处理 ──\r\nconst autoResize = () => {\r\n const el = textareaRef.value;\r\n if (!el) return;\r\n el.style.height = 'auto';\r\n el.style.height = `${Math.min(el.scrollHeight, 200)}px`;\r\n};\r\n\r\nconst handleKeydown = (e: KeyboardEvent) => {\r\n if (e.key === 'Enter' && !e.shiftKey) {\r\n e.preventDefault();\r\n handleSubmit();\r\n }\r\n};\r\n\r\nconst handleSubmit = () => {\r\n const text = inputText.value.trim();\r\n if (!text || isLoading.value) return;\r\n\r\n chat.sendMessage({ text });\r\n inputText.value = '';\r\n\r\n nextTick(() => {\r\n if (textareaRef.value) {\r\n textareaRef.value.style.height = 'auto';\r\n }\r\n });\r\n};\r\n\r\nconst handleSuggestionClick = (suggestion: string) => {\r\n chat.sendMessage({ text: suggestion });\r\n};\r\n\r\nconst handleStop = () => {\r\n chat.stop();\r\n};\r\n\r\n// ── 重新生成 ──\r\nconst handleRegenerate = (assistantMessageId: string) => {\r\n const msgs = chat.messages;\r\n const index = msgs.findIndex((m: UIMessage) => m.id === assistantMessageId);\r\n if (index <= 0) return;\r\n\r\n // 找到前一条 user 消息\r\n let userMsg: UIMessage | null = null;\r\n for (let i = index - 1; i >= 0; i--) {\r\n if (msgs[i].role === 'user') {\r\n userMsg = msgs[i];\r\n break;\r\n }\r\n }\r\n if (!userMsg) return;\r\n\r\n const userText = userMsg.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('');\r\n\r\n // 截断消息到 user 消息之前,然后重新发送\r\n chat.messages = msgs.slice(0, msgs.indexOf(userMsg));\r\n\r\n nextTick(() => {\r\n chat.sendMessage({ text: userText });\r\n });\r\n};\r\n\r\n// ── 复制 ──\r\nconst handleCopy = async (message: UIMessage) => {\r\n const text = message.parts\r\n .filter((p: any) => p.type === 'text')\r\n .map((p: any) => p.text)\r\n .join('');\r\n\r\n try {\r\n await navigator.clipboard.writeText(text);\r\n copiedId.value = message.id;\r\n setTimeout(() => {\r\n copiedId.value = null;\r\n }, 2000);\r\n } catch {\r\n console.error('Failed to copy');\r\n }\r\n};\r\n\r\n// ── 工具状态判断 ──\r\nconst isToolPart = (part: any): boolean => {\r\n return typeof part.type === 'string' && part.type.startsWith('tool-');\r\n};\r\n\r\nconst isToolLoading = (part: any): boolean => {\r\n return part.state === 'partial-call' || part.state === 'call' ||\r\n part.state === 'input-streaming' || part.state === 'input-available';\r\n};\r\n\r\nconst isToolDone = (part: any): boolean => {\r\n return part.state === 'result' || part.state === 'output-available';\r\n};\r\n\r\nconst isToolError = (part: any): boolean => {\r\n return part.state === 'error' || part.state === 'output-error';\r\n};\r\n\r\nconst getToolName = (part: any): string => {\r\n return part.toolName || part.type?.replace('tool-', '') || 'unknown';\r\n};\r\n\r\nconst getToolDisplayName = (name: string): string => {\r\n return props.toolNames?.[name] || toolDisplayNames[name] || name;\r\n};\r\n\r\n// ── 流式判断 ──\r\nconst isStreamingMessage = (messageId: string): boolean => {\r\n if (chat.status !== 'streaming' && chat.status !== 'submitted') return false;\r\n const msgs = chat.messages;\r\n return msgs.length > 0 && msgs[msgs.length - 1].id === messageId;\r\n};\r\n\r\n// ── 推理折叠 ──\r\nconst toggleReasoning = (messageId: string) => {\r\n reasoningOpen[messageId] = !reasoningOpen[messageId];\r\n};\r\n\r\n// ── Markdown 简单渲染 ──\r\nconst renderMarkdown = (text: string): string => {\r\n if (!text) return '';\r\n return text\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')\r\n .replace(/\\*(.*?)\\*/g, '<em>$1</em>')\r\n .replace(/`([^`]+)`/g, '<code>$1</code>')\r\n .replace(/```(\\w*)\\n([\\s\\S]*?)```/g, '<pre><code class=\"language-$1\">$2</code></pre>')\r\n .replace(/\\n/g, '<br/>');\r\n};\r\n\r\n// ── 初始化 ──\r\nonMounted(() => {\r\n autoResize();\r\n});\r\n\r\n// ── 暴露 chat 实例给父组件 ──\r\ndefineExpose({\r\n chat,\r\n sendMessage: (text: string) => chat.sendMessage({ text }),\r\n clearMessages: () => { chat.messages = []; },\r\n stop: () => chat.stop(),\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.ai-chat {\r\n --chat-bg: #ffffff;\r\n --chat-text: #1a1a1a;\r\n --chat-text-secondary: #6b7280;\r\n --chat-border: #e5e7eb;\r\n --chat-user-bg: #f3f4f6;\r\n --chat-assistant-bg: transparent;\r\n --chat-input-bg: #f9fafb;\r\n --chat-input-border: #d1d5db;\r\n --chat-input-focus: #3b82f6;\r\n --chat-btn-bg: #3b82f6;\r\n --chat-btn-text: #ffffff;\r\n --chat-suggestion-bg: #f3f4f6;\r\n --chat-suggestion-hover: #e5e7eb;\r\n --chat-tool-accent: #6366f1;\r\n --chat-tool-success: #10b981;\r\n --chat-tool-error: #ef4444;\r\n --chat-code-bg: #f3f4f6;\r\n --chat-scroll-btn-bg: #ffffff;\r\n\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n min-width: 0;\r\n overflow: hidden;\r\n background: var(--chat-bg);\r\n color: var(--chat-text);\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n font-size: 14px;\r\n line-height: 1.6;\r\n position: relative;\r\n}\r\n\r\n// ── 欢迎页 ──\r\n.ai-chat__welcome {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n flex: 1;\r\n padding: 24px;\r\n overflow-y: auto;\r\n}\r\n\r\n.ai-chat__welcome-header {\r\n text-align: center;\r\n margin-bottom: 32px;\r\n}\r\n\r\n.ai-chat__welcome-title {\r\n font-size: 24px;\r\n font-weight: 700;\r\n margin: 0 0 8px;\r\n}\r\n\r\n.ai-chat__welcome-desc {\r\n color: var(--chat-text-secondary);\r\n margin: 0;\r\n max-width: 480px;\r\n}\r\n\r\n// ── 消息区域 ──\r\n.ai-chat__messages {\r\n flex: 1;\r\n overflow-y: auto;\r\n scroll-behavior: smooth;\r\n\r\n &::-webkit-scrollbar {\r\n width: 6px;\r\n }\r\n &::-webkit-scrollbar-thumb {\r\n background: rgba(0, 0, 0, 0.15);\r\n border-radius: 3px;\r\n }\r\n}\r\n\r\n.ai-chat__messages-inner {\r\n max-width: 768px;\r\n margin: 0 auto;\r\n padding: 16px 16px 8px;\r\n\r\n .ai-chat--full-width & {\r\n max-width: 100%;\r\n padding: 16px 48px 8px;\r\n }\r\n}\r\n\r\n// ── 消息 ──\r\n.ai-chat__message-group {\r\n margin-bottom: 16px;\r\n}\r\n\r\n.ai-chat__message {\r\n display: flex;\r\n margin-bottom: 4px;\r\n\r\n &--user {\r\n justify-content: flex-end;\r\n\r\n .ai-chat__message-content {\r\n background: var(--chat-user-bg);\r\n border-radius: 16px 16px 4px 16px;\r\n max-width: 85%;\r\n }\r\n }\r\n\r\n &--assistant {\r\n justify-content: flex-start;\r\n\r\n .ai-chat__message-content {\r\n background: var(--chat-assistant-bg);\r\n max-width: 100%;\r\n }\r\n }\r\n}\r\n\r\n.ai-chat__message-content {\r\n padding: 10px 14px;\r\n border-radius: 16px;\r\n word-break: break-word;\r\n}\r\n\r\n.ai-chat__message-text {\r\n :deep(code) {\r\n background: var(--chat-code-bg);\r\n padding: 1px 4px;\r\n border-radius: 3px;\r\n font-size: 13px;\r\n font-family: 'SF Mono', Monaco, Consolas, monospace;\r\n }\r\n\r\n :deep(pre) {\r\n background: var(--chat-code-bg);\r\n padding: 12px;\r\n border-radius: 8px;\r\n overflow-x: auto;\r\n margin: 8px 0;\r\n\r\n code {\r\n background: transparent;\r\n padding: 0;\r\n }\r\n }\r\n\r\n :deep(strong) {\r\n font-weight: 600;\r\n }\r\n}\r\n\r\n// ── 推理/思考 ──\r\n.ai-chat__reasoning {\r\n margin: 4px 0;\r\n}\r\n\r\n.ai-chat__reasoning-trigger {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n background: none;\r\n border: none;\r\n color: var(--chat-text-secondary);\r\n font-size: 12px;\r\n cursor: pointer;\r\n padding: 4px 8px;\r\n border-radius: 6px;\r\n transition: background 0.15s;\r\n\r\n &:hover {\r\n background: var(--chat-suggestion-bg);\r\n }\r\n}\r\n\r\n.ai-chat__reasoning-icon {\r\n transition: transform 0.2s;\r\n &--open {\r\n transform: rotate(90deg);\r\n }\r\n}\r\n\r\n.ai-chat__reasoning-streaming {\r\n width: 6px;\r\n height: 6px;\r\n border-radius: 50%;\r\n background: var(--chat-tool-accent);\r\n animation: pulse 1s infinite;\r\n}\r\n\r\n.ai-chat__reasoning-content {\r\n margin: 4px 0 4px 20px;\r\n padding: 8px 12px;\r\n border-left: 2px solid var(--chat-border);\r\n color: var(--chat-text-secondary);\r\n font-size: 13px;\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n// ── 工具 ──\r\n.ai-chat__tool {\r\n margin: 2px 0;\r\n}\r\n\r\n.ai-chat__tool-step {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n padding: 4px 10px;\r\n border-radius: 8px;\r\n font-size: 12px;\r\n font-weight: 500;\r\n animation: slide-in 0.25s ease;\r\n\r\n &--loading {\r\n .ai-chat__tool-icon { color: var(--chat-tool-accent); }\r\n .ai-chat__tool-name { color: var(--chat-text-secondary); }\r\n }\r\n\r\n &--done {\r\n .ai-chat__tool-icon { color: var(--chat-tool-success); }\r\n .ai-chat__tool-name { color: var(--chat-text-secondary); opacity: 0.7; }\r\n }\r\n\r\n &--error {\r\n .ai-chat__tool-icon { color: var(--chat-tool-error); }\r\n .ai-chat__tool-name { color: var(--chat-tool-error); }\r\n }\r\n}\r\n\r\n.ai-chat__tool-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 18px;\r\n height: 18px;\r\n flex-shrink: 0;\r\n}\r\n\r\n.ai-chat__tool-spinner {\r\n animation: spin 0.8s linear infinite;\r\n}\r\n\r\n.ai-chat__tool-name {\r\n white-space: nowrap;\r\n}\r\n\r\n// ── 消息操作 ──\r\n.ai-chat__message-actions {\r\n display: flex;\r\n gap: 4px;\r\n margin-top: 4px;\r\n opacity: 0;\r\n transition: opacity 0.2s;\r\n\r\n .ai-chat__message-group:hover & {\r\n opacity: 1;\r\n }\r\n}\r\n\r\n.ai-chat__action-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 28px;\r\n height: 28px;\r\n border-radius: 6px;\r\n border: 1px solid var(--chat-border);\r\n background: var(--chat-bg);\r\n color: var(--chat-text-secondary);\r\n cursor: pointer;\r\n transition: all 0.15s;\r\n\r\n &:hover {\r\n background: var(--chat-suggestion-bg);\r\n color: var(--chat-text);\r\n }\r\n}\r\n\r\n// ── 思考中 ──\r\n.ai-chat__thinking {\r\n padding: 8px 0;\r\n}\r\n\r\n.ai-chat__thinking-dots {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n\r\n span {\r\n width: 6px;\r\n height: 6px;\r\n border-radius: 50%;\r\n background: var(--chat-text-secondary);\r\n animation: thinking-bounce 1s infinite ease-in-out;\r\n\r\n &:nth-child(2) { animation-delay: 0.15s; }\r\n &:nth-child(3) { animation-delay: 0.3s; }\r\n }\r\n}\r\n\r\n// ── 滚动按钮 ──\r\n.ai-chat__scroll-btn {\r\n position: absolute;\r\n bottom: 80px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n width: 36px;\r\n height: 36px;\r\n border-radius: 50%;\r\n border: 1px solid var(--chat-border);\r\n background: var(--chat-scroll-btn-bg);\r\n color: var(--chat-text-secondary);\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);\r\n transition: all 0.15s;\r\n z-index: 10;\r\n\r\n &:hover {\r\n background: var(--chat-suggestion-bg);\r\n color: var(--chat-text);\r\n }\r\n}\r\n\r\n// ── 输入区域 ──\r\n.ai-chat__input-area {\r\n width: 100%;\r\n max-width: 768px;\r\n margin: 0 auto;\r\n padding: 0 16px;\r\n\r\n .ai-chat--full-width & {\r\n max-width: 100%;\r\n padding: 0 48px;\r\n }\r\n\r\n &--bottom {\r\n padding-bottom: 16px;\r\n flex-shrink: 0;\r\n }\r\n}\r\n\r\n.ai-chat__form {\r\n width: 100%;\r\n}\r\n\r\n.ai-chat__input-wrapper {\r\n display: flex;\r\n align-items: flex-end;\r\n gap: 8px;\r\n border: 1px solid var(--chat-input-border);\r\n border-radius: 12px;\r\n padding: 8px 12px;\r\n background: var(--chat-input-bg);\r\n transition: border-color 0.2s, box-shadow 0.2s;\r\n\r\n &:focus-within {\r\n border-color: var(--chat-input-focus);\r\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.15);\r\n }\r\n}\r\n\r\n.ai-chat__textarea {\r\n flex: 1;\r\n border: none;\r\n outline: none;\r\n resize: none;\r\n background: transparent;\r\n color: var(--chat-text);\r\n font-size: 14px;\r\n line-height: 1.5;\r\n font-family: inherit;\r\n min-height: 24px;\r\n max-height: 200px;\r\n\r\n &::placeholder {\r\n color: var(--chat-text-secondary);\r\n }\r\n}\r\n\r\n.ai-chat__send-btn,\r\n.ai-chat__stop-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 8px;\r\n border: none;\r\n cursor: pointer;\r\n flex-shrink: 0;\r\n transition: all 0.15s;\r\n}\r\n\r\n.ai-chat__send-btn {\r\n background: var(--chat-btn-bg);\r\n color: var(--chat-btn-text);\r\n\r\n &:hover:not(:disabled) {\r\n opacity: 0.9;\r\n }\r\n\r\n &:disabled {\r\n opacity: 0.4;\r\n cursor: not-allowed;\r\n }\r\n}\r\n\r\n.ai-chat__stop-btn {\r\n background: var(--chat-tool-error);\r\n color: white;\r\n\r\n &:hover {\r\n opacity: 0.9;\r\n }\r\n}\r\n\r\n// ── 建议 ──\r\n.ai-chat__suggestions {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n margin-top: 12px;\r\n}\r\n\r\n.ai-chat__suggestion {\r\n padding: 8px 14px;\r\n border-radius: 12px;\r\n border: 1px solid var(--chat-border);\r\n background: var(--chat-suggestion-bg);\r\n color: var(--chat-text);\r\n font-size: 13px;\r\n cursor: pointer;\r\n transition: all 0.15s;\r\n text-align: left;\r\n line-height: 1.4;\r\n\r\n &:hover {\r\n background: var(--chat-suggestion-hover);\r\n border-color: var(--chat-input-border);\r\n }\r\n}\r\n\r\n// ── 动画 ──\r\n@keyframes spin {\r\n from { transform: rotate(0deg); }\r\n to { transform: rotate(360deg); }\r\n}\r\n\r\n@keyframes pulse {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.4; }\r\n}\r\n\r\n@keyframes thinking-bounce {\r\n 0%, 100% { transform: translateY(0); opacity: 0.3; }\r\n 50% { transform: translateY(-3px); opacity: 1; }\r\n}\r\n\r\n@keyframes slide-in {\r\n from { opacity: 0; transform: translateX(-6px); }\r\n to { opacity: 1; transform: translateX(0); }\r\n}\r\n\r\n.fade-enter-active,\r\n.fade-leave-active {\r\n transition: opacity 0.2s;\r\n}\r\n.fade-enter-from,\r\n.fade-leave-to {\r\n opacity: 0;\r\n}\r\n</style>\r\n","/**\r\n * AI SDK Stream Protocol Parser for Vue\r\n *\r\n * Handles THREE possible response formats from the agent/chat service:\r\n *\r\n * Format A – UI Message Stream Protocol (pipeUIMessageStreamToResponse) ★ PRIMARY\r\n * SSE format with JSON objects containing a \"type\" field:\r\n * data: {\"type\":\"start\",\"messageId\":\"...\"}\r\n * data: {\"type\":\"text-delta\",\"id\":\"...\",\"delta\":\"Hello\"}\r\n * data: {\"type\":\"tool-input-start\",\"toolCallId\":\"...\",\"toolName\":\"...\"}\r\n * data: {\"type\":\"tool-input-delta\",\"toolCallId\":\"...\",\"inputTextDelta\":\"...\"}\r\n * data: {\"type\":\"tool-input-available\",\"toolCallId\":\"...\",\"toolName\":\"...\",\"input\":{...}}\r\n * data: {\"type\":\"tool-output-available\",\"toolCallId\":\"...\",\"output\":{...}}\r\n * data: {\"type\":\"finish-step\"}\r\n * data: {\"type\":\"finish\"}\r\n * data: [DONE]\r\n *\r\n * Format B – Legacy Data Stream Protocol (pipeDataStreamToResponse)\r\n * Each line: CODE:JSON_VALUE\\n\r\n * 0:\"text\" 9:{toolCallId,toolName} c:{toolCallId,toolName,args} a:{toolCallId,result}\r\n *\r\n * Format C – Plain text stream (pipeTextStreamToResponse fallback)\r\n * Raw UTF-8 text chunks with no protocol framing.\r\n *\r\n * The parser auto-detects the format from the first chunk.\r\n */\r\n\r\n// ── Part types (mirrors AI SDK UIMessage.parts) ──────────────────────\r\n\r\nexport type ToolState =\r\n | 'partial-call' // streaming tool call args\r\n | 'call' // tool call complete, waiting for result\r\n | 'result' // tool result received\r\n | 'error'; // tool call errored\r\n\r\nexport interface TextPart {\r\n type: 'text';\r\n text: string;\r\n}\r\n\r\nexport interface ToolCallPart {\r\n type: 'tool-call';\r\n toolCallId: string;\r\n toolName: string;\r\n args: any;\r\n state: ToolState;\r\n}\r\n\r\nexport interface ToolResultPart {\r\n type: 'tool-result';\r\n toolCallId: string;\r\n toolName: string;\r\n args: any;\r\n result: any;\r\n state: ToolState;\r\n}\r\n\r\nexport type MessagePart = TextPart | ToolCallPart | ToolResultPart;\r\n\r\nexport interface StreamMessage {\r\n id: string;\r\n role: 'user' | 'assistant';\r\n parts: MessagePart[];\r\n createdAt: number;\r\n}\r\n\r\n// ── Internal tracking for tool calls ─────────────────────────────────\r\n\r\ninterface ToolCallTracker {\r\n toolCallId: string;\r\n toolName: string;\r\n argsText: string;\r\n args: any;\r\n result?: any;\r\n state: ToolState;\r\n}\r\n\r\n// ── Stream event types ───────────────────────────────────────────────\r\n\r\nexport type StreamEventType =\r\n | 'text-delta'\r\n | 'tool-call-start'\r\n | 'tool-call-delta'\r\n | 'tool-call-complete'\r\n | 'tool-result'\r\n | 'step-finish'\r\n | 'finish'\r\n | 'error';\r\n\r\nexport interface StreamEvent {\r\n type: StreamEventType;\r\n data: any;\r\n}\r\n\r\n// ── Parser callbacks ─────────────────────────────────────────────────\r\n\r\nexport interface DataStreamCallbacks {\r\n onTextDelta?: (text: string) => void;\r\n onToolCallStart?: (toolCallId: string, toolName: string) => void;\r\n onToolCallDelta?: (toolCallId: string, argsTextDelta: string) => void;\r\n onToolCallComplete?: (toolCallId: string, toolName: string, args: any) => void;\r\n onToolResult?: (toolCallId: string, result: any) => void;\r\n onStepFinish?: (data: any) => void;\r\n onFinish?: (data: any) => void;\r\n onError?: (error: string, data?: any) => void;\r\n}\r\n\r\n// ── Format detection ─────────────────────────────────────────────────\r\n\r\ntype StreamFormat = 'ui-message-stream' | 'data-stream' | 'plain-text';\r\n\r\nconst DATA_STREAM_LINE_RE = /^[0-9a-f]:/;\r\n\r\nfunction detectFormat(firstChunk: string): StreamFormat {\r\n const trimmed = firstChunk.trimStart();\r\n\r\n // UI Message Stream (SSE with JSON type objects) — this is the primary format\r\n // from pipeUIMessageStreamToResponse\r\n if (trimmed.startsWith('data:')) {\r\n // Try to parse the first data line to check if it's UI Message Stream\r\n const firstLine = trimmed.split('\\n')[0];\r\n const payload = firstLine.slice(5).trim();\r\n try {\r\n const parsed = JSON.parse(payload);\r\n if (parsed && typeof parsed.type === 'string') {\r\n return 'ui-message-stream';\r\n }\r\n } catch {\r\n // Not JSON with type → could be old data stream inside SSE, or [DONE]\r\n }\r\n // SSE with old data stream lines inside (e.g., data: 0:\"text\")\r\n if (DATA_STREAM_LINE_RE.test(payload)) {\r\n return 'data-stream';\r\n }\r\n // SSE but unknown content — treat as UI message stream (most likely)\r\n return 'ui-message-stream';\r\n }\r\n\r\n // Legacy data stream protocol: lines like 0:\"text\"\\n\r\n if (DATA_STREAM_LINE_RE.test(trimmed)) {\r\n return 'data-stream';\r\n }\r\n\r\n // Fallback: plain text\r\n return 'plain-text';\r\n}\r\n\r\n// ── UI Message Stream Protocol parser ────────────────────────────────\r\n\r\nfunction processUIMessageStreamEvent(payload: string, callbacks: DataStreamCallbacks): void {\r\n const trimmed = payload.trim();\r\n if (!trimmed || trimmed === '[DONE]') {\r\n callbacks.onFinish?.({});\r\n return;\r\n }\r\n\r\n let parsed: any;\r\n try {\r\n parsed = JSON.parse(trimmed);\r\n } catch {\r\n // Not valid JSON — ignore\r\n console.warn('[DataStreamParser] failed to parse UI message stream event:', trimmed.slice(0, 100));\r\n return;\r\n }\r\n\r\n const type = parsed?.type;\r\n if (!type) return;\r\n\r\n switch (type) {\r\n case 'text-delta':\r\n // {\"type\":\"text-delta\",\"id\":\"...\",\"delta\":\"Hello\"}\r\n if (typeof parsed.delta === 'string') {\r\n callbacks.onTextDelta?.(parsed.delta);\r\n }\r\n break;\r\n\r\n case 'tool-input-start':\r\n // {\"type\":\"tool-input-start\",\"toolCallId\":\"...\",\"toolName\":\"...\"}\r\n callbacks.onToolCallStart?.(parsed.toolCallId, parsed.toolName);\r\n break;\r\n\r\n case 'tool-input-delta':\r\n // {\"type\":\"tool-input-delta\",\"toolCallId\":\"...\",\"inputTextDelta\":\"...\"}\r\n callbacks.onToolCallDelta?.(parsed.toolCallId, parsed.inputTextDelta);\r\n break;\r\n\r\n case 'tool-input-available':\r\n // {\"type\":\"tool-input-available\",\"toolCallId\":\"...\",\"toolName\":\"...\",\"input\":{...}}\r\n callbacks.onToolCallComplete?.(parsed.toolCallId, parsed.toolName, parsed.input);\r\n break;\r\n\r\n case 'tool-output-available':\r\n // {\"type\":\"tool-output-available\",\"toolCallId\":\"...\",\"output\":{...}}\r\n callbacks.onToolResult?.(parsed.toolCallId, parsed.output);\r\n break;\r\n\r\n case 'finish-step':\r\n callbacks.onStepFinish?.(parsed);\r\n break;\r\n\r\n case 'finish':\r\n callbacks.onFinish?.(parsed);\r\n break;\r\n\r\n case 'error':\r\n case 'tool-output-error':\r\n callbacks.onError?.(parsed.errorText || parsed.error || 'Unknown error', parsed);\r\n break;\r\n\r\n // Parts we acknowledge but don't need to act on:\r\n case 'start':\r\n case 'text-start':\r\n case 'text-end':\r\n case 'start-step':\r\n case 'reasoning-start':\r\n case 'reasoning-delta':\r\n case 'reasoning-end':\r\n case 'source-url':\r\n case 'source-document':\r\n case 'file':\r\n case 'abort':\r\n // No-op for voice assistant\r\n break;\r\n\r\n default:\r\n // Unknown type — log and ignore\r\n if (type.startsWith('data-')) {\r\n // Custom data parts — ignore\r\n } else {\r\n console.log('[DataStreamParser] unhandled UI message stream type:', type);\r\n }\r\n break;\r\n }\r\n}\r\n\r\n// ── Legacy Data Stream Protocol parser ───────────────────────────────\r\n\r\nfunction parseLegacyProtocolLine(line: string, callbacks: DataStreamCallbacks): void {\r\n if (!line || !DATA_STREAM_LINE_RE.test(line)) return;\r\n\r\n const code = line[0];\r\n const rawValue = line.slice(2);\r\n\r\n let value: any;\r\n try {\r\n value = JSON.parse(rawValue);\r\n } catch {\r\n value = rawValue;\r\n }\r\n\r\n switch (code) {\r\n case '0':\r\n callbacks.onTextDelta?.(value);\r\n break;\r\n case '9':\r\n callbacks.onToolCallStart?.(value.toolCallId, value.toolName);\r\n break;\r\n case 'b':\r\n callbacks.onToolCallDelta?.(value.toolCallId, value.argsTextDelta);\r\n break;\r\n case 'c':\r\n callbacks.onToolCallComplete?.(value.toolCallId, value.toolName, value.args);\r\n break;\r\n case 'a':\r\n callbacks.onToolResult?.(value.toolCallId, value.result);\r\n break;\r\n case 'e':\r\n callbacks.onStepFinish?.(value);\r\n break;\r\n case 'd':\r\n callbacks.onFinish?.(value);\r\n break;\r\n case '3':\r\n callbacks.onError?.(value);\r\n break;\r\n }\r\n}\r\n\r\n// ── Read and parse a stream response (auto-detecting format) ─────────\r\n\r\nexport async function readDataStream(response: Response, callbacks: DataStreamCallbacks): Promise<void> {\r\n if (!response.body) return;\r\n\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n let format: StreamFormat | null = null;\r\n\r\n while (true) {\r\n const { value, done } = await reader.read();\r\n if (done) break;\r\n\r\n const chunk = decoder.decode(value, { stream: true });\r\n buffer += chunk;\r\n\r\n // Auto-detect format from the first meaningful content\r\n if (format === null && buffer.trim().length > 0) {\r\n format = detectFormat(buffer);\r\n console.log('[DataStreamParser] detected format:', format, '| first 200 chars:', buffer.slice(0, 200));\r\n }\r\n\r\n if (format === 'plain-text') {\r\n const text = buffer;\r\n buffer = '';\r\n if (text) callbacks.onTextDelta?.(text);\r\n continue;\r\n }\r\n\r\n if (format === 'ui-message-stream') {\r\n // SSE format: events separated by \\n\\n\r\n while (true) {\r\n const eventEnd = buffer.indexOf('\\n\\n');\r\n if (eventEnd === -1) break;\r\n\r\n const eventBlock = buffer.slice(0, eventEnd);\r\n buffer = buffer.slice(eventEnd + 2);\r\n\r\n // Extract data lines from SSE event block\r\n const dataLines = eventBlock\r\n .split(/\\r?\\n/)\r\n .filter((l) => l.startsWith('data:'))\r\n .map((l) => l.slice(5).trimStart());\r\n\r\n for (const dataLine of dataLines) {\r\n processUIMessageStreamEvent(dataLine, callbacks);\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (format === 'data-stream') {\r\n // Legacy data stream or SSE-wrapped legacy\r\n // Check if it looks like SSE (data: prefix)\r\n const isSSEWrapped = buffer.trimStart().startsWith('data:');\r\n\r\n if (isSSEWrapped) {\r\n while (true) {\r\n const eventEnd = buffer.indexOf('\\n\\n');\r\n if (eventEnd === -1) break;\r\n\r\n const eventBlock = buffer.slice(0, eventEnd);\r\n buffer = buffer.slice(eventEnd + 2);\r\n\r\n const dataLines = eventBlock\r\n .split(/\\r?\\n/)\r\n .filter((l) => l.startsWith('data:'))\r\n .map((l) => l.slice(5).trimStart());\r\n\r\n for (const dl of dataLines) {\r\n const t = dl.trim();\r\n if (!t || t === '[DONE]') {\r\n if (t === '[DONE]') callbacks.onFinish?.({});\r\n continue;\r\n }\r\n parseLegacyProtocolLine(t, callbacks);\r\n }\r\n }\r\n } else {\r\n // Raw data stream lines separated by \\n\r\n while (true) {\r\n const newlineIdx = buffer.indexOf('\\n');\r\n if (newlineIdx === -1) break;\r\n\r\n const line = buffer.slice(0, newlineIdx).trim();\r\n buffer = buffer.slice(newlineIdx + 1);\r\n\r\n if (line) parseLegacyProtocolLine(line, callbacks);\r\n }\r\n }\r\n continue;\r\n }\r\n }\r\n\r\n // Process remaining buffer\r\n const tail = decoder.decode();\r\n if (tail) buffer += tail;\r\n\r\n if (buffer.trim()) {\r\n if (format === 'plain-text') {\r\n callbacks.onTextDelta?.(buffer);\r\n } else if (format === 'ui-message-stream') {\r\n const dataLines = buffer\r\n .split(/\\r?\\n/)\r\n .filter((l) => l.startsWith('data:'))\r\n .map((l) => l.slice(5).trimStart());\r\n for (const dl of dataLines) {\r\n processUIMessageStreamEvent(dl, callbacks);\r\n }\r\n } else if (format === 'data-stream') {\r\n parseLegacyProtocolLine(buffer.trim(), callbacks);\r\n }\r\n }\r\n\r\n callbacks.onFinish?.({});\r\n}\r\n\r\n// ── High-level: parse stream into MessageParts ───────────────────────\r\n\r\nexport interface StreamParseResult {\r\n textContent: string;\r\n parts: MessagePart[];\r\n toolCalls: Map<string, ToolCallTracker>;\r\n}\r\n\r\nexport async function parseDataStreamToMessage(\r\n response: Response,\r\n onUpdate: (result: StreamParseResult) => void,\r\n): Promise<StreamParseResult> {\r\n let textContent = '';\r\n const parts: MessagePart[] = [];\r\n const toolCalls = new Map<string, ToolCallTracker>();\r\n\r\n const ensureTextPart = (): TextPart => {\r\n for (let i = parts.length - 1; i >= 0; i--) {\r\n if (parts[i].type === 'text') {\r\n return parts[i] as TextPart;\r\n }\r\n }\r\n const textPart: TextPart = { type: 'text', text: '' };\r\n parts.push(textPart);\r\n return textPart;\r\n };\r\n\r\n const findToolPartIndex = (toolCallId: string): number => {\r\n return parts.findIndex((p) => (p.type === 'tool-call' || p.type === 'tool-result') && p.toolCallId === toolCallId);\r\n };\r\n\r\n const emitUpdate = () => {\r\n onUpdate({ textContent, parts: [...parts], toolCalls: new Map(toolCalls) });\r\n };\r\n\r\n await readDataStream(response, {\r\n onTextDelta(text) {\r\n textContent += text;\r\n const textPart = ensureTextPart();\r\n textPart.text = textContent;\r\n emitUpdate();\r\n },\r\n\r\n onToolCallStart(toolCallId, toolName) {\r\n const tracker: ToolCallTracker = {\r\n toolCallId,\r\n toolName,\r\n argsText: '',\r\n args: undefined,\r\n state: 'partial-call',\r\n };\r\n toolCalls.set(toolCallId, tracker);\r\n\r\n const part: ToolCallPart = {\r\n type: 'tool-call',\r\n toolCallId,\r\n toolName,\r\n args: undefined,\r\n state: 'partial-call',\r\n };\r\n parts.push(part);\r\n emitUpdate();\r\n },\r\n\r\n onToolCallDelta(toolCallId, argsTextDelta) {\r\n const tracker = toolCalls.get(toolCallId);\r\n if (tracker) {\r\n tracker.argsText += argsTextDelta;\r\n try {\r\n tracker.args = JSON.parse(tracker.argsText);\r\n } catch {\r\n // Not valid JSON yet\r\n }\r\n const idx = findToolPartIndex(toolCallId);\r\n if (idx !== -1 && parts[idx].type === 'tool-call') {\r\n (parts[idx] as ToolCallPart).args = tracker.args;\r\n }\r\n emitUpdate();\r\n }\r\n },\r\n\r\n onToolCallComplete(toolCallId, toolName, args) {\r\n const tracker = toolCalls.get(toolCallId);\r\n if (tracker) {\r\n tracker.state = 'call';\r\n tracker.args = typeof args === 'string' ? safeJsonParse(args) : args;\r\n } else {\r\n toolCalls.set(toolCallId, {\r\n toolCallId,\r\n toolName,\r\n argsText: typeof args === 'string' ? args : JSON.stringify(args),\r\n args: typeof args === 'string' ? safeJsonParse(args) : args,\r\n state: 'call',\r\n });\r\n }\r\n\r\n const idx = findToolPartIndex(toolCallId);\r\n if (idx !== -1) {\r\n (parts[idx] as ToolCallPart).state = 'call';\r\n (parts[idx] as ToolCallPart).toolName = toolName;\r\n (parts[idx] as ToolCallPart).args = toolCalls.get(toolCallId)!.args;\r\n } else {\r\n parts.push({\r\n type: 'tool-call',\r\n toolCallId,\r\n toolName,\r\n args: toolCalls.get(toolCallId)!.args,\r\n state: 'call',\r\n });\r\n }\r\n emitUpdate();\r\n },\r\n\r\n onToolResult(toolCallId, result) {\r\n const tracker = toolCalls.get(toolCallId);\r\n if (tracker) {\r\n tracker.result = result;\r\n tracker.state = 'result';\r\n }\r\n\r\n const idx = findToolPartIndex(toolCallId);\r\n if (idx !== -1) {\r\n const existing = parts[idx] as ToolCallPart;\r\n const resultPart: ToolResultPart = {\r\n type: 'tool-result',\r\n toolCallId,\r\n toolName: existing.toolName,\r\n args: existing.args,\r\n result,\r\n state: 'result',\r\n };\r\n parts[idx] = resultPart;\r\n } else {\r\n parts.push({\r\n type: 'tool-result',\r\n toolCallId,\r\n toolName: tracker?.toolName || 'unknown',\r\n args: tracker?.args,\r\n result,\r\n state: 'result',\r\n });\r\n }\r\n emitUpdate();\r\n },\r\n\r\n onError(error, data) {\r\n const toolCallId = data?.toolCallId;\r\n if (toolCallId) {\r\n toolCalls.delete(toolCallId);\r\n const idx = findToolPartIndex(toolCallId);\r\n if (idx !== -1) {\r\n parts.splice(idx, 1);\r\n emitUpdate();\r\n }\r\n }\r\n console.error('[DataStreamParser] stream error:', error);\r\n },\r\n\r\n onStepFinish(_data) {\r\n emitUpdate();\r\n },\r\n\r\n onFinish(_data) {\r\n emitUpdate();\r\n },\r\n });\r\n\r\n return { textContent, parts, toolCalls };\r\n}\r\n\r\n// ── Utilities ────────────────────────────────────────────────────────\r\n\r\nfunction safeJsonParse(str: string): any {\r\n try {\r\n return JSON.parse(str);\r\n } catch {\r\n return str;\r\n }\r\n}\r\n","import { computed, ref } from 'vue';\r\nimport {\r\n parseDataStreamToMessage,\r\n type StreamParseResult,\r\n type ToolCallPart,\r\n type ToolResultPart,\r\n} from '../lib/data-stream-parser';\r\nimport type { AiChatbotXContext } from '../types';\r\nimport type { DiscoveredCommand } from '../utils/command-types';\r\n\r\nexport interface UseAgentInvokeOptions {\r\n endpoint: string;\r\n projectId?: string;\r\n appToken?: string;\r\n aiChatbotX: AiChatbotXContext;\r\n /** TTS 控制 */\r\n tts: {\r\n speak: (text: string) => void;\r\n feed: (delta: string) => void;\r\n flush: () => void;\r\n stop: () => void;\r\n };\r\n /** 气泡控制 */\r\n bubble: {\r\n open: () => void;\r\n scheduleDismiss: () => void;\r\n scrollToBottom: () => void;\r\n };\r\n /** 会话记忆超时(ms),超过此时间未发起新对话则自动清空历史,默认 120000(2分钟) */\r\n sessionTimeoutMs?: number;\r\n /** 最大保留历史轮数(一轮 = user + assistant),默认 10 */\r\n maxHistoryTurns?: number;\r\n}\r\n\r\n// ── 工具名称映射 ──\r\nconst toolDisplayNames: Record<string, string> = {\r\n generateReport: '生成报告',\r\n searchKnowledge: '知识库检索',\r\n resolveInstanceTargets: '解析实例目标',\r\n getHistoryMetrics: '历史数据查询',\r\n getRealtimeMetrics: '实时数据查询',\r\n queryBitableData: '多维表格查询',\r\n searchUser: '搜索用户',\r\n createBitableRecord: '创建表格记录',\r\n timeTool: '时间工具',\r\n loadSkill: '加载技能',\r\n executeCommand: '执行命令',\r\n dataAnalyzer: '数据分析',\r\n dataPredictor: '数据预测',\r\n};\r\n\r\n/**\r\n * Agent 调用 composable\r\n *\r\n * 管理 Agent 调用、流式解析、工具执行、文本/工具状态。\r\n * 支持中断(abort)以便在唤醒时取消正在进行的调用。\r\n */\r\nexport function useAgentInvoke(options: UseAgentInvokeOptions) {\r\n const { aiChatbotX, tts, bubble } = options;\r\n\r\n const sessionTimeoutMs = options.sessionTimeoutMs ?? 120_000;\r\n const maxHistoryTurns = options.maxHistoryTurns ?? 10;\r\n\r\n const isInvoking = ref(false);\r\n const currentTextContent = ref('');\r\n const currentToolParts = ref<(ToolCallPart | ToolResultPart)[]>([]);\r\n const executingTools = ref<Set<string>>(new Set());\r\n\r\n // ── 对话历史 ──\r\n type HistoryMessage = { role: 'user' | 'assistant'; content: string };\r\n const conversationHistory = ref<HistoryMessage[]>([]);\r\n let lastInteractionTime = 0;\r\n\r\n /** 检查会话是否超时,超时则自动清空历史 */\r\n const checkSessionTimeout = () => {\r\n if (lastInteractionTime > 0 && Date.now() - lastInteractionTime > sessionTimeoutMs) {\r\n conversationHistory.value = [];\r\n }\r\n };\r\n\r\n /** 追加消息到历史(自动裁剪超出 maxHistoryTurns 的旧记录) */\r\n const appendToHistory = (role: 'user' | 'assistant', content: string) => {\r\n conversationHistory.value.push({ role, content });\r\n // 一轮 = 2 条消息(user + assistant),裁剪到 maxHistoryTurns * 2\r\n const maxLen = maxHistoryTurns * 2;\r\n if (conversationHistory.value.length > maxLen) {\r\n conversationHistory.value = conversationHistory.value.slice(-maxLen);\r\n }\r\n };\r\n\r\n /** 手动清空对话历史 */\r\n const clearHistory = () => {\r\n conversationHistory.value = [];\r\n };\r\n\r\n // AbortController 用于中断正在进行的请求\r\n let abortController: AbortController | null = null;\r\n\r\n const hasAnyContent = computed(() => {\r\n return !!(currentTextContent.value || currentToolParts.value.length > 0);\r\n });\r\n\r\n const toolDisplayName = (name: string) => toolDisplayNames[name] || name;\r\n\r\n // ── 重置状态 ──\r\n\r\n const resetState = () => {\r\n currentTextContent.value = '';\r\n currentToolParts.value = [];\r\n executingTools.value = new Set();\r\n };\r\n\r\n // ── 宿主命令执行 ──\r\n\r\n const extractExecutableCommands = (payload: any): { name: string; args: any[] }[] => {\r\n if (!payload || typeof payload !== 'object') return [];\r\n const commands = payload.commands;\r\n if (!Array.isArray(commands) || commands.length === 0) return [];\r\n\r\n return commands\r\n .filter((cmd) => cmd && typeof cmd === 'object' && typeof cmd.name === 'string' && cmd.name.trim())\r\n .map((cmd) => ({\r\n name: cmd.name,\r\n args: Array.isArray(cmd.args) ? cmd.args : [],\r\n }));\r\n };\r\n\r\n const buildCommandDefinitionMap = (commands: DiscoveredCommand[]) => {\r\n return new Map(commands.map((command) => [command.name, command]));\r\n };\r\n\r\n const toExecutableCommand = (\r\n toolName: string,\r\n payload: any,\r\n commandDefinitions: Map<string, DiscoveredCommand>,\r\n ): { name: string; args: any[] } | null => {\r\n const commandDefinition = commandDefinitions.get(toolName);\r\n if (!commandDefinition) {\r\n return null;\r\n }\r\n\r\n const parameters = commandDefinition.parameters || [];\r\n\r\n if (Array.isArray(payload)) {\r\n return {\r\n name: toolName,\r\n args: payload,\r\n };\r\n }\r\n\r\n if (!payload || typeof payload !== 'object') {\r\n return {\r\n name: toolName,\r\n args: [],\r\n };\r\n }\r\n\r\n const payloadRecord = payload as Record<string, any>;\r\n\r\n return {\r\n name: toolName,\r\n args: parameters.map((parameter) => payloadRecord[parameter.name]),\r\n };\r\n };\r\n\r\n const resolveExecutableCommands = (\r\n toolName: string,\r\n payload: any,\r\n commandDefinitions: Map<string, DiscoveredCommand>,\r\n ): { name: string; args: any[] }[] => {\r\n const extractedCommands = extractExecutableCommands(payload);\r\n if (extractedCommands.length > 0) {\r\n return extractedCommands;\r\n }\r\n\r\n const directCommand = toExecutableCommand(toolName, payload, commandDefinitions);\r\n return directCommand ? [directCommand] : [];\r\n };\r\n\r\n const executeHostCommands = async (\r\n toolCallId: string,\r\n toolName: string,\r\n payload: any,\r\n commandDefinitions: Map<string, DiscoveredCommand>,\r\n ) => {\r\n const commands = resolveExecutableCommands(toolName, payload, commandDefinitions);\r\n if (commands.length === 0) return false;\r\n\r\n try {\r\n executingTools.value = new Set([...executingTools.value, toolCallId]);\r\n for (const cmd of commands) {\r\n try {\r\n await aiChatbotX.executeCommand(cmd.name, cmd.args);\r\n } catch (cmdErr) {\r\n console.error(`[AgentInvoke] 执行命令 ${cmd.name} 失败:`, cmdErr);\r\n }\r\n }\r\n return true;\r\n } finally {\r\n const next = new Set(executingTools.value);\r\n next.delete(toolCallId);\r\n executingTools.value = next;\r\n }\r\n };\r\n\r\n // ── JSON 响应解析 ──\r\n\r\n const parseAssistantText = (payload: unknown): string => {\r\n if (!payload) return '';\r\n if (typeof payload === 'string') return payload;\r\n if (typeof payload === 'object') {\r\n const data = payload as Record<string, any>;\r\n const directText = data.output || data.answer || data.message || data.result;\r\n if (typeof directText === 'string' && directText.trim()) return directText;\r\n if (data.data && typeof data.data === 'object') {\r\n const nested = data.data as Record<string, any>;\r\n const nestedText = nested.output || nested.answer || nested.message || nested.result;\r\n if (typeof nestedText === 'string' && nestedText.trim()) return nestedText;\r\n }\r\n return JSON.stringify(payload);\r\n }\r\n return String(payload);\r\n };\r\n\r\n // ── 核心调用 ──\r\n\r\n const invoke = async (question: string) => {\r\n const content = question.trim();\r\n if (!content) return;\r\n\r\n // 如果有正在进行的调用,先中断\r\n abort();\r\n\r\n // 检查会话超时,必要时清空历史\r\n checkSessionTimeout();\r\n\r\n resetState();\r\n tts.stop();\r\n isInvoking.value = true;\r\n bubble.open();\r\n\r\n let prevTextLength = 0;\r\n const processedToolResults = new Set<string>();\r\n const processingToolResults = new Set<string>();\r\n abortController = new AbortController();\r\n\r\n const commands = await aiChatbotX.getCommads();\r\n const commandDefinitions = buildCommandDefinitionMap(commands);\r\n\r\n // 构造请求体:包含历史消息\r\n const historyToSend = conversationHistory.value.length > 0 ? [...conversationHistory.value] : undefined;\r\n\r\n try {\r\n const response = await fetch(options.endpoint, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${options.appToken || ''}` },\r\n body: JSON.stringify({\r\n input: content,\r\n projectId: options.projectId || '',\r\n commands: commands.length > 0 ? commands : undefined,\r\n // messages: historyToSend,\r\n }),\r\n signal: abortController.signal,\r\n });\r\n\r\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\r\n\r\n const contentType = response.headers.get('content-type') || '';\r\n const isJsonResponse = contentType.includes('application/json');\r\n\r\n if (isJsonResponse) {\r\n const data = await response.json();\r\n const reply = parseAssistantText(data) || '已收到,但没有返回可展示的文本内容。';\r\n currentTextContent.value = reply;\r\n tts.speak(reply);\r\n\r\n // 追加到对话历史\r\n appendToHistory('user', content);\r\n appendToHistory('assistant', reply);\r\n\r\n if (data.toolResults && Array.isArray(data.toolResults)) {\r\n for (const tr of data.toolResults) {\r\n const toolPart: ToolResultPart = {\r\n type: 'tool-result',\r\n toolCallId: `invoke-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\r\n toolName: tr.toolName,\r\n args: tr.args,\r\n result: tr.result,\r\n state: 'result',\r\n };\r\n currentToolParts.value = [...currentToolParts.value, toolPart];\r\n if (commandDefinitions.has(tr.toolName)) {\r\n void executeHostCommands(toolPart.toolCallId, tr.toolName, tr.result, commandDefinitions);\r\n }\r\n }\r\n }\r\n } else {\r\n await parseDataStreamToMessage(response, (result: StreamParseResult) => {\r\n currentTextContent.value = result.textContent;\r\n\r\n if (result.textContent.length > prevTextLength) {\r\n const delta = result.textContent.slice(prevTextLength);\r\n prevTextLength = result.textContent.length;\r\n tts.feed(delta);\r\n }\r\n\r\n const toolParts: (ToolCallPart | ToolResultPart)[] = result.parts.filter(\r\n (p): p is ToolCallPart | ToolResultPart => p.type === 'tool-call' || p.type === 'tool-result',\r\n );\r\n currentToolParts.value = toolParts;\r\n\r\n for (const part of toolParts) {\r\n if (\r\n commandDefinitions.has(part.toolName) &&\r\n !processedToolResults.has(part.toolCallId) &&\r\n !processingToolResults.has(part.toolCallId)\r\n ) {\r\n if (part.type === 'tool-call' && part.state === 'call' && part.args) {\r\n processingToolResults.add(part.toolCallId);\r\n void executeHostCommands(part.toolCallId, part.toolName, part.args, commandDefinitions).then(\r\n (executed) => {\r\n if (executed) {\r\n processedToolResults.add(part.toolCallId);\r\n }\r\n processingToolResults.delete(part.toolCallId);\r\n },\r\n );\r\n } else if (part.type === 'tool-result' && part.result) {\r\n processingToolResults.add(part.toolCallId);\r\n void executeHostCommands(part.toolCallId, part.toolName, part.result, commandDefinitions).then(\r\n (executed) => {\r\n if (executed) {\r\n processedToolResults.add(part.toolCallId);\r\n }\r\n processingToolResults.delete(part.toolCallId);\r\n },\r\n );\r\n }\r\n }\r\n }\r\n\r\n bubble.scrollToBottom();\r\n });\r\n\r\n tts.flush();\r\n\r\n // 流式响应完成后,追加到对话历史\r\n const assistantReply = currentTextContent.value.trim();\r\n appendToHistory('user', content);\r\n if (assistantReply) {\r\n appendToHistory('assistant', assistantReply);\r\n }\r\n\r\n if (!assistantReply && currentToolParts.value.length === 0) {\r\n currentTextContent.value = '已收到,但没有返回可展示的文本内容。';\r\n }\r\n }\r\n } catch (error: any) {\r\n if (error.name === 'AbortError') {\r\n // 被中断,静默处理\r\n return;\r\n }\r\n console.error('[AgentInvoke] invoke failed:', error);\r\n tts.stop();\r\n currentTextContent.value = '请求失败,请检查服务地址或稍后重试。';\r\n } finally {\r\n isInvoking.value = false;\r\n abortController = null;\r\n lastInteractionTime = Date.now();\r\n bubble.scheduleDismiss();\r\n }\r\n };\r\n\r\n // ── 中断当前调用 ──\r\n\r\n const abort = () => {\r\n if (abortController) {\r\n abortController.abort();\r\n abortController = null;\r\n }\r\n tts.stop();\r\n isInvoking.value = false;\r\n };\r\n\r\n return {\r\n isInvoking,\r\n currentTextContent,\r\n currentToolParts,\r\n executingTools,\r\n hasAnyContent,\r\n conversationHistory,\r\n toolDisplayName,\r\n invoke,\r\n abort,\r\n resetState,\r\n clearHistory,\r\n };\r\n}\r\n","import type { Ref } from 'vue';\r\nimport { computed, nextTick, ref, watch } from 'vue';\r\n\r\nexport interface BubbleSize {\r\n /** 气泡最大宽度,如 '380px' 或 '86vw' */\r\n width?: string;\r\n /** 气泡最大高度,如 '520px' 或 '58vh' */\r\n maxHeight?: string;\r\n}\r\n\r\nexport interface UseBubbleOptions {\r\n /** 自动消失延迟 (ms),默认 4000 */\r\n dismissDelay?: number;\r\n /** 外部 isSpeaking 引用,TTS 播报期间阻止消失 */\r\n isSpeaking?: Ref<boolean>;\r\n /** 外部 hasPendingAudio 引用,TTS 已提交内容但尚未开始播放(覆盖异步窗口期) */\r\n hasPendingAudio?: Ref<boolean>;\r\n /** 外部 isInvoking 引用,调用期间阻止消失 */\r\n isInvoking?: Ref<boolean>;\r\n /** 气泡尺寸 */\r\n bubbleSize?: BubbleSize;\r\n}\r\n\r\n/**\r\n * 气泡生命周期 composable\r\n *\r\n * 管理气泡显示/隐藏、自动消失倒计时、滚动。\r\n * 核心保证:TTS 播报期间(含异步等待 WebSocket 的窗口期)气泡绝不消失。\r\n */\r\nexport function useBubble(options: UseBubbleOptions = {}) {\r\n const visible = ref(false);\r\n const fadingOut = ref(false);\r\n const stackRef = ref<HTMLElement | null>(null);\r\n let dismissTimer: ReturnType<typeof setTimeout> | null = null;\r\n\r\n // 气泡是否被打开过(防止 TTS 状态单独触发空气泡)\r\n const hasOpened = ref(false);\r\n\r\n /** TTS 是否活跃:正在播报 OR 有待播放内容(覆盖异步初始化窗口) */\r\n const isTTSActive = () => !!(options.isSpeaking?.value || options.hasPendingAudio?.value);\r\n\r\n /** 任何阻止气泡消失的条件 */\r\n const isBusy = () => !!(options.isInvoking?.value || isTTSActive());\r\n\r\n // 核心 show:只要 hasOpened 且(visible 或 TTS 活跃),气泡就必须可见\r\n const show = computed(() => {\r\n if (!hasOpened.value) return false;\r\n if (isTTSActive()) return true;\r\n return visible.value && !fadingOut.value;\r\n });\r\n\r\n const style = computed(() => ({\r\n width: options.bubbleSize?.width || undefined,\r\n maxHeight: options.bubbleSize?.maxHeight || undefined,\r\n }));\r\n\r\n // ── 打开气泡(取消任何挂起的消失计时器) ──\r\n\r\n const open = () => {\r\n cancelDismiss();\r\n fadingOut.value = false;\r\n visible.value = true;\r\n hasOpened.value = true;\r\n };\r\n\r\n // ── 取消消失计时器 ──\r\n\r\n const cancelDismiss = () => {\r\n if (dismissTimer) {\r\n clearTimeout(dismissTimer);\r\n dismissTimer = null;\r\n }\r\n };\r\n\r\n // ── 安排消失(严格检查所有阻止条件) ──\r\n\r\n const scheduleDismiss = () => {\r\n cancelDismiss();\r\n\r\n if (isBusy()) return;\r\n\r\n const delay = options.dismissDelay ?? 4000;\r\n dismissTimer = setTimeout(() => {\r\n // 再次检查:等待期间 TTS 可能已经异步启动\r\n if (isBusy()) return;\r\n\r\n fadingOut.value = true;\r\n setTimeout(() => {\r\n // 最终检查:淡出动画期间 TTS 也可能启动\r\n if (isBusy()) {\r\n fadingOut.value = false;\r\n return;\r\n }\r\n visible.value = false;\r\n fadingOut.value = false;\r\n hasOpened.value = false;\r\n }, 400);\r\n }, delay);\r\n };\r\n\r\n // ── 监听 TTS 状态变化 ──\r\n\r\n const watchTTSRef = (ttsRef: Ref<boolean>) => {\r\n watch(ttsRef, (active) => {\r\n if (active && hasOpened.value) {\r\n // TTS 变为活跃 → 取消消失计时器,撤销淡出\r\n cancelDismiss();\r\n if (fadingOut.value) fadingOut.value = false;\r\n } else if (!active && hasOpened.value && !isBusy()) {\r\n // TTS 变为非活跃且无其他阻止条件 → 安排消失\r\n scheduleDismiss();\r\n }\r\n });\r\n };\r\n\r\n if (options.isSpeaking) watchTTSRef(options.isSpeaking);\r\n if (options.hasPendingAudio) watchTTSRef(options.hasPendingAudio);\r\n\r\n // ── 立即隐藏(中断场景) ──\r\n\r\n const hide = () => {\r\n cancelDismiss();\r\n fadingOut.value = false;\r\n visible.value = false;\r\n hasOpened.value = false;\r\n };\r\n\r\n // ── 滚动到底部 ──\r\n\r\n const scrollToBottom = () => {\r\n nextTick(() => {\r\n if (stackRef.value) {\r\n stackRef.value.scrollTop = stackRef.value.scrollHeight;\r\n }\r\n });\r\n };\r\n\r\n // ── 清理 ──\r\n\r\n const destroy = () => {\r\n cancelDismiss();\r\n };\r\n\r\n return {\r\n visible,\r\n fadingOut,\r\n show,\r\n style,\r\n stackRef,\r\n open,\r\n hide,\r\n cancelDismiss,\r\n scheduleDismiss,\r\n scrollToBottom,\r\n destroy,\r\n };\r\n}\r\n","import type { InjectionKey } from 'vue'\r\nimport type { AiChatbotXContext } from './types'\r\nimport { inject } from 'vue'\r\n\r\nexport const AiChatbotXKey: InjectionKey<AiChatbotXContext> = Symbol('sime-x')\r\n\r\nexport function injectStrict<T>(key: InjectionKey<T>): T\r\nexport function injectStrict<T>(key: InjectionKey<T>, defaultValue: T, treatDefaultAsFactory?: false): T\r\nexport function injectStrict<T>(key: InjectionKey<T>, defaultValue: T | (() => T), treatDefaultAsFactory: true): T\r\nexport function injectStrict<T>(key: InjectionKey<T>, defaultValue?: T | (() => T), treatDefaultAsFactory?: boolean): T {\r\n let result: T | undefined\r\n\r\n if (defaultValue === undefined) {\r\n result = inject(key) as T | undefined\r\n }\r\n else if (treatDefaultAsFactory === true) {\r\n result = inject(key, defaultValue as T | (() => T), true)\r\n }\r\n else {\r\n result = inject(key, defaultValue as T, false)\r\n }\r\n\r\n if (!result) {\r\n throw new Error(`Could not resolve ${key.description}`)\r\n }\r\n return result\r\n}\r\n","<template>\r\n <div class=\"command-test\" :data-theme=\"currentTheme\">\r\n <button @click=\"test\">测试</button>\r\n <button @click=\"test1\">测试1</button>\r\n <!-- ── 气泡区域:agent 回复 ── -->\r\n <transition name=\"bubble-fade\">\r\n <div class=\"bubble-stack\" v-if=\"showBubble\" ref=\"bubbleStackRef\" :style=\"bubbleStyle\">\r\n <div class=\"agent-bubble\">\r\n <!-- 工具执行步骤 -->\r\n <div v-if=\"currentToolParts.length > 0\" class=\"tool-steps\">\r\n <div\r\n v-for=\"toolPart in currentToolParts\"\r\n :key=\"toolPart.toolCallId\"\r\n class=\"tool-step\"\r\n :class=\"{\r\n 'tool-step--loading': toolPart.state === 'partial-call' || toolPart.state === 'call',\r\n 'tool-step--done': toolPart.state === 'result',\r\n 'tool-step--error': toolPart.state === 'error',\r\n 'tool-step--executing': executingTools.has(toolPart.toolCallId),\r\n }\"\r\n >\r\n <span class=\"tool-step__icon\">\r\n <svg\r\n v-if=\"toolPart.state === 'partial-call' || toolPart.state === 'call'\"\r\n class=\"tool-step__spinner\"\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n >\r\n <circle\r\n cx=\"12\"\r\n cy=\"12\"\r\n r=\"10\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"31.4 31.4\"\r\n />\r\n </svg>\r\n <svg v-else-if=\"toolPart.state === 'result'\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M20 6L9 17l-5-5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n <svg v-else-if=\"toolPart.state === 'error'\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <path d=\"M15 9l-6 6M9 9l6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n </span>\r\n <span class=\"tool-step__name\">{{ toolDisplayName(toolPart.toolName) }}</span>\r\n <span v-if=\"executingTools.has(toolPart.toolCallId)\" class=\"tool-step__tag tool-step__tag--exec\"\r\n >命令执行中</span\r\n >\r\n </div>\r\n </div>\r\n\r\n <!-- 思考中动画 -->\r\n <div v-if=\"isInvoking && !hasAnyContent\" class=\"thinking-dots\">\r\n <span></span>\r\n <span></span>\r\n <span></span>\r\n </div>\r\n\r\n <!-- 文本内容 -->\r\n <div v-if=\"currentTextContent\" class=\"agent-text\">{{ currentTextContent }}</div>\r\n </div>\r\n </div>\r\n </transition>\r\n\r\n <!-- ── 输入区域 ── -->\r\n <div class=\"input-bar\">\r\n <input\r\n v-model=\"inputText\"\r\n type=\"text\"\r\n class=\"input-field\"\r\n placeholder=\"输入指令...\"\r\n :disabled=\"isInvoking\"\r\n @keydown.enter=\"handleSubmit\"\r\n />\r\n <button class=\"submit-btn\" :disabled=\"isInvoking || !inputText.trim()\" @click=\"handleSubmit\">\r\n <svg v-if=\"isInvoking\" class=\"btn-spinner\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle\r\n cx=\"12\"\r\n cy=\"12\"\r\n r=\"10\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"31.4 31.4\"\r\n />\r\n </svg>\r\n <svg v-else width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M22 2L11 13\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M22 2L15 22l-4-9-9-4 20-7z\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { onBeforeUnmount, ref } from 'vue';\r\nimport { useAgentInvoke } from '../composables/use-agent-invoke';\r\nimport { useBubble } from '../composables/use-bubble';\r\nimport { AiChatbotXKey, injectStrict } from '../injection-key';\r\n\r\ninterface BubbleSize {\r\n width?: string;\r\n maxHeight?: string;\r\n}\r\n\r\nconst props = defineProps<{\r\n agentId?: string;\r\n projectId?: string;\r\n bubbleSize?: BubbleSize;\r\n bubbleDismissDelay?: number;\r\n}>();\r\n\r\nconst aiChatbotX = injectStrict(AiChatbotXKey);\r\n\r\nconst currentTheme = 'dark' as const;\r\nconst inputText = ref('');\r\n\r\n// ── TTS no-op(文本测试组件不需要语音播报) ──\r\n\r\nconst noopTts = {\r\n speak: (_text: string) => {},\r\n feed: (_delta: string) => {},\r\n flush: () => {},\r\n stop: () => {},\r\n};\r\n\r\n// ── Bubble bridge(与 voice-assistant 相同模式) ──\r\n\r\nconst bubbleBridge = {\r\n open: () => {},\r\n scheduleDismiss: () => {},\r\n scrollToBottom: () => {},\r\n};\r\n\r\nconst test = () => {\r\n [\r\n '1你好,世界,今天是想起五天气横扫的缺点',\r\n '2你好,世界,今天是想起五天气横扫的缺点',\r\n '3你好,世界,今天是想起五天气横扫的缺点',\r\n ].forEach((text, index) => {\r\n setTimeout(() => {\r\n aiChatbotX.speakText(text);\r\n }, index * 1000);\r\n });\r\n};\r\n\r\nconst test1 = () => {\r\n aiChatbotX.abortInvoke();\r\n};\r\n\r\n// ── Agent invoke ──\r\n\r\nconst endpoint = `/sime/proxy/organizations/${aiChatbotX.organizationId()}/agents/${props.agentId}/stream-invoke`;\r\n\r\nconst agent = useAgentInvoke({\r\n endpoint,\r\n appToken: aiChatbotX.appToken(),\r\n projectId: props.projectId,\r\n aiChatbotX,\r\n tts: noopTts,\r\n bubble: {\r\n open: () => bubbleBridge.open(),\r\n scheduleDismiss: () => bubbleBridge.scheduleDismiss(),\r\n scrollToBottom: () => bubbleBridge.scrollToBottom(),\r\n },\r\n});\r\n\r\n// ── Bubble ──\r\n\r\nconst bubble = useBubble({\r\n dismissDelay: props.bubbleDismissDelay ?? 8000,\r\n isInvoking: agent.isInvoking,\r\n bubbleSize: props.bubbleSize,\r\n});\r\n\r\nbubbleBridge.open = bubble.open;\r\nbubbleBridge.scheduleDismiss = bubble.scheduleDismiss;\r\nbubbleBridge.scrollToBottom = bubble.scrollToBottom;\r\n\r\nconst { show: showBubble, style: bubbleStyle, stackRef: bubbleStackRef } = bubble;\r\n\r\n// ── 提交 ──\r\n\r\nconst handleSubmit = () => {\r\n const text = inputText.value.trim();\r\n if (!text || agent.isInvoking.value) return;\r\n inputText.value = '';\r\n agent.invoke(text);\r\n};\r\n\r\n// ── 模板暴露 ──\r\n\r\nconst { isInvoking, currentTextContent, currentToolParts, executingTools, hasAnyContent, toolDisplayName } = agent;\r\n\r\n// ── 清理 ──\r\n\r\nonBeforeUnmount(() => {\r\n bubble.destroy();\r\n agent.abort();\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.command-test {\r\n --text-primary: #e6edf7;\r\n --text-secondary: #95a8c8;\r\n --glass-bg: rgba(8, 16, 32, 0.72);\r\n --glass-border: rgba(125, 160, 220, 0.28);\r\n --shadow-md: 0 18px 36px rgba(1, 6, 20, 0.56);\r\n --color-success: #4ade80;\r\n --color-error: #f87171;\r\n --color-accent: #818cf8;\r\n\r\n position: relative;\r\n display: inline-flex;\r\n flex-direction: column;\r\n align-items: flex-end;\r\n gap: 12px;\r\n}\r\n\r\n/* ── 输入栏 ── */\r\n.input-bar {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n width: 100%;\r\n min-width: 320px;\r\n}\r\n\r\n.input-field {\r\n flex: 1;\r\n padding: 10px 14px;\r\n border-radius: 12px;\r\n border: 1px solid var(--glass-border);\r\n background: var(--glass-bg);\r\n color: var(--text-primary);\r\n font-size: 14px;\r\n outline: none;\r\n backdrop-filter: blur(10px);\r\n transition: border-color 0.2s ease;\r\n\r\n &::placeholder {\r\n color: var(--text-secondary);\r\n }\r\n\r\n &:focus {\r\n border-color: var(--color-accent);\r\n }\r\n\r\n &:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n}\r\n\r\n.submit-btn {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 40px;\r\n height: 40px;\r\n border-radius: 12px;\r\n border: 1px solid var(--glass-border);\r\n background: var(--glass-bg);\r\n color: var(--color-accent);\r\n cursor: pointer;\r\n backdrop-filter: blur(10px);\r\n transition:\r\n background 0.2s ease,\r\n transform 0.15s ease,\r\n opacity 0.2s ease;\r\n\r\n &:hover:not(:disabled) {\r\n background: rgba(129, 140, 248, 0.12);\r\n transform: scale(1.05);\r\n }\r\n\r\n &:disabled {\r\n opacity: 0.4;\r\n cursor: not-allowed;\r\n }\r\n}\r\n\r\n.btn-spinner {\r\n animation: tool-spin 0.8s linear infinite;\r\n}\r\n\r\n/* ── 气泡容器 ── */\r\n.bubble-stack {\r\n position: absolute;\r\n right: 0;\r\n bottom: calc(100% + 12px);\r\n width: min(380px, 86vw);\r\n max-height: min(58vh, 520px);\r\n overflow: auto;\r\n\r\n &::-webkit-scrollbar {\r\n width: 4px;\r\n }\r\n\r\n &::-webkit-scrollbar-thumb {\r\n background: rgba(126, 155, 204, 0.3);\r\n border-radius: 999px;\r\n }\r\n}\r\n\r\n/* ── Agent 气泡 ── */\r\n.agent-bubble {\r\n border-radius: 16px;\r\n padding: 12px 14px;\r\n background:\r\n radial-gradient(circle at 12% 10%, rgba(80, 122, 255, 0.14), transparent 50%),\r\n linear-gradient(155deg, rgba(24, 42, 72, 0.96), rgba(14, 24, 46, 0.97));\r\n border: 1px solid rgba(108, 141, 204, 0.2);\r\n box-shadow:\r\n 0 12px 32px rgba(1, 6, 20, 0.5),\r\n inset 0 1px 0 rgba(255, 255, 255, 0.04);\r\n backdrop-filter: blur(16px);\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n animation: bubble-appear 0.3s cubic-bezier(0.16, 1, 0.3, 1);\r\n}\r\n\r\n@keyframes bubble-appear {\r\n from {\r\n opacity: 0;\r\n transform: translateY(8px) scale(0.97);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0) scale(1);\r\n }\r\n}\r\n\r\n/* ── 工具执行步骤 ── */\r\n.tool-steps {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n margin-bottom: 6px;\r\n padding-bottom: 8px;\r\n border-bottom: 1px solid rgba(125, 160, 220, 0.1);\r\n}\r\n\r\n.tool-step {\r\n display: flex;\r\n align-items: center;\r\n gap: 7px;\r\n padding: 4px 6px;\r\n border-radius: 8px;\r\n transition: background 0.2s ease;\r\n animation: step-in 0.25s cubic-bezier(0.16, 1, 0.3, 1);\r\n\r\n &--loading {\r\n .tool-step__icon {\r\n color: var(--color-accent);\r\n }\r\n .tool-step__name {\r\n color: rgba(200, 215, 240, 0.85);\r\n }\r\n }\r\n\r\n &--done {\r\n .tool-step__icon {\r\n color: var(--color-success);\r\n }\r\n .tool-step__name {\r\n color: rgba(200, 215, 240, 0.55);\r\n }\r\n }\r\n\r\n &--error {\r\n .tool-step__icon {\r\n color: var(--color-error);\r\n }\r\n .tool-step__name {\r\n color: rgba(248, 113, 113, 0.8);\r\n }\r\n }\r\n\r\n &--executing {\r\n background: rgba(129, 140, 248, 0.06);\r\n .tool-step__icon {\r\n color: var(--color-accent);\r\n }\r\n }\r\n}\r\n\r\n@keyframes step-in {\r\n from {\r\n opacity: 0;\r\n transform: translateX(-6px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateX(0);\r\n }\r\n}\r\n\r\n.tool-step__icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 18px;\r\n height: 18px;\r\n flex-shrink: 0;\r\n}\r\n\r\n.tool-step__spinner {\r\n animation: tool-spin 0.8s linear infinite;\r\n}\r\n\r\n@keyframes tool-spin {\r\n from {\r\n transform: rotate(0deg);\r\n }\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n.tool-step__name {\r\n font-size: 12px;\r\n font-weight: 500;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n transition: color 0.2s ease;\r\n}\r\n\r\n.tool-step__tag {\r\n font-size: 10px;\r\n font-weight: 500;\r\n padding: 1px 6px;\r\n border-radius: 4px;\r\n white-space: nowrap;\r\n flex-shrink: 0;\r\n\r\n &--exec {\r\n background: rgba(129, 140, 248, 0.12);\r\n color: var(--color-accent);\r\n }\r\n}\r\n\r\n/* ── 思考中动画 ── */\r\n.thinking-dots {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 5px;\r\n padding: 2px 0;\r\n\r\n span {\r\n width: 5px;\r\n height: 5px;\r\n border-radius: 50%;\r\n background: var(--text-secondary);\r\n animation: thinking-bounce 1s infinite ease-in-out;\r\n }\r\n\r\n span:nth-child(2) {\r\n animation-delay: 0.15s;\r\n }\r\n\r\n span:nth-child(3) {\r\n animation-delay: 0.3s;\r\n }\r\n}\r\n\r\n@keyframes thinking-bounce {\r\n 0%,\r\n 100% {\r\n transform: translateY(0);\r\n opacity: 0.3;\r\n }\r\n 50% {\r\n transform: translateY(-3px);\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* ── 文本内容 ── */\r\n.agent-text {\r\n font-size: 14px;\r\n line-height: 1.55;\r\n color: var(--text-primary);\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n/* ── 气泡过渡 ── */\r\n.bubble-fade-enter-active {\r\n transition: all 0.35s cubic-bezier(0.16, 1, 0.3, 1);\r\n}\r\n\r\n.bubble-fade-leave-active {\r\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n}\r\n\r\n.bubble-fade-enter-from {\r\n opacity: 0;\r\n transform: translateY(12px) scale(0.95);\r\n}\r\n\r\n.bubble-fade-leave-to {\r\n opacity: 0;\r\n transform: translateY(8px) scale(0.97);\r\n}\r\n\r\n@media (max-width: 768px) {\r\n .bubble-stack {\r\n width: min(320px, 88vw);\r\n max-height: min(54vh, 420px);\r\n }\r\n\r\n .input-bar {\r\n min-width: 260px;\r\n }\r\n}\r\n</style>\r\n","import type { CommandDefinition, DiscoveredCommand } from './command-types';\r\n\r\nexport interface CommandManagerOptions {\r\n debug?: boolean;\r\n}\r\n\r\nexport class CommandManager {\r\n private commands: Map<string, CommandDefinition> = new Map();\r\n private debug: boolean;\r\n\r\n constructor(options: CommandManagerOptions = {}) {\r\n this.debug = options.debug ?? false;\r\n }\r\n\r\n public registerCommand(command: CommandDefinition): void {\r\n this.commands.set(command.name, command);\r\n this.log('注册命令', `${command.name}: ${command.description}`);\r\n }\r\n\r\n public unregisterCommand(name: string): void {\r\n const deleted = this.commands.delete(name);\r\n if (deleted) {\r\n this.log('命令已注销', name);\r\n }\r\n }\r\n\r\n public async executeCommand(command: string, args: any[] = []): Promise<any> {\r\n const commandDef = this.commands.get(command);\r\n if (!commandDef) {\r\n throw new Error(`命令 \"${command}\" 未找到`);\r\n }\r\n\r\n this.log('执行命令', command, args);\r\n return await commandDef.handler(...args);\r\n }\r\n\r\n public getCommands(): DiscoveredCommand[] {\r\n return Array.from(this.commands.values()).map((cmd) => ({\r\n name: cmd.name,\r\n description: cmd.description,\r\n parameters: cmd.parameters,\r\n }));\r\n }\r\n\r\n public hasCommand(name: string): boolean {\r\n return this.commands.has(name);\r\n }\r\n\r\n public clear(): void {\r\n this.commands.clear();\r\n this.log('', '所有命令已清空');\r\n }\r\n\r\n private log(prefix: string, msg: string, ...args: any[]): void {\r\n const time = new Date().toLocaleTimeString([], {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n second: '2-digit',\r\n });\r\n\r\n console.log(\r\n `%c ${prefix}`,\r\n 'background:#7c3aed;color:white;padding:2px 6px;border-radius:3px 0 0 3px;font-weight:bold;',\r\n `${msg}`,\r\n );\r\n\r\n if (args.length > 0) {\r\n console.log(...args);\r\n }\r\n }\r\n}\r\n","<template>\r\n <slot></slot>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { provide, shallowRef } from 'vue';\r\nimport { AiChatbotXKey } from '../injection-key';\r\nimport { CommandManager } from '../utils/command-manager';\r\nimport type { CommandDefinition } from '../utils/command-types';\r\n\r\nconst props = defineProps<{\r\n /** appToken */\r\n appToken: string;\r\n /** organizationId */\r\n organizationId: string;\r\n /** projectId for stream-invoke (used by voice-assistant) */\r\n projectId?: string;\r\n}>();\r\n\r\nconst commandManager = shallowRef<CommandManager>(new CommandManager({ debug: false }));\r\n\r\nconst startListeningRef = shallowRef<() => Promise<void>>(async () => {});\r\nconst stopListeningRef = shallowRef<() => Promise<void>>(async () => {});\r\nconst stopBroadcastRef = shallowRef<() => Promise<void>>(async () => {});\r\n\r\nconst voiceAssistantRef = shallowRef<{\r\n agentInvoke: (text: string) => Promise<void>;\r\n agentAbort: () => void;\r\n speakText: (text: string) => void;\r\n stopSpeak: () => void;\r\n} | null>(null);\r\n\r\nprovide(AiChatbotXKey, {\r\n appToken: () => props.appToken,\r\n organizationId: () => props.organizationId,\r\n startListening: () => startListeningRef.value(),\r\n stopListening: () => stopListeningRef.value(),\r\n stopBroadcast: () => stopBroadcastRef.value(),\r\n registerVoiceMethods: (methods: {\r\n stopBroadcast?: () => Promise<void>;\r\n start: () => Promise<void>;\r\n stop: () => Promise<void>;\r\n }) => {\r\n if (methods.stopBroadcast) stopBroadcastRef.value = methods.stopBroadcast;\r\n if (methods.start) startListeningRef.value = methods.start;\r\n if (methods.stop) stopListeningRef.value = methods.stop;\r\n },\r\n registerVoiceAssistant: (methods: {\r\n agentInvoke: (text: string) => Promise<void>;\r\n agentAbort: () => void;\r\n speakText: (text: string) => void;\r\n stopSpeak: () => void;\r\n }) => {\r\n voiceAssistantRef.value = methods;\r\n },\r\n getCommads: async () => commandManager.value.getCommands(),\r\n registerCommand: (cmd: CommandDefinition) => {\r\n commandManager.value.registerCommand(cmd);\r\n },\r\n unregisterCommand: (name) => {\r\n commandManager.value.unregisterCommand(name);\r\n },\r\n async executeCommand(commandName, args = []) {\r\n return await commandManager.value.executeCommand(commandName, args);\r\n },\r\n sendMessage: async (text: string) => {\r\n voiceAssistantRef.value?.agentInvoke(text);\r\n },\r\n speakText: (text: string) => {\r\n voiceAssistantRef.value?.speakText(text);\r\n },\r\n stopSpeak: () => {\r\n voiceAssistantRef.value?.stopSpeak();\r\n },\r\n abortInvoke: () => {\r\n voiceAssistantRef.value?.agentAbort();\r\n },\r\n});\r\n</script>\r\n","import { ref } from 'vue';\r\nimport { SpeechSynthesizerStandalone } from 'web-voice-kit';\r\nimport type { VoiceConfig } from '../types';\r\n\r\n/**\r\n * TTS 语音播报 composable\r\n *\r\n * 管理讯飞 SpeechSynthesizerStandalone 的生命周期、\r\n * 句子级缓冲、Markdown 清理、AudioContext 预热。\r\n */\r\nexport function useTTS(getVoiceConfig: () => VoiceConfig | null) {\r\n const isSpeaking = ref(false);\r\n // hasPendingAudio: true 从 speak/feed 被调用开始,直到 onQueueEmpty。\r\n // 覆盖了 speak 异步等待 ensureInstance 的窗口期,此时 isSpeaking 尚为 false。\r\n const hasPendingAudio = ref(false);\r\n\r\n let instance: SpeechSynthesizerStandalone | null = null;\r\n let initPromise: Promise<SpeechSynthesizerStandalone | null> | null = null;\r\n let audioCtx: AudioContext | null = null;\r\n\r\n // 句子缓冲\r\n let sentenceBuffer = '';\r\n const SENTENCE_DELIMITERS = /[。!?;\\n!?;]/;\r\n const LEADING_WEAK_PUNCTUATION = /^[\\s,、;:,.!?。]+/;\r\n const TRAILING_SENTENCE_PUNCTUATION = /[。!?.!?;;]$/;\r\n\r\n const findSentenceBoundary = (text: string): number => {\r\n for (let i = 0; i < text.length; i++) {\r\n const char = text[i];\r\n if (SENTENCE_DELIMITERS.test(char)) {\r\n return i;\r\n }\r\n }\r\n return -1;\r\n };\r\n\r\n // ── helpers ──\r\n\r\n const normalizeNumbers = (text: string): string => {\r\n return text\r\n .replace(/(-?\\d[\\d,]*\\.?\\d*)\\s*%/g, (_, num) => {\r\n const cleanNum = num.replace(/,/g, '');\r\n const n = parseFloat(cleanNum);\r\n const spoken = cleanNum.replace('.', '点');\r\n if (n < 0) return `负百分之${spoken.replace('-', '')}`;\r\n return `百分之${spoken}`;\r\n })\r\n .replace(/(-?\\d[\\d,]*)\\.(\\d+)/g, (_, intPart, decPart) => {\r\n const cleanInt = intPart.replace(/,/g, '');\r\n if (cleanInt.startsWith('-')) {\r\n return `负${cleanInt.slice(1)}点${decPart}`;\r\n }\r\n return `${cleanInt}点${decPart}`;\r\n })\r\n .replace(/-(\\d)/g, '负$1');\r\n };\r\n\r\n const stripMarkdown = (text: string): string => {\r\n let result = text\r\n .replace(/```[\\s\\S]*?```/g, '')\r\n .replace(/\\|[^\\n]*\\|/g, '')\r\n .replace(/#{1,6}\\s*/g, '')\r\n .replace(/\\*\\*(.*?)\\*\\*/g, '$1')\r\n .replace(/\\*(.*?)\\*/g, '$1')\r\n .replace(/`([^`]*)`/g, '$1')\r\n .replace(/\\[([^\\]]*)\\]\\([^)]*\\)/g, '$1')\r\n .replace(/^[-*+]\\s+/gm, '')\r\n .replace(/^>\\s+/gm, '');\r\n result = normalizeNumbers(result);\r\n result = result\r\n .replace(/\\s*\\+\\s*(?=\\d)/g, '加')\r\n .replace(/\\s*\\+\\s*/g, '加')\r\n .replace(/\\s*-\\s*(?=\\d)/g, '减')\r\n .replace(/\\s*-\\s*/g, '减')\r\n .replace(/\\s*×\\s*/g, '乘')\r\n .replace(/\\s*÷\\s*/g, '除')\r\n .replace(/\\s*=\\s*/g, '等于')\r\n .replace(/\\n{2,}/g, '。')\r\n .replace(/\\n/g, ',')\r\n .trim();\r\n return result;\r\n };\r\n\r\n const normalizeSpeakText = (text: string, options?: { isFinalChunk?: boolean }): string => {\r\n const clean = stripMarkdown(text).replace(LEADING_WEAK_PUNCTUATION, '').trim();\r\n if (!clean) return '';\r\n if (options?.isFinalChunk && !TRAILING_SENTENCE_PUNCTUATION.test(clean)) {\r\n return `${clean}。`;\r\n }\r\n return clean;\r\n };\r\n\r\n // ── AudioContext 预热 ──\r\n\r\n const warmUpAudio = () => {\r\n if (!audioCtx || audioCtx.state === 'closed') {\r\n try {\r\n audioCtx = new AudioContext();\r\n } catch {\r\n return;\r\n }\r\n }\r\n if (audioCtx.state === 'suspended') {\r\n audioCtx.resume();\r\n }\r\n };\r\n\r\n // ── 懒初始化 ──\r\n\r\n /** 回调:TTS 队列清空时触发(外部可监听) */\r\n let onQueueEmptyCb: (() => void) | null = null;\r\n\r\n const ensureInstance = async (): Promise<SpeechSynthesizerStandalone | null> => {\r\n if (instance) return instance;\r\n if (initPromise) return initPromise;\r\n\r\n const vc = getVoiceConfig();\r\n if (!vc || !vc.apiSecret) {\r\n console.warn('[TTS] 缺少 voiceConfig 或 apiSecret,语音播报已禁用');\r\n return null;\r\n }\r\n\r\n initPromise = (async () => {\r\n try {\r\n const tts = new SpeechSynthesizerStandalone({\r\n appId: vc.appId,\r\n apiKey: vc.ttsApiKey || vc.apiKey,\r\n apiSecret: vc.apiSecret!,\r\n websocketUrl: vc.ttsWebsocketUrl || 'wss://tts-api.xfyun.cn/v2/tts',\r\n vcn: vc.ttsVcn || 'xiaoyan',\r\n speed: vc.speed || 55,\r\n volume: vc.volume || 90,\r\n pitch: vc.pitch || 50,\r\n aue: 'raw',\r\n auf: 'audio/L16;rate=16000',\r\n tte: 'UTF8',\r\n autoPlay: true,\r\n });\r\n\r\n tts.onStart(() => {\r\n isSpeaking.value = true;\r\n });\r\n\r\n tts.onEnd(() => {\r\n // 每段文本结束,队列可能还有后续\r\n });\r\n\r\n tts.onQueueEmpty(() => {\r\n isSpeaking.value = false;\r\n hasPendingAudio.value = false;\r\n onQueueEmptyCb?.();\r\n });\r\n\r\n tts.onError((err: any) => {\r\n console.error('[TTS] Error:', err);\r\n isSpeaking.value = false;\r\n });\r\n\r\n // 注入预热的 AudioContext\r\n if (audioCtx && audioCtx.state === 'running') {\r\n (tts as any).audioContext = audioCtx;\r\n (tts as any).gainNode = audioCtx.createGain();\r\n (tts as any).gainNode.connect(audioCtx.destination);\r\n }\r\n\r\n instance = tts;\r\n initPromise = null;\r\n return tts;\r\n } catch (err) {\r\n console.error('[TTS] 初始化失败:', err);\r\n initPromise = null;\r\n return null;\r\n }\r\n })();\r\n\r\n return initPromise;\r\n };\r\n\r\n // ── 公开方法 ──\r\n\r\n const speak = async (text: string) => {\r\n const clean = normalizeSpeakText(text);\r\n if (!clean.trim()) return;\r\n hasPendingAudio.value = true;\r\n const tts = await ensureInstance();\r\n if (!tts) return;\r\n try {\r\n tts.speak(clean);\r\n } catch (err) {\r\n console.error('[TTS] speak 失败:', err);\r\n }\r\n };\r\n\r\n /**\r\n * 播报文本并等待播完(Promise 化)。\r\n * 用于外部排队场景:await speakAndWait(text) 保证播完后才继续。\r\n * 内部设置 60 s 安全超时,防止回调丢失导致 Promise 永久挂起。\r\n */\r\n const speakAndWait = async (text: string): Promise<void> => {\r\n const clean = normalizeSpeakText(text);\r\n if (!clean.trim()) return;\r\n\r\n hasPendingAudio.value = true;\r\n const ttsInst = await ensureInstance();\r\n if (!ttsInst) {\r\n hasPendingAudio.value = false;\r\n return;\r\n }\r\n\r\n return new Promise<void>((resolve) => {\r\n let settled = false;\r\n const settle = () => {\r\n if (settled) return;\r\n settled = true;\r\n clearTimeout(safetyTimer);\r\n onQueueEmptyCb = null;\r\n resolve();\r\n };\r\n\r\n // 安全超时:60 s 后强制 resolve,避免永久挂起\r\n const safetyTimer = setTimeout(() => {\r\n console.warn('[TTS] speakAndWait 安全超时,强制 resolve');\r\n settle();\r\n }, 60_000);\r\n\r\n onQueueEmptyCb = settle;\r\n\r\n try {\r\n ttsInst.speak(clean);\r\n } catch (err) {\r\n console.error('[TTS] speak 失败:', err);\r\n settle();\r\n }\r\n });\r\n };\r\n\r\n const feed = (delta: string) => {\r\n sentenceBuffer += delta;\r\n while (true) {\r\n const boundaryIndex = findSentenceBoundary(sentenceBuffer);\r\n if (boundaryIndex === -1) break;\r\n const sentence = sentenceBuffer.slice(0, boundaryIndex + 1).trim();\r\n sentenceBuffer = sentenceBuffer.slice(boundaryIndex + 1);\r\n if (sentence.length > 0) speak(sentence);\r\n }\r\n };\r\n\r\n const flush = () => {\r\n const remaining = sentenceBuffer.trim();\r\n sentenceBuffer = '';\r\n if (remaining.length > 0) {\r\n const clean = normalizeSpeakText(remaining, { isFinalChunk: true });\r\n if (clean) void speak(clean);\r\n }\r\n };\r\n\r\n const stop = () => {\r\n sentenceBuffer = '';\r\n isSpeaking.value = false;\r\n hasPendingAudio.value = false;\r\n // 立即 resolve 任何挂起的 speakAndWait Promise,防止队列卡死\r\n if (onQueueEmptyCb) {\r\n const cb = onQueueEmptyCb;\r\n onQueueEmptyCb = null;\r\n cb();\r\n }\r\n if (instance) {\r\n try {\r\n instance.stop();\r\n } catch {\r\n // ignore\r\n }\r\n }\r\n };\r\n\r\n const setOnQueueEmpty = (cb: () => void) => {\r\n onQueueEmptyCb = cb;\r\n };\r\n\r\n const destroy = () => {\r\n stop();\r\n if (instance) {\r\n try {\r\n instance.destroy();\r\n } catch {\r\n // ignore\r\n }\r\n instance = null;\r\n }\r\n if (audioCtx) {\r\n try {\r\n audioCtx.close();\r\n } catch {\r\n // ignore\r\n }\r\n audioCtx = null;\r\n }\r\n };\r\n\r\n return {\r\n isSpeaking,\r\n hasPendingAudio,\r\n warmUpAudio,\r\n speak,\r\n speakAndWait,\r\n feed,\r\n flush,\r\n stop,\r\n destroy,\r\n setOnQueueEmpty,\r\n };\r\n}\r\n","import { DiscoveredCommand } from '../utils/command-types';\r\n\r\nexport const ensureMicrophonePermission = async () => {\r\n // 检查浏览器环境\r\n if (typeof navigator === 'undefined' || typeof window === 'undefined') {\r\n console.log('当前环境不支持麦克风访问');\r\n return false;\r\n }\r\n\r\n // 检查 MediaDevices API 支持\r\n if (!navigator.mediaDevices?.getUserMedia || !navigator.mediaDevices?.enumerateDevices) {\r\n console.log('当前环境不支持麦克风访问');\r\n return false;\r\n }\r\n\r\n try {\r\n // 1. 首先枚举设备,检查是否有音频输入设备\r\n const devices = await navigator.mediaDevices.enumerateDevices();\r\n const audioInputDevices = devices.filter((device) => device.kind === 'audioinput');\r\n\r\n if (audioInputDevices.length === 0) {\r\n console.log('未检测到麦克风设备,请连接麦克风后重试。');\r\n return false;\r\n }\r\n\r\n // 2. 检查权限状态(如果浏览器支持)\r\n if ('permissions' in navigator && navigator.permissions?.query) {\r\n try {\r\n const status = await navigator.permissions.query({ name: 'microphone' as PermissionName });\r\n\r\n if (status.state === 'denied') {\r\n console.log('麦克风权限被禁用,请在浏览器设置中开启。');\r\n return false;\r\n }\r\n } catch (e) {\r\n // 某些浏览器可能不支持 microphone 权限查询,继续执行\r\n console.warn('Permission query not supported:', e);\r\n }\r\n }\r\n\r\n // 3. 尝试获取麦克风流以确认权限和设备可用性\r\n let stream: MediaStream | null = null;\r\n try {\r\n stream = await navigator.mediaDevices.getUserMedia({\r\n audio: {\r\n echoCancellation: true,\r\n noiseSuppression: true,\r\n autoGainControl: true,\r\n },\r\n });\r\n\r\n // 检查流是否有活动的音频轨道\r\n const audioTracks = stream.getAudioTracks();\r\n if (audioTracks.length === 0) {\r\n console.log('无法获取麦克风音频轨道。');\r\n return false;\r\n }\r\n\r\n // 检查音频轨道是否启用且可读\r\n const activeTrack = audioTracks[0];\r\n if (!activeTrack.enabled || activeTrack.readyState !== 'live') {\r\n console.log('麦克风设备不可用,请检查设备连接。');\r\n return false;\r\n }\r\n\r\n return true;\r\n } finally {\r\n // 确保释放流资源\r\n if (stream) {\r\n stream.getTracks().forEach((track) => track.stop());\r\n }\r\n }\r\n } catch (error: any) {\r\n console.error('Microphone permission check failed', error);\r\n\r\n // 根据错误类型提供更具体的提示\r\n if (error.name === 'NotFoundError' || error.name === 'DevicesNotFoundError') {\r\n console.log('未检测到麦克风设备,请连接麦克风后重试。');\r\n } else if (error.name === 'NotAllowedError' || error.name === 'PermissionDeniedError') {\r\n console.log('麦克风权限被拒绝,请在浏览器设置中允许访问。');\r\n } else if (error.name === 'NotReadableError' || error.name === 'TrackStartError') {\r\n console.log('麦克风被其他应用占用或无法访问。');\r\n } else {\r\n console.log('无法访问麦克风,请检查设备连接和浏览器权限。');\r\n }\r\n\r\n return false;\r\n }\r\n};\r\n\r\n/**\r\n * 语音命令匹配函数\r\n * @param {string} userInput - 用户输入的原始语音文本\r\n * @param {Array} commandList - 命令列表对象数组\r\n * @param {number} threshold - 相似度阈值 (0-1),默认 0.5\r\n */\r\nexport function matchVoiceCommand(userInput: string, commandList: DiscoveredCommand[], threshold = 0.5) {\r\n if (!userInput || typeof userInput !== 'string') return null;\r\n\r\n // 1. 预处理:转小写、去空格、去标点、去语气词\r\n const cleanInput = userInput\r\n .trim()\r\n .toLowerCase()\r\n // 1. 去除所有标点符号及特殊字符\r\n .replace(/[,。?!;:、“”()()<>《》\\s\\.\\,\\?\\!]/g, '')\r\n // 2. 去除常见的前缀 (增加“给我”、“能不能”等)\r\n .replace(/^(请帮我|我想|帮我|麻烦|我要|你好|您好|帮我把|给我|能不能帮我|请问|那个)/g, '')\r\n // 3. 去除中间的动作虚词 (如“把...给...”)\r\n .replace(/给(?=(打开|开启|关闭|停止))/g, '')\r\n // 4. 去除常见的后缀 (增加“就可以了”、“就行”、“模式”)\r\n .replace(/(一下|了|吧|输出|就可以了|就行|模式|操作|功能)$/g, '');\r\n\r\n let bestMatch = null;\r\n let maxScore = 0;\r\n\r\n // 编辑距离算法 (Levenshtein Distance)\r\n const getSimilarity = (s1: string, s2: string) => {\r\n const [l1, l2] = [s1.length, s2.length];\r\n const matrix = Array.from({ length: l1 + 1 }, () => Array(l2 + 1).fill(0));\r\n for (let i = 0; i <= l1; i++) matrix[i][0] = i;\r\n for (let j = 0; j <= l2; j++) matrix[0][j] = j;\r\n\r\n for (let i = 1; i <= l1; i++) {\r\n for (let j = 1; j <= l2; j++) {\r\n const cost = s1[i - 1] === s2[j - 1] ? 0 : 1;\r\n matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + cost);\r\n }\r\n }\r\n return 1 - matrix[l1][l2] / Math.max(l1, l2);\r\n };\r\n\r\n // 2. 遍历命令列表进行比对\r\n for (const cmd of commandList) {\r\n const target = cmd.description.toLowerCase();\r\n let currentScore = 0;\r\n\r\n // 策略 A:直接包含 (如输入“帮我开启漫游吧”,描述是“开启漫游”)\r\n if (cleanInput.includes(target) || target.includes(cleanInput)) {\r\n // 计算包含关系的得分,越接近 1 分越高\r\n currentScore = Math.min(target.length, cleanInput.length) / Math.max(target.length, cleanInput.length);\r\n // 给予包含匹配更高的基础权重\r\n currentScore = 0.8 + currentScore * 0.2;\r\n }\r\n // 策略 B:模糊匹配 (处理同音字错误,如“开启慢游”)\r\n else {\r\n currentScore = getSimilarity(cleanInput, target);\r\n }\r\n\r\n // 更新最高分项\r\n if (currentScore > maxScore) {\r\n maxScore = currentScore;\r\n bestMatch = { ...cmd, confidence: maxScore };\r\n }\r\n }\r\n\r\n // 3. 结果过滤\r\n return maxScore >= threshold ? bestMatch : null;\r\n}\r\n","import { ref } from 'vue';\r\nimport { SpeechTranscriberStandalone, WakeWordDetectorStandalone } from 'web-voice-kit';\r\nimport type { VoiceConfig } from '../types';\r\nimport { ensureMicrophonePermission } from '../lib/utils';\r\n\r\nexport type VoiceStatus = 'standby' | 'listening';\r\n\r\nexport interface UseVoiceRecognitionOptions {\r\n modelPath?: string;\r\n wakeWords?: string[];\r\n getVoiceConfig: () => VoiceConfig | null;\r\n /** 唤醒时回调 */\r\n onWake?: () => void;\r\n /** 转写完成(autoStop)时回调 */\r\n onTranscriptionDone?: (text: string) => void;\r\n}\r\n\r\n/**\r\n * 语音识别 composable\r\n *\r\n * 管理唤醒词检测器 + 语音转写器的生命周期。\r\n */\r\nexport function useVoiceRecognition(options: UseVoiceRecognitionOptions) {\r\n const voiceStatus = ref<VoiceStatus>('standby');\r\n const isTranscribing = ref(false);\r\n const isInitializing = ref(false);\r\n const transcriptionText = ref('');\r\n const wakeAnimating = ref(false);\r\n\r\n let detector: WakeWordDetectorStandalone | null = null;\r\n let transcriber: SpeechTranscriberStandalone | null = null;\r\n\r\n // ── 转写器 ──\r\n\r\n const initTranscriber = () => {\r\n if (transcriber) return;\r\n\r\n const vc = options.getVoiceConfig();\r\n if (!vc || !vc.appId || !vc.apiKey || !vc.websocketUrl) {\r\n console.error('[VoiceRecognition] 缺少 voiceConfig,无法初始化转写器');\r\n return;\r\n }\r\n\r\n transcriber = new SpeechTranscriberStandalone({\r\n appId: vc.appId,\r\n apiKey: vc.apiKey,\r\n websocketUrl: vc.websocketUrl,\r\n autoStop: {\r\n enabled: true,\r\n silenceTimeoutMs: 2000,\r\n noSpeechTimeoutMs: 5000,\r\n maxDurationMs: 45000,\r\n },\r\n });\r\n\r\n transcriber.onResult((result) => {\r\n transcriptionText.value = result.transcript || '';\r\n });\r\n\r\n transcriber.onAutoStop(async () => {\r\n const finalText = transcriptionText.value;\r\n await stopTranscribing();\r\n transcriptionText.value = '';\r\n if (finalText.trim()) {\r\n options.onTranscriptionDone?.(finalText);\r\n }\r\n });\r\n\r\n transcriber.onError((error: any) => {\r\n console.error('[VoiceRecognition] 转写错误:', error);\r\n stopTranscribing();\r\n transcriptionText.value = '';\r\n });\r\n };\r\n\r\n const startTranscribing = async () => {\r\n if (isTranscribing.value) return;\r\n if (!transcriber) initTranscriber();\r\n if (!transcriber) return;\r\n\r\n try {\r\n await transcriber.start();\r\n isTranscribing.value = true;\r\n transcriptionText.value = '';\r\n } catch (error) {\r\n console.error('[VoiceRecognition] 启动转写失败:', error);\r\n }\r\n };\r\n\r\n const stopTranscribing = async () => {\r\n if (!transcriber || !transcriber.isActive()) {\r\n isTranscribing.value = false;\r\n return;\r\n }\r\n try {\r\n await transcriber.stop();\r\n } catch (error) {\r\n console.error('[VoiceRecognition] 停止转写失败:', error);\r\n } finally {\r\n isTranscribing.value = false;\r\n }\r\n };\r\n\r\n // ── 唤醒词检测器 ──\r\n\r\n const initDetector = () => {\r\n if (detector || isInitializing.value) return;\r\n if (!options.modelPath) {\r\n console.error('[VoiceRecognition] 未传入 modelPath,无法启用唤醒词');\r\n return;\r\n }\r\n\r\n isInitializing.value = true;\r\n try {\r\n detector = new WakeWordDetectorStandalone({\r\n modelPath: options.modelPath,\r\n sampleRate: 16000,\r\n usePartial: true,\r\n autoReset: {\r\n enabled: true,\r\n resetDelayMs: 4000,\r\n },\r\n });\r\n\r\n detector.setWakeWords(options.wakeWords || ['你好', '您好']);\r\n detector.onWake(async () => {\r\n wakeAnimating.value = true;\r\n options.onWake?.();\r\n await startTranscribing();\r\n setTimeout(() => {\r\n wakeAnimating.value = false;\r\n }, 1200);\r\n });\r\n\r\n detector.onError((error: any) => {\r\n console.error('[VoiceRecognition] 唤醒监听错误:', error);\r\n voiceStatus.value = 'standby';\r\n stopTranscribing();\r\n });\r\n } finally {\r\n isInitializing.value = false;\r\n }\r\n };\r\n\r\n // ── 切换语音模式 ──\r\n\r\n const toggleVoiceMode = async (targetState?: boolean) => {\r\n const permission = await ensureMicrophonePermission();\r\n if (!permission || isInitializing.value) return;\r\n\r\n if (!detector) {\r\n initDetector();\r\n if (!detector) return;\r\n }\r\n\r\n const isListening = voiceStatus.value === 'listening';\r\n const shouldStart = targetState !== undefined ? targetState : !isListening;\r\n if (isListening === shouldStart) return;\r\n\r\n try {\r\n if (shouldStart) {\r\n await detector.start();\r\n voiceStatus.value = 'listening';\r\n } else {\r\n await detector.stop();\r\n voiceStatus.value = 'standby';\r\n transcriptionText.value = '';\r\n await stopTranscribing();\r\n }\r\n } catch (error) {\r\n console.error('[VoiceRecognition] 监听切换失败:', error);\r\n voiceStatus.value = 'standby';\r\n }\r\n };\r\n\r\n // ── 中断当前转写(唤醒中断场景) ──\r\n\r\n const abortTranscription = async () => {\r\n transcriptionText.value = '';\r\n await stopTranscribing();\r\n };\r\n\r\n // ── 清理 ──\r\n\r\n const destroy = async () => {\r\n if (detector) {\r\n try {\r\n if (detector.isActive()) await detector.stop();\r\n } catch {\r\n // ignore\r\n }\r\n detector = null;\r\n }\r\n if (transcriber) {\r\n try {\r\n if (transcriber.isActive()) await transcriber.stop();\r\n } catch {\r\n // ignore\r\n }\r\n transcriber = null;\r\n }\r\n };\r\n\r\n return {\r\n voiceStatus,\r\n isTranscribing,\r\n isInitializing,\r\n transcriptionText,\r\n wakeAnimating,\r\n startTranscribing,\r\n stopTranscribing,\r\n abortTranscription,\r\n toggleVoiceMode,\r\n destroy,\r\n };\r\n}\r\n","<template>\r\n <div class=\"voice-assistant\" :data-theme=\"currentTheme\">\r\n <!-- ── 气泡区域:仅渲染 agent 回复 ── -->\r\n <transition name=\"bubble-fade\">\r\n <div class=\"bubble-stack\" v-if=\"showBubble\" ref=\"bubbleStackRef\" :style=\"bubbleStyle\">\r\n <div class=\"agent-bubble\">\r\n <!-- 工具执行步骤(内联紧凑样式) -->\r\n <div v-if=\"currentToolParts.length > 0\" class=\"tool-steps\">\r\n <div\r\n v-for=\"toolPart in currentToolParts\"\r\n :key=\"toolPart.toolCallId\"\r\n class=\"tool-step\"\r\n :class=\"{\r\n 'tool-step--loading': toolPart.state === 'partial-call' || toolPart.state === 'call',\r\n 'tool-step--done': toolPart.state === 'result',\r\n 'tool-step--error': toolPart.state === 'error',\r\n 'tool-step--executing': executingTools.has(toolPart.toolCallId),\r\n }\"\r\n >\r\n <!-- 状态图标 -->\r\n <span class=\"tool-step__icon\">\r\n <svg\r\n v-if=\"toolPart.state === 'partial-call' || toolPart.state === 'call'\"\r\n class=\"tool-step__spinner\"\r\n width=\"14\"\r\n height=\"14\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n >\r\n <circle\r\n cx=\"12\"\r\n cy=\"12\"\r\n r=\"10\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n stroke-dasharray=\"31.4 31.4\"\r\n />\r\n </svg>\r\n <svg v-else-if=\"toolPart.state === 'result'\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M20 6L9 17l-5-5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2.5\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </svg>\r\n <svg v-else-if=\"toolPart.state === 'error'\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"2\" />\r\n <path d=\"M15 9l-6 6M9 9l6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\r\n </svg>\r\n </span>\r\n <span class=\"tool-step__name\">{{ toolDisplayName(toolPart.toolName) }}</span>\r\n <span v-if=\"executingTools.has(toolPart.toolCallId)\" class=\"tool-step__tag tool-step__tag--exec\"\r\n >命令执行中</span\r\n >\r\n </div>\r\n </div>\r\n\r\n <!-- 思考中动画(无工具、无文本时显示) -->\r\n <div v-if=\"isInvoking && !hasAnyContent\" class=\"thinking-dots\">\r\n <span></span>\r\n <span></span>\r\n <span></span>\r\n </div>\r\n\r\n <!-- 文本内容 -->\r\n <div v-if=\"currentTextContent\" class=\"agent-text\">{{ currentTextContent }}</div>\r\n </div>\r\n </div>\r\n </transition>\r\n\r\n <!-- ── FAB 按钮 ── -->\r\n <div class=\"assistant-fab\" @click=\"toggleVoiceMode()\">\r\n <div v-if=\"transcriptionText || isInvoking\" class=\"status-pill\">\r\n {{ isInvoking ? '正在思考中...' : transcriptionText }}\r\n </div>\r\n <div class=\"fab-avatar-wrapper\">\r\n <img\r\n :src=\"xLogo ? xLogo : '/x.png'\"\r\n alt=\"voice assistant\"\r\n :style=\"{\r\n width: `${xSize?.width || 88}px`,\r\n }\"\r\n />\r\n\r\n <transition name=\"indicator-fade\">\r\n <div\r\n v-if=\"voiceStatus === 'listening'\"\r\n class=\"listening-badge\"\r\n :class=\"{ 'wake-active': wakeAnimating || isTranscribing || isInvoking }\"\r\n >\r\n <div class=\"listening-waves\">\r\n <div class=\"wave wave-1\"></div>\r\n <div class=\"wave wave-2\"></div>\r\n <div class=\"wave wave-3\"></div>\r\n </div>\r\n <div class=\"listening-icon\">\r\n <svg width=\"22\" height=\"22\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path\r\n d=\"M12 14c1.66 0 3-1.34 3-3V5c0-1.66-1.34-3-3-3S9 3.34 9 5v6c0 1.66 1.34 3 3 3z\"\r\n fill=\"currentColor\"\r\n />\r\n <path\r\n d=\"M17 11c0 2.76-2.24 5-5 5s-5-2.24-5-5\"\r\n stroke=\"currentColor\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n />\r\n </svg>\r\n </div>\r\n </div>\r\n </transition>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<script lang=\"ts\" setup>\r\nimport { computed, onBeforeUnmount } from 'vue';\r\nimport { useAgentInvoke } from '../composables/use-agent-invoke';\r\nimport { useBubble } from '../composables/use-bubble';\r\nimport { useTTS } from '../composables/use-tts';\r\nimport { useVoiceRecognition } from '../composables/use-voice-recognition';\r\nimport { AiChatbotXKey, injectStrict } from '../injection-key';\r\nimport type { VoiceConfig } from '../types';\r\n\r\ninterface XSize {\r\n width: number;\r\n height: number;\r\n}\r\n\r\ninterface BubbleSize {\r\n width?: string;\r\n maxHeight?: string;\r\n}\r\n\r\nconst props = defineProps<{\r\n xLogo?: string;\r\n xTitle?: string;\r\n xSize?: XSize;\r\n xTheme?: 'light' | 'dark' | 'system';\r\n wakeWords?: string[];\r\n wakeResponses?: string[];\r\n modelPath?: string;\r\n agentId?: string;\r\n projectId?: string;\r\n voiceConfig?: VoiceConfig;\r\n bubbleSize?: BubbleSize;\r\n bubbleDismissDelay?: number;\r\n}>();\r\n\r\nconst emit = defineEmits<{\r\n (e: 'wake-up'): void;\r\n}>();\r\n\r\nconst aiChatbotX = injectStrict(AiChatbotXKey);\r\n\r\nconst getVoiceConfig = (): VoiceConfig | null => {\r\n if (props.voiceConfig) return props.voiceConfig;\r\n return null;\r\n};\r\n\r\nconst currentTheme = 'dark' as const;\r\n\r\nconst wakeResponses = computed(() => props.wakeResponses || ['在呢']);\r\nconst agentId = computed(() => props.agentId);\r\n\r\n// ── 1. TTS ──\r\n\r\nconst tts = useTTS(getVoiceConfig);\r\n\r\n// ── 2. Agent 调用(先创建,以获取 isInvoking ref) ──\r\n\r\n// 先声明 bubble 方法引用,后面绑定到真实 bubble 实例\r\nconst bubbleBridge = {\r\n open: () => {},\r\n scheduleDismiss: () => {},\r\n scrollToBottom: () => {},\r\n};\r\n\r\nconst endpoint = `/sime/proxy/organizations/${aiChatbotX.organizationId()}/agents/${agentId.value}/stream-invoke`;\r\n\r\nconst agent = useAgentInvoke({\r\n endpoint,\r\n appToken: aiChatbotX.appToken(),\r\n projectId: props.projectId,\r\n aiChatbotX,\r\n tts: {\r\n speak: tts.speak,\r\n feed: tts.feed,\r\n flush: tts.flush,\r\n stop: tts.stop,\r\n },\r\n bubble: {\r\n open: () => bubbleBridge.open(),\r\n scheduleDismiss: () => bubbleBridge.scheduleDismiss(),\r\n scrollToBottom: () => bubbleBridge.scrollToBottom(),\r\n },\r\n});\r\n\r\n// ── 3. 气泡(用 agent.isInvoking + tts.isSpeaking 保证气泡不会提前消失) ──\r\n\r\nconst bubble = useBubble({\r\n dismissDelay: props.bubbleDismissDelay,\r\n isSpeaking: tts.isSpeaking,\r\n hasPendingAudio: tts.hasPendingAudio,\r\n isInvoking: agent.isInvoking,\r\n bubbleSize: props.bubbleSize,\r\n});\r\n\r\n// 绑定真实 bubble 方法\r\nbubbleBridge.open = bubble.open;\r\nbubbleBridge.scheduleDismiss = bubble.scheduleDismiss;\r\nbubbleBridge.scrollToBottom = bubble.scrollToBottom;\r\n\r\nconst { show: showBubble, style: bubbleStyle, stackRef: bubbleStackRef } = bubble;\r\n\r\n// TTS 播报结束后的气泡消失由 useBubble 内部 watch(isSpeaking) 自动处理,无需额外回调\r\n\r\n// ── 4. 中断回复:唤醒时中断当前播报和调用 ──\r\n\r\nconst interruptCurrentResponse = () => {\r\n agent.abort();\r\n agent.resetState();\r\n tts.stop();\r\n bubble.hide();\r\n};\r\n\r\n// ── 4.5 TTS 纯播报(带气泡,排队机制) ──\r\n\r\nconst speakQueue: string[] = [];\r\nlet isProcessingSpeakQueue = false;\r\n\r\nconst processSpeakQueue = async () => {\r\n if (isProcessingSpeakQueue) return;\r\n isProcessingSpeakQueue = true;\r\n\r\n // 保持 hasPendingAudio 在整个队列处理期间为 true,防止气泡闪烁\r\n tts.hasPendingAudio.value = true;\r\n\r\n while (speakQueue.length > 0) {\r\n const text = speakQueue.shift()!;\r\n bubble.open();\r\n agent.currentTextContent.value = text;\r\n\r\n try {\r\n await tts.speakAndWait(text);\r\n } catch (e) {\r\n console.error('[speakQueue] 播报失败:', e);\r\n }\r\n\r\n // onQueueEmpty 会将 hasPendingAudio 置 false;若队列还有项则立即恢复\r\n if (speakQueue.length > 0) {\r\n tts.hasPendingAudio.value = true;\r\n }\r\n }\r\n\r\n isProcessingSpeakQueue = false;\r\n // 队列全部播完,确保状态干净\r\n tts.hasPendingAudio.value = false;\r\n bubble.scheduleDismiss();\r\n};\r\n\r\nconst speakTextWithBubble = (text: string) => {\r\n speakQueue.push(text);\r\n if (!isProcessingSpeakQueue) {\r\n processSpeakQueue();\r\n }\r\n};\r\n\r\nconst stopSpeak = () => {\r\n speakQueue.length = 0;\r\n isProcessingSpeakQueue = false;\r\n tts.stop();\r\n};\r\n\r\n// ── 5. 语音识别 ──\r\n\r\nconst voice = useVoiceRecognition({\r\n modelPath: props.modelPath,\r\n wakeWords: props.wakeWords,\r\n getVoiceConfig,\r\n onWake: () => {\r\n emit('wake-up');\r\n interruptCurrentResponse();\r\n tts.warmUpAudio();\r\n const text = wakeResponses.value[Math.floor(Math.random() * wakeResponses.value.length)];\r\n tts.speak(text);\r\n },\r\n onTranscriptionDone: (text) => {\r\n agent.invoke(text);\r\n },\r\n});\r\n\r\n// ── 切换语音模式(点击 FAB) ──\r\n\r\nconst toggleVoiceMode = async (targetState?: boolean) => {\r\n tts.warmUpAudio();\r\n await voice.toggleVoiceMode(targetState);\r\n};\r\n\r\n// ── 模板暴露 ──\r\n\r\nconst { voiceStatus, transcriptionText, wakeAnimating, isTranscribing } = voice;\r\nconst { isInvoking, currentTextContent, currentToolParts, executingTools, hasAnyContent, toolDisplayName } = agent;\r\n\r\n// ── 外部方法注册 ──\r\n\r\naiChatbotX?.registerVoiceMethods({\r\n stopBroadcast: async () => interruptCurrentResponse(),\r\n start: () => toggleVoiceMode(true),\r\n stop: () => toggleVoiceMode(false),\r\n});\r\n\r\naiChatbotX?.registerVoiceAssistant({\r\n agentInvoke: agent.invoke,\r\n agentAbort: agent.abort,\r\n speakText: speakTextWithBubble,\r\n stopSpeak: stopSpeak,\r\n});\r\n\r\n// ── 清理 ──\r\n\r\nonBeforeUnmount(async () => {\r\n bubble.destroy();\r\n agent.abort();\r\n tts.destroy();\r\n await voice.destroy();\r\n});\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n.voice-assistant {\r\n --text-primary: #e6edf7;\r\n --text-secondary: #95a8c8;\r\n --glass-bg: rgba(8, 16, 32, 0.72);\r\n --glass-border: rgba(125, 160, 220, 0.28);\r\n --shadow-md: 0 18px 36px rgba(1, 6, 20, 0.56);\r\n --color-success: #4ade80;\r\n --color-error: #f87171;\r\n --color-accent: #818cf8;\r\n\r\n position: relative;\r\n display: inline-flex;\r\n flex-direction: column;\r\n align-items: flex-end;\r\n gap: 12px;\r\n}\r\n\r\n/* ── FAB 按钮 ── */\r\n.assistant-fab {\r\n position: relative;\r\n cursor: pointer;\r\n transition:\r\n transform 0.2s ease,\r\n filter 0.2s ease;\r\n\r\n &:hover {\r\n transform: translateY(-1px) scale(1.03);\r\n filter: brightness(1.06);\r\n }\r\n}\r\n\r\n.status-pill {\r\n position: absolute;\r\n right: calc(100% + 12px);\r\n top: 50%;\r\n transform: translateY(-50%);\r\n max-width: 280px;\r\n background: var(--glass-bg);\r\n color: var(--text-primary);\r\n font-size: 12px;\r\n line-height: 1.45;\r\n padding: 8px 13px;\r\n border-radius: 999px;\r\n border: 1px solid var(--glass-border);\r\n backdrop-filter: blur(10px);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n box-shadow: 0 10px 20px rgba(2, 8, 24, 0.38);\r\n}\r\n\r\n.fab-avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n img {\r\n display: block;\r\n height: auto;\r\n object-fit: contain;\r\n filter: drop-shadow(var(--shadow-md)) saturate(1.05);\r\n }\r\n}\r\n\r\n/* ── 气泡容器 ── */\r\n.bubble-stack {\r\n position: absolute;\r\n right: 0;\r\n bottom: calc(100% + 16px);\r\n width: min(380px, 86vw);\r\n max-height: min(58vh, 520px);\r\n overflow: auto;\r\n\r\n &::-webkit-scrollbar {\r\n width: 4px;\r\n }\r\n\r\n &::-webkit-scrollbar-thumb {\r\n background: rgba(126, 155, 204, 0.3);\r\n border-radius: 999px;\r\n }\r\n}\r\n\r\n/* ── 统一 agent 气泡 ── */\r\n.agent-bubble {\r\n border-radius: 16px;\r\n padding: 12px 14px;\r\n background:\r\n radial-gradient(circle at 12% 10%, rgba(80, 122, 255, 0.14), transparent 50%),\r\n linear-gradient(155deg, rgba(24, 42, 72, 0.96), rgba(14, 24, 46, 0.97));\r\n border: 1px solid rgba(108, 141, 204, 0.2);\r\n box-shadow:\r\n 0 12px 32px rgba(1, 6, 20, 0.5),\r\n inset 0 1px 0 rgba(255, 255, 255, 0.04);\r\n backdrop-filter: blur(16px);\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n animation: bubble-appear 0.3s cubic-bezier(0.16, 1, 0.3, 1);\r\n}\r\n\r\n@keyframes bubble-appear {\r\n from {\r\n opacity: 0;\r\n transform: translateY(8px) scale(0.97);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0) scale(1);\r\n }\r\n}\r\n\r\n/* ── 工具执行步骤(内联紧凑) ── */\r\n.tool-steps {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n margin-bottom: 6px;\r\n padding-bottom: 8px;\r\n border-bottom: 1px solid rgba(125, 160, 220, 0.1);\r\n}\r\n\r\n.tool-step {\r\n display: flex;\r\n align-items: center;\r\n gap: 7px;\r\n padding: 4px 6px;\r\n border-radius: 8px;\r\n transition: background 0.2s ease;\r\n animation: step-in 0.25s cubic-bezier(0.16, 1, 0.3, 1);\r\n\r\n &--loading {\r\n .tool-step__icon {\r\n color: var(--color-accent);\r\n }\r\n .tool-step__name {\r\n color: rgba(200, 215, 240, 0.85);\r\n }\r\n }\r\n\r\n &--done {\r\n .tool-step__icon {\r\n color: var(--color-success);\r\n }\r\n .tool-step__name {\r\n color: rgba(200, 215, 240, 0.55);\r\n }\r\n }\r\n\r\n &--error {\r\n .tool-step__icon {\r\n color: var(--color-error);\r\n }\r\n .tool-step__name {\r\n color: rgba(248, 113, 113, 0.8);\r\n }\r\n }\r\n\r\n &--executing {\r\n background: rgba(129, 140, 248, 0.06);\r\n .tool-step__icon {\r\n color: var(--color-accent);\r\n }\r\n }\r\n}\r\n\r\n@keyframes step-in {\r\n from {\r\n opacity: 0;\r\n transform: translateX(-6px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateX(0);\r\n }\r\n}\r\n\r\n.tool-step__icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 18px;\r\n height: 18px;\r\n flex-shrink: 0;\r\n}\r\n\r\n.tool-step__spinner {\r\n animation: tool-spin 0.8s linear infinite;\r\n}\r\n\r\n@keyframes tool-spin {\r\n from {\r\n transform: rotate(0deg);\r\n }\r\n to {\r\n transform: rotate(360deg);\r\n }\r\n}\r\n\r\n.tool-step__name {\r\n font-size: 12px;\r\n font-weight: 500;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n transition: color 0.2s ease;\r\n}\r\n\r\n.tool-step__tag {\r\n font-size: 10px;\r\n font-weight: 500;\r\n padding: 1px 6px;\r\n border-radius: 4px;\r\n white-space: nowrap;\r\n flex-shrink: 0;\r\n\r\n &--exec {\r\n background: rgba(129, 140, 248, 0.12);\r\n color: var(--color-accent);\r\n }\r\n}\r\n\r\n/* ── 思考中动画 ── */\r\n.thinking-dots {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 5px;\r\n padding: 2px 0;\r\n\r\n span {\r\n width: 5px;\r\n height: 5px;\r\n border-radius: 50%;\r\n background: var(--text-secondary);\r\n animation: thinking-bounce 1s infinite ease-in-out;\r\n }\r\n\r\n span:nth-child(2) {\r\n animation-delay: 0.15s;\r\n }\r\n\r\n span:nth-child(3) {\r\n animation-delay: 0.3s;\r\n }\r\n}\r\n\r\n@keyframes thinking-bounce {\r\n 0%,\r\n 100% {\r\n transform: translateY(0);\r\n opacity: 0.3;\r\n }\r\n 50% {\r\n transform: translateY(-3px);\r\n opacity: 1;\r\n }\r\n}\r\n\r\n/* ── 文本内容 ── */\r\n.agent-text {\r\n font-size: 14px;\r\n line-height: 1.55;\r\n color: var(--text-primary);\r\n white-space: pre-wrap;\r\n word-break: break-word;\r\n}\r\n\r\n/* ── 气泡淡入淡出过渡 ── */\r\n.bubble-fade-enter-active {\r\n transition: all 0.35s cubic-bezier(0.16, 1, 0.3, 1);\r\n}\r\n\r\n.bubble-fade-leave-active {\r\n transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n}\r\n\r\n.bubble-fade-enter-from {\r\n opacity: 0;\r\n transform: translateY(12px) scale(0.95);\r\n}\r\n\r\n.bubble-fade-leave-to {\r\n opacity: 0;\r\n transform: translateY(8px) scale(0.97);\r\n}\r\n\r\n/* ── 监听状态指示器 ── */\r\n.listening-badge {\r\n position: absolute;\r\n top: -8px;\r\n right: -8px;\r\n width: 32px;\r\n height: 32px;\r\n border-radius: 50%;\r\n background-color: rgba(0, 0, 0, 0.72);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.listening-waves {\r\n position: absolute;\r\n inset: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n}\r\n\r\n.wave {\r\n position: absolute;\r\n width: 100%;\r\n height: 100%;\r\n border-radius: 50%;\r\n border: 2px solid rgba(255, 255, 255, 0.65);\r\n animation: wave-expand 3s ease-out infinite;\r\n}\r\n\r\n.wave-1 {\r\n animation-delay: 0s;\r\n}\r\n\r\n.wave-2 {\r\n animation-delay: 0.6s;\r\n}\r\n\r\n.wave-3 {\r\n animation-delay: 1.2s;\r\n}\r\n\r\n.listening-icon {\r\n position: relative;\r\n color: #fff;\r\n}\r\n\r\n.listening-badge.wake-active {\r\n background-color: rgba(34, 197, 94, 0.9);\r\n animation: wake-badge-pop 0.35s ease;\r\n}\r\n\r\n.indicator-fade-enter-active,\r\n.indicator-fade-leave-active {\r\n transition: all 0.2s ease;\r\n}\r\n\r\n.indicator-fade-enter-from,\r\n.indicator-fade-leave-to {\r\n opacity: 0;\r\n transform: translateY(6px);\r\n}\r\n\r\n@media (max-width: 768px) {\r\n .bubble-stack {\r\n width: min(320px, 88vw);\r\n max-height: min(54vh, 420px);\r\n }\r\n\r\n .status-pill {\r\n max-width: 220px;\r\n }\r\n}\r\n\r\n@keyframes wave-expand {\r\n 0% {\r\n transform: scale(0.8);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: scale(1.2);\r\n opacity: 0;\r\n }\r\n}\r\n\r\n@keyframes wake-badge-pop {\r\n 0% {\r\n transform: scale(1);\r\n }\r\n 50% {\r\n transform: scale(1.35);\r\n }\r\n 100% {\r\n transform: scale(1);\r\n }\r\n}\r\n</style>\r\n","import type { CommandDefinition, DiscoveredCommand } from './utils/command-types';\r\n\r\nexport enum clientCommandKey {\r\n SET_THEME = 'SiMeAgent_setTheme',\r\n APPEND_MESSAGE = 'SiMeAgent_appendMessage',\r\n WAKE = 'SiMeAgent_wake',\r\n TRANSITION = 'SiMeAgent_transition',\r\n TRANSITION_END = 'SiMeAgent_transition_end',\r\n START_NEW_CONVERSATION = 'SiMeAgent_startNewConversation',\r\n RECOGNITION = 'SiMeAgent_recognition',\r\n}\r\n\r\nexport interface VoiceConfig {\r\n appId: string;\r\n /** STT(语音转写)apiKey */\r\n apiKey: string;\r\n /** apiSecret,TTS 鉴权必需 */\r\n apiSecret?: string;\r\n /** STT(语音转写)WebSocket 地址 */\r\n websocketUrl: string;\r\n /** TTS apiKey(可选,不填则复用 apiKey) */\r\n ttsApiKey?: string;\r\n /** TTS(语音合成)WebSocket 地址 */\r\n ttsWebsocketUrl?: string;\r\n /** TTS 发音人,默认 xiaoyan */\r\n ttsVcn?: string;\r\n /** TTS 发音速度 */\r\n speed?: number;\r\n /** TTS 发音音量 */\r\n volume?: number;\r\n /** TTS 发音音调 */\r\n pitch?: number;\r\n}\r\n\r\nexport interface AiChatbotXContext {\r\n appToken: () => string;\r\n organizationId: () => string;\r\n registerCommand: (cmd: CommandDefinition) => void;\r\n unregisterCommand: (name: string) => void;\r\n getCommads: () => Promise<DiscoveredCommand[]>;\r\n /** 中止当前语音播报并关闭气泡 */\r\n stopBroadcast: () => Promise<void>;\r\n startListening: () => Promise<void>;\r\n stopListening: () => Promise<void>;\r\n registerVoiceMethods: (methods: {\r\n stopBroadcast?: () => Promise<void>;\r\n start: () => Promise<void>;\r\n stop: () => Promise<void>;\r\n }) => void;\r\n registerVoiceAssistant: (methods: {\r\n agentInvoke: (text: string) => Promise<void>;\r\n agentAbort: () => void;\r\n speakText: (text: string) => void;\r\n stopSpeak: () => void;\r\n }) => void;\r\n executeCommand: (commandName: string, args?: any[]) => Promise<any>;\r\n sendMessage: (text: string) => Promise<void>;\r\n speakText: (text: string) => void;\r\n stopSpeak: () => void;\r\n abortInvoke: () => void;\r\n}\r\n"],"names":["DefaultChatTransport","Chat","ref","reactive","computed","nextTick","watch","onMounted","_createElementBlock","_normalizeClass","_openBlock","_hoisted_1","_createElementVNode","_hoisted_2","_hoisted_3","_toDisplayString","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_8","_Fragment","_renderList","_hoisted_9","_hoisted_10","_unref","_hoisted_11","_hoisted_13","_hoisted_15","_createVNode","_Transition","inject","currentTheme","onBeforeUnmount","_hoisted_7","shallowRef","provide","_renderSlot","SpeechSynthesizerStandalone","SpeechTranscriberStandalone","WakeWordDetectorStandalone","_normalizeStyle","clientCommandKey"],"mappings":"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"}
|