@blueking/chat-x 0.0.46-beta.2 → 0.0.46-beta.4

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.
@@ -45,6 +45,10 @@ export declare const lang: {
45
45
  readonly 待执行: "To Be Executed";
46
46
  readonly 详情: "Details";
47
47
  readonly 重试: "Retry";
48
+ readonly 重试中: "Retrying";
49
+ readonly 跳过中: "Skipping";
50
+ readonly '\u4EFB\u52A1\u6B63\u5728\u91CD\u8BD5\u4E2D\uFF0C\u4E0D\u53EF\u8DF3\u8FC7': "The task is retrying and cannot be skipped";
51
+ readonly '\u4EFB\u52A1\u6B63\u5728\u8DF3\u8FC7\u4E2D\uFF0C\u4E0D\u53EF\u91CD\u8BD5': "The task is skipping and cannot be retried";
48
52
  readonly 节点: "Node";
49
53
  readonly 节点配置: "Node Config";
50
54
  readonly 节点输出: "Node Output";
@@ -71,6 +75,7 @@ export declare const lang: {
71
75
  readonly 更多: "More";
72
76
  readonly 算法方案评审单: "Algorithm Plan Review Ticket";
73
77
  readonly 评审中: "Reviewing";
78
+ readonly 审批中: "Approving";
74
79
  readonly 已废弃: "Abandoned";
75
80
  readonly 已批准: "Approved";
76
81
  readonly 已通过: "Approved";
@@ -133,4 +138,4 @@ export declare const lang: {
133
138
  readonly 已回复: "Replied";
134
139
  readonly '\u8BF7\u8F93\u5165...': "Please enter...";
135
140
  };
136
- export declare const t: (key: keyof typeof lang) => "Send" | "Stop" | "Ask AI" | "Copy" | "Share" | "Like" | "Unsatisfied" | "Delete" | "Quote" | "Regenerate" | "Regenerating will clear the content below" | "Submit" | "Cancel" | "Preview Content" | "Jump to Detail" | "Call Tool:" | "Calling..." | "Call Success" | "Call Failed" | "Tell us your thoughts" | "What makes you satisfied?" | "What makes you dissatisfied?" | "Return Content" | "Edit" | "Deep Thinking" | "Loading image..." | "Failed to load image" | "Thinking..." | "Thinking Completed" | "Thinking Failed" | "Copy Success" | "Copy Failed" | "Return to bottom" | "Stop generating" | "Stopping" | "Duration" | "Parameters" | "Description" | "Execution Status" | "Running" | "Success" | "Failed" | "Pending" | "To Be Executed" | "Details" | "Retry" | "Node" | "Node Config" | "Node Output" | "Basic Info" | "Flow Template" | "Node Name" | "Step Name" | "Execution Plan" | "Optional" | "Failure Handler" | "Timeout Control" | "Yes" | "No" | "Input Params" | "Output Params" | "Param Name" | "Param Value" | "Name" | "Structured Output" | "Manual Skip" | "No Data" | "Call MCP:" | "More" | "Algorithm Plan Review Ticket" | "Reviewing" | "Abandoned" | "Approved" | "Cancelled" | "Expired" | "Rejected" | "Revoked" | "Ticket No." | "Submitted At" | "Current Handler" | "None" | "View Ticket Detail" | "Copy Ticket" | "Copy Ticket Link" | "Cancel Approval" | "There are {count} pending approval tickets in the current conversation. To continue, cancel approval first." | "Unsupported interrupt message" | "Searching" | "Search Completed" | "Upload File" | "Requesting..." | "Cancel satisfied" | "Cancel dissatisfied" | "Confirm delete this answer?" | "This operation cannot be undone. Please proceed with caution!" | "Preview" | "Zoom Out" | "Zoom In" | "Rotate" | "Download" | "Sorry, image loading failed. Please try reloading." | "Reset" | "Reload" | "W" | "H" | "Upload Image" | "Search keyword" | "Select date" | "Locate in Chat" | "Select All" | "Confirm" | "Upload Image, up to 3 images supported, max 2.4MB each" | "Hello, I am BlueKing AI Bot" | "Clear Search" | "Search Result is Empty" | "Valid Evidence" | "Full Screen" | "Exit Full Screen" | "Please choose to continue" | "Continue" | "Received: " | "Done" | "Skip" | "Single" | "Multiple" | "Others" | "Answers" | "Replied" | "Please enter..." | "发送" | "停止" | "问问小鲸" | "复制" | "分享" | "点赞" | "不满意" | "删除" | "引用" | "重新生成" | "重新生成将清空下文内容" | "提交" | "取消" | "预览内容" | "跳转详情" | "调用工具:" | "调用中" | "调用成功" | "调用失败" | "说出您的想法" | "什么原因让你满意?" | "什么原因让你不满意?" | "返回内容" | "编辑" | "深度思考" | "图片加载中..." | "图片加载失败" | "思考中" | "已思考完成" | "思考失败" | "复制成功" | "复制失败" | "返回底部" | "停止生成" | "正在停止" | "耗时" | "参数" | "描述" | "执行情况" | "执行中" | "成功" | "失败" | "挂起" | "待执行" | "详情" | "重试" | "节点" | "节点配置" | "节点输出" | "基础信息" | "流程模板" | "节点名称" | "步骤名称" | "执行方案" | "是否可选" | "失败处理" | "超时控制" | "是" | "否" | "输入参数" | "输出参数" | "参数名" | "参数值" | "名称" | "变量说明" | "结构化输出" | "手动跳过" | "暂无数据" | "调用 MCP:" | "更多" | "算法方案评审单" | "评审中" | "已废弃" | "已批准" | "已通过" | "已取消" | "已过期" | "已拒绝" | "已撤销" | "单据编号" | "提交时间" | "当前处理人" | "无" | "查看单据详情" | "复制单据" | "复制单据链接" | "取消审批" | "当前会话有 {count} 个待审批单,如需继续,请先取消审批" | "暂不支持的中断消息" | "检索中" | "检索完成" | "上传文件" | "请求中..." | "取消满意" | "取消不满意" | "确认删除该回答?" | "删除操作无法撤回,请谨慎操作!" | "预览" | "缩小" | "放大" | "旋转" | "下载" | "抱歉,图片加载失败,可尝试重新加载" | "重置" | "重新加载" | "宽" | "高" | "上传图片" | "搜索 关键字" | "选择日期" | "在对话中定位" | "全选" | "确定" | "上传图片, 最多支持上传 3 个, 最大支持 2.4MB" | "你好,我是小鲸" | "清空搜索" | "搜索结果为空" | "有效证据" | "全屏" | "退出全屏" | "请选择以继续" | "继续" | "收到信息:" | "待审批" | "已审批" | "完成" | "跳过" | "单选" | "多选" | "其他" | "回答内容" | "已回复" | "请输入...";
141
+ export declare const t: (key: keyof typeof lang) => "Send" | "Stop" | "Ask AI" | "Copy" | "Share" | "Like" | "Unsatisfied" | "Delete" | "Quote" | "Regenerate" | "Regenerating will clear the content below" | "Submit" | "Cancel" | "Preview Content" | "Jump to Detail" | "Call Tool:" | "Calling..." | "Call Success" | "Call Failed" | "Tell us your thoughts" | "What makes you satisfied?" | "What makes you dissatisfied?" | "Return Content" | "Edit" | "Deep Thinking" | "Loading image..." | "Failed to load image" | "Thinking..." | "Thinking Completed" | "Thinking Failed" | "Copy Success" | "Copy Failed" | "Return to bottom" | "Stop generating" | "Stopping" | "Duration" | "Parameters" | "Description" | "Execution Status" | "Running" | "Success" | "Failed" | "Pending" | "To Be Executed" | "Details" | "Retry" | "Retrying" | "Skipping" | "The task is retrying and cannot be skipped" | "The task is skipping and cannot be retried" | "Node" | "Node Config" | "Node Output" | "Basic Info" | "Flow Template" | "Node Name" | "Step Name" | "Execution Plan" | "Optional" | "Failure Handler" | "Timeout Control" | "Yes" | "No" | "Input Params" | "Output Params" | "Param Name" | "Param Value" | "Name" | "Structured Output" | "Manual Skip" | "No Data" | "Call MCP:" | "More" | "Algorithm Plan Review Ticket" | "Reviewing" | "Approving" | "Abandoned" | "Approved" | "Cancelled" | "Expired" | "Rejected" | "Revoked" | "Ticket No." | "Submitted At" | "Current Handler" | "None" | "View Ticket Detail" | "Copy Ticket" | "Copy Ticket Link" | "Cancel Approval" | "There are {count} pending approval tickets in the current conversation. To continue, cancel approval first." | "Unsupported interrupt message" | "Searching" | "Search Completed" | "Upload File" | "Requesting..." | "Cancel satisfied" | "Cancel dissatisfied" | "Confirm delete this answer?" | "This operation cannot be undone. Please proceed with caution!" | "Preview" | "Zoom Out" | "Zoom In" | "Rotate" | "Download" | "Sorry, image loading failed. Please try reloading." | "Reset" | "Reload" | "W" | "H" | "Upload Image" | "Search keyword" | "Select date" | "Locate in Chat" | "Select All" | "Confirm" | "Upload Image, up to 3 images supported, max 2.4MB each" | "Hello, I am BlueKing AI Bot" | "Clear Search" | "Search Result is Empty" | "Valid Evidence" | "Full Screen" | "Exit Full Screen" | "Please choose to continue" | "Continue" | "Received: " | "Done" | "Skip" | "Single" | "Multiple" | "Others" | "Answers" | "Replied" | "Please enter..." | "发送" | "停止" | "问问小鲸" | "复制" | "分享" | "点赞" | "不满意" | "删除" | "引用" | "重新生成" | "重新生成将清空下文内容" | "提交" | "取消" | "预览内容" | "跳转详情" | "调用工具:" | "调用中" | "调用成功" | "调用失败" | "说出您的想法" | "什么原因让你满意?" | "什么原因让你不满意?" | "返回内容" | "编辑" | "深度思考" | "图片加载中..." | "图片加载失败" | "思考中" | "已思考完成" | "思考失败" | "复制成功" | "复制失败" | "返回底部" | "停止生成" | "正在停止" | "耗时" | "参数" | "描述" | "执行情况" | "执行中" | "成功" | "失败" | "挂起" | "待执行" | "详情" | "重试" | "重试中" | "跳过中" | "任务正在重试中,不可跳过" | "任务正在跳过中,不可重试" | "节点" | "节点配置" | "节点输出" | "基础信息" | "流程模板" | "节点名称" | "步骤名称" | "执行方案" | "是否可选" | "失败处理" | "超时控制" | "是" | "否" | "输入参数" | "输出参数" | "参数名" | "参数值" | "名称" | "变量说明" | "结构化输出" | "手动跳过" | "暂无数据" | "调用 MCP:" | "更多" | "算法方案评审单" | "评审中" | "审批中" | "已废弃" | "已批准" | "已通过" | "已取消" | "已过期" | "已拒绝" | "已撤销" | "单据编号" | "提交时间" | "当前处理人" | "无" | "查看单据详情" | "复制单据" | "复制单据链接" | "取消审批" | "当前会话有 {count} 个待审批单,如需继续,请先取消审批" | "暂不支持的中断消息" | "检索中" | "检索完成" | "上传文件" | "请求中..." | "取消满意" | "取消不满意" | "确认删除该回答?" | "删除操作无法撤回,请谨慎操作!" | "预览" | "缩小" | "放大" | "旋转" | "下载" | "抱歉,图片加载失败,可尝试重新加载" | "重置" | "重新加载" | "宽" | "高" | "上传图片" | "搜索 关键字" | "选择日期" | "在对话中定位" | "全选" | "确定" | "上传图片, 最多支持上传 3 个, 最大支持 2.4MB" | "你好,我是小鲸" | "清空搜索" | "搜索结果为空" | "有效证据" | "全屏" | "退出全屏" | "请选择以继续" | "继续" | "收到信息:" | "待审批" | "已审批" | "完成" | "跳过" | "单选" | "多选" | "其他" | "回答内容" | "已回复" | "请输入...";
@@ -313,7 +313,7 @@ const messages = [
313
313
  | 场景 | `tab.name` 格式 |
314
314
  | ---------- | ---------------------------------------- |
315
315
  | 任务详情 | `{task_id}` |
316
- | 有效证据 | `{task_id}`(与任务 Tab 同名,label 为「有效证据」) |
316
+ | 有效证据 | `{task_id}`(与任务 Tab 同名,label 为「有效证据」,`order: 10` 固定排在「执行情况」之后、节点详情之前) |
317
317
  | 节点详情 | `{task_id}\|{node.id}\|{node.name}` |
318
318
 
319
319
  `CustomBkFlowTabData` 支持 `has_confidence?: boolean`,用于侧栏详情组件区分证据视图与节点视图。应用层可通过 `ChatContainer` 的 `getSideRenderComponent` 覆盖渲染组件。
@@ -35,7 +35,7 @@
35
35
  - **侧栏全屏**:Tab 栏右侧提供全屏/退出全屏按钮,基于 `useFullScreen` 将侧栏区域(`.ai-full-screen-wrapper`)以浏览器原生全屏展示;全屏时 Tippy 的 `appendTo` 自动切换为全屏容器,避免 tooltip 被遮挡
36
36
  - **自定义 Tab**:通过 `useCustomTabProvider` 支持动态添加自定义 Tab(如节点详情)
37
37
  - **分享模式**:内置消息多选分享流程,选中用户消息后确认分享
38
- - **渲染模式注入**:`renderMode` 会通过内部 Provider 下传给后代内容组件;例如 FlowAgent 节点在 `Share` 模式下隐藏耗时和「详情」入口
38
+ - **渲染模式注入**:`renderMode` 会通过内部 Provider 下传给后代内容组件;`Share` 分享态开放流程智能体只读查看(侧栏 Tab / 执行情况 / 节点「详情」「有效证据」/ 耗时均保留),仅隐藏底部输入区与「重试 / 跳过」等交互操作
39
39
  - **字号主题**:通过 `size` 控制 `small`(默认 12px)/ `normal`(14px)两档字号;根节点设置 `data-ai-size`,子组件通过 CSS 变量(`--ai-font-size` 等)响应式缩放;浮层(Tippy / Teleport)会同步 `document.body.dataset.aiSize`,卸载时自动清理
40
40
  - **空状态欢迎页**:无消息时展示欢迎语和开场白
41
41
 
@@ -142,7 +142,7 @@ ai-chat-container(:data-ai-size="size")
142
142
 
143
143
  侧边栏默认包含「执行情况」Tab,展示所有工具调用和 FlowAgent 类型的 Activity 消息。支持关键词搜索过滤和点击定位到对话中的消息位置。
144
144
 
145
- **展示条件**:当 `executionGroups` 为空且 `keyword` 为空时,不渲染侧栏 Tab 与 `ExecutionSummary`(折叠按钮亦隐藏);主区域仍可正常展示 `messages` 中的对话内容。用户在执行情况中输入搜索词后,侧栏会保持展示以显示「搜索结果为空」等状态。`renderMode === Share` 时侧栏隐藏,且分栏会应用与折叠一致的样式。
145
+ **展示条件**:当 `executionGroups` 为空且 `keyword` 为空时,不渲染侧栏 Tab 与 `ExecutionSummary`(折叠按钮亦隐藏);主区域仍可正常展示 `messages` 中的对话内容。用户在执行情况中输入搜索词后,侧栏会保持展示以显示「搜索结果为空」等状态。`renderMode === Share` 分享态同样按上述执行数据条件展示侧栏(开放只读查看流程智能体详情/证据/执行情况),不再强制隐藏折叠;仅底部输入区保持隐藏。
146
146
 
147
147
  **自定义 Tab 联动**:当 `executionGroups` 变为空且搜索词已清空时,容器会**自动重置自定义 Tab**(`resetCustomTab`),避免残留节点详情等 Tab;若用户仍在搜索(`keyword` 非空),不会触发重置。
148
148
 
@@ -194,6 +194,20 @@ ai-chat-container(:data-ai-size="size")
194
194
 
195
195
  通过 `ref` 获取组件实例后,使用 `addCustomTab` / `removeCustomTab` 动态管理侧边栏 Tab。若 **`executionGroups` 变为空且搜索词已清空**,容器会清空自定义 Tab 状态(与侧栏执行数据联动,见上文「侧边栏与执行摘要」)。
196
196
 
197
+ ### Tab 排序与显隐
198
+
199
+ `CustomTab` 支持 `order` / `visible` / `closable` 三个可选字段,用于控制 Tab 栏的排序与显隐:
200
+
201
+ | 字段 | 默认值 | 说明 |
202
+ | ---- | ------ | ---- |
203
+ | `order` | `100` | 排序权重,升序,越小越靠前。「执行情况」固定 `0`;FlowAgent「有效证据」固定 `10`(紧随执行情况),节点详情走默认 `100` |
204
+ | `visible` | `true` | 是否在 Tab 栏展示。`false` 时从栏内隐藏,但仍可被 `addCustomTab` / `selectCustomTab` 程序化选中;若被隐藏的 Tab 当前正被选中,则自动切到首个可见 Tab、内容不再渲染 |
205
+ | `closable` | `true` | 是否展示关闭按钮。「执行情况」强制不可关闭 |
206
+
207
+ - 排序为稳定排序,`order` 相同的 Tab 保持插入先后顺序。
208
+ - 「执行情况」Tab 的显隐统一由 `executionTabVisible` Prop 控制(见 Props 表),不通过 `visible` 字段配置。
209
+ - 同名(同 `name`)`addCustomTab` 会**合并更新**已有 Tab,可用于运行时调整 `order` / `visible` / `label`。
210
+
197
211
  ### 侧栏渲染扩展
198
212
 
199
213
  应用层可通过以下 Props 覆盖默认 Tab 标签与侧栏内容区的渲染逻辑(例如 FlowAgent 节点详情使用业务自定义组件):
@@ -533,6 +547,7 @@ ChatContainer 的 Props 继承自 `ChatInputProps` 和 `MessageContainerProps`
533
547
  | ------------------ | ---------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
534
548
  | chatLoading | `boolean` | — | 整体加载状态,`true` 时显示 Loading 遮罩 |
535
549
  | commonTippyOptions | `AITippyProps` | — | 通用 Tippy 配置(`appendTo` / `placement` / `zIndex`),传入的选项会注入到所有使用 `v-overflow-tips` 的子组件中 |
550
+ | executionTabVisible | `boolean` | `true` | 「执行情况」Tab 是否展示;为 `false` 时从 Tab 栏隐藏,若其正被选中则自动切到首个可见 Tab,内容不再渲染 |
536
551
  | getSideRenderComponent | `(h, props?) => VNode \| undefined` | — | 自定义侧栏内容区渲染;未返回时使用 `selectedTab.data.component` |
537
552
  | getSideTabRenderComponent | `(h, tab, { removeCustomTab }) => VNode \| undefined` | — | 自定义侧栏 Tab 标签渲染;未返回时使用默认图标 + 文案 + 关闭按钮 |
538
553
  | openingRemark | `string` | — | 开场白,无消息时显示,支持 Markdown |
@@ -550,7 +565,7 @@ ChatContainer 的 Props 继承自 `ChatInputProps` 和 `MessageContainerProps`
550
565
  | modelValue | `string \| TagSchema` | 输入框内容,支持纯文本或标签结构 |
551
566
  | selectedShortcut | `Shortcut \| null` | 当前选中的快捷指令 |
552
567
  | cite | `string` | 引用内容 |
553
- | renderMode | `RenderMode` | 渲染模式(默认 `Chat`)。`Share` 模式隐藏侧边栏和折叠按钮;`Test` 模式隐藏分享按钮 |
568
+ | renderMode | `RenderMode` | 渲染模式(默认 `Chat`)。`Share` 分享态开放侧栏只读查看(流程智能体详情/证据/执行情况),隐藏底部输入区与「重试/跳过」等交互;`Test` 模式隐藏分享按钮 |
554
569
 
555
570
  ### Events
556
571
 
@@ -593,7 +608,7 @@ ChatContainer 的 Props 继承自 `ChatInputProps` 和 `MessageContainerProps`
593
608
  | `renderMode` | 侧边栏 Tab / 折叠按钮 | 底部输入区域 | MessageTools 工具栏 | 说明 |
594
609
  | ------------ | ---------------------- | --------------------------------- | --------------------- | -------------------------------- |
595
610
  | `Chat` | 正常显示 | 正常显示(ChatInput / ShortcutRender / SelectionFooter) | 全部工具按钮 | 默认对话模式 |
596
- | `Share` | **隐藏** | **隐藏** | **隐藏**(多选模式) | 分享预览模式,仅展示消息;FlowAgent 节点会隐藏耗时和「详情」入口 |
611
+ | `Share` | **按执行数据展示**(开放只读查看) | **隐藏** | **隐藏**(多选模式) | 分享预览模式;开放流程智能体侧栏详情/证据/执行情况与耗时,仅隐藏「重试/跳过」等交互 |
597
612
  | `Test` | 正常显示 | 正常显示 | 过滤掉「分享」按钮 | 测试/嵌入模式,隐藏分享入口 |
598
613
 
599
614
  ```vue
@@ -30,8 +30,9 @@
30
30
  - **两级折叠**:任务整体由 `ActivityLayout` 折叠;每个任务节点列表可单独展开/收起
31
31
  - **耗时格式化**:节点耗时与任务总耗时按 `d/h/m/s` 紧凑展示,小于 1 秒显示 `<1s`
32
32
  - **节点行尾操作**:hover 失败节点行显示「重试 / 跳过 / 详情」按钮组(间距 12px);成功 / 运行中等非失败节点仅显示「详情」。重试 / 跳过依赖节点 `retryable` / `skippable` 能力位,通过 `onInterruptResume` 回传 Agent
33
+ - **重试 / 跳过进行中态**:点击后节点行进入 `is-pending`,按钮组常驻显示(无需 hover);进行中按钮切换为 loading +「重试中 / 跳过中」,重试与跳过互斥禁用;被阻塞按钮 hover 显示提示(如「任务正在重试中,不可跳过」);详情不受影响。pending 以 `task_id:node_id:retry` 为键,后端 `retry` 计数变化后自动失效
33
34
  - **详情入口联动**:「详情」按钮点击后通过自定义 Tab 挂载 `FlowAgentNodeDetail`
34
- - **分享态降级**:`RenderMode.Share` 下隐藏耗时与行尾操作按钮,仅保留只读的执行状态
35
+ - **分享态只读查看**:`RenderMode.Share` 下保留耗时、「详情」「有效证据」等只读查看入口,仅隐藏「重试 / 跳过」等交互式 resume 操作
35
36
 
36
37
  ## 状态映射
37
38
 
@@ -93,7 +94,20 @@
93
94
 
94
95
  ## 失败节点重试 / 跳过
95
96
 
96
- 失败节点(`convergedState === 'failed'`)且具备对应能力位时,hover 行尾展示「重试」或「跳过」按钮。点击后调用 `onInterruptResume`,**不传** `interrupt` 参数:
97
+ 失败节点(`convergedState === 'failed'`)且具备对应能力位时,hover 行尾展示「重试」或「跳过」按钮。点击后:
98
+
99
+ 1. 节点行添加 `is-pending` class,按钮组常驻显示(设计稿:鼠标移出后仍可见进行中反馈)
100
+ 2. 被点击按钮进入 loading +「重试中 / 跳过中」,重试与跳过均禁用(`is-disabled`,置灰色 `#c4c6cc`)
101
+ 3. 另一按钮 hover 显示阻塞提示(`v-tippy`)
102
+ 4. 调用 `onInterruptResume`,**不传** `interrupt` 参数;进行中重复点击被 `handleActionClick` 拦截
103
+
104
+ ```typescript
105
+ // 组件层点击分发(禁用态不执行 run)
106
+ const handleActionClick = (action: FlowNodeActionVM) => {
107
+ if (action.disabled) return;
108
+ action.run();
109
+ };
110
+ ```
97
111
 
98
112
  ```typescript
99
113
  // 重试
@@ -109,11 +123,11 @@ onInterruptResume?.({
109
123
  });
110
124
  ```
111
125
 
112
- | 按钮 | 显隐条件 | `operation` |
113
- | ---- | ------------------------------------- | ---------------------- |
114
- | 重试 | 失败态且 `node.retryable === true` | `flow_node_retry` |
115
- | 跳过 | 失败态且 `node.skippable === true` | `flow_node_skip` |
116
- | 详情 | 始终展示(Share 模式除外) | —(打开侧栏 Tab,不走 resume) |
126
+ | 按钮 | 显隐条件 | 进行中表现 | `operation` |
127
+ | ---- | ------------------------------------- | ---------------------------------- | ---------------------- |
128
+ | 重试 | 失败态且 `node.retryable === true` | loading +「重试中」,二者均禁用 | `flow_node_retry` |
129
+ | 跳过 | 失败态且 `node.skippable === true` | loading +「跳过中」,二者均禁用 | `flow_node_skip` |
130
+ | 详情 | 始终展示(含 Share 分享态) | 不受 pending 影响 | —(打开侧栏 Tab,不走 resume) |
117
131
 
118
132
  行尾操作由内部 composable [`useFlowNodeActions`](/composables/use-flow-node-actions) 聚合为声明式列表,组件层仅遍历渲染。
119
133
 
@@ -156,15 +170,15 @@ ActivityLayout(activity-type=flow_agent,v-model:collapsed)
156
170
  │ ├── task-name(HighlightKeyword + 溢出提示)
157
171
  │ └── task-time(任务总耗时 = 各节点耗时累加)
158
172
  └── flow-agent-task-nodes(v-show 折叠)
159
- └── flow-agent-node-item × N(节点)
173
+ └── flow-agent-node-item × N(节点;`is-pending` 时按钮组常驻)
160
174
  ├── node-status(Loading / 状态圆点)
161
175
  ├── node-name(HighlightKeyword + 溢出提示)
162
- └── node-trailing(非 Share 态)
163
- ├── node-time(节点耗时,hover 时隐藏)
164
- └── node-actions(hover 时显示按钮组,间距 12px)
165
- ├── node-action-btn「重试」(失败 + retryable
166
- ├── node-action-btn「跳过」(失败 + skippable
167
- └── node-action-btn「详情」(始终,点击挂载详情 Tab)
176
+ └── node-trailing(含 Share 分享态)
177
+ ├── node-time(节点耗时,hover / pending 时隐藏)
178
+ └── node-actions(hover `is-pending` 时显示,间距 12px)
179
+ ├── node-action-btn「重试」(失败 + retryable;Share 态隐藏;进行中 loading + 禁用)
180
+ ├── node-action-btn「跳过」(失败 + skippable;Share 态隐藏;进行中 loading + 禁用)
181
+ └── node-action-btn「详情」(始终可用,含 Share 态,点击挂载详情 Tab)
168
182
  ```
169
183
 
170
184
  ## API
@@ -239,8 +253,9 @@ interface BkFlowNode {
239
253
  3. **任务总耗时为节点累加**:`task-time` 由各节点 `elapsed_time` 求和得到,并非任务级独立字段。
240
254
  4. **`task_outputs` 暂不渲染**:模板中任务输出展示区块已注释,传入也不会显示。
241
255
  5. **未知状态兜底为 `running`**:`getConvergedState` 对未识别的原始状态统一归为运行中。
242
- 6. **Share 模式降级**:`RenderMode.Share` 下不渲染节点耗时与行尾操作按钮(重试 / 跳过 / 详情),仅保留只读执行状态。
256
+ 6. **Share 模式只读查看**:`RenderMode.Share` 下保留节点/任务耗时与「详情」「有效证据」查看入口,仅过滤「重试 / 跳过」等交互式 resume 操作(由 `useFlowNodeActions` 的 `hideResumeActions` 收敛)。
243
257
  7. **`onInterruptResume` 透传链路**:`MessageRender` → `ActivityMessage` → `FlowAgentContent`;未传入时重试 / 跳过按钮仍展示但点击无回调。
258
+ 8. **pending 自动收敛**:`useFlowNodeActions` 以 `task_id:node_id:retry` 为 pending 键;节点重试再次失败(`retry` +1)后键变化,进行中态自动解除,无需手动清理。
244
259
 
245
260
  ## 关联组件
246
261
 
@@ -26,9 +26,9 @@ AI Dev 第三方工具审批(`InterruptReason.AIDevToolApproval`)专用卡
26
26
 
27
27
  ```
28
28
  ToolApprovalCard
29
- ├── 标题栏:左侧色条 + 单据标题 + 复制图标 + 状态徽章(评审中/已通过/已拒绝/已撤销等)
29
+ ├── 标题栏:左侧色条 + 单据标题 + 复制图标 + 状态徽章(审批中/已通过/已拒绝/已撤销等)
30
30
  ├── 字段区:单据编号、提交时间
31
- ├── 处理人:当前处理人(overflow-tips 省略)
31
+ ├── 处理人:仅 `pending` / `draft` 时展示当前处理人(overflow-tips 省略)
32
32
  └── 操作区:查看单据详情(新窗口打开 url)、取消审批(仅 pending / draft 且非 readonly;点击后 loading 防重复提交;分享只读渲染下禁用)
33
33
  ```
34
34
 
@@ -42,7 +42,7 @@ ToolApprovalCard
42
42
 
43
43
  | `ticket.status` | 视觉 |
44
44
  | --------------------------------------- | -------- |
45
- | `pending`、`draft` | 蓝色评审中 |
45
+ | `pending`、`draft` | 蓝色审批中 |
46
46
  | `approved` | 绿色通过 |
47
47
  | `rejected`、`cancelled`、`expired`、`abandoned` | 红色终态 |
48
48
  | `revoked` | 橙色已撤销 |
@@ -21,9 +21,12 @@ Provider/Consumer 模式的自定义 Tab 管理,用于 `ChatContainer` 侧边
21
21
 
22
22
  ```typescript
23
23
  function useCustomTabProvider<T extends Record<string, unknown>>(options: {
24
+ // 执行情况 Tab 是否展示,缺省 true;传 getter 以保持响应式
25
+ executionTabVisible?: () => boolean | undefined;
24
26
  onTabChange?: (tab: CustomTab<T>) => void;
25
27
  }): {
26
28
  tabs: ShallowRef<CustomTab<T>[]>;
29
+ displayTabs: ComputedRef<CustomTab<T>[]>;
27
30
  selectedTab: Ref<CustomTab<T>>;
28
31
  isCollapse: ShallowRef<boolean>;
29
32
  addCustomTab: (tab: CustomTab<T>) => void;
@@ -40,6 +43,7 @@ function useCustomTabConsumer<T extends Record<string, unknown>>():
40
43
  | undefined
41
44
  | {
42
45
  tabs: ShallowRef<CustomTab<T>[]>;
46
+ displayTabs: ComputedRef<CustomTab<T>[]>;
43
47
  selectedTab: ShallowRef<CustomTab<T> | null>;
44
48
  addCustomTab: (tab: CustomTab<T>) => void;
45
49
  removeCustomTab: (tabName: string) => void;
@@ -88,19 +92,21 @@ tabManager?.removeCustomTab('node-detail-123');
88
92
 
89
93
  ## 内置常量
90
94
 
91
- | 常量名 | 值 | 说明 |
92
- | -------------------- | ------------- | ------------------------- |
93
- | `EXECUTION_TAB_NAME` | `'execution'` | 执行情况 Tab 的固定标识 |
94
- | `CUSTOM_TAB_TOKEN` | `Symbol` | provide/inject 注入 Token |
95
+ | 常量名 | 值 | 说明 |
96
+ | -------------------- | ------------- | ------------------------------------------ |
97
+ | `EXECUTION_TAB_NAME` | `'execution'` | 执行情况 Tab 的固定标识 |
98
+ | `DEFAULT_TAB_ORDER` | `100` | Tab 默认排序权重;执行情况固定为 `0` |
99
+ | `CUSTOM_TAB_TOKEN` | `Symbol` | provide/inject 注入 Token |
95
100
 
96
101
  ## 返回值说明
97
102
 
98
103
  | 属性/方法名 | 类型 | 说明 |
99
104
  | --------------- | --------------------------- | ------------------------------------------------- |
100
- | tabs | `ShallowRef<CustomTab[]>` | 所有 Tab 列表(含默认的执行情况 Tab|
101
- | selectedTab | `Ref<CustomTab>` | 当前选中的 Tab |
105
+ | tabs | `ShallowRef<CustomTab[]>` | 所有 Tab 列表(含默认的执行情况 Tab,保留隐藏项) |
106
+ | displayTabs | `ComputedRef<CustomTab[]>` | Tab 栏实际展示列表:过滤 `visible === false`,按 `order` 升序稳定排序 |
107
+ | selectedTab | `Ref<CustomTab>` | 当前选中的 Tab;选中项被隐藏时自动回退到首个可见 Tab |
102
108
  | isCollapse | `ShallowRef<boolean>` | 侧边栏折叠状态;`addCustomTab` 时自动设为 `false` |
103
- | addCustomTab | `(tab: CustomTab) => void` | 添加 Tab(同名 Tab 不重复添加) |
109
+ | addCustomTab | `(tab: CustomTab) => void` | 添加 Tab;同名 Tab 合并更新(可改 `order` / `visible` / `label`) |
104
110
  | removeCustomTab | `(tabName: string) => void` | 移除指定 Tab |
105
111
  | selectCustomTab | `(tab: CustomTab) => void` | 切换到指定 Tab,触发 `onTabChange` 回调 |
106
112
  | resetCustomTab | `() => void` | 重置为仅保留「执行情况」Tab、折叠侧栏并选中默认 Tab;`ChatContainer` 在卸载时调用,避免残留自定义 Tab |
@@ -113,14 +119,23 @@ interface CustomTab<T = Record<string, unknown>> {
113
119
  name: string;
114
120
  /** 可与 `component` / `props` 并列;用于侧栏「在对话中定位」与主消息 `message.uid` 对齐 */
115
121
  data?: T & { messageUid?: string };
122
+ /** 排序权重,升序,越小越靠前;缺省 100,执行情况默认 0 */
123
+ order?: number;
124
+ /** 是否在 Tab 栏展示,缺省 true;false 时仍可被程序化选中,但内容不渲染、会自动切到首个可见 Tab */
125
+ visible?: boolean;
126
+ /** 是否可关闭,缺省 true;执行情况强制不可关闭 */
127
+ closable?: boolean;
116
128
  }
117
129
  ```
118
130
 
119
131
  ## 设计特点
120
132
 
121
133
  - `tabs` 使用 `shallowRef`,`addCustomTab` 通过展开新数组触发更新,避免 `UnwrapRef<T>` 类型问题
122
- - 默认的「执行情况」Tab 始终存在且不可关闭
123
- - `addCustomTab` 同时展开侧边栏(`isCollapse = false`)并在 `nextTick` 后自动选中新 Tab
134
+ - 默认的「执行情况」Tab 始终存在且不可关闭,`order` 固定 `0`;可通过 `executionTabVisible` 配置显隐
135
+ - `displayTabs` 负责「过滤显隐 + `order` 排序」;原始 `tabs` 仍保留全部 Tab 供程序化选中与查找
136
+ - 排序为稳定排序,`order` 相同的 Tab 保持插入先后顺序
137
+ - 选中的 Tab 被配置隐藏时,内容不再渲染,自动切换到首个可见 Tab
138
+ - `addCustomTab` 同时展开侧边栏(`isCollapse = false`)并在 `nextTick` 后自动选中目标 Tab;同名 Tab 合并更新
124
139
 
125
140
  ## 关联组件
126
141
 
@@ -1,7 +1,7 @@
1
1
  <!-- AI SUMMARY -->
2
2
  ## 快速了解
3
3
 
4
- useFlowNodeActions 接收 onInterruptResume 与 openNodeDetail,返回 getNodeActions(task, node)。 失败节点按 retryable/skippable 展示重试/跳过,详情恒在末尾;点击 resume 时不传 interrupt。
4
+ useFlowNodeActions 接收 onInterruptResume 与 openNodeDetail,返回 getNodeActions 与 isNodePending。 失败节点按 retryable/skippable 展示重试/跳过,详情恒在末尾;点击后进入 pending 防重复提交, 以 task_id:node_id:retry 为键自动收敛;点击 resume 时不传 interrupt。
5
5
 
6
6
  ### 关联组件
7
7
  - **flow-agent-content** — FlowAgentContent 内部消费,驱动节点行尾按钮组渲染
@@ -21,12 +21,16 @@ useFlowNodeActions 接收 onInterruptResume 与 openNodeDetail,返回 getNodeA
21
21
 
22
22
  ```typescript
23
23
  function useFlowNodeActions(options: {
24
+ /** 隐藏重试 / 跳过等交互式 resume 操作(分享态只读,仅保留「详情」查看入口) */
25
+ hideResumeActions?: Ref<boolean>;
24
26
  /** resume 回调(与第三方审批取消同一回调,按 payload.operation 分流) */
25
27
  onInterruptResume: Ref<OnInterruptResume | undefined>;
26
28
  /** 打开节点详情侧栏(复用 useFlowTab 的能力) */
27
29
  openNodeDetail: (task: BkFlowTask, node: BkFlowNode) => void;
28
30
  }): {
29
31
  getNodeActions: (task: FlowTaskVM, node: FlowNodeVM) => FlowNodeActionVM[];
32
+ /** 当前节点是否有进行中的 resume 操作(供视图层常驻显示按钮组) */
33
+ isNodePending: (task: FlowTaskVM, node: FlowNodeVM) => boolean;
30
34
  };
31
35
  ```
32
36
 
@@ -39,19 +43,29 @@ type FlowNodeActionId =
39
43
  | InterruptResumeOperation.FlowNodeSkip;
40
44
 
41
45
  interface FlowNodeActionVM {
46
+ /** 是否禁用点击(任一 resume 操作进行中时,重试 / 跳过均禁用) */
47
+ disabled: boolean;
42
48
  icon: Component;
43
49
  id: FlowNodeActionId;
50
+ /** 国际化文案(进行中时切换为「重试中 / 跳过中」) */
44
51
  label: string;
52
+ /** 是否处于进行中态:图标切换为 loading */
53
+ loading: boolean;
54
+ /** 因另一操作进行中而禁用时的 hover 提示 */
55
+ tooltip?: string;
45
56
  run: () => void;
46
57
  }
47
58
  ```
48
59
 
49
- | 字段 | 说明 |
50
- | ------- | ------------------------------ |
51
- | `icon` | 按钮图标组件 |
52
- | `id` | 唯一标识,用于 `v-for` key |
53
- | `label` | 国际化文案 |
54
- | `run` | 点击执行(详情或 resume) |
60
+ | 字段 | 说明 |
61
+ | ---------- | -------------------------------------------------------------- |
62
+ | `disabled` | 禁用点击;resume 进行中时重试 / 跳过均为 `true`,详情恒为 `false` |
63
+ | `icon` | 按钮图标组件(`loading` 时由上层切换为 Loading 组件) |
64
+ | `id` | 唯一标识,用于 `v-for` key |
65
+ | `label` | 国际化文案;进行中为「重试中 / 跳过中」 |
66
+ | `loading` | 本操作进行中时为 `true` |
67
+ | `tooltip` | 被另一操作阻塞时的 hover 提示(如「任务正在重试中,不可跳过」) |
68
+ | `run` | 点击执行(详情或 resume);进行中重复调用被内部忽略 |
55
69
 
56
70
  ## 操作显隐规则
57
71
 
@@ -59,10 +73,23 @@ interface FlowNodeActionVM {
59
73
  | ---- | ------------------ | ------------------------------------------ | --------------------------------------------- |
60
74
  | 重试 | `flow_node_retry` | `convergedState === 'failed'` 且 `retryable` | 调用 `onInterruptResume`,**不传** `interrupt` |
61
75
  | 跳过 | `flow_node_skip` | `convergedState === 'failed'` 且 `skippable` | 同上 |
62
- | 详情 | `detail` | 始终(Share 模式由上层组件隐藏整组) | 调用 `openNodeDetail(task.raw, node.raw)` |
76
+ | 详情 | `detail` | 始终(含 Share 分享态) | 调用 `openNodeDetail(task.raw, node.raw)` |
63
77
 
64
78
  展示顺序:重试 → 跳过 → 详情。
65
79
 
80
+ > **分享态过滤**:传入 `hideResumeActions`(`Ref<boolean>`,如 `RenderMode.Share`)为 `true` 时,`getNodeActions` 直接过滤掉重试 / 跳过,仅返回「详情」查看入口;用于只读分享场景放开查看、禁止交互。
81
+
82
+ ## pending 态与防重复提交
83
+
84
+ 点击重试或跳过后:
85
+
86
+ 1. 以 `task_id:node_id:retry` 为键写入 `pendingMap`,同一节点仅允许一个进行中的 resume 操作
87
+ 2. 进行中按钮:`loading: true`、`disabled: true`、`label` 切换为「重试中 / 跳过中」
88
+ 3. 另一 resume 按钮:`disabled: true`,`tooltip` 给出阻塞原因
89
+ 4. 详情按钮:不受影响
90
+ 5. `isNodePending(task, node)` 返回 `true`,供视图层添加 `is-pending` class 常驻显示按钮组
91
+ 6. 后端推送新状态且 `node.retry` 变化时,pending 键自动失效,按钮恢复可用
92
+
66
93
  ## resume 负载格式
67
94
 
68
95
  ```typescript
@@ -88,14 +115,19 @@ import { toRef } from 'vue';
88
115
  import { useFlowNodeActions } from '@blueking/chat-x';
89
116
  // 或相对路径:'./use-flow-node-actions'
90
117
 
91
- const { getNodeActions } = useFlowNodeActions({
118
+ const { getNodeActions, isNodePending } = useFlowNodeActions({
119
+ // 分享态只读:过滤重试 / 跳过,仅保留详情
120
+ hideResumeActions: computed(() => renderMode.value === RenderMode.Share),
92
121
  onInterruptResume: toRef(props, 'onInterruptResume'),
93
122
  openNodeDetail,
94
123
  });
95
124
 
96
125
  // 模板中
126
+ // :class="{ 'is-pending': isNodePending(task, node) }"
97
127
  // v-for="action in getNodeActions(task, node)" :key="action.id"
98
- // @click.stop="action.run()"
128
+ // :class="{ 'is-disabled': action.disabled }"
129
+ // v-tippy="action.tooltip ? { content: action.tooltip } : { content: '' }"
130
+ // @click.stop="handleActionClick(action)" // 禁用态拦截,避免重复提交
99
131
  ```
100
132
 
101
133
  ## 扩展新操作
@@ -106,9 +138,11 @@ const { getNodeActions } = useFlowNodeActions({
106
138
  const RESUME_ACTION_DEFS: FlowNodeResumeActionDef[] = [
107
139
  // 现有:重试、跳过
108
140
  {
141
+ blockedTip: () => t('另一操作进行中的提示'),
109
142
  icon: MyIcon,
110
143
  id: InterruptResumeOperation.MyNewOp, // 需先在 InterruptResumeOperation 扩展
111
144
  label: () => t('新操作'),
145
+ pendingLabel: () => t('新操作进行中'),
112
146
  visible: node => /* 自定义显隐 */,
113
147
  },
114
148
  ];
@@ -39,7 +39,7 @@
39
39
 
40
40
  ├── .ai-user-message-content(气泡:bg #e1ecff,padding 8×12,border-radius 4px)
41
41
  │ v-if: cite 为数组 → KeyValueContent(title + key/value 列表)
42
- │ v-else-if: content → MarkdownContent × N(每个 text 项一个实例)
42
+ │ v-else-if: content → TextContent × N(textParts 中每个文本片段一个实例)
43
43
 
44
44
  └── MessageTools(.ai-user-message-tools)
45
45
  v-if: messageToolsStatus !== 'hidden'
@@ -58,7 +58,7 @@
58
58
  │ @submit(formModel) → onShortcutConfirm(formModel) + isEdit=false
59
59
 
60
60
  └── ChatInput(v-else,带自定义 #send-icon slot)
61
- v-model: editContent(仅含文本内容,数组时取第一个 text 项)
61
+ v-model: editContent(取 textParts[0],即第一个文本片段)
62
62
  defaultUploadFiles: binaryFiles
63
63
  #send-icon slot → .user-edit-footer
64
64
  Button "取消" → isEdit=false
@@ -67,7 +67,7 @@
67
67
 
68
68
  ## 基础用法
69
69
 
70
- `content` 为字符串时,通过 `MarkdownContent` 渲染(支持 Markdown 语法)。
70
+ `content` 为字符串时,通过 `TextContent` 渲染(内部使用 `MarkdownContent`,支持 Markdown 语法)。
71
71
 
72
72
  ```vue
73
73
  <template>
@@ -97,7 +97,7 @@
97
97
  - **图片文件**(`binaryImageFiles`):判断 `url` 存在或 `mimeType` / `file.type` 以 `image/` 开头的文件,统一放入一个 `FileContent`(`readonly=true`)中渲染,支持点击缩略图全屏预览
98
98
  - **非图片文件**(`binaryNonImageFiles`):每个文件单独渲染在 `FileContent`(`readonly=true`)中
99
99
 
100
- `text` 项按顺序各渲染一个 `MarkdownContent`。
100
+ `text` 项经 `textParts` 计算属性统一为 `string[]`,按顺序各渲染一个 `TextContent`。
101
101
 
102
102
  ```vue
103
103
  <script setup lang="ts">
@@ -228,12 +228,12 @@
228
228
  **`editContent` 的初始化逻辑**(仅文本部分,二进制文件通过 `defaultUploadFiles` 恢复):
229
229
 
230
230
  ```
231
- content 为 string → editContent = content
232
- textContent string → editContent = textContent
233
- textContent 为 array → editContent = textContent[0]?.text(取第一个文本项)
234
- binaryFiles 有值 → 进入编辑模式(editContent 可为空)
231
+ textParts 有值 → editContent = textParts[0](取第一个文本片段)
232
+ binaryFiles 有值进入编辑模式(editContent 可为空)
235
233
  ```
236
234
 
235
+ `textParts` 由 `content` 统一计算:`string` 转为单元素数组,`InputContent[]` 则过滤出 `type: 'text'` 且非空的项并映射为 `string[]`。
236
+
237
237
  ```vue
238
238
  <template>
239
239
  <UserMessage
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "2.0.0",
3
- "generatedAt": "2026-06-29T06:55:07.217Z",
3
+ "generatedAt": "2026-07-06T06:56:57.153Z",
4
4
  "domains": {
5
5
  "setup": {
6
6
  "label": "对话搭建",
@@ -1544,7 +1544,7 @@
1544
1544
  "slug": "use-flow-node-actions",
1545
1545
  "kind": "composable",
1546
1546
  "description": "聚合 FlowAgent 节点行尾操作(详情 / 重试 / 跳过)为声明式视图模型列表,显隐与 resume 回调收敛于此。",
1547
- "aiSummary": "useFlowNodeActions 接收 onInterruptResume 与 openNodeDetail,返回 getNodeActions(task, node)。 失败节点按 retryable/skippable 展示重试/跳过,详情恒在末尾;点击 resume 时不传 interrupt。",
1547
+ "aiSummary": "useFlowNodeActions 接收 onInterruptResume 与 openNodeDetail,返回 getNodeActions 与 isNodePending。 失败节点按 retryable/skippable 展示重试/跳过,详情恒在末尾;点击后进入 pending 防重复提交, 以 task_id:node_id:retry 为键自动收敛;点击 resume 时不传 interrupt。",
1548
1548
  "relatedComponents": [
1549
1549
  {
1550
1550
  "slug": "flow-agent-content",
package/dist/mcp/index.js CHANGED
File without changes
@@ -10,12 +10,15 @@ export type CustomBkFlowTabData = CustomTabData<{
10
10
  task_name?: string;
11
11
  }>;
12
12
  export type CustomTab<T extends CustomTabData<Record<string, unknown>>> = {
13
+ closable?: boolean;
13
14
  data?: T & {
14
15
  messageUid?: string;
15
16
  };
16
17
  icon?: string;
17
18
  label: string;
18
19
  name: string;
20
+ order?: number;
21
+ visible?: boolean;
19
22
  };
20
23
  export type CustomTabData<T extends Record<string, unknown>> = {
21
24
  component?: Component;
@@ -14,6 +14,7 @@ export interface IAiSlashMenuItem {
14
14
  }
15
15
  export declare const resourceTypeMap: {
16
16
  readonly tool: "工具";
17
+ readonly skill: "Skill";
17
18
  readonly mcp: "MCP";
18
19
  readonly doc: "知识库";
19
20
  readonly knowledgebase: "知识库";
package/package.json CHANGED
@@ -1,26 +1,8 @@
1
1
  {
2
2
  "name": "@blueking/chat-x",
3
- "version": "0.0.46-beta.2",
3
+ "version": "0.0.46-beta.4",
4
4
  "description": "蓝鲸智云 AI Chat 组件库 —— 遵循 AG-UI,为 AI Agent 和人类开发者共同设计的对话 UI 组件库。",
5
5
  "main": "index.js",
6
- "scripts": {
7
- "prepublishOnly": "vite --config vite.config.ts build && pnpm dts && pnpm mcp:build",
8
- "dev": "vite --config vite.config.ts",
9
- "dts": "vue-tsc --project tsconfig.dts.json",
10
- "build": "vitest && vite --config vite.config.ts build && pnpm dts",
11
- "preview": "vite --config vite.config.ts build --mode preview && pnpm dts",
12
- "lint:script": "eslint . --ext .vue,.ts --fix",
13
- "lint:style": "stylelint \"**/*.{scss,css,vue}\" --fix",
14
- "lint:all": "pnpm lint:script && pnpm lint:style",
15
- "test": "vitest",
16
- "test:coverage": "vitest run --coverage",
17
- "wiki:dev": "vitepress dev wikis",
18
- "wiki:build": "vitepress build wikis",
19
- "mcp:build:index": "tsx mcp/scripts/build-index.ts",
20
- "mcp:build": "tsc -p mcp/tsconfig.json && pnpm mcp:build:index",
21
- "mcp:start": "node dist/mcp/index.js",
22
- "mcp:dev": "tsx mcp/src/index.ts"
23
- },
24
6
  "bin": {
25
7
  "chat-x-mcp": "dist/mcp/index.js"
26
8
  },
@@ -68,7 +50,6 @@
68
50
  "zod": "^4.3.6"
69
51
  },
70
52
  "devDependencies": {
71
- "@blueking/chat-helper": "workspace:*",
72
53
  "@types/katex": "^0.16.7",
73
54
  "@types/lodash": "^4.17.23",
74
55
  "@types/markdown-it": "^14.1.2",
@@ -97,6 +78,24 @@
97
78
  "vite-bundle-analyzer": "^1.3.2",
98
79
  "vitepress": "2.0.0-alpha.16",
99
80
  "vitest": "^4.0.18",
100
- "vue-tsc": "^3.1.4"
81
+ "vue-tsc": "^3.1.4",
82
+ "@blueking/chat-helper": "0.0.12-beta.4"
83
+ },
84
+ "scripts": {
85
+ "dev": "vite --config vite.config.ts",
86
+ "dts": "vue-tsc --project tsconfig.dts.json",
87
+ "build": "vitest && vite --config vite.config.ts build && pnpm dts",
88
+ "preview": "vite --config vite.config.ts build --mode preview && pnpm dts",
89
+ "lint:script": "eslint . --ext .vue,.ts --fix",
90
+ "lint:style": "stylelint \"**/*.{scss,css,vue}\" --fix",
91
+ "lint:all": "pnpm lint:script && pnpm lint:style",
92
+ "test": "vitest",
93
+ "test:coverage": "vitest run --coverage",
94
+ "wiki:dev": "vitepress dev wikis",
95
+ "wiki:build": "vitepress build wikis",
96
+ "mcp:build:index": "tsx mcp/scripts/build-index.ts",
97
+ "mcp:build": "tsc -p mcp/tsconfig.json && pnpm mcp:build:index",
98
+ "mcp:start": "node dist/mcp/index.js",
99
+ "mcp:dev": "tsx mcp/src/index.ts"
101
100
  }
102
101
  }