@blueking/chat-x 0.0.51-beta.5 → 0.0.52-dev.1

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.
Files changed (198) hide show
  1. package/README.md +15 -8
  2. package/dist/ag-ui/types/contents.d.ts +2 -0
  3. package/dist/ag-ui/types/messages.d.ts +6 -1
  4. package/dist/common/constants.d.ts +2 -0
  5. package/dist/components/ai-buttons/add-menu-btn/add-menu-btn.vue.d.ts +24 -0
  6. package/dist/components/chat-content/collapsible-content/collapsible-content.vue.d.ts +28 -0
  7. package/dist/components/chat-content/file-content/upload-file-item.vue.d.ts +5 -2
  8. package/dist/components/chat-content/file-content/upload-image-item.vue.d.ts +1 -0
  9. package/dist/components/chat-content/flow-agent-content/use-flow-node-actions.d.ts +1 -1
  10. package/dist/components/chat-input/ai-slash-input/ai-slash-input.vue.d.ts +21 -10
  11. package/dist/components/chat-input/ai-slash-input/command.d.ts +6 -3
  12. package/dist/components/chat-input/ai-slash-input/constants.d.ts +2 -0
  13. package/dist/components/chat-input/ai-slash-input/use-menu-trigger.d.ts +17 -0
  14. package/dist/components/chat-input/build-default-placeholder.d.ts +9 -3
  15. package/dist/components/chat-input/chat-input.vue.d.ts +30 -18
  16. package/dist/components/chat-input/input-menu/constants.d.ts +60 -0
  17. package/dist/components/chat-input/input-menu/index.d.ts +4 -0
  18. package/dist/components/chat-input/input-menu/input-menu-option.vue.d.ts +14 -0
  19. package/dist/components/chat-input/input-menu/input-menu-panel.vue.d.ts +17 -0
  20. package/dist/components/chat-input/input-menu/use-input-menu.d.ts +22 -0
  21. package/dist/components/chat-input/model-selector/types.d.ts +3 -2
  22. package/dist/components/chat-message/message-container/message-container.vue.d.ts +1 -1
  23. package/dist/components/chat-message/user-message/user-message.vue.d.ts +1 -1
  24. package/dist/components/mention/create-mention-tippy.d.ts +27 -0
  25. package/dist/components/mention/index.d.ts +4 -0
  26. package/dist/components/{chat-input/ai-slash-input/ai-prompt-list/ai-prompt-list.vue.d.ts → mention/mention-popover.vue.d.ts} +3 -2
  27. package/dist/components/{chat-input/ai-slash-input/ai-skill-list/ai-skill-list.vue.d.ts → mention/mention-tag.vue.d.ts} +7 -3
  28. package/dist/components/{chat-input/ai-slash-input/ai-slash-menu/ai-slash-menu.vue.d.ts → mention/mention-text.vue.d.ts} +3 -3
  29. package/dist/components/resource-icon/index.d.ts +1 -0
  30. package/dist/components/resource-icon/resource-icon.vue.d.ts +11 -0
  31. package/dist/composables/index.d.ts +1 -0
  32. package/dist/composables/use-artifact-preview.d.ts +5 -2
  33. package/dist/composables/use-common.d.ts +0 -9
  34. package/dist/composables/use-global-config.d.ts +4 -0
  35. package/dist/composables/use-input-mention.d.ts +13 -0
  36. package/dist/composables/use-message-group.d.ts +1011 -72
  37. package/dist/icons/index.d.ts +1 -0
  38. package/dist/icons/input.d.ts +21 -0
  39. package/dist/icons/menu-item.d.ts +22 -0
  40. package/dist/index.css +1 -1
  41. package/dist/index.js +4953 -4429
  42. package/dist/index.js.map +1 -1
  43. package/dist/lang/lang.d.ts +13 -3
  44. package/dist/mcp/generated/docs/activity-message.md +3 -3
  45. package/dist/mcp/generated/docs/add-menu-btn.md +91 -0
  46. package/dist/mcp/generated/docs/ai-slash-input.md +72 -26
  47. package/dist/mcp/generated/docs/assistant-message.md +7 -1
  48. package/dist/mcp/generated/docs/chat-container.md +45 -6
  49. package/dist/mcp/generated/docs/chat-input.md +327 -483
  50. package/dist/mcp/generated/docs/collapsible-content.md +78 -0
  51. package/dist/mcp/generated/docs/constants.md +36 -3
  52. package/dist/mcp/generated/docs/execution-summary.md +1 -23
  53. package/dist/mcp/generated/docs/file-artifact-panel.md +24 -5
  54. package/dist/mcp/generated/docs/file-content.md +4 -0
  55. package/dist/mcp/generated/docs/file-upload-btn.md +15 -12
  56. package/dist/mcp/generated/docs/flow-agent-content.md +10 -12
  57. package/dist/mcp/generated/docs/input-menu-panel.md +166 -0
  58. package/dist/mcp/generated/docs/mention-tag.md +83 -0
  59. package/dist/mcp/generated/docs/mention-text.md +86 -0
  60. package/dist/mcp/generated/docs/message-container.md +1 -1
  61. package/dist/mcp/generated/docs/message-render.md +1 -1
  62. package/dist/mcp/generated/docs/message-tools.md +15 -4
  63. package/dist/mcp/generated/docs/messages.md +3 -0
  64. package/dist/mcp/generated/docs/model-selector.md +4 -2
  65. package/dist/mcp/generated/docs/overflow-tips.md +3 -3
  66. package/dist/mcp/generated/docs/resource-icon.md +102 -0
  67. package/dist/mcp/generated/docs/text-content.md +7 -3
  68. package/dist/mcp/generated/docs/theme.md +27 -35
  69. package/dist/mcp/generated/docs/use-artifact-preview.md +7 -3
  70. package/dist/mcp/generated/docs/use-command-selection.md +1 -1
  71. package/dist/mcp/generated/docs/use-container-scroll.md +2 -1
  72. package/dist/mcp/generated/docs/use-flow-node-actions.md +8 -15
  73. package/dist/mcp/generated/docs/use-global-config.md +11 -4
  74. package/dist/mcp/generated/docs/use-input-mention.md +119 -0
  75. package/dist/mcp/generated/docs/use-menu-keydown.md +15 -16
  76. package/dist/mcp/generated/docs/use-message-group.md +3 -6
  77. package/dist/mcp/generated/docs/user-message.md +39 -17
  78. package/dist/mcp/generated/index.json +233 -81
  79. package/dist/types/editor.d.ts +0 -29
  80. package/dist/types/index.d.ts +1 -0
  81. package/dist/types/input-menu.d.ts +46 -0
  82. package/dist/utils/artifact-tags.d.ts +36 -0
  83. package/dist/utils/collect-message-artifacts.d.ts +14 -0
  84. package/dist/utils/file.d.ts +3 -3
  85. package/dist/utils/index.d.ts +2 -1
  86. package/dist/utils/upload-file.d.ts +6 -1
  87. package/package.json +3 -2
  88. package/skills/blueking-chat-x/SKILL.md +143 -0
  89. package/skills/blueking-chat-x/references/_index.md +153 -0
  90. package/skills/blueking-chat-x/references/components/activity-layout.md +134 -0
  91. package/skills/blueking-chat-x/references/components/activity-message.md +486 -0
  92. package/skills/blueking-chat-x/references/components/add-menu-btn.md +88 -0
  93. package/skills/blueking-chat-x/references/components/ai-image.md +230 -0
  94. package/skills/blueking-chat-x/references/components/ai-loading.md +131 -0
  95. package/skills/blueking-chat-x/references/components/ai-selection.md +439 -0
  96. package/skills/blueking-chat-x/references/components/ai-slash-input.md +102 -0
  97. package/skills/blueking-chat-x/references/components/animation-text.md +202 -0
  98. package/skills/blueking-chat-x/references/components/assistant-message.md +504 -0
  99. package/skills/blueking-chat-x/references/components/chat-container.md +912 -0
  100. package/skills/blueking-chat-x/references/components/chat-input.md +614 -0
  101. package/skills/blueking-chat-x/references/components/cite-content.md +142 -0
  102. package/skills/blueking-chat-x/references/components/code-content.md +211 -0
  103. package/skills/blueking-chat-x/references/components/collapsible-content.md +76 -0
  104. package/skills/blueking-chat-x/references/components/common-error-content.md +73 -0
  105. package/skills/blueking-chat-x/references/components/content-render.md +233 -0
  106. package/skills/blueking-chat-x/references/components/delete-tool.md +191 -0
  107. package/skills/blueking-chat-x/references/components/desc-panel.md +162 -0
  108. package/skills/blueking-chat-x/references/components/detail-section.md +91 -0
  109. package/skills/blueking-chat-x/references/components/execution-summary.md +150 -0
  110. package/skills/blueking-chat-x/references/components/file-artifact-panel.md +307 -0
  111. package/skills/blueking-chat-x/references/components/file-content.md +340 -0
  112. package/skills/blueking-chat-x/references/components/file-icon.md +109 -0
  113. package/skills/blueking-chat-x/references/components/file-upload-btn.md +162 -0
  114. package/skills/blueking-chat-x/references/components/flow-agent-content.md +266 -0
  115. package/skills/blueking-chat-x/references/components/flow-agent-node-detail.md +236 -0
  116. package/skills/blueking-chat-x/references/components/highlight-keyword.md +146 -0
  117. package/skills/blueking-chat-x/references/components/image-content.md +182 -0
  118. package/skills/blueking-chat-x/references/components/image-preview-group.md +184 -0
  119. package/skills/blueking-chat-x/references/components/image-preview.md +226 -0
  120. package/skills/blueking-chat-x/references/components/info-message.md +144 -0
  121. package/skills/blueking-chat-x/references/components/input-attachment.md +49 -0
  122. package/skills/blueking-chat-x/references/components/input-info-alert.md +42 -0
  123. package/skills/blueking-chat-x/references/components/input-menu-panel.md +162 -0
  124. package/skills/blueking-chat-x/references/components/interrupt-message.md +212 -0
  125. package/skills/blueking-chat-x/references/components/key-value-content.md +128 -0
  126. package/skills/blueking-chat-x/references/components/knowledge-rag-content.md +122 -0
  127. package/skills/blueking-chat-x/references/components/latex-content.md +200 -0
  128. package/skills/blueking-chat-x/references/components/loading-message.md +192 -0
  129. package/skills/blueking-chat-x/references/components/markdown-content.md +232 -0
  130. package/skills/blueking-chat-x/references/components/mention-tag.md +79 -0
  131. package/skills/blueking-chat-x/references/components/mention-text.md +83 -0
  132. package/skills/blueking-chat-x/references/components/mermaid-content.md +189 -0
  133. package/skills/blueking-chat-x/references/components/message-container.md +645 -0
  134. package/skills/blueking-chat-x/references/components/message-loading.md +118 -0
  135. package/skills/blueking-chat-x/references/components/message-render.md +327 -0
  136. package/skills/blueking-chat-x/references/components/message-time.md +177 -0
  137. package/skills/blueking-chat-x/references/components/message-tools.md +427 -0
  138. package/skills/blueking-chat-x/references/components/model-selector.md +157 -0
  139. package/skills/blueking-chat-x/references/components/preview-toolbar.md +42 -0
  140. package/skills/blueking-chat-x/references/components/questions-container.md +85 -0
  141. package/skills/blueking-chat-x/references/components/reasoning-message.md +232 -0
  142. package/skills/blueking-chat-x/references/components/reference-content.md +135 -0
  143. package/skills/blueking-chat-x/references/components/reference-doc-content.md +109 -0
  144. package/skills/blueking-chat-x/references/components/resource-icon.md +98 -0
  145. package/skills/blueking-chat-x/references/components/scroll-btn.md +159 -0
  146. package/skills/blueking-chat-x/references/components/selection-footer.md +78 -0
  147. package/skills/blueking-chat-x/references/components/selection-question.md +88 -0
  148. package/skills/blueking-chat-x/references/components/shortcut-btn.md +204 -0
  149. package/skills/blueking-chat-x/references/components/shortcut-btns.md +266 -0
  150. package/skills/blueking-chat-x/references/components/shortcut-render.md +424 -0
  151. package/skills/blueking-chat-x/references/components/simple-table.md +101 -0
  152. package/skills/blueking-chat-x/references/components/text-content.md +80 -0
  153. package/skills/blueking-chat-x/references/components/tool-approval-card.md +183 -0
  154. package/skills/blueking-chat-x/references/components/tool-btn.md +317 -0
  155. package/skills/blueking-chat-x/references/components/tool-message.md +235 -0
  156. package/skills/blueking-chat-x/references/components/toolcall-render.md +348 -0
  157. package/skills/blueking-chat-x/references/components/user-feedback.md +233 -0
  158. package/skills/blueking-chat-x/references/components/user-message.md +444 -0
  159. package/skills/blueking-chat-x/references/components/user-question-answered-card.md +104 -0
  160. package/skills/blueking-chat-x/references/components/user-question-card.md +231 -0
  161. package/skills/blueking-chat-x/references/components/user-question-choice.md +105 -0
  162. package/skills/blueking-chat-x/references/components/user-question-option.md +42 -0
  163. package/skills/blueking-chat-x/references/components/vnode-renderer.md +122 -0
  164. package/skills/blueking-chat-x/references/composables/use-animation-text.md +196 -0
  165. package/skills/blueking-chat-x/references/composables/use-artifact-preview.md +235 -0
  166. package/skills/blueking-chat-x/references/composables/use-clipboard.md +203 -0
  167. package/skills/blueking-chat-x/references/composables/use-command-selection.md +150 -0
  168. package/skills/blueking-chat-x/references/composables/use-container-scroll.md +57 -0
  169. package/skills/blueking-chat-x/references/composables/use-custom-tab.md +158 -0
  170. package/skills/blueking-chat-x/references/composables/use-flow-node-actions.md +164 -0
  171. package/skills/blueking-chat-x/references/composables/use-full-screen.md +112 -0
  172. package/skills/blueking-chat-x/references/composables/use-global-config.md +155 -0
  173. package/skills/blueking-chat-x/references/composables/use-input-mention.md +115 -0
  174. package/skills/blueking-chat-x/references/composables/use-menu-keydown.md +161 -0
  175. package/skills/blueking-chat-x/references/composables/use-message-group.md +244 -0
  176. package/skills/blueking-chat-x/references/composables/use-observer-visible-list.md +188 -0
  177. package/skills/blueking-chat-x/references/composables/use-parent-scrolling.md +46 -0
  178. package/skills/blueking-chat-x/references/directives/index.md +61 -0
  179. package/skills/blueking-chat-x/references/directives/overflow-tips.md +205 -0
  180. package/skills/blueking-chat-x/references/icons/index.md +185 -0
  181. package/skills/blueking-chat-x/references/plugins/index.md +56 -0
  182. package/skills/blueking-chat-x/references/plugins/markdown-container.md +55 -0
  183. package/skills/blueking-chat-x/references/plugins/markdown-latex.md +205 -0
  184. package/skills/blueking-chat-x/references/plugins/markdown-mermaid.md +247 -0
  185. package/skills/blueking-chat-x/references/theme/theme.md +423 -0
  186. package/skills/blueking-chat-x/references/types/constants.md +340 -0
  187. package/skills/blueking-chat-x/references/types/index.md +120 -0
  188. package/skills/blueking-chat-x/references/types/interrupt.md +379 -0
  189. package/skills/blueking-chat-x/references/types/messages.md +556 -0
  190. package/skills/blueking-chat-x/references/types/schema.md +91 -0
  191. package/skills/blueking-chat-x/references/utils/index.md +196 -0
  192. package/skills/blueking-chat-x/scripts/generate-references.mjs +536 -0
  193. package/dist/components/chat-input/ai-slash-editor/ai-slash-editor.vue.d.ts +0 -28
  194. package/dist/components/chat-input/ai-slash-editor/theme.d.ts +0 -24
  195. package/dist/mcp/generated/docs/ai-prompt-list.md +0 -45
  196. package/dist/mcp/generated/docs/ai-skill-list.md +0 -75
  197. package/dist/mcp/generated/docs/ai-slash-editor.md +0 -43
  198. package/dist/mcp/generated/docs/ai-slash-menu.md +0 -42
@@ -1,7 +1,7 @@
1
1
  <!-- AI SUMMARY -->
2
2
  ## 快速了解
3
3
 
4
- useGlobalConfig 接收 GlobalConfig(含 size?: ComputedRef<AiSizeMode>、supportUpload: ComputedRef<boolean>、timezone?: ComputedRef<string | undefined>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer 在 setup 中调用 useGlobalConfig 注入 size、supportUpload 与 timezone; 后代组件可通过 injectGlobalConfig 读取配置;字号主题主要通过根节点 data-ai-size 与 CSS 变量生效。
4
+ useGlobalConfig 接收 GlobalConfig(含 size?: ComputedRef<AiSizeMode>、supportUpload: ComputedRef<boolean>、timezone?: ComputedRef<string | undefined>、menuSources?: ComputedRef<IInputMenuItem[]>),以 GLOBAL_CONFIG_TOKEN provide 给后代; injectGlobalConfig 在子组件中取出配置,无 Provider 时返回 undefined。ChatContainer 在 setup 中调用 useGlobalConfig 注入 size、supportUpload、timezonemenuSources; 后代组件可通过 injectGlobalConfig 读取配置;字号主题主要通过根节点 data-ai-size 与 CSS 变量生效。
5
5
 
6
6
  ### 关联组件
7
7
  - **chat-container** — 根容器调用 useGlobalConfig 注入 supportUpload
@@ -14,7 +14,7 @@ useGlobalConfig 接收 GlobalConfig(含 size?: ComputedRef<AiSizeMode>、suppo
14
14
 
15
15
  > **分类**:composable
16
16
 
17
- 在聊天容器根组件与子组件之间通过 Vue `provide` / `inject` 共享**全局展示相关配置**(当前包括字号主题档位 `size`、是否支持上传 `supportUpload`、消息时间时区 `timezone`)。与 Teleport 插槽 ID 无关。
17
+ 在聊天容器根组件与子组件之间通过 Vue `provide` / `inject` 共享**全局展示相关配置**(当前包括字号主题档位 `size`、是否支持上传 `supportUpload`、消息时间时区 `timezone`、输入框菜单数据源 `menuSources`)。与 Teleport 插槽 ID 无关。
18
18
 
19
19
  > 字号主题主要通过 `ChatContainer` 根节点的 `data-ai-size` 与 CSS 变量(`--ai-font-size` 等)生效;`GlobalConfig.size` 供后代在逻辑层读取当前档位,样式层无需逐组件传参。
20
20
 
@@ -27,8 +27,9 @@ ChatContainer(根)
27
27
  │ size: computed(() => props.size ?? 'small'),
28
28
  │ supportUpload: computed(() => props.supportUpload ?? false),
29
29
  │ timezone: computed(() => props.timezone),
30
+ │ menuSources: resolvedMenuSources,
30
31
  │ })
31
- │ └── provide(GLOBAL_CONFIG_TOKEN, { size, supportUpload, timezone })
32
+ │ └── provide(GLOBAL_CONFIG_TOKEN, { size, supportUpload, timezone, menuSources })
32
33
 
33
34
  └── MessageContainer → … → UserMessage / MessageTime 等
34
35
 
@@ -94,12 +95,15 @@ export type GlobalConfig = {
94
95
  size?: ComputedRef<AiSizeMode>;
95
96
  supportUpload: ComputedRef<boolean>;
96
97
  timezone?: ComputedRef<string | undefined>;
98
+ /** 输入框菜单数据源;消息编辑态的内嵌输入框据此渲染 @ / \ 与 + 号菜单 */
99
+ menuSources?: ComputedRef<IInputMenuItem[]>;
97
100
  };
98
101
 
99
102
  export function useGlobalConfig(options: GlobalConfig): {
100
103
  size?: ComputedRef<AiSizeMode>;
101
104
  supportUpload: ComputedRef<boolean>;
102
105
  timezone?: ComputedRef<string | undefined>;
106
+ menuSources?: ComputedRef<IInputMenuItem[]>;
103
107
  };
104
108
 
105
109
  export function injectGlobalConfig(): GlobalConfig | undefined;
@@ -117,7 +121,9 @@ export function injectGlobalConfig(): GlobalConfig | undefined;
117
121
  | --------------- | ------------------------------------------------------------------------ |
118
122
  | `size` | 可选。字号主题档位 `normal`(14px)/ `small`(12px),与 `ChatContainer.size` 对齐 |
119
123
  | `supportUpload` | 是否支持上传,与根容器 `ChatContainer` 的 `supportUpload` 等展示策略对齐 |
124
+ | `menuSources` | 可选。输入框菜单数据源,供消息编辑态的内嵌 `ChatInput` 使用 |
120
125
  | `timezone` | 可选。消息时间展示所用的 IANA 时区名,与 `ChatContainer.timezone` 对齐;未配置时 `MessageTime` 按浏览器时区展示 |
126
+ | `menuSources` | 可选。输入框菜单数据源,与 `ChatInput.menuSources` 同源(`ChatContainer` 传入的是补齐会话产物后的结果);[UserMessage](../components/message/user-message) 编辑态据此渲染菜单,未配置时编辑态无菜单 |
121
127
 
122
128
  ### `useGlobalConfig(options)`
123
129
 
@@ -145,6 +151,7 @@ export function injectGlobalConfig(): GlobalConfig | undefined;
145
151
 
146
152
  ## 关联组件
147
153
 
148
- - [ChatContainer](../components/setup/chat-container) — 调用 `useGlobalConfig` 注入 `size`、`supportUpload` 与 `timezone`
154
+ - [ChatContainer](../components/setup/chat-container) — 调用 `useGlobalConfig` 注入 `size`、`supportUpload`、`timezone` 与 `menuSources`
155
+ - [UserMessage](../components/message/user-message) — 编辑态读取 `supportUpload` 与 `menuSources`
149
156
  - [MessageTime](../components/feedback/message-time) — 读取 `timezone` 展示消息时间
150
157
  - [主题配置](../theme/theme) — `data-ai-size` 与 CSS 变量说明
@@ -0,0 +1,119 @@
1
+ <!-- AI SUMMARY -->
2
+ ## 快速了解
3
+
4
+ useInputMentionProvider 由持有输入框的容器(ChatContainer)提供 insertMention, useInputMentionConsumer 在任意后代取出;无 Provider(只读 / 分享态)时返回 undefined,调用方据此隐藏「引用」入口。 消息区文件卡片与侧栏产物面板即用它把文件以标签形式追加进输入框。 源码位置:src/composables/use-input-mention.ts。
5
+
6
+ ### 关联组件
7
+ - **chat-container** — 根容器提供 insertMention,内部转发给 ChatInput 实例
8
+ - **chat-input** — 实际执行插入的组件,expose insertMention
9
+ - **file-artifact-panel** — 侧栏产物面板据此展示「引用」按钮
10
+ - **assistant-message** — 消息内文件卡片据此展示「引用」按钮
11
+
12
+ ---
13
+ <!-- FULL DOC -->
14
+
15
+ # useInputMention 资源插入输入框
16
+
17
+ > **分类**:composable
18
+
19
+ 把「把某个资源 `@` 进输入框」这件事从组件层级里解耦出来:消息区的文件卡片、侧栏的产物面板可能嵌套得很深,逐层透传输入框实例既啰嗦又容易漏。
20
+
21
+ ## 工作原理
22
+
23
+ ```
24
+ ChatContainer(根)
25
+ ├── useInputMentionProvider({
26
+ │ insertMention: item => chatInputRef.value?.insertMention?.(item),
27
+ │ })
28
+ │ └── provide(INPUT_MENTION_TOKEN, context)
29
+
30
+ ├── ChatInput(ref="chatInputRef")
31
+ │ └── expose insertMention → AiSlashInput.appendMention(追加到文档末尾)
32
+
33
+ └── MessageContainer → … → ArtifactFileCard / FileArtifactPanel
34
+ └── useInputMentionConsumer() → InputMentionContext | undefined
35
+ └── 有值才渲染「引用」按钮
36
+ ```
37
+
38
+ 无 Provider 时 `useInputMentionConsumer()` 返回 `undefined`,因此只读 / 分享态(没有输入框)自动不显示引用入口,不需要额外开关。
39
+
40
+ ## 消费方用法
41
+
42
+ ```vue
43
+ <template>
44
+ <span
45
+ v-if="inputMention"
46
+ v-tippy="{ content: t('引用') }"
47
+ @click.stop="handleCite"
48
+ >
49
+ <CiteIcon />
50
+ </span>
51
+ </template>
52
+
53
+ <script setup lang="ts">
54
+ import { toArtifactMenuItem, useInputMentionConsumer } from '@blueking/chat-x';
55
+
56
+ const props = defineProps<{ file: AIFileInfo }>();
57
+
58
+ // 无输入框上下文时为 undefined,据此隐藏入口
59
+ const inputMention = useInputMentionConsumer();
60
+
61
+ const handleCite = () => {
62
+ inputMention?.insertMention(toArtifactMenuItem(props.file));
63
+ };
64
+ </script>
65
+ ```
66
+
67
+ ::: warning id 必须与菜单一致
68
+ 把文件转成菜单条目时统一走 [`toArtifactMenuItem`](/utils/#会话产物收集):`id` 不一致会导致 `@` 菜单的去重与已插入标签的匹配同时失效(同一个文件既能重复插入、又无法从候选中剔除)。
69
+ :::
70
+
71
+ ## 自建容器用法
72
+
73
+ 不使用 [ChatContainer](/components/setup/chat-container)、自行组合 `MessageContainer` + `ChatInput` 时,需要自己提供上下文:
74
+
75
+ ```vue
76
+ <script setup lang="ts">
77
+ import { useTemplateRef } from 'vue';
78
+ import { ChatInput, useInputMentionProvider } from '@blueking/chat-x';
79
+
80
+ const chatInputRef = useTemplateRef<InstanceType<typeof ChatInput>>('chatInputRef');
81
+
82
+ useInputMentionProvider({
83
+ insertMention: item => chatInputRef.value?.insertMention?.(item),
84
+ });
85
+ </script>
86
+ ```
87
+
88
+ ## API
89
+
90
+ ```typescript
91
+ export const INPUT_MENTION_TOKEN: unique symbol;
92
+
93
+ export type InputMentionContext = {
94
+ /** 把一个条目以标签形式追加到输入框,效果等同于用户通过 `@` 菜单选中它 */
95
+ insertMention: (item: IInputMenuItem) => void;
96
+ };
97
+
98
+ export function useInputMentionProvider(context: InputMentionContext): InputMentionContext;
99
+
100
+ export function useInputMentionConsumer(): InputMentionContext | undefined;
101
+ ```
102
+
103
+ | 函数 | 说明 |
104
+ | --------------------------- | ---------------------------------------------------------------------- |
105
+ | `useInputMentionProvider` | 在祖先 `setup` 中调用,`provide` 上下文并原样返回,便于就地复用 |
106
+ | `useInputMentionConsumer` | 在任意后代 `setup` 中调用,无 Provider 时返回 `undefined` |
107
+
108
+ ## 注意事项
109
+
110
+ 1. **插入位置不依赖光标**:底层走 `AiSlashInput.appendMention`,标签追加到文档末尾——外部调用时编辑器通常没有焦点,依赖光标会插错位置。
111
+ 2. **插入的资源可能不在 `menuSources` 里**:`ChatInput` 的 `update:modelValue` 第二参数只回传能在 `menuSources` 中反查到的条目。`ChatContainer` 会自动收集消息里的会话产物,所以经容器使用时产物标签能被反查到。
112
+ 3. **必须在 `setup` 中调用**:与 Vue `provide` / `inject` 的要求一致。
113
+
114
+ ## 关联组件
115
+
116
+ - [ChatContainer](../components/setup/chat-container) — 默认的 Provider
117
+ - [ChatInput](../components/input/chat-input) — `insertMention` 的实际执行者
118
+ - [FileArtifactPanel](../components/message/file-artifact-panel) — 侧栏产物面板的引用入口
119
+ - [Utils 工具函数](../utils/) — `collectMessageArtifacts` / `toArtifactMenuItem`
@@ -1,10 +1,11 @@
1
1
  <!-- AI SUMMARY -->
2
2
  ## 快速了解
3
3
 
4
- useMenuKeydown 接收 items、menuRef、onSelect,在 window 捕获阶段监听 keydown;菜单不可见(offsetParent 为空)或列表为空时不响应。 维护 activeIndex,处理 ArrowUp/ArrowDown 循环与 Enter 选中,并 scrollIntoView 当前 .is-active 项。 AiSlashMenu、AiPromptList(ChatInput 子模块)内部使用。
4
+ useMenuKeydown 接收 items、menuRef、onSelect,在 window 捕获阶段监听 keydown;菜单不可见(offsetParent 为空)或列表为空时不响应。 维护 activeIndex,处理 ArrowUp/ArrowDown 循环与 Enter 选中,并 scrollIntoView 当前 .is-active 项。 InputMenuPanel(输入框统一菜单)与 ModelSelectorPanel(模型下拉)内部使用。
5
5
 
6
6
  ### 关联组件
7
- - **chat-input** — AiSlashMenu / AiPromptList 键盘导航
7
+ - **input-menu-panel** — 输入框菜单的键盘导航
8
+ - **model-selector** — 模型下拉的键盘导航
8
9
 
9
10
  ---
10
11
  <!-- FULL DOC -->
@@ -94,25 +95,23 @@ scrollToActive():nextTick → menuRef.querySelector('.is-active')?.scrollIntoV
94
95
  </style>
95
96
  ```
96
97
 
97
- ## 在 AiSlashInput 内部的实际用法
98
+ ## 库内部的实际用法
98
99
 
99
- `useMenuKeydown` 被 `AiSlashMenu`(`@` 资源菜单)和 `AiPromptList`(`/` 提示词列表)内部使用:
100
+ `useMenuKeydown` 被 [InputMenuPanel](/components/input/input-menu-panel)(输入框统一菜单)与 [ModelSelector](/components/input/model-selector) 的下拉面板内部使用:
100
101
 
101
102
  ```typescript
102
- // AiPromptList
103
- const promptListRef = useTemplateRef<HTMLElement>('promptListRef');
104
- const { activeIndex } = useMenuKeydown<string>({
105
- items: computed(() => props.prompts), // ComputedRef 也可传入
106
- onSelect: props.onSelect,
107
- menuRef: promptListRef,
103
+ // InputMenuPanel 中:items 为跨分组扁平化后的可选条目
104
+ const panelRef = useTemplateRef<HTMLElement>('panelRef');
105
+ const flatItems = computed(() => props.flatItems);
106
+ const { activeIndex } = useMenuKeydown<IInputMenuItem>({
107
+ items: flatItems, // ComputedRef 也可传入
108
+ onSelect: item => emit('select', item),
109
+ menuRef: panelRef,
108
110
  });
109
111
 
110
- // AiSlashMenu 中
111
- const menuRef = useTemplateRef<HTMLElement>('menuRef');
112
- const { activeIndex } = useMenuKeydown<IAiSlashMenuItem>({
113
- items: sortedResourceList,
114
- onSelect: props.onSelect,
115
- menuRef,
112
+ // 结果集变化后旧的高亮下标已无意义,回到首项
113
+ watch(flatItems, () => {
114
+ activeIndex.value = 0;
116
115
  });
117
116
  ```
118
117
 
@@ -122,17 +122,14 @@ const isExecutionMessage = (m: Message): boolean => {
122
122
 
123
123
  ## sessionArtifacts 会话级文件产物
124
124
 
125
- `sessionArtifacts` 拍平当前会话所有 `AssistantMessage.property.artifacts`,供 `ChatContainer` 侧栏「文件产物」Tab 聚合预览。以 **`outputId`** 为会话内唯一键去重(同 `outputId` 视为同一文件),保留最后一次出现的文件信息,列表顺序与「最后一次出现」的相对顺序一致:
125
+ `sessionArtifacts` 收集当前会话具有 `outputId` 的助手产物与用户上传附件,供 `ChatContainer` 侧栏「文件产物」Tab 聚合预览。以 **`outputId`** 为会话内唯一键去重(同 `outputId` 视为同一文件),保留最后一次出现的文件信息,列表顺序与「最后一次出现」的相对顺序一致:
126
126
 
127
127
  ```typescript
128
128
  const sessionArtifacts = computed(() => {
129
129
  // delete + set:同 key 覆盖内容,并把该项挪到 Map 末尾,保证「最后出现」顺序
130
130
  const byOutputId = new Map();
131
131
  for (const message of messages.value) {
132
- if (message.role !== MessageRole.Assistant) continue;
133
- const artifacts = message.property?.artifacts;
134
- if (!artifacts?.length) continue;
135
- for (const file of artifacts) {
132
+ for (const file of getMessageArtifacts(message)) {
136
133
  if (byOutputId.has(file.outputId)) {
137
134
  byOutputId.delete(file.outputId);
138
135
  }
@@ -217,7 +214,7 @@ const {
217
214
  | ---------------- | ----------------------------- | --------------------------------------------------------------------------- |
218
215
  | messageGroups | `Ref<MessageGroup[]>` | 完整消息分组列表 |
219
216
  | executionGroups | `ComputedRef<MessageGroup[]>` | 仅包含执行类消息的分组(工具调用 + FlowAgent),自动提取 `userMessageTitle` |
220
- | sessionArtifacts | `ComputedRef<SessionArtifact[]>` | 拍平会话所有 AssistantMessage 文件产物,按 `outputId` 去重(保留最后一次) |
217
+ | sessionArtifacts | `ComputedRef<SessionArtifact[]>` | 收集助手产物与具有 `outputId` 的上传附件,按 `outputId` 去重(保留最后一次) |
221
218
  | pendingApprovalCount | `ComputedRef<number>` | 当前消息中待审批 AI Dev 审批中断的数量 |
222
219
  | pendingApprovalTipText | `ComputedRef<string>` | 待审批阻塞发送提示文案;无待审批时为空字符串 |
223
220
  | isShareMode | `ShallowRef<boolean>` | 是否处于分享模式 |
@@ -1,9 +1,11 @@
1
1
  <!-- AI SUMMARY -->
2
2
  ## 快速了解
3
3
 
4
- 渲染用户消息:纯文本(非 Markdown)、键值引用、二进制附件与编辑态 ChatInput / ShortcutRender; 工具栏含 copy / cite / edit / delete。源码位置:src/components/chat-message/user-message/user-message.vue。
4
+ 渲染用户消息:纯文本(非 Markdown)、键值引用、二进制附件与编辑态 ChatInput / ShortcutRender; 正文经 CollapsibleContent 限高 200px,property.docSchema 含标签时改用 MentionText 还原资源标签; 工具栏含 copy / edit / delete。源码位置:src/components/chat-message/user-message/user-message.vue。
5
5
 
6
6
  ### 关联组件
7
+ - **mention-text** — 文档含标签时用它还原已选资源
8
+ - **collapsible-content** — 正文超过 200px 时折叠
7
9
  - **message-render** — 由 MessageRender 在 role 为 user 时创建
8
10
  - **message-tools** — 消息工具栏交互与状态由 MessageTools 体系承载
9
11
  - **message-time** — createdAt 经工具栏 prepend 插槽展示
@@ -41,13 +43,15 @@
41
43
  │ .ai-user-message-binary-files → FileContent(readonly=true,每个文件独立渲染)
42
44
 
43
45
  ├── .ai-user-message-content(气泡:bg #e1ecff,padding 8×12,border-radius 4px)
44
- v-if: cite 为数组 → KeyValueContenttitle + key/value 列表)
45
- v-else-if: content TextContent × N(textParts 中每个文本片段一个实例)
46
+ └── CollapsibleContentmaxHeight = CONST_USER_MESSAGE_MAX_HEIGHT,200px)
47
+ v-if: cite 为数组 KeyValueContent(title + key/value 列表)
48
+ │ v-else-if: 文档含标签 → MentionText(还原 @ 选中的资源)
49
+ │ v-else-if: content → TextContent × N(textParts 中每个文本片段一个实例)
46
50
 
47
51
  └── MessageTools(.ai-user-message-tools)
48
52
  v-if: messageToolsStatus !== 'hidden'
49
53
  visibility: hidden(默认)→ visible(:hover 时)
50
- tools: [copy, cite, edit, delete],updateTools: []
54
+ tools: [copy, edit, delete],updateTools: []
51
55
  #prepend slot → MessageTime(createdAt,工具图标左侧)
52
56
  ```
53
57
 
@@ -64,13 +68,26 @@
64
68
  │ @submit(formModel) → onShortcutConfirm(formModel) + isEdit=false
65
69
 
66
70
  └── ChatInput(v-else,带自定义 #send-icon slot)
67
- v-model: editContent(取 textParts[0],即第一个文本片段)
71
+ v-model: editContent(有富文本文档时用文档回填,否则取 textParts[0]
68
72
  defaultUploadFiles: binaryFiles
73
+ menuSources: injectGlobalConfig().menuSources
69
74
  #send-icon slot → .user-edit-footer
70
75
  Button "取消" → isEdit=false
71
76
  Button primary "发送" → chatInputRef.triggerSendMessage() + isEdit=false
72
77
  ```
73
78
 
79
+ ## 资源标签回显与正文折叠
80
+
81
+ **标签回显**:`property.docSchema` 是发送时输入框的富文本文档。**只有文档里真的含标签节点时**才走 [MentionText](/components/rendering/mention-text) 结构化渲染,纯文本文档仍走 `TextContent`——历史消息与第三方消息的表现因此保持不变。`content` 始终是纯文本,后端契约不变。
82
+
83
+ **附件标签不重复展示**:`ChatInput` 发送时会把待发送附件补成 `artifact` 标签写进文档,本组件在渲染与编辑回填前会剥掉 `value` 命中当前附件的那些标签(`outputId` 与 `id` 都参与匹配,历史消息经 chat-helper 转换后只剩 `id`),同一文件只由 `FileContent` 卡片承载。整行标签被剥掉后不留空行,用户手输的空行照常保留;`@` 选中的其它资源、以及没有附件承载的 `artifact` 标签都照常回显。
84
+
85
+ 编辑态同样以 `docSchema` 回填,否则改完这条消息已选资源会退化成纯文本;因此业务侧在 `onInputConfirm` 里要把新的 `docSchema` 一起写回。
86
+
87
+ **正文折叠**:正文外层套 [CollapsibleContent](/components/rendering/collapsible-content),超过 `CONST_USER_MESSAGE_MAX_HEIGHT`(200px)时折叠并展示「显示更多 / 收起」。
88
+
89
+ **编辑态自动聚焦**:点击 `edit` 后编辑态输入框才开始渲染,组件在 `nextTick` 后调用 `focus()`,光标落到已有内容末尾。
90
+
74
91
  ## 基础用法
75
92
 
76
93
  `content` 为字符串时,通过 `TextContent` 以**纯文本**插值渲染(`{{ content }}`),**不**走 Markdown。
@@ -95,13 +112,13 @@
95
112
  };
96
113
 
97
114
  const handleAction = async (tool: IToolBtn) => {
98
- // copy / edit 有内置行为;cite / delete 需业务侧处理
115
+ // copy / edit 有内置行为;delete 需业务侧处理
99
116
  console.log('工具操作:', tool.id);
100
117
  };
101
118
  </script>
102
119
  ```
103
120
 
104
- > **工具栏**:悬停时显示「复制」「引用」「编辑」「删除」(CSS `visibility`,始终占位)。
121
+ > **工具栏**:悬停时显示「复制」「编辑」「删除」(CSS `visibility`,始终占位)。
105
122
 
106
123
  ## 多媒体消息
107
124
 
@@ -252,8 +269,10 @@
252
269
  **`editContent` 的初始化逻辑**(仅文本部分,二进制文件通过 `defaultUploadFiles` 恢复):
253
270
 
254
271
  ```
255
- textParts 有值 → editContent = textParts[0](取第一个文本片段)
256
- binaryFiles 有值 → 进入编辑模式(editContent 可为空)
272
+ 文档含标签 → editContent = property.docSchema(保留已选资源)
273
+ 否则 textParts 有值 → editContent = textParts[0](取第一个文本片段)
274
+ binaryFiles 有值 → 进入编辑模式(editContent 可为空)
275
+ 进入编辑态后 → nextTick 后自动 focus,光标落在内容末尾
257
276
  ```
258
277
 
259
278
  `textParts` 由 `content` 统一计算:`string` 转为单元素数组,`InputContent[]` 则过滤出 `type: 'text'` 且非空的项并映射为 `string[]`。
@@ -288,7 +307,7 @@ binaryFiles 有值 → 进入编辑模式(editContent 可为空)
288
307
 
289
308
  const handleAction = async (tool: IToolBtn) => {
290
309
  // edit → 组件内切编辑态;copy → 组件内复制
291
- // cite / delete → 无内置行为,业务侧处理(如删除会话消息)
310
+ // delete → 无内置行为,业务侧处理(如删除会话消息)
292
311
  console.log('工具:', tool.id);
293
312
  };
294
313
 
@@ -311,10 +330,11 @@ binaryFiles 有值 → 进入编辑模式(editContent 可为空)
311
330
  | 工具 ID | 名称 | 内置行为 |
312
331
  | -------- | ---- | -------------------------------------------- |
313
332
  | `copy` | 复制 | 字符串直接复制;数组 `JSON.stringify` 后复制 |
314
- | `cite` | 引用 | 无内置行为,需通过 `onAction` 外部处理 |
315
- | `edit` | 编辑 | 切换 `isEdit=true`,进入编辑模式 |
333
+ | `edit` | 编辑 | 切换 `isEdit=true`,进入编辑模式并自动聚焦 |
316
334
  | `delete` | 删除 | 无内置行为,需通过 `onAction` 外部处理 |
317
335
 
336
+ > `cite`(引用)已从内置列表移除,后续不再支持;需要类似能力时通过 `messageTools` 自行追加按钮并在 `onAction` 中处理。
337
+
318
338
  可通过 `messageTools` 按 id 覆盖/追加,`{ id: 'edit', hidden: true }` 可隐藏内置项。
319
339
 
320
340
  ```vue
@@ -329,9 +349,9 @@ binaryFiles 有值 → 进入编辑模式(editContent 可为空)
329
349
  />
330
350
  ```
331
351
 
332
- ## supportUpload 透传
352
+ ## 全局配置透传
333
353
 
334
- 编辑态 `ChatInput` 的上传能力来自 `injectGlobalConfig().supportUpload`(通常由 `ChatContainer` 的 `supportUpload` prop 注册)。自定义 `#message` 插槽时须把同一配置链路保留,否则编辑态会与主输入区不一致。
354
+ 编辑态 `ChatInput` 的上传能力与菜单数据源都来自 `injectGlobalConfig()`——`supportUpload` 与 `menuSources`(通常由 `ChatContainer` 注册)。自定义 `#message` 插槽时须把同一配置链路保留,否则编辑态会与主输入区不一致(菜单为空、无法上传)。
335
355
 
336
356
  ```vue
337
357
  <template>
@@ -363,10 +383,10 @@ binaryFiles 有值 → 进入编辑模式(editContent 可为空)
363
383
  | ------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------- |
364
384
  | content | `string \| InputContent[]` | 消息内容,字符串或含 text/binary 的数组 |
365
385
  | createdAt | `number \| string` | 消息创建时间,经 `MessageTools` 的 `#prepend` 插槽交给 `MessageTime` 渲染在工具图标左侧;无值时不展示 |
366
- | property | `{ extra?: MessageExtra; artifacts?: AIFileInfo[] }` | 附加属性;本组件消费 `extra.cite` / `shortcut` / `context` |
386
+ | property | `{ docSchema?: TagSchema; extra?: MessageExtra; artifacts?: AIFileInfo[] }` | 附加属性;本组件消费 `docSchema` 与 `extra.cite` / `extra.shortcut` / `extra.context` |
367
387
  | messageTools | `IToolBtn[]` | 自定义用户消息工具组;按 id 与 `CONST_USER_MESSAGE_TOOLS` 合并,`{ id, hidden: true }` 可隐藏 |
368
388
  | messageToolsStatus | `MessageToolsStatus` | 工具按钮状态,`disabled` 禁用、`hidden` 从 DOM 移除 |
369
- | onAction | `MessageToolsProps['onAction']` | 工具回调;`copy`/`edit` 有内置行为,`cite`/`delete` 需外部处理 |
389
+ | onAction | `MessageToolsProps['onAction']` | 工具回调;`copy`/`edit` 有内置行为,`delete` 需外部处理 |
370
390
  | onInputConfirm | `(content: UserMessage['content'], docSchema: TagSchema) => Promise<void>` | 普通消息编辑确认回调 |
371
391
  | onShortcutConfirm | `(formModel: Record<string, unknown>) => Promise<void>` | 快捷指令消息编辑确认回调 |
372
392
  | tippyOptions | `Partial<Omit<TippyOptions, 'getReferenceClientRect' \| 'triggerTarget'>>` | 自定义工具栏 Tippy 配置,透传给内部 `MessageTools` |
@@ -377,7 +397,7 @@ binaryFiles 有值 → 进入编辑模式(editContent 可为空)
377
397
 
378
398
  ### 全局配置依赖
379
399
 
380
- 编辑态 `ChatInput` 通过 `injectGlobalConfig()` 读取 `supportUpload`。祖先需已 `useGlobalConfig()`(通常由 `ChatContainer` 注册)。
400
+ 编辑态 `ChatInput` 通过 `injectGlobalConfig()` 读取 `supportUpload` `menuSources`(缺省为空数组,即编辑态无菜单)。祖先需已 `useGlobalConfig()`(通常由 `ChatContainer` 注册)。
381
401
 
382
402
  ## 类型定义
383
403
 
@@ -424,6 +444,8 @@ type MessageExtra = {
424
444
  ## 关联组件
425
445
 
426
446
  - [MessageRender](/components/message/message-render) — user 角色由其实例化
447
+ - [MentionText](/components/rendering/mention-text) — 含标签文档的回显
448
+ - [CollapsibleContent](/components/rendering/collapsible-content) — 正文 200px 折叠
427
449
  - [MessageTools](/components/feedback/message-tools) — 工具栏交互
428
450
  - [MessageTime](/components/feedback/message-time) — 工具栏左侧的消息时间
429
451
  - [MessageContainer](/components/setup/message-container) — 列表与多选容器