@blueking/chat-x 0.0.51 → 0.0.52-dev.2

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 (199) 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 +5116 -4595
  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-selection.md +1 -1
  47. package/dist/mcp/generated/docs/ai-slash-input.md +72 -26
  48. package/dist/mcp/generated/docs/assistant-message.md +7 -1
  49. package/dist/mcp/generated/docs/chat-container.md +45 -6
  50. package/dist/mcp/generated/docs/chat-input.md +327 -483
  51. package/dist/mcp/generated/docs/collapsible-content.md +78 -0
  52. package/dist/mcp/generated/docs/constants.md +36 -3
  53. package/dist/mcp/generated/docs/execution-summary.md +1 -23
  54. package/dist/mcp/generated/docs/file-artifact-panel.md +24 -5
  55. package/dist/mcp/generated/docs/file-content.md +4 -0
  56. package/dist/mcp/generated/docs/file-upload-btn.md +15 -12
  57. package/dist/mcp/generated/docs/flow-agent-content.md +10 -12
  58. package/dist/mcp/generated/docs/input-menu-panel.md +166 -0
  59. package/dist/mcp/generated/docs/mention-tag.md +83 -0
  60. package/dist/mcp/generated/docs/mention-text.md +86 -0
  61. package/dist/mcp/generated/docs/message-container.md +1 -1
  62. package/dist/mcp/generated/docs/message-render.md +1 -1
  63. package/dist/mcp/generated/docs/message-tools.md +15 -4
  64. package/dist/mcp/generated/docs/messages.md +3 -0
  65. package/dist/mcp/generated/docs/model-selector.md +4 -2
  66. package/dist/mcp/generated/docs/overflow-tips.md +3 -3
  67. package/dist/mcp/generated/docs/resource-icon.md +102 -0
  68. package/dist/mcp/generated/docs/text-content.md +7 -3
  69. package/dist/mcp/generated/docs/theme.md +27 -35
  70. package/dist/mcp/generated/docs/use-artifact-preview.md +7 -3
  71. package/dist/mcp/generated/docs/use-command-selection.md +1 -1
  72. package/dist/mcp/generated/docs/use-container-scroll.md +2 -1
  73. package/dist/mcp/generated/docs/use-flow-node-actions.md +8 -15
  74. package/dist/mcp/generated/docs/use-global-config.md +11 -4
  75. package/dist/mcp/generated/docs/use-input-mention.md +119 -0
  76. package/dist/mcp/generated/docs/use-menu-keydown.md +15 -16
  77. package/dist/mcp/generated/docs/use-message-group.md +3 -6
  78. package/dist/mcp/generated/docs/user-message.md +39 -17
  79. package/dist/mcp/generated/index.json +233 -81
  80. package/dist/types/editor.d.ts +0 -29
  81. package/dist/types/index.d.ts +1 -0
  82. package/dist/types/input-menu.d.ts +46 -0
  83. package/dist/utils/artifact-tags.d.ts +36 -0
  84. package/dist/utils/collect-message-artifacts.d.ts +14 -0
  85. package/dist/utils/file.d.ts +3 -3
  86. package/dist/utils/index.d.ts +2 -1
  87. package/dist/utils/upload-file.d.ts +6 -1
  88. package/package.json +4 -3
  89. package/skills/blueking-chat-x/SKILL.md +143 -0
  90. package/skills/blueking-chat-x/references/_index.md +153 -0
  91. package/skills/blueking-chat-x/references/components/activity-layout.md +134 -0
  92. package/skills/blueking-chat-x/references/components/activity-message.md +486 -0
  93. package/skills/blueking-chat-x/references/components/add-menu-btn.md +88 -0
  94. package/skills/blueking-chat-x/references/components/ai-image.md +230 -0
  95. package/skills/blueking-chat-x/references/components/ai-loading.md +131 -0
  96. package/skills/blueking-chat-x/references/components/ai-selection.md +439 -0
  97. package/skills/blueking-chat-x/references/components/ai-slash-input.md +102 -0
  98. package/skills/blueking-chat-x/references/components/animation-text.md +202 -0
  99. package/skills/blueking-chat-x/references/components/assistant-message.md +504 -0
  100. package/skills/blueking-chat-x/references/components/chat-container.md +912 -0
  101. package/skills/blueking-chat-x/references/components/chat-input.md +614 -0
  102. package/skills/blueking-chat-x/references/components/cite-content.md +142 -0
  103. package/skills/blueking-chat-x/references/components/code-content.md +211 -0
  104. package/skills/blueking-chat-x/references/components/collapsible-content.md +76 -0
  105. package/skills/blueking-chat-x/references/components/common-error-content.md +73 -0
  106. package/skills/blueking-chat-x/references/components/content-render.md +233 -0
  107. package/skills/blueking-chat-x/references/components/delete-tool.md +191 -0
  108. package/skills/blueking-chat-x/references/components/desc-panel.md +162 -0
  109. package/skills/blueking-chat-x/references/components/detail-section.md +91 -0
  110. package/skills/blueking-chat-x/references/components/execution-summary.md +150 -0
  111. package/skills/blueking-chat-x/references/components/file-artifact-panel.md +307 -0
  112. package/skills/blueking-chat-x/references/components/file-content.md +340 -0
  113. package/skills/blueking-chat-x/references/components/file-icon.md +109 -0
  114. package/skills/blueking-chat-x/references/components/file-upload-btn.md +162 -0
  115. package/skills/blueking-chat-x/references/components/flow-agent-content.md +266 -0
  116. package/skills/blueking-chat-x/references/components/flow-agent-node-detail.md +236 -0
  117. package/skills/blueking-chat-x/references/components/highlight-keyword.md +146 -0
  118. package/skills/blueking-chat-x/references/components/image-content.md +182 -0
  119. package/skills/blueking-chat-x/references/components/image-preview-group.md +184 -0
  120. package/skills/blueking-chat-x/references/components/image-preview.md +226 -0
  121. package/skills/blueking-chat-x/references/components/info-message.md +144 -0
  122. package/skills/blueking-chat-x/references/components/input-attachment.md +49 -0
  123. package/skills/blueking-chat-x/references/components/input-info-alert.md +42 -0
  124. package/skills/blueking-chat-x/references/components/input-menu-panel.md +162 -0
  125. package/skills/blueking-chat-x/references/components/interrupt-message.md +212 -0
  126. package/skills/blueking-chat-x/references/components/key-value-content.md +128 -0
  127. package/skills/blueking-chat-x/references/components/knowledge-rag-content.md +122 -0
  128. package/skills/blueking-chat-x/references/components/latex-content.md +200 -0
  129. package/skills/blueking-chat-x/references/components/loading-message.md +192 -0
  130. package/skills/blueking-chat-x/references/components/markdown-content.md +232 -0
  131. package/skills/blueking-chat-x/references/components/mention-tag.md +79 -0
  132. package/skills/blueking-chat-x/references/components/mention-text.md +83 -0
  133. package/skills/blueking-chat-x/references/components/mermaid-content.md +189 -0
  134. package/skills/blueking-chat-x/references/components/message-container.md +645 -0
  135. package/skills/blueking-chat-x/references/components/message-loading.md +118 -0
  136. package/skills/blueking-chat-x/references/components/message-render.md +327 -0
  137. package/skills/blueking-chat-x/references/components/message-time.md +177 -0
  138. package/skills/blueking-chat-x/references/components/message-tools.md +427 -0
  139. package/skills/blueking-chat-x/references/components/model-selector.md +157 -0
  140. package/skills/blueking-chat-x/references/components/preview-toolbar.md +42 -0
  141. package/skills/blueking-chat-x/references/components/questions-container.md +85 -0
  142. package/skills/blueking-chat-x/references/components/reasoning-message.md +232 -0
  143. package/skills/blueking-chat-x/references/components/reference-content.md +135 -0
  144. package/skills/blueking-chat-x/references/components/reference-doc-content.md +109 -0
  145. package/skills/blueking-chat-x/references/components/resource-icon.md +98 -0
  146. package/skills/blueking-chat-x/references/components/scroll-btn.md +159 -0
  147. package/skills/blueking-chat-x/references/components/selection-footer.md +78 -0
  148. package/skills/blueking-chat-x/references/components/selection-question.md +88 -0
  149. package/skills/blueking-chat-x/references/components/shortcut-btn.md +204 -0
  150. package/skills/blueking-chat-x/references/components/shortcut-btns.md +266 -0
  151. package/skills/blueking-chat-x/references/components/shortcut-render.md +424 -0
  152. package/skills/blueking-chat-x/references/components/simple-table.md +101 -0
  153. package/skills/blueking-chat-x/references/components/text-content.md +80 -0
  154. package/skills/blueking-chat-x/references/components/tool-approval-card.md +183 -0
  155. package/skills/blueking-chat-x/references/components/tool-btn.md +317 -0
  156. package/skills/blueking-chat-x/references/components/tool-message.md +235 -0
  157. package/skills/blueking-chat-x/references/components/toolcall-render.md +348 -0
  158. package/skills/blueking-chat-x/references/components/user-feedback.md +233 -0
  159. package/skills/blueking-chat-x/references/components/user-message.md +444 -0
  160. package/skills/blueking-chat-x/references/components/user-question-answered-card.md +104 -0
  161. package/skills/blueking-chat-x/references/components/user-question-card.md +231 -0
  162. package/skills/blueking-chat-x/references/components/user-question-choice.md +105 -0
  163. package/skills/blueking-chat-x/references/components/user-question-option.md +42 -0
  164. package/skills/blueking-chat-x/references/components/vnode-renderer.md +122 -0
  165. package/skills/blueking-chat-x/references/composables/use-animation-text.md +196 -0
  166. package/skills/blueking-chat-x/references/composables/use-artifact-preview.md +235 -0
  167. package/skills/blueking-chat-x/references/composables/use-clipboard.md +203 -0
  168. package/skills/blueking-chat-x/references/composables/use-command-selection.md +150 -0
  169. package/skills/blueking-chat-x/references/composables/use-container-scroll.md +57 -0
  170. package/skills/blueking-chat-x/references/composables/use-custom-tab.md +158 -0
  171. package/skills/blueking-chat-x/references/composables/use-flow-node-actions.md +164 -0
  172. package/skills/blueking-chat-x/references/composables/use-full-screen.md +112 -0
  173. package/skills/blueking-chat-x/references/composables/use-global-config.md +155 -0
  174. package/skills/blueking-chat-x/references/composables/use-input-mention.md +115 -0
  175. package/skills/blueking-chat-x/references/composables/use-menu-keydown.md +161 -0
  176. package/skills/blueking-chat-x/references/composables/use-message-group.md +244 -0
  177. package/skills/blueking-chat-x/references/composables/use-observer-visible-list.md +188 -0
  178. package/skills/blueking-chat-x/references/composables/use-parent-scrolling.md +46 -0
  179. package/skills/blueking-chat-x/references/directives/index.md +61 -0
  180. package/skills/blueking-chat-x/references/directives/overflow-tips.md +205 -0
  181. package/skills/blueking-chat-x/references/icons/index.md +185 -0
  182. package/skills/blueking-chat-x/references/plugins/index.md +56 -0
  183. package/skills/blueking-chat-x/references/plugins/markdown-container.md +55 -0
  184. package/skills/blueking-chat-x/references/plugins/markdown-latex.md +205 -0
  185. package/skills/blueking-chat-x/references/plugins/markdown-mermaid.md +247 -0
  186. package/skills/blueking-chat-x/references/theme/theme.md +423 -0
  187. package/skills/blueking-chat-x/references/types/constants.md +340 -0
  188. package/skills/blueking-chat-x/references/types/index.md +120 -0
  189. package/skills/blueking-chat-x/references/types/interrupt.md +379 -0
  190. package/skills/blueking-chat-x/references/types/messages.md +556 -0
  191. package/skills/blueking-chat-x/references/types/schema.md +91 -0
  192. package/skills/blueking-chat-x/references/utils/index.md +196 -0
  193. package/skills/blueking-chat-x/scripts/generate-references.mjs +536 -0
  194. package/dist/components/chat-input/ai-slash-editor/ai-slash-editor.vue.d.ts +0 -28
  195. package/dist/components/chat-input/ai-slash-editor/theme.d.ts +0 -24
  196. package/dist/mcp/generated/docs/ai-prompt-list.md +0 -45
  197. package/dist/mcp/generated/docs/ai-skill-list.md +0 -75
  198. package/dist/mcp/generated/docs/ai-slash-editor.md +0 -43
  199. package/dist/mcp/generated/docs/ai-slash-menu.md +0 -42
@@ -0,0 +1,232 @@
1
+ # MarkdownContent Markdown 内容渲染
2
+
3
+ > 能力域:内容渲染 | 导入:`import { MarkdownContent } from '@blueking/chat-x'` | since 1.0.0
4
+
5
+ Markdown 主渲染器,集成代码块、公式、错误降级和 codeHeader 插槽。 源码位置:src/components/chat-content/markdown-content/markdown-content.vue。
6
+
7
+ **关联**:code-content(fence 代码块语法高亮与复制)、latex-content(数学公式 token 的 KaTeX 渲染)、mermaid-content(mermaid 代码块的图表渲染)、content-render(上层按类型分发到本组件渲染 Markdown 字符串)
8
+
9
+ ---
10
+
11
+ # MarkdownContent Markdown 内容渲染
12
+ ## 源码事实
13
+
14
+ - **源码位置**:`src/components/chat-content/markdown-content/markdown-content.vue`
15
+ - **能力域**:内容渲染
16
+ - **能力说明**:Markdown 主渲染器,集成代码块、公式、错误降级和 codeHeader 插槽。
17
+
18
+ > **能力域**:内容渲染
19
+
20
+ AI 消息内容渲染的核心基础组件,集成代码高亮、LaTeX 公式、Mermaid 图表等能力,内置流式渲染优化(5ms throttle + 语法补全 + 防闪烁)。
21
+
22
+ 由 `AssistantMessage`、`ReasoningMessage` 等组合组件内部自动使用,通常不需要手动引入。
23
+
24
+ ## 组件结构与渲染流程
25
+
26
+ ```
27
+ props.content → completeMarkdownSyntax → md.parse → groupTokens → groupedTokens
28
+
29
+ div.ai-markdown-content(contain: layout style)
30
+
31
+ status === 'error' → CommonErrorContent(:content)
32
+
33
+ else → div.ai-markdown-body[data-theme](contain: content)
34
+
35
+ v-for groupedToken
36
+
37
+ ┌─────────────┼────────────────────┬───────────────┐
38
+ │ │ │ │
39
+ hasMermaid? hasLatex? hasCode? else
40
+ ↓ ↓ ↓ ↓
41
+ MermaidContent LatexContent CodeContent VNodeRenderer
42
+ @mounted @mounted @mounted @vue:mounted
43
+
44
+ └──── handleTokenMounted(throttle 100ms)→ containerScroll.toScrollBottom()
45
+ ```
46
+
47
+ `VNodeRenderer` 的 `options` 中包含与当前 `MarkdownIt` 实例一致的 `mditOptions`(即 `md.options`),以便 `tokensToVNodes` 调用 `renderer.rules` 时第三参与 markdown-it 原生规则签名一致。
48
+
49
+ ### Token 分组(groupTokens)
50
+
51
+ `groupTokens` 使用栈将扁平 Token 数组转为分组数组,每组对应一个顶层 DOM 节点(段落、标题、列表、代码块等):
52
+
53
+ - `nesting === 1`(open)→ 入栈,建立新 group;顶层 group 立刻加入结果
54
+ - `nesting === -1`(close)→ 出栈,完成该 group;嵌套 group 合并到父 group
55
+ - `nesting === 0`(自闭合/inline)→ 无栈时独立成组,有栈时追加到当前 group
56
+
57
+ 每组第一个 token 的 `attrs` 追加 `class="ai-blueking-markdown-fade-in"`,触发渐显动画。
58
+
59
+ ### 子组件优先级
60
+
61
+ 对每个 token 组按以下顺序判断:
62
+
63
+ | 优先级 | 检测逻辑 | 使用组件 |
64
+ | ------ | -------------------------------------------------------------------- | ----------------------------------------- |
65
+ | 1 | `fence` token 且 `info === 'mermaid'` | `MermaidContent` |
66
+ | 2 | `math_inline` / `math_block`,或 children 中递归含有(inline token) | `LatexContent` |
67
+ | 3 | `fence`(非 mermaid)或 `code_block` | `CodeContent` |
68
+ | 4 | 其余 | `VNodeRenderer`(HTML 由 DOMPurify 过滤) |
69
+
70
+ ## 基础用法
71
+
72
+ ```vue
73
+ <template>
74
+ <MarkdownContent
75
+ :content="markdownText"
76
+ :status="MessageStatus.Complete"
77
+ />
78
+ </template>
79
+
80
+ <script setup lang="ts">
81
+ import { MarkdownContent, MessageStatus } from '@blueking/chat-x';
82
+
83
+ const markdownText = `# 标题\n\n这是一段 **Markdown** 内容。`;
84
+ </script>
85
+ ```
86
+
87
+ ## 扩展文本格式
88
+
89
+ 支持标准 Markdown + 扩展插件:`++下划线++`(markdown-it-ins)、`==高亮==`(markdown-it-mark)、`~下标~`(markdown-it-sub)、`^上标^`(markdown-it-sup):
90
+
91
+ ## 列表与任务清单
92
+
93
+ ## 代码块
94
+
95
+ 代码块由 `CodeContent` 渲染,支持 highlight.js 语法高亮、语言标签、一键复制。语法高亮主题样式由 `CodeContent` 侧引入(`github-dark`),`MarkdownContent` **不再**全局引入 `highlight.js` 主题 CSS,避免与代码块组件重复加载、并保持与消息区样式一致。
96
+
97
+ ## 表格
98
+
99
+ ## 对齐容器(markdown-it-container)
100
+
101
+ 支持 `::: hljs-left` / `::: hljs-center` / `::: hljs-right` 自定义容器,内容渲染在带对应 class 的块级容器中,由内置样式控制 `text-align`:
102
+
103
+ ## LaTeX 公式
104
+
105
+ 公式由 `LatexContent`(KaTeX)渲染,支持行内 `$...$` 和块级 `$$...$$`:
106
+
107
+ ## Mermaid 图表
108
+
109
+ ## 错误状态
110
+
111
+ `status === MessageStatus.Error` 时渲染 `CommonErrorContent`,将 `content` 作为错误文本显示:
112
+
113
+ ## 流式渲染
114
+
115
+ ````vue
116
+ <template>
117
+ <MarkdownContent
118
+ :content="streamingContent"
119
+ :status="isStreaming ? MessageStatus.Streaming : MessageStatus.Complete"
120
+ />
121
+ </template>
122
+
123
+ <script setup lang="ts">
124
+ import { ref } from 'vue';
125
+ import { MarkdownContent, MessageStatus } from '@blueking/chat-x';
126
+
127
+ const streamingContent = ref('');
128
+ const isStreaming = ref(false);
129
+
130
+ const simulate = async () => {
131
+ const fullText = '## Hello\n\n**流式输出**演示。\n\n```js\nconsole.log(1);\n```';
132
+ isStreaming.value = true;
133
+ for (const char of fullText) {
134
+ await new Promise(r => setTimeout(r, 30));
135
+ streamingContent.value += char;
136
+ }
137
+ isStreaming.value = false;
138
+ };
139
+ </script>
140
+ ````
141
+
142
+ ### 流式优化机制
143
+
144
+ | 机制 | 实现 | 作用 |
145
+ | ----------------- | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
146
+ | 极速节流 | `parseMarkdownContent` throttle **5ms**,leading + trailing | 每 5ms 最多解析一次,兼顾实时性与性能 |
147
+ | Markdown 语法补全 | `completeMarkdownSyntax(content)` | 自动闭合代码块、行内代码、粗斜体、删除线、链接等未完成语法 |
148
+ | LaTeX 防闪烁 | `isIncomplete=true` 且已有渲染结果 → **跳过本次更新** | 正在输入 LaTeX 命令时保持上一帧,避免闪白 |
149
+ | 子组件 throttle | `handleTokenMounted` throttle 100ms | 限制子组件挂载后触发的滚动到底部频率 |
150
+ | CSS contain | `.ai-markdown-content { contain: layout style }`<br>`.ai-markdown-body { contain: content }` | 限制重排/重绘范围,减少流式渲染的布局开销 |
151
+ | 渐显动画 | 每组首 token 追加 `.ai-blueking-markdown-fade-in` | 新内容块淡入,减少视觉跳跃感 |
152
+
153
+ ## 主题支持
154
+
155
+ 组件通过 `data-theme` 属性和本地 `markdown-content.css`(由 GitHub Markdown 样式 vendoring 而来,类前缀为 `ai-markdown-body`)控制主题,默认为 `light`,避免受宿主页面 `@media (prefers-color-scheme)` 影响。
156
+
157
+ - **Light 模式**(默认):`.ai-markdown-body[data-theme="light"]`,light 变量 + `color-scheme: light`
158
+ - **Dark 模式**:`.ai-markdown-body[data-theme="dark"]`,dark 变量 + `color-scheme: dark`
159
+
160
+ > 外层包裹类名为 `.ai-markdown-content`,内层正文区为 `.ai-markdown-body`,避免与宿主或其他库的 `.markdown-body` 全局样式冲突。
161
+
162
+ ## API
163
+
164
+ ### Props
165
+
166
+ | 属性名 | 类型 | 必填 | 说明 |
167
+ | ------- | --------------- | ---- | --------------------------------------------------------- |
168
+ | content | `string` | — | Markdown 文本;为空时清空渲染结果 |
169
+ | status | `MessageStatus` | — | `'error'` 时显示 `CommonErrorContent`,其余状态均正常渲染 |
170
+
171
+ ### Slots
172
+
173
+ | 插槽名 | 参数 | 说明 |
174
+ | ---------- | -------------------------------------- | --------------------------------------------------------------------------------------- |
175
+ | codeHeader | `{ language: string; token: Token[] }` | 代码块头部自定义操作区域,透传给 CodeContent 的 header 插槽,可添加"插入"、"应用"等按钮 |
176
+
177
+ ### 内置插件
178
+
179
+ | 插件 | 语法 | 功能 |
180
+ | --------------------------- | ------------------- | -------------------- |
181
+ | `markdownItBkInlineStyle` | 见下文「蓝鲸行内样式」 | 安全行内颜色/字号/粗斜体(非 HTML) |
182
+ | `markdown-it-footnote` | `[^1]` | 脚注 |
183
+ | `markdown-it-ins` | `++text++` | 下划线 |
184
+ | `markdown-it-mark` | `==text==` | 高亮 |
185
+ | `markdown-it-sub` | `~text~` | 下标 |
186
+ | `markdown-it-sup` | `^text^` | 上标 |
187
+ | `markdown-it-task-checkbox` | `- [x]` | 任务列表 |
188
+ | `markdownItMermaid` | ` ```mermaid ` | Mermaid 图表 token |
189
+ | `markdownItLatex` | `$...$` / `$$...$$` | KaTeX 数学公式 token |
190
+ | `markdownItContainer` | `::: hljs-left` 等 | 自定义对齐容器(class 与 highlight.js 命名对齐) |
191
+
192
+ ### 蓝鲸行内样式(`markdownItBkInlineStyle`)
193
+
194
+ 不开启 `html: true`,由专用语法生成带白名单 `style` 的 `<span class="bk-md-inline-style">`。
195
+
196
+ **语法**:`::bk{` *属性* `}` *正文* `:/bk::`
197
+
198
+ - 属性写在 `{}` 内,使用 `;` 分隔;每项为 `键=值` 或 `键:值`。
199
+ - 正文支持行内 Markdown(如 `**粗体**`)。
200
+ - 结束标记必须为字面量 `:/bk::`,请勿在正文中出现该序列。
201
+
202
+ **支持的键**:`color` / `c`、`background-color`、`font-size`、`bold`、`italic`(详见 `plugins/markdown-bk-inline-style.ts` 内注释)。
203
+
204
+ **示例**:
205
+
206
+ ```markdown
207
+ ::bk{color:#c00;font-size:18px}**重要**:/bk::
208
+ ::bk{background-color:yellow}高亮:/bk::
209
+ ::bk{bold;italic}强调:/bk::
210
+ ```
211
+
212
+ ### 安全性
213
+
214
+ `MarkdownIt` **不**开启 `html: true`,用户无法插入任意 HTML 标签;行内彩色/字号等请使用上文「蓝鲸行内样式」扩展。
215
+
216
+ `VNodeRenderer` 渲染的 HTML 统一经过 DOMPurify 过滤,并额外允许 KaTeX 所需标签:
217
+
218
+ ```typescript
219
+ const domPurifyConfig = {
220
+ ADD_TAGS: ['semantics', 'mrow', 'mi', 'mo', 'mn', 'msup', 'msub', 'mfrac', 'mtext', 'annotation'],
221
+ ADD_ATTR: ['xmlns', 'mathvariant', 'encoding', 'style'],
222
+ };
223
+ ```
224
+
225
+ > `CodeContent`、`MermaidContent`、`LatexContent` 各自内部处理安全性(KaTeX `errorColor`、highlight.js 转义等),不经过 DOMPurify。
226
+
227
+ ## 关联组件
228
+
229
+ - [CodeContent](/components/rendering/code-content) — 代码 fence 高亮
230
+ - [LatexContent](/components/rendering/latex-content) — 公式渲染
231
+ - [MermaidContent](/components/rendering/mermaid-content) — Mermaid 图表
232
+ - [ContentRender](/components/rendering/content-render) — 内容类型分发入口
@@ -0,0 +1,79 @@
1
+ # MentionTag 资源标签
2
+
3
+ > 能力域:内容渲染 | 未从包入口导出:内部组件,请通过上层组件使用 | since 0.0.51
4
+
5
+ MentionTag 渲染「图标 + 蓝色名称」的内联资源标签:节点数据全部落在 data-tag-* 属性上, 既是编辑器 void 节点的识别依据,也让消息里复制的标签能原样还原; description 非空时 hover / 点击弹出「类型:名称 + 描述」气泡;type 为 artifact 且存在产物预览上下文时点击打开侧栏预览。 源码位置:src/components/mention/mention-tag.vue(气泡见 mention-popover.vue 与 create-mention-tippy.ts)。
6
+
7
+ **关联**:mention-text(按文档结构批量渲染标签与文本)、ai-slash-input(编辑器内的 tag 节点由本组件渲染)、resource-icon(标签左侧图标)、file-artifact-panel(artifact 标签点击后打开的侧栏预览)
8
+
9
+ ---
10
+
11
+ # MentionTag 资源标签
12
+
13
+ > **能力域**:内容渲染
14
+
15
+ ## 源码事实
16
+
17
+ - **标签**:`src/components/mention/mention-tag.vue`
18
+ - **气泡内容**:`src/components/mention/mention-popover.vue`
19
+ - **气泡配置**:`src/components/mention/create-mention-tippy.ts`
20
+ - **能力说明**:设计稿形态为「图标 + 蓝色文字」内联展示,无背景块;高度 22px,`vertical-align: bottom`。
21
+
22
+ ## data-tag-\* 属性
23
+
24
+ 标签把节点数据全部写在 DOM 属性上,这不是冗余:
25
+
26
+ | 属性 | 作用 |
27
+ | ---------------------- | -------------------------------------------------------- |
28
+ | `data-tag-type` | 与 `contenteditable="false"` 一起作为编辑器 void 节点的识别依据 |
29
+ | `data-tag-value` | 资源 id,`artifact` 点击预览、`skill` 序列化都取它 |
30
+ | `data-tag-label` | 展示名,避免从 `textContent` 读取时混入图标带来的空白 |
31
+ | `data-tag-icon` | 图标 URL(组件形式的图标无法序列化,此时为空) |
32
+ | `data-tag-description` | 描述文案,让气泡脱离 `menuSources` 独立工作 |
33
+
34
+ 因此从消息里复制一段带标签的文本再粘贴回输入框,标签能被原样还原。
35
+
36
+ ## 交互
37
+
38
+ - **描述气泡**:`description` 非空时才创建气泡(否则 `onShow` 直接返回 `false`)。标题格式为 `类型:名称`,类型名与菜单分组标题同源(`getMenuTypeLabel`)。
39
+ - **触发方式**:`mouseenter focus click`,展示延迟 300ms、关闭无延迟;`hideOnClick` 关闭并改用 `onClickOutside` 收起,因此再次点击标签不会把气泡收掉,触屏也能点开。
40
+ - **产物预览**:`type` 为 `artifact` 且存在 [useArtifactPreview](/composables/use-artifact-preview) 上下文时,点击标签以 `{ file: { outputId: value } }` 打开侧栏预览。
41
+ - **可交互暗示**:仅在「有描述」或「可预览」时给出 `cursor: pointer` 与名称下划线。
42
+
43
+ ::: info 为什么用指令而不是 `<Tippy>` 组件
44
+ 标签渲染在 `contenteditable` 内部,多包一层元素会干扰编辑器对 void 节点的识别与 DOM 比对,因此气泡走 `v-tippy` 指令。
45
+ :::
46
+
47
+ ## 渲染示例
48
+
49
+ > 前三个标签中「翻译」「天气查询」带描述,hover 可见气泡;`artifact` 标签在有产物预览上下文时可点击。
50
+
51
+ ## API
52
+
53
+ ### Props
54
+
55
+ | 属性名 | 类型 | 必填 | 说明 |
56
+ | ----------- | -------- | ---- | ----------------------------------------------------- |
57
+ | label | `string` | ✅ | 标签展示名 |
58
+ | value | `string` | ✅ | 资源 id |
59
+ | type | `string` | ✅ | 资源类型,决定兜底图标、气泡标题与是否可预览 |
60
+ | icon | `string` | - | 图标 URL;缺省时按 `type` 兜底 |
61
+ | description | `string` | - | 描述文案,非空时启用气泡 |
62
+
63
+ ### MentionPopover Props
64
+
65
+ | 属性名 | 类型 | 必填 | 说明 |
66
+ | ----------- | -------- | ---- | ------------------------------------ |
67
+ | title | `string` | ✅ | 形如「工具:天气查询」 |
68
+ | description | `string` | - | 描述正文,最大宽度 240px,自动换行 |
69
+
70
+ ### Emits / Slots / Expose
71
+
72
+ - 无。
73
+
74
+ ## 关联组件
75
+
76
+ - [MentionText](/components/rendering/mention-text) — 按文档结构批量渲染
77
+ - [AiSlashInput](/components/input/ai-slash-input) — 编辑器内的标签宿主
78
+ - [ResourceIcon](/components/helper/resource-icon) — 标签图标
79
+ - [useArtifactPreview](/composables/use-artifact-preview) — 产物预览上下文
@@ -0,0 +1,83 @@
1
+ # MentionText 标签文本
2
+
3
+ > 能力域:内容渲染 | 未从包入口导出:内部组件,请通过上层组件使用 | since 0.0.51
4
+
5
+ MentionText 接收一份 TagSchema 文档(二维数组:行 → 节点),逐行渲染:text 节点输出文本、 tag 节点交给 MentionTag;行间用 <br> 分隔,空白以 pre-wrap 保留。 UserMessage 在 property.docSchema 含标签时用它替代 TextContent。 源码位置:src/components/mention/mention-text.vue。
6
+
7
+ **关联**:mention-tag(tag 节点的实际渲染者)、user-message(用户消息在文档含标签时改用本组件回显)、text-content(纯文本消息仍走 TextContent)
8
+
9
+ ---
10
+
11
+ # MentionText 标签文本
12
+
13
+ > **能力域**:内容渲染
14
+
15
+ ## 源码事实
16
+
17
+ - **源码位置**:`src/components/mention/mention-text.vue`
18
+ - **能力说明**:把 `TagSchema` 文档渲染成「文本 + 资源标签」,让用户消息里 `@` 选中的资源保持标签形态而不是退化成纯文本。
19
+ - **样式**:`width: fit-content`、`word-break: break-all`、`white-space: pre-wrap`(行间换行由 `<br>` 承担,行内连续空格与纯文本分支表现一致)。
20
+
21
+ ## 数据流:消息里的标签怎么活下来
22
+
23
+ ```
24
+ 用户在输入框选中资源
25
+ → onSendMessage(content, docSchema) content 仍是纯文本,不改后端契约
26
+ → 业务侧把 docSchema 存进 message.property.docSchema
27
+ → UserMessage 检测到文档中存在 tag 节点
28
+ → 用 MentionText 渲染(否则回退 TextContent)
29
+ ```
30
+
31
+ 业务侧不保存 `docSchema` 时一切照旧:历史消息与第三方消息仍走 [TextContent](/components/rendering/text-content) 渲染纯文本。编辑消息后也需要把新的 `docSchema` 写回,否则改完这条消息标签就丢了。
32
+
33
+ ```typescript
34
+ // 发送
35
+ const handleSendMessage = async (content: UserMessage['content'], docSchema: TagSchema) => {
36
+ messages.value.push({
37
+ id, messageId: id, role: MessageRole.User, content,
38
+ property: { docSchema },
39
+ });
40
+ };
41
+
42
+ // 编辑确认
43
+ const handleUserInputConfirm = async (message: Message, content: UserMessage['content'], docSchema: TagSchema) => {
44
+ target.content = content;
45
+ target.property = { ...target.property, docSchema };
46
+ };
47
+ ```
48
+
49
+ ## 渲染示例
50
+
51
+ ## API
52
+
53
+ ### Props
54
+
55
+ | 属性名 | 类型 | 必填 | 说明 |
56
+ | ------ | ----------- | ---- | ------------------------------------------ |
57
+ | doc | `TagSchema` | ✅ | 发送时随消息一起保存的编辑器文档 |
58
+
59
+ ### Emits / Slots / Expose
60
+
61
+ - 无。
62
+
63
+ ### 文档结构
64
+
65
+ ```typescript
66
+ type TagSchema = Array<
67
+ Array<
68
+ | { type: 'text'; text: string }
69
+ | {
70
+ type: 'tag';
71
+ data: { label: string; value: string; type: string; icon: string; description: string };
72
+ }
73
+ >
74
+ >;
75
+ ```
76
+
77
+ 外层数组是行,内层数组是行内节点。渲染时第 2 行起前置一个 `<br>`。
78
+
79
+ ## 关联组件
80
+
81
+ - [MentionTag](/components/rendering/mention-tag) — 单个标签渲染与气泡
82
+ - [UserMessage](/components/message/user-message) — 使用方
83
+ - [TextContent](/components/rendering/text-content) — 无文档时的回退渲染
@@ -0,0 +1,189 @@
1
+ # MermaidContent Mermaid 图表
2
+
3
+ > 能力域:内容渲染 | 导入:`import { MermaidContent } from '@blueking/chat-x'` | since 1.0.0
4
+
5
+ 渲染 Mermaid 图表并处理渲染事件。 源码位置:src/components/markdown-token/mermaid-content/mermaid-content.vue。
6
+
7
+ **关联**:markdown-content(解析 mermaid 类型 fence 代码块后传入 token)
8
+
9
+ ---
10
+
11
+ # MermaidContent Mermaid 图表渲染
12
+ ## 源码事实
13
+
14
+ - **源码位置**:`src/components/markdown-token/mermaid-content/mermaid-content.vue`
15
+ - **能力域**:内容渲染
16
+ - **能力说明**:渲染 Mermaid 图表并处理渲染事件。
17
+
18
+ > **能力域**:内容渲染
19
+
20
+ Markdown Token 层的 Mermaid 图表渲染基础组件,被 `MarkdownContent` 在检测到 mermaid fence token 时自动调用,通常无需手动引入。
21
+
22
+ 核心能力:**按需懒加载 Mermaid**(动态 import 单例)、**三级去重跳过**(代码比对 → 语法校验 → SVG 比对)、**100ms throttle** 流式防抖、**错误静默**(parse 失败时保持上一次 SVG)。
23
+
24
+ ## 组件结构与渲染流程
25
+
26
+ ```
27
+ props.token(Token[])
28
+
29
+ ├─ extractMermaidCode(tokens)
30
+ │ → 遍历找第一个 type==='fence' && info.trim()==='mermaid' && content 非空的 token
31
+ │ → 返回 content(无匹配返回空字符串)
32
+
33
+ └─ renderMermaid(throttle 100ms,leading + trailing)
34
+
35
+ ├─ 1. newCode === lastMermaidCode → return(代码未变,跳过)
36
+ ├─ 2. lastMermaidCode = newCode
37
+ ├─ 3. getMermaidInstance() → 动态 import('mermaid') 单例,初始化一次
38
+ ├─ 4. mermaid.parse(code, { suppressErrors: true })
39
+ │ → !isValid → return(语法无效,保持上次 SVG)
40
+ ├─ 5. mermaid.render('mermaid-content-' + randomId, code) → { svg }
41
+ ├─ 6. svgDomStr.value === svg → return(SVG 无变化,跳过)
42
+ └─ 7. svgDomStr.value = svg
43
+ nextTick → emit('mounted', { get el() { return mermaidContentRef.value } })
44
+
45
+ 模板:
46
+ div.ai-mermaid-content(:key="svgDomStr",v-html="svgDomStr")
47
+ 注::key 绑定 svgDomStr,每次 SVG 变化会重建 div 而非就地 patch
48
+ ```
49
+
50
+ ## 基础用法
51
+
52
+ ```vue
53
+ <template>
54
+ <MermaidContent
55
+ :token="tokens"
56
+ @mounted="handleMounted"
57
+ />
58
+ </template>
59
+
60
+ <script setup lang="ts">
61
+ import { MermaidContent } from '@blueking/chat-x';
62
+ import type { Token } from 'markdown-it';
63
+
64
+ const tokens: Token[] = [
65
+ {
66
+ type: 'fence',
67
+ tag: 'code',
68
+ info: 'mermaid',
69
+ content: `graph TD
70
+ A[开始] --> B{判断}
71
+ B -->|是| C[执行]
72
+ B -->|否| D[结束]`,
73
+ } as Token,
74
+ ];
75
+
76
+ const handleMounted = ({ el }: { el: HTMLElement | null }) => {
77
+ // el 是 lazy getter,值为渲染后的 .ai-mermaid-content 元素
78
+ console.log('渲染完成:', el);
79
+ };
80
+ </script>
81
+ ```
82
+
83
+ ## 支持的图表类型
84
+
85
+ ### 时序图(Sequence Diagram)
86
+
87
+ ### 甘特图(Gantt)
88
+
89
+ ### 类图(Class Diagram)
90
+
91
+ ### 状态图(State Diagram)
92
+
93
+ ### 饼图(Pie Chart)
94
+
95
+ ## 流式渲染
96
+
97
+ 流式输入时 Mermaid 语法逐步完整,组件通过 throttle + `parse` 语法校验避免无效渲染:
98
+
99
+ ```vue
100
+ <template>
101
+ <MermaidContent :token="streamingTokens" />
102
+ </template>
103
+
104
+ <script setup lang="ts">
105
+ import { ref } from 'vue';
106
+ import { MermaidContent } from '@blueking/chat-x';
107
+
108
+ const streamingTokens = ref([{ type: 'fence', tag: 'code', info: 'mermaid', content: '' }]);
109
+
110
+ const simulate = async () => {
111
+ const code = `graph TD\n A[开始] --> B[处理]\n B --> C[结束]`;
112
+ let content = '';
113
+ for (const char of code) {
114
+ await new Promise(r => setTimeout(r, 50));
115
+ content += char;
116
+ streamingTokens.value = [{ type: 'fence', tag: 'code', info: 'mermaid', content }];
117
+ }
118
+ };
119
+ </script>
120
+ ```
121
+
122
+ **流式过程中的行为**:
123
+
124
+ | 阶段 | `parse` 结果 | 行为 |
125
+ | -------------------------- | ------------ | ----------------------------------------- |
126
+ | 代码未变化 | — | 三级去重第 1 关:直接跳过,不调用 Mermaid |
127
+ | 语法不完整(如 `graph T`) | `false` | 三级去重第 2 关:跳过渲染,保持上次 SVG |
128
+ | 语法完整,SVG 相同 | `true` | 三级去重第 3 关:跳过 DOM 更新 |
129
+ | 语法完整,SVG 变化 | `true` | 更新 SVG,触发 `mounted` 事件 |
130
+
131
+ ## API
132
+
133
+ ### Props
134
+
135
+ | 属性名 | 类型 | 必填 | 说明 |
136
+ | ------ | --------- | ---- | -------------------------------------------------------------------------------------------- |
137
+ | token | `Token[]` | ✓ | markdown-it Token 数组;组件自动从中提取第一个 `type==='fence' && info==='mermaid'` 的 token |
138
+
139
+ ### Events
140
+
141
+ | 事件名 | 参数 | 触发时机 |
142
+ | ------- | ----------------------------- | ---------------------------------------------------------------------------------- |
143
+ | mounted | `{ el: HTMLElement \| null }` | SVG 更新后的 `nextTick`;`el` 为 lazy getter,返回当前 `.ai-mermaid-content` 元素引用 |
144
+
145
+ ### Token 结构
146
+
147
+ ```typescript
148
+ // 组件只识别 type === 'fence' 且 info.trim() === 'mermaid' 的 token
149
+ {
150
+ type: 'fence';
151
+ tag?: 'code'; // 可选
152
+ info: 'mermaid'; // 必须严格等于 'mermaid'(trim 后)
153
+ content: string; // Mermaid 图表定义语法
154
+ }
155
+ ```
156
+
157
+ ## 性能与错误处理细节
158
+
159
+ ### 单例 Mermaid 实例
160
+
161
+ ```typescript
162
+ // 模块级变量,所有 MermaidContent 实例共享同一个 mermaid 模块
163
+ let mermaidInstance: MermaidModule | null = null;
164
+
165
+ // 初始化时调用一次(suppressErrorRendering: true 抑制 Mermaid 内部错误 UI)
166
+ mermaidInstance.default.initialize({ suppressErrorRendering: true });
167
+ ```
168
+
169
+ 首次渲染因动态 import 会有约 200~500ms 的网络加载延迟,之后复用实例无额外开销。
170
+
171
+ ### SVG ID 随机化
172
+
173
+ 每次调用 `mermaid.render` 时生成随机 ID:
174
+
175
+ ```typescript
176
+ mermaid.default.render('mermaid-content-' + Math.random().toString(36).substring(2, 15), code);
177
+ ```
178
+
179
+ 避免多个 MermaidContent 实例或同一实例多次渲染时 DOM ID 冲突。
180
+
181
+ ### 错误静默
182
+
183
+ - `mermaid.parse` 失败(语法无效)→ `return`,不修改 `svgDomStr`,保持上次成功的 SVG
184
+ - `mermaid.render` 抛出异常 → `console.warn`,不修改 `svgDomStr`,保持上次成功的 SVG
185
+ - 两种情况下组件界面均无错误提示(静默降级)
186
+
187
+ ## 关联组件
188
+
189
+ - [MarkdownContent](/components/rendering/markdown-content) — mermaid fence token 的来源与挂载