@blueking/chat-x 0.0.49-beta.8 → 0.0.49-beta.9

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.
@@ -37,6 +37,7 @@ export declare const lang: {
37
37
  readonly 停止生成: "Stop generating";
38
38
  readonly 正在停止: "Stopping";
39
39
  readonly 耗时: "Duration";
40
+ readonly 昨天: "Yesterday";
40
41
  readonly 参数: "Parameters";
41
42
  readonly 描述: "Description";
42
43
  readonly 执行情况: "Execution Status";
@@ -156,4 +157,4 @@ export declare const lang: {
156
157
  readonly 预览加载失败: "Failed to load preview";
157
158
  readonly 暂无可预览的文件: "No file to preview";
158
159
  };
159
- 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" | "Quick Thinking" | "Image to Text" | "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" | "Approval Cancelled" | "Refresh Ticket Status" | "This ticket has been rejected and cannot be cancelled" | "This ticket has been approved and cannot be cancelled" | "This ticket has been cancelled, no need to click again" | "Approval cannot be cancelled in the current status" | "There are {count} pending approval tickets in the current conversation. To continue, cancel approval first." | "Unsupported interrupt message" | "Searching" | "Search Completed" | "Upload File" | "Select model" | "Search models" | "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" | "Completed" | "question(s)" | "Answers" | "Replied" | "Please enter..." | "File Artifacts" | "File List" | "Search file keyword" | "Failed to load preview" | "No file to preview" | "发送" | "停止" | "问问小鲸" | "复制" | "分享" | "点赞" | "不满意" | "删除" | "引用" | "重新生成" | "重新生成将清空下文内容" | "提交" | "取消" | "预览内容" | "跳转详情" | "调用工具:" | "调用中" | "调用成功" | "调用失败" | "说出您的想法" | "什么原因让你满意?" | "什么原因让你不满意?" | "返回内容" | "编辑" | "深度思考" | "快速思考" | "图生文" | "图片加载中..." | "图片加载失败" | "思考中" | "已思考完成" | "思考失败" | "复制成功" | "复制失败" | "返回底部" | "停止生成" | "正在停止" | "耗时" | "参数" | "描述" | "执行情况" | "执行中" | "成功" | "失败" | "挂起" | "待执行" | "详情" | "重试" | "重试中" | "跳过中" | "任务正在重试中,不可跳过" | "任务正在跳过中,不可重试" | "节点" | "节点配置" | "节点输出" | "基础信息" | "流程模板" | "节点名称" | "步骤名称" | "执行方案" | "是否可选" | "失败处理" | "超时控制" | "是" | "否" | "输入参数" | "输出参数" | "参数名" | "参数值" | "名称" | "变量说明" | "结构化输出" | "手动跳过" | "暂无数据" | "调用 MCP:" | "更多" | "算法方案评审单" | "评审中" | "审批中" | "已废弃" | "已批准" | "已通过" | "已取消" | "已过期" | "已拒绝" | "已撤销" | "单据编号" | "提交时间" | "当前处理人" | "无" | "查看单据详情" | "复制单据" | "复制单据链接" | "取消审批" | "已取消审批" | "刷新单据状态" | "单据已取消审批" | "该单据已被拒绝,无法取消" | "该单据已通过,无法取消" | "单据已取消,无需重复点击" | "当前状态无法取消审批" | "当前会话有 {count} 个待审批单,如需继续,请先取消审批" | "暂不支持的中断消息" | "检索中" | "检索完成" | "上传文件" | "选择模型" | "搜索模型关键字" | "请求中..." | "取消满意" | "取消不满意" | "确认删除该回答?" | "删除操作无法撤回,请谨慎操作!" | "预览" | "缩小" | "放大" | "旋转" | "下载" | "抱歉,图片加载失败,可尝试重新加载" | "重置" | "重新加载" | "宽" | "高" | "上传图片" | "搜索 关键字" | "选择日期" | "在对话中定位" | "全选" | "确定" | "上传图片, 最多支持上传 3 个, 最大支持 2.4MB" | "你好,我是小鲸" | "清空搜索" | "搜索结果为空" | "有效证据" | "全屏" | "退出全屏" | "请选择以继续" | "继续" | "收到信息:" | "待审批" | "已审批" | "完成" | "跳过" | "单选" | "多选" | "其他" | "已完成" | "题" | "回答内容" | "已回复" | "请输入..." | "文件产物" | "文件列表" | "搜索文件关键字" | "预览加载失败" | "暂无可预览的文件";
160
+ 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" | "Quick Thinking" | "Image to Text" | "Loading image..." | "Failed to load image" | "Thinking..." | "Thinking Completed" | "Thinking Failed" | "Copy Success" | "Copy Failed" | "Return to bottom" | "Stop generating" | "Stopping" | "Duration" | "Yesterday" | "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" | "Approval Cancelled" | "Refresh Ticket Status" | "This ticket has been rejected and cannot be cancelled" | "This ticket has been approved and cannot be cancelled" | "This ticket has been cancelled, no need to click again" | "Approval cannot be cancelled in the current status" | "There are {count} pending approval tickets in the current conversation. To continue, cancel approval first." | "Unsupported interrupt message" | "Searching" | "Search Completed" | "Upload File" | "Select model" | "Search models" | "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" | "Completed" | "question(s)" | "Answers" | "Replied" | "Please enter..." | "File Artifacts" | "File List" | "Search file keyword" | "Failed to load preview" | "No file to preview" | "发送" | "停止" | "问问小鲸" | "复制" | "分享" | "点赞" | "不满意" | "删除" | "引用" | "重新生成" | "重新生成将清空下文内容" | "提交" | "取消" | "预览内容" | "跳转详情" | "调用工具:" | "调用中" | "调用成功" | "调用失败" | "说出您的想法" | "什么原因让你满意?" | "什么原因让你不满意?" | "返回内容" | "编辑" | "深度思考" | "快速思考" | "图生文" | "图片加载中..." | "图片加载失败" | "思考中" | "已思考完成" | "思考失败" | "复制成功" | "复制失败" | "返回底部" | "停止生成" | "正在停止" | "耗时" | "昨天" | "参数" | "描述" | "执行情况" | "执行中" | "成功" | "失败" | "挂起" | "待执行" | "详情" | "重试" | "重试中" | "跳过中" | "任务正在重试中,不可跳过" | "任务正在跳过中,不可重试" | "节点" | "节点配置" | "节点输出" | "基础信息" | "流程模板" | "节点名称" | "步骤名称" | "执行方案" | "是否可选" | "失败处理" | "超时控制" | "是" | "否" | "输入参数" | "输出参数" | "参数名" | "参数值" | "名称" | "变量说明" | "结构化输出" | "手动跳过" | "暂无数据" | "调用 MCP:" | "更多" | "算法方案评审单" | "评审中" | "审批中" | "已废弃" | "已批准" | "已通过" | "已取消" | "已过期" | "已拒绝" | "已撤销" | "单据编号" | "提交时间" | "当前处理人" | "无" | "查看单据详情" | "复制单据" | "复制单据链接" | "取消审批" | "已取消审批" | "刷新单据状态" | "单据已取消审批" | "该单据已被拒绝,无法取消" | "该单据已通过,无法取消" | "单据已取消,无需重复点击" | "当前状态无法取消审批" | "当前会话有 {count} 个待审批单,如需继续,请先取消审批" | "暂不支持的中断消息" | "检索中" | "检索完成" | "上传文件" | "选择模型" | "搜索模型关键字" | "请求中..." | "取消满意" | "取消不满意" | "确认删除该回答?" | "删除操作无法撤回,请谨慎操作!" | "预览" | "缩小" | "放大" | "旋转" | "下载" | "抱歉,图片加载失败,可尝试重新加载" | "重置" | "重新加载" | "宽" | "高" | "上传图片" | "搜索 关键字" | "选择日期" | "在对话中定位" | "全选" | "确定" | "上传图片, 最多支持上传 3 个, 最大支持 2.4MB" | "你好,我是小鲸" | "清空搜索" | "搜索结果为空" | "有效证据" | "全屏" | "退出全屏" | "请选择以继续" | "继续" | "收到信息:" | "待审批" | "已审批" | "完成" | "跳过" | "单选" | "多选" | "其他" | "已完成" | "题" | "回答内容" | "已回复" | "请输入..." | "文件产物" | "文件列表" | "搜索文件关键字" | "预览加载失败" | "暂无可预览的文件";
@@ -31,6 +31,7 @@
31
31
  - **模型选择**:透传 `models`、`v-model:selectedModel` 与 `@modelChange` 至 `ChatInput`,传入 `models` 后在发送按钮左侧展示 [ModelSelector](/components/input/model-selector)
32
32
  - **分享模式 / 渲染模式**:内置多选分享;`renderMode` 经 Provider 下传。`Share` 态开放侧栏只读查看,隐藏底部输入与「重试 / 跳过」等交互
33
33
  - **字号主题**:`size` 为 `small`(默认 12px)/ `normal`(14px);根节点 `data-ai-size`,浮层同步 `document.body.dataset.aiSize`
34
+ - **消息时间时区**:`timezone` 经 `useGlobalConfig` 下传给 `MessageTime`,统一整个会话的时间展示时区;未配置时按浏览器时区
34
35
  - **空状态欢迎页**:无消息时展示 Banner、`welcomeTitle`(默认「你好,我是小鲸」)与 `openingRemark`
35
36
 
36
37
  ## 组件结构
@@ -708,6 +709,7 @@ ChatContainer 的 Props 继承自 `ChatInputProps` 和 `MessageContainerProps`
708
709
  | placement | `'left' \| 'right'` | `'left'` | 侧边栏位置 |
709
710
  | resizeProps | `{ disabled?: boolean; initialDivide?: number \| string; max?: number; min?: number }` | — | 透传给内部 `ResizeLayout`;与默认 `collapsible: false`、`immediate: true`、`min: 400` 合并;`placement` 始终取自本组件。**数字型** `initialDivide` 还会作为内部侧栏宽度初值(驱动 `--resize-main-width`,并在展开时作为 `collapseChange` 的 `width`);百分比等字符串则回退为 `400` |
710
711
  | size | `'normal' \| 'small'` | `'small'` | 字号主题:`small` 12px / `normal` 14px;根节点设置 `data-ai-size` 并注入 `useGlobalConfig` |
712
+ | timezone | `string` | — | 消息时间展示所用的 IANA 时区名(如 `Asia/Shanghai`);经 `useGlobalConfig` 注入,未配置时按浏览器时区展示,详见 [MessageTime](/components/feedback/message-time) |
711
713
  | welcomeTitle | `string` | — | 欢迎页标题;未传时默认展示「你好,我是小鲸」 |
712
714
  | onCustomTabChange | `(tab: CustomTab) => Promise<any>` | — | 自定义 Tab 切换回调,返回值作为 Tab 组件 props |
713
715
  | onArtifactClick | `(file: AIFileInfo) => Promise<{ download_url?: string; preview_url?: string }>` | — | 异步获取下载 / 预览链接(每次调用重新获取,无缓存;同文件并发去重)。文本类预览依赖 `download_url`,iframe 类依赖 `preview_url`;未传则隐藏下载、预览无数据 |
@@ -865,5 +867,5 @@ interface Shortcut {
865
867
  - [SelectionFooter](/components/input/selection-footer) — 多选操作栏
866
868
  - [ToolBtn](/components/feedback/tool-btn) — 侧栏全屏按钮
867
869
  - [useFullScreen](/composables/use-full-screen) — 侧栏全屏控制
868
- - [useGlobalConfig](/composables/use-global-config) — 注入 `size` 与 `supportUpload`
870
+ - [useGlobalConfig](/composables/use-global-config) — 注入 `size`、`supportUpload` 与 `timezone`
869
871
  - [主题配置](/theme/theme) — 字号主题 CSS 变量
@@ -124,6 +124,7 @@
124
124
  - `renderMode === RenderMode.Share`(分享预览模式)
125
125
  - 消息组的 `pause` 为 `true`(来源于 `message.property?.extra?.pause`)
126
126
  - 多选模式(`enableSelection`)开启且消息组不是 Loading 类型
127
+ - AI 消息组的时间通过 `MessageTools` 的 `#append` 插槽渲染在工具图标右侧,取值为组内**最后一条**带 `createdAt` 的消息(即本轮回答完成时间);组内 `reasoning` / `activity` 等子消息不单独展示时间,全组都没有 `createdAt` 时不展示
127
128
  - `renderMode === RenderMode.Test` 时,工具栏会过滤掉「分享」按钮,其余正常
128
129
  - `renderMode === RenderMode.Share` 时,`message-group-messages` 自动添加 `message-group-enabled-selection` 类名(与 `enableSelection: true` 一致的多选视觉效果)
129
130
  - Loading 消息组的 `type` 是 `MessageRole.Loading`,不显示工具栏和多选 Checkbox
@@ -641,6 +642,7 @@ enum MessageToolsStatus {
641
642
  ## 关联组件
642
643
 
643
644
  - [MessageRender](/components/message/message-render) — 按组渲染每条消息时委托使用
645
+ - [MessageTime](/components/feedback/message-time) — AI 消息组工具栏右侧的时间
644
646
  - [InterruptMessage 中断消息](/components/agent/interrupt-message) — `role: 'interrupt'` 的渲染与 `onInterruptResume` 透传
645
647
  - [ChatInput](/components/input/chat-input) — 常与输入区组合构成完整对话界面
646
648
  - [LoadingMessage](/components/message/loading-message) — 末尾为用户消息时自动追加加载组
@@ -0,0 +1,180 @@
1
+ <!-- AI SUMMARY -->
2
+ ## 快速了解
3
+
4
+ 按 createdAt 展示消息时间,四档格式:今天 `12:00`、昨天 `昨天 12:00`、今年内更早 `3-12 12:00`、非今年 `2025-3-12 12:00`; 时区取 props.timezone,未传时回退 injectGlobalConfig().timezone(由 ChatContainer 的 timezone prop 注入),都没有则用浏览器时区; 无值或非法时间不渲染任何 DOM。通常通过 MessageTools 的 prepend / append 插槽使用。 源码位置:src/components/message-tools/message-time/message-time.vue。
5
+
6
+ ### 关联组件
7
+ - **message-tools** — 通过 prepend / append 插槽嵌入工具栏
8
+ - **user-message** — 用户消息在工具栏左侧展示时间
9
+ - **message-container** — AI 消息组在工具栏右侧展示本轮回答时间
10
+
11
+ ---
12
+ <!-- FULL DOC -->
13
+
14
+ # MessageTime 消息时间
15
+
16
+ ## 源码事实
17
+
18
+ - **源码位置**:`src/components/message-tools/message-time/message-time.vue`
19
+ - **格式化工具**:`src/components/message-tools/message-time/format-message-time.ts`
20
+ - **能力域**:工具与反馈
21
+ - **能力说明**:按「今天 / 昨天 / 今年内 / 跨年」四档格式展示消息创建时间。
22
+
23
+ > **能力域**:工具与反馈
24
+
25
+ 展示单条消息(或一组 AI 回答)的创建时间。组件本身只负责格式化与渲染一段文本,**位置由使用方决定**——项目内通过 `MessageTools` 的 `prepend` / `append` 插槽嵌入工具栏。
26
+
27
+ ## 格式规则
28
+
29
+ 时间按与「今天」的日历日差值分四档,同一档内时分固定 `HH:mm`(24 小时制,补零),月日**不补零**:
30
+
31
+ | 档位 | 判定条件 | 输出示例 |
32
+ | ------------ | ---------------------- | --------------- |
33
+ | 今天 | 与今天同一日历日 | `12:00` |
34
+ | 昨天 | 与今天相差 1 个日历日 | `昨天 12:00` |
35
+ | 今年内更早 | 相差 ≥ 2 天且年份相同 | `3-12 12:00` |
36
+ | 非今年 | 年份不同 | `2025-3-12 12:00` |
37
+
38
+ - 分档与展示取**同一时区**的日历日:既避免「昨天 23:59」与「今天 00:01」因毫秒差不足一天被判成同一天,也避免按浏览器时区分档、按配置时区显示时分导致的错位
39
+ - `昨天` 走 `t('昨天')` 国际化,英文环境输出 `Yesterday 12:00`
40
+
41
+ ## 基础用法
42
+
43
+ `createdAt` 接受 ISO 字符串或毫秒时间戳:
44
+
45
+ ```vue
46
+ <template>
47
+ <MessageTime :created-at="message.createdAt" />
48
+ </template>
49
+
50
+ <script setup lang="ts">
51
+ import { MessageTime } from '@blueking/chat-x';
52
+
53
+ const message = {
54
+ id: '1',
55
+ messageId: '1',
56
+ role: 'user',
57
+ content: '你好',
58
+ status: 'completed',
59
+ createdAt: '2026-08-17T04:00:00.000Z',
60
+ };
61
+ </script>
62
+ ```
63
+
64
+ > **无值不渲染**:`createdAt` 为空、为空字符串或无法解析成合法时间时,组件不渲染任何 DOM(`v-if`),使用方无需额外判空。
65
+
66
+ ## 时区配置
67
+
68
+ 时区按以下优先级取值,均未配置时使用**浏览器时区**:
69
+
70
+ ```
71
+ props.timezone
72
+ └─ 未传 → injectGlobalConfig()?.timezone(由 ChatContainer 的 timezone prop 注入)
73
+ └─ 未配置 → 浏览器时区
74
+ ```
75
+
76
+ ```vue
77
+ <template>
78
+ <!-- 整个会话统一按北京时间展示 -->
79
+ <ChatContainer
80
+ :messages="messages"
81
+ timezone="Asia/Shanghai"
82
+ />
83
+ </template>
84
+ ```
85
+
86
+ ```vue
87
+ <template>
88
+ <!-- 单个实例覆盖全局配置 -->
89
+ <MessageTime
90
+ :created-at="message.createdAt"
91
+ timezone="UTC"
92
+ />
93
+ </template>
94
+ ```
95
+
96
+ - 取值为 [IANA 时区名](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)(如 `Asia/Shanghai`、`UTC`、`America/New_York`)
97
+ - 传入非法时区名时回退到浏览器时区,不会导致渲染失败
98
+ - 同一时区的 `Intl.DateTimeFormat` 实例内部有缓存,长会话中不会为每条消息重复构造
99
+
100
+ ## 在消息工具栏中的使用
101
+
102
+ `MessageTools` 提供 `prepend`(工具图标左侧)与 `append`(工具图标右侧)两个插槽,项目内的时间位置即由此决定:
103
+
104
+ | 场景 | 插槽 | 时间取值 |
105
+ | ------------ | --------- | -------------------------------------------- |
106
+ | 用户消息 | `prepend` | 该条消息的 `createdAt` |
107
+ | AI 消息组 | `append` | 组内**最后一条**带 `createdAt` 的消息,即本轮回答完成时间 |
108
+
109
+ ```vue
110
+ <template>
111
+ <MessageTools :on-action="handleAction">
112
+ <template #append>
113
+ <MessageTime :created-at="createdAt" />
114
+ </template>
115
+ </MessageTools>
116
+ </template>
117
+
118
+ <script setup lang="ts">
119
+ import { MessageTime, MessageTools } from '@blueking/chat-x';
120
+ </script>
121
+ ```
122
+
123
+ > 组内 `reasoning` / `activity` 等子消息不单独展示时间,一个 AI 回答组只显示一次。
124
+
125
+ ## API
126
+
127
+ ### Props
128
+
129
+ | 属性名 | 类型 | 必填 | 默认值 | 说明 |
130
+ | --------- | ------------------ | ---- | ------ | -------------------------------------------------------------------- |
131
+ | createdAt | `number \| string` | 否 | — | 消息创建时间,ISO 字符串或毫秒时间戳;无值或非法时不渲染 |
132
+ | timezone | `string` | 否 | — | IANA 时区名;优先于全局配置,两者都未配置时按浏览器时区展示 |
133
+
134
+ ### Events / Slots / Expose
135
+
136
+ 无。
137
+
138
+ ### 全局配置依赖
139
+
140
+ 通过 `injectGlobalConfig()` 读取 `timezone`。祖先需已调用 `useGlobalConfig()`(通常由 `ChatContainer` 的 `timezone` prop 注册);无 Provider 时按浏览器时区展示。
141
+
142
+ ## 类型定义
143
+
144
+ ```typescript
145
+ export type MessageTimeProps = {
146
+ createdAt?: number | string;
147
+ timezone?: string;
148
+ };
149
+
150
+ // 独立可用的格式化函数(组件内部使用,未从包入口导出)
151
+ declare const formatMessageTime: (createdAt?: number | string, timezone?: string) => string;
152
+ ```
153
+
154
+ ## 样式说明
155
+
156
+ ```scss
157
+ .ai-message-time {
158
+ flex: none;
159
+ font-size: var(--ai-font-size, 12px);
160
+ line-height: 16px;
161
+ color: $color-text-secondary;
162
+ white-space: nowrap;
163
+ }
164
+ ```
165
+
166
+ - 字号跟随 `--ai-font-size`(`ChatContainer` 的 `size` 档位),颜色使用次要文本语义色
167
+ - `flex: none` + `nowrap` 保证在工具栏 flex 布局中不被压缩换行
168
+
169
+ ## 注意事项
170
+
171
+ 1. **时间来源**:`createdAt` 由消息层(`chat-helper`)写入 `BaseMessage`,组件不参与取数
172
+ 2. **不做相对时间**:不提供「几分钟前」这类相对描述,四档格式固定
173
+ 3. **空值语义**:不渲染而非渲染占位,工具栏侧的 `prepend` / `append` 包裹容器会因 `:empty` 收起,不留多余间距
174
+
175
+ ## 关联组件
176
+
177
+ - [MessageTools](/components/feedback/message-tools) — 通过 `prepend` / `append` 插槽嵌入
178
+ - [UserMessage](/components/message/user-message) — 用户消息时间位置
179
+ - [MessageContainer](/components/setup/message-container) — AI 消息组时间位置
180
+ - [useGlobalConfig](/composables/use-global-config) — `timezone` 全局配置
@@ -1,12 +1,13 @@
1
1
  <!-- AI SUMMARY -->
2
2
  ## 快速了解
3
3
 
4
- 消息悬浮工具栏,组合复制、删除、反馈等工具按钮。 源码位置:src/components/message-tools/message-tools.vue。
4
+ 消息悬浮工具栏,组合复制、删除、反馈等工具按钮;提供 prepend / append 两端插槽承载消息时间等附加内容。 源码位置:src/components/message-tools/message-tools.vue。
5
5
 
6
6
  ### 关联组件
7
7
  - **tool-btn** — 普通工具项由 ToolBtn 渲染
8
8
  - **user-feedback** — like/unlike 时弹出反馈表单
9
9
  - **delete-tool** — id 为 delete 时替换为带确认的删除按钮
10
+ - **message-time** — 通过 prepend / append 插槽嵌入消息时间
10
11
 
11
12
  ---
12
13
  <!-- FULL DOC -->
@@ -20,22 +21,22 @@
20
21
 
21
22
  > **能力域**:工具与反馈
22
23
 
23
- AI 消息的操作工具栏组件,由**左侧消息工具区**和**右侧更新工具区**两部分组成,中间以分隔线分隔。仅 `like` / `unlike` 按钮会弹出反馈表单(`UserFeedback`),其余按钮直接触发 `onAction`。
24
+ AI 消息的操作工具栏组件,由**左侧消息工具区**和**右侧更新工具区**两部分组成,中间以分隔线分隔;两端另有 `prepend` / `append` 插槽用于挂载消息时间等附加内容。仅 `like` / `unlike` 按钮会弹出反馈表单(`UserFeedback`),其余按钮直接触发 `onAction`。
24
25
 
25
26
  ## 组件结构
26
27
 
27
28
  ```
28
- ┌─────────────────────────────────────────────────────┐
29
- │ .ai-message-tools-container
30
- │ ┌─────────────────────┐ │ ┌───────────────────┐
31
- │ │ messageTools │ │ │ updateTools │ │
32
- │ │ copy cite rebuild… │ │ │ like unlike del │ │
33
- │ └─────────────────────┘ │ └───────────────────┘
34
- 左侧区域 分隔线 右侧区域 │
35
- └─────────────────────────────────────────────────────┘
29
+ ┌───────────────────────────────────────────────────────────────────────┐
30
+ │ .ai-message-tools-container(display: flex,gap: 4px)
31
+ ┌────────┐ ┌─────────────────────┐ │ ┌───────────────┐ ┌───────┐
32
+ │#prependmessageTools │ │ │ updateTools │#append│
33
+ │ │ copy cite rebuild… │ │ │ like unlike │ │
34
+ └────────┘ └─────────────────────┘ │ └───────────────┘ └───────┘
35
+ 插槽区 左侧区域 分隔线 右侧区域 插槽区
36
+ └───────────────────────────────────────────────────────────────────────┘
36
37
  ```
37
38
 
38
- - 分隔线(`.ai-divider`)仅在 `updateTools` 非空时显示
39
+ - 分隔线(`.ai-divider`)与**右侧更新工具区**均仅在 `updateTools` 非空时渲染
39
40
  - `updateTools` 中 `id` 为 `like` / `unlike` 的按钮被 `Tippy` 弹窗包裹,点击后展示 `UserFeedback` 反馈表单
40
41
  - `updateTools` 中 `id` 为 `delete` 的按钮使用 `DeleteTool` 组件,点击后展示**确认删除弹窗**(含"删除"/"取消"按钮),确认后触发 `onAction`
41
42
  - `updateTools` 中其他按钮直接触发 `onAction`,不弹表单
@@ -224,6 +225,32 @@ const CONST_UPDATE_TOOLS = [
224
225
 
225
226
  **渲染效果**
226
227
 
228
+ ## 两端插槽(prepend / append)
229
+
230
+ `prepend`(工具图标左侧)与 `append`(工具图标右侧)用于在工具栏两端挂载附加内容,项目内用于放置 [MessageTime 消息时间](/components/feedback/message-time):
231
+
232
+ | 场景 | 使用插槽 | 效果 |
233
+ | --------- | --------- | --------------------------------------- |
234
+ | 用户消息 | `prepend` | 时间显示在工具图标左侧 |
235
+ | AI 消息组 | `append` | 时间显示在工具图标右侧 |
236
+
237
+ ```vue
238
+ <template>
239
+ <MessageTools :on-action="handleAction">
240
+ <template #append>
241
+ <MessageTime :created-at="createdAt" />
242
+ </template>
243
+ </MessageTools>
244
+ </template>
245
+
246
+ <script setup lang="ts">
247
+ import { MessageTime, MessageTools } from '@blueking/chat-x';
248
+ </script>
249
+ ```
250
+
251
+ - 插槽包裹容器(`.ai-message-tools-prepend` / `.ai-message-tools-append`)仅在对应插槽传入时渲染
252
+ - 插槽内容为空时(如消息无 `createdAt`,`MessageTime` 不渲染任何 DOM),包裹容器命中 `:empty` 被收起,不会留下多余间距
253
+
227
254
  ## 工具栏状态控制
228
255
 
229
256
  `messageToolsStatus` 控制工具栏整体状态:
@@ -357,6 +384,13 @@ const CONST_UPDATE_TOOLS = [
357
384
  | -------- | ------------------------------------------------------------- | ------------------------------------------ |
358
385
  | feedback | `(tool: IToolBtn, reasonList: string[], otherReason: string)` | 用户在反馈表单点击"提交"后触发(not 取消) |
359
386
 
387
+ ### Slots
388
+
389
+ | 插槽名 | 作用域参数 | 说明 |
390
+ | ------- | ---------- | ------------------------------------------------ |
391
+ | prepend | — | 工具图标左侧的附加内容,如用户消息的时间 |
392
+ | append | — | 工具图标右侧的附加内容,如 AI 消息组的时间 |
393
+
360
394
  ## 类型定义
361
395
 
362
396
  ```typescript
@@ -382,4 +416,5 @@ enum MessageToolsStatus {
382
416
 
383
417
  - [ToolBtn](/components/feedback/tool-btn) — 单项工具按钮
384
418
  - [UserFeedback](/components/feedback/user-feedback) — 点赞/踩反馈面板
385
- - [DeleteTool](/components/feedback/delete-tool) — 删除二次确认
419
+ - [DeleteTool](/components/feedback/delete-tool) — 删除二次确认
420
+ - [MessageTime](/components/feedback/message-time) — 两端插槽内的消息时间
@@ -54,6 +54,10 @@ interface BaseMessage<T extends MessageType, C = string> {
54
54
  // 消息名称(可选)
55
55
  name?: string;
56
56
 
57
+ // 可选:消息创建时间,ISO 字符串或毫秒时间戳,由消息层(chat-helper)写入
58
+ // 用于 MessageTime 展示;缺省时不展示时间
59
+ createdAt?: number | string;
60
+
57
61
  // 消息属性(可选)
58
62
  property?: {
59
63
  extra?: {
@@ -1,10 +1,11 @@
1
1
  <!-- AI SUMMARY -->
2
2
  ## 快速了解
3
3
 
4
- useGlobalConfig 接收 GlobalConfig(含 size?: ComputedRef<AiSizeMode>、supportUpload: ComputedRef<boolean>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer 在 setup 中调用 useGlobalConfig 注入 size 与 supportUpload; 后代组件可通过 injectGlobalConfig 读取配置;字号主题主要通过根节点 data-ai-size 与 CSS 变量生效。
4
+ useGlobalConfig 接收 GlobalConfig(含 size?: ComputedRef<AiSizeMode>、supportUpload: ComputedRef<boolean>、timezone?: ComputedRef<string | undefined>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer 在 setup 中调用 useGlobalConfig 注入 size、supportUploadtimezone; 后代组件可通过 injectGlobalConfig 读取配置;字号主题主要通过根节点 data-ai-size 与 CSS 变量生效。
5
5
 
6
6
  ### 关联组件
7
7
  - **chat-container** — 根容器调用 useGlobalConfig 注入 supportUpload
8
+ - **message-time** — 消息时间组件读取 timezone
8
9
 
9
10
  ---
10
11
  <!-- FULL DOC -->
@@ -13,7 +14,7 @@ useGlobalConfig 接收 GlobalConfig(含 size?: ComputedRef<AiSizeMode>、suppo
13
14
 
14
15
  > **分类**:composable
15
16
 
16
- 在聊天容器根组件与子组件之间通过 Vue `provide` / `inject` 共享**全局展示相关配置**(当前包括字号主题档位 `size`、是否支持上传 `supportUpload`)。与 Teleport 插槽 ID 无关。
17
+ 在聊天容器根组件与子组件之间通过 Vue `provide` / `inject` 共享**全局展示相关配置**(当前包括字号主题档位 `size`、是否支持上传 `supportUpload`、消息时间时区 `timezone`)。与 Teleport 插槽 ID 无关。
17
18
 
18
19
  > 字号主题主要通过 `ChatContainer` 根节点的 `data-ai-size` 与 CSS 变量(`--ai-font-size` 等)生效;`GlobalConfig.size` 供后代在逻辑层读取当前档位,样式层无需逐组件传参。
19
20
 
@@ -25,10 +26,11 @@ ChatContainer(根)
25
26
  ├── useGlobalConfig({
26
27
  │ size: computed(() => props.size ?? 'small'),
27
28
  │ supportUpload: computed(() => props.supportUpload ?? false),
29
+ │ timezone: computed(() => props.timezone),
28
30
  │ })
29
- │ └── provide(GLOBAL_CONFIG_TOKEN, { size, supportUpload })
31
+ │ └── provide(GLOBAL_CONFIG_TOKEN, { size, supportUpload, timezone })
30
32
 
31
- └── MessageContainer → … → UserMessage 等
33
+ └── MessageContainer → … → UserMessage / MessageTime
32
34
 
33
35
  UserMessage(后代)
34
36
  ├── injectGlobalConfig()
@@ -51,11 +53,14 @@ UserMessage(后代)
51
53
  const props = defineProps<{
52
54
  size?: 'normal' | 'small';
53
55
  supportUpload?: boolean;
56
+ timezone?: string;
54
57
  }>();
55
58
 
56
59
  useGlobalConfig({
57
60
  size: computed(() => props.size ?? 'small'),
58
61
  supportUpload: computed(() => props.supportUpload ?? false),
62
+ // 无默认值:未配置时由 MessageTime 回退到浏览器时区
63
+ timezone: computed(() => props.timezone),
59
64
  });
60
65
  </script>
61
66
  ```
@@ -88,11 +93,13 @@ export type AiSizeMode = 'normal' | 'small';
88
93
  export type GlobalConfig = {
89
94
  size?: ComputedRef<AiSizeMode>;
90
95
  supportUpload: ComputedRef<boolean>;
96
+ timezone?: ComputedRef<string | undefined>;
91
97
  };
92
98
 
93
99
  export function useGlobalConfig(options: GlobalConfig): {
94
100
  size?: ComputedRef<AiSizeMode>;
95
101
  supportUpload: ComputedRef<boolean>;
102
+ timezone?: ComputedRef<string | undefined>;
96
103
  };
97
104
 
98
105
  export function injectGlobalConfig(): GlobalConfig | undefined;
@@ -110,6 +117,7 @@ export function injectGlobalConfig(): GlobalConfig | undefined;
110
117
  | --------------- | ------------------------------------------------------------------------ |
111
118
  | `size` | 可选。字号主题档位 `normal`(14px)/ `small`(12px),与 `ChatContainer.size` 对齐 |
112
119
  | `supportUpload` | 是否支持上传,与根容器 `ChatContainer` 的 `supportUpload` 等展示策略对齐 |
120
+ | `timezone` | 可选。消息时间展示所用的 IANA 时区名,与 `ChatContainer.timezone` 对齐;未配置时 `MessageTime` 按浏览器时区展示 |
113
121
 
114
122
  ### `useGlobalConfig(options)`
115
123
 
@@ -117,6 +125,7 @@ export function injectGlobalConfig(): GlobalConfig | undefined;
117
125
  | ----------------------- | ------------------------------------------------------------------------------------- |
118
126
  | `options.size` | 可选。字号主题档位,建议使用 `computed(() => props.size ?? 'small')` 与根 props 同步 |
119
127
  | `options.supportUpload` | 是否支持上传,建议使用 `computed(() => props.supportUpload ?? false)` 与根 props 同步 |
128
+ | `options.timezone` | 可选。消息时间时区,建议使用 `computed(() => props.timezone)` 与根 props 同步;不设默认值,交由 `MessageTime` 回退浏览器时区 |
120
129
 
121
130
  - 调用后立即 `provide(GLOBAL_CONFIG_TOKEN, options)`。
122
131
  - 必须在具有组件实例上下文的 `setup` 中调用(与 Vue `provide` 要求一致)。
@@ -136,5 +145,6 @@ export function injectGlobalConfig(): GlobalConfig | undefined;
136
145
 
137
146
  ## 关联组件
138
147
 
139
- - [ChatContainer](../components/setup/chat-container) — 调用 `useGlobalConfig` 注入 `size` 与 `supportUpload`
148
+ - [ChatContainer](../components/setup/chat-container) — 调用 `useGlobalConfig` 注入 `size`、`supportUpload` 与 `timezone`
149
+ - [MessageTime](../components/feedback/message-time) — 读取 `timezone` 展示消息时间
140
150
  - [主题配置](../theme/theme) — `data-ai-size` 与 CSS 变量说明
@@ -6,6 +6,7 @@
6
6
  ### 关联组件
7
7
  - **message-render** — 由 MessageRender 在 role 为 user 时创建
8
8
  - **message-tools** — 消息工具栏交互与状态由 MessageTools 体系承载
9
+ - **message-time** — createdAt 经工具栏 prepend 插槽展示
9
10
  - **message-container** — 嵌入列表时由 MessageContainer 管理分组与多选
10
11
  - **chat-input** — 编辑态普通消息使用 ChatInput
11
12
 
@@ -47,8 +48,11 @@
47
48
  v-if: messageToolsStatus !== 'hidden'
48
49
  visibility: hidden(默认)→ visible(:hover 时)
49
50
  tools: [copy, cite, edit, delete],updateTools: []
51
+ #prepend slot → MessageTime(createdAt,工具图标左侧)
50
52
  ```
51
53
 
54
+ > **时间随工具栏显隐**:时间位于工具栏内,与工具按钮共用 `visibility` 控制,因此同样在悬停消息时才可见。
55
+
52
56
  **编辑模式**(点击 `edit` 按钮后 `isEdit=true`)
53
57
 
54
58
  ```
@@ -356,6 +360,7 @@ binaryFiles 有值 → 进入编辑模式(editContent 可为空)
356
360
  | 属性名 | 类型 | 说明 |
357
361
  | ------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------- |
358
362
  | content | `string \| InputContent[]` | 消息内容,字符串或含 text/binary 的数组 |
363
+ | createdAt | `number \| string` | 消息创建时间,经 `MessageTools` 的 `#prepend` 插槽交给 `MessageTime` 渲染在工具图标左侧;无值时不展示 |
359
364
  | property | `{ extra?: MessageExtra; artifacts?: AIFileInfo[] }` | 附加属性;本组件消费 `extra.cite` / `shortcut` / `context` |
360
365
  | messageToolsStatus | `MessageToolsStatus` | 工具按钮状态,`disabled` 禁用、`hidden` 从 DOM 移除 |
361
366
  | onAction | `MessageToolsProps['onAction']` | 工具回调;`copy`/`edit` 有内置行为,`cite`/`delete` 需外部处理 |
@@ -417,4 +422,5 @@ type MessageExtra = {
417
422
 
418
423
  - [MessageRender](/components/message/message-render) — user 角色由其实例化
419
424
  - [MessageTools](/components/feedback/message-tools) — 工具栏交互
425
+ - [MessageTime](/components/feedback/message-time) — 工具栏左侧的消息时间
420
426
  - [MessageContainer](/components/setup/message-container) — 列表与多选容器
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "2.0.0",
3
- "generatedAt": "2026-08-13T08:14:13.454Z",
3
+ "generatedAt": "2026-08-17T11:24:59.221Z",
4
4
  "domains": {
5
5
  "setup": {
6
6
  "label": "对话搭建",
@@ -83,6 +83,7 @@
83
83
  "label": "工具与反馈",
84
84
  "components": [
85
85
  "delete-tool",
86
+ "message-time",
86
87
  "message-tools",
87
88
  "scroll-btn",
88
89
  "tool-btn",
@@ -434,12 +435,35 @@
434
435
  "docFile": "docs/delete-tool.md",
435
436
  "domain": "feedback"
436
437
  },
438
+ {
439
+ "name": "MessageTime 消息时间",
440
+ "slug": "message-time",
441
+ "kind": "component",
442
+ "description": "按「今天 / 昨天 / 今年内 / 跨年」四档格式展示消息创建时间。",
443
+ "aiSummary": "按 createdAt 展示消息时间,四档格式:今天 `12:00`、昨天 `昨天 12:00`、今年内更早 `3-12 12:00`、非今年 `2025-3-12 12:00`; 时区取 props.timezone,未传时回退 injectGlobalConfig().timezone(由 ChatContainer 的 timezone prop 注入),都没有则用浏览器时区; 无值或非法时间不渲染任何 DOM。通常通过 MessageTools 的 prepend / append 插槽使用。 源码位置:src/components/message-tools/message-time/message-time.vue。",
444
+ "relatedComponents": [
445
+ {
446
+ "slug": "message-tools",
447
+ "relation": "通过 prepend / append 插槽嵌入工具栏"
448
+ },
449
+ {
450
+ "slug": "user-message",
451
+ "relation": "用户消息在工具栏左侧展示时间"
452
+ },
453
+ {
454
+ "slug": "message-container",
455
+ "relation": "AI 消息组在工具栏右侧展示本轮回答时间"
456
+ }
457
+ ],
458
+ "docFile": "docs/message-time.md",
459
+ "domain": "feedback"
460
+ },
437
461
  {
438
462
  "name": "MessageTools 消息工具栏",
439
463
  "slug": "message-tools",
440
464
  "kind": "component",
441
465
  "description": "消息悬浮工具栏,组合复制、删除、反馈等工具按钮。",
442
- "aiSummary": "消息悬浮工具栏,组合复制、删除、反馈等工具按钮。 源码位置:src/components/message-tools/message-tools.vue。",
466
+ "aiSummary": "消息悬浮工具栏,组合复制、删除、反馈等工具按钮;提供 prepend / append 两端插槽承载消息时间等附加内容。 源码位置:src/components/message-tools/message-tools.vue。",
443
467
  "relatedComponents": [
444
468
  {
445
469
  "slug": "tool-btn",
@@ -452,6 +476,10 @@
452
476
  {
453
477
  "slug": "delete-tool",
454
478
  "relation": "id 为 delete 时替换为带确认的删除按钮"
479
+ },
480
+ {
481
+ "slug": "message-time",
482
+ "relation": "通过 prepend / append 插槽嵌入消息时间"
455
483
  }
456
484
  ],
457
485
  "docFile": "docs/message-tools.md",
@@ -1287,6 +1315,10 @@
1287
1315
  "slug": "message-tools",
1288
1316
  "relation": "消息工具栏交互与状态由 MessageTools 体系承载"
1289
1317
  },
1318
+ {
1319
+ "slug": "message-time",
1320
+ "relation": "createdAt 经工具栏 prepend 插槽展示"
1321
+ },
1290
1322
  {
1291
1323
  "slug": "message-container",
1292
1324
  "relation": "嵌入列表时由 MessageContainer 管理分组与多选"
@@ -1731,12 +1763,16 @@
1731
1763
  "name": "useGlobalConfig",
1732
1764
  "slug": "use-global-config",
1733
1765
  "kind": "composable",
1734
- "description": "在聊天根容器与子组件之间通过 provide/inject 共享全局展示配置(字号主题档位、是否支持上传等)。",
1735
- "aiSummary": "useGlobalConfig 接收 GlobalConfig(含 size?: ComputedRef<AiSizeMode>、supportUpload: ComputedRef<boolean>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer 在 setup 中调用 useGlobalConfig 注入 size 与 supportUpload; 后代组件可通过 injectGlobalConfig 读取配置;字号主题主要通过根节点 data-ai-size 与 CSS 变量生效。",
1766
+ "description": "在聊天根容器与子组件之间通过 provide/inject 共享全局展示配置(字号主题档位、是否支持上传、消息时间时区等)。",
1767
+ "aiSummary": "useGlobalConfig 接收 GlobalConfig(含 size?: ComputedRef<AiSizeMode>、supportUpload: ComputedRef<boolean>、timezone?: ComputedRef<string | undefined>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer 在 setup 中调用 useGlobalConfig 注入 size、supportUploadtimezone; 后代组件可通过 injectGlobalConfig 读取配置;字号主题主要通过根节点 data-ai-size 与 CSS 变量生效。",
1736
1768
  "relatedComponents": [
1737
1769
  {
1738
1770
  "slug": "chat-container",
1739
1771
  "relation": "根容器调用 useGlobalConfig 注入 supportUpload"
1772
+ },
1773
+ {
1774
+ "slug": "message-time",
1775
+ "relation": "消息时间组件读取 timezone"
1740
1776
  }
1741
1777
  ],
1742
1778
  "docFile": "docs/use-global-config.md"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blueking/chat-x",
3
- "version": "0.0.49-beta.8",
3
+ "version": "0.0.49-beta.9",
4
4
  "description": "蓝鲸智云 AI Chat 组件库 —— 遵循 AG-UI,为 AI Agent 和人类开发者共同设计的对话 UI 组件库。",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -79,7 +79,7 @@
79
79
  "vitepress": "2.0.0-alpha.16",
80
80
  "vitest": "^4.0.18",
81
81
  "vue-tsc": "^3.1.4",
82
- "@blueking/chat-helper": "0.0.12-beta.19"
82
+ "@blueking/chat-helper": "0.0.12-beta.20"
83
83
  },
84
84
  "scripts": {
85
85
  "dev": "vite --config vite.config.ts",