@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.
- package/README.md +15 -8
- package/dist/ag-ui/types/contents.d.ts +2 -0
- package/dist/ag-ui/types/messages.d.ts +6 -1
- package/dist/common/constants.d.ts +2 -0
- package/dist/components/ai-buttons/add-menu-btn/add-menu-btn.vue.d.ts +24 -0
- package/dist/components/chat-content/collapsible-content/collapsible-content.vue.d.ts +28 -0
- package/dist/components/chat-content/file-content/upload-file-item.vue.d.ts +5 -2
- package/dist/components/chat-content/file-content/upload-image-item.vue.d.ts +1 -0
- package/dist/components/chat-content/flow-agent-content/use-flow-node-actions.d.ts +1 -1
- package/dist/components/chat-input/ai-slash-input/ai-slash-input.vue.d.ts +21 -10
- package/dist/components/chat-input/ai-slash-input/command.d.ts +6 -3
- package/dist/components/chat-input/ai-slash-input/constants.d.ts +2 -0
- package/dist/components/chat-input/ai-slash-input/use-menu-trigger.d.ts +17 -0
- package/dist/components/chat-input/build-default-placeholder.d.ts +9 -3
- package/dist/components/chat-input/chat-input.vue.d.ts +30 -18
- package/dist/components/chat-input/input-menu/constants.d.ts +60 -0
- package/dist/components/chat-input/input-menu/index.d.ts +4 -0
- package/dist/components/chat-input/input-menu/input-menu-option.vue.d.ts +14 -0
- package/dist/components/chat-input/input-menu/input-menu-panel.vue.d.ts +17 -0
- package/dist/components/chat-input/input-menu/use-input-menu.d.ts +22 -0
- package/dist/components/chat-input/model-selector/types.d.ts +3 -2
- package/dist/components/chat-message/message-container/message-container.vue.d.ts +1 -1
- package/dist/components/chat-message/user-message/user-message.vue.d.ts +1 -1
- package/dist/components/mention/create-mention-tippy.d.ts +27 -0
- package/dist/components/mention/index.d.ts +4 -0
- 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
- 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
- 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
- package/dist/components/resource-icon/index.d.ts +1 -0
- package/dist/components/resource-icon/resource-icon.vue.d.ts +11 -0
- package/dist/composables/index.d.ts +1 -0
- package/dist/composables/use-artifact-preview.d.ts +5 -2
- package/dist/composables/use-common.d.ts +0 -9
- package/dist/composables/use-global-config.d.ts +4 -0
- package/dist/composables/use-input-mention.d.ts +13 -0
- package/dist/composables/use-message-group.d.ts +1011 -72
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/input.d.ts +21 -0
- package/dist/icons/menu-item.d.ts +22 -0
- package/dist/index.css +1 -1
- package/dist/index.js +5116 -4595
- package/dist/index.js.map +1 -1
- package/dist/lang/lang.d.ts +13 -3
- package/dist/mcp/generated/docs/activity-message.md +3 -3
- package/dist/mcp/generated/docs/add-menu-btn.md +91 -0
- package/dist/mcp/generated/docs/ai-selection.md +1 -1
- package/dist/mcp/generated/docs/ai-slash-input.md +72 -26
- package/dist/mcp/generated/docs/assistant-message.md +7 -1
- package/dist/mcp/generated/docs/chat-container.md +45 -6
- package/dist/mcp/generated/docs/chat-input.md +327 -483
- package/dist/mcp/generated/docs/collapsible-content.md +78 -0
- package/dist/mcp/generated/docs/constants.md +36 -3
- package/dist/mcp/generated/docs/execution-summary.md +1 -23
- package/dist/mcp/generated/docs/file-artifact-panel.md +24 -5
- package/dist/mcp/generated/docs/file-content.md +4 -0
- package/dist/mcp/generated/docs/file-upload-btn.md +15 -12
- package/dist/mcp/generated/docs/flow-agent-content.md +10 -12
- package/dist/mcp/generated/docs/input-menu-panel.md +166 -0
- package/dist/mcp/generated/docs/mention-tag.md +83 -0
- package/dist/mcp/generated/docs/mention-text.md +86 -0
- package/dist/mcp/generated/docs/message-container.md +1 -1
- package/dist/mcp/generated/docs/message-render.md +1 -1
- package/dist/mcp/generated/docs/message-tools.md +15 -4
- package/dist/mcp/generated/docs/messages.md +3 -0
- package/dist/mcp/generated/docs/model-selector.md +4 -2
- package/dist/mcp/generated/docs/overflow-tips.md +3 -3
- package/dist/mcp/generated/docs/resource-icon.md +102 -0
- package/dist/mcp/generated/docs/text-content.md +7 -3
- package/dist/mcp/generated/docs/theme.md +27 -35
- package/dist/mcp/generated/docs/use-artifact-preview.md +7 -3
- package/dist/mcp/generated/docs/use-command-selection.md +1 -1
- package/dist/mcp/generated/docs/use-container-scroll.md +2 -1
- package/dist/mcp/generated/docs/use-flow-node-actions.md +8 -15
- package/dist/mcp/generated/docs/use-global-config.md +11 -4
- package/dist/mcp/generated/docs/use-input-mention.md +119 -0
- package/dist/mcp/generated/docs/use-menu-keydown.md +15 -16
- package/dist/mcp/generated/docs/use-message-group.md +3 -6
- package/dist/mcp/generated/docs/user-message.md +39 -17
- package/dist/mcp/generated/index.json +233 -81
- package/dist/types/editor.d.ts +0 -29
- package/dist/types/index.d.ts +1 -0
- package/dist/types/input-menu.d.ts +46 -0
- package/dist/utils/artifact-tags.d.ts +36 -0
- package/dist/utils/collect-message-artifacts.d.ts +14 -0
- package/dist/utils/file.d.ts +3 -3
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/upload-file.d.ts +6 -1
- package/package.json +4 -3
- package/skills/blueking-chat-x/SKILL.md +143 -0
- package/skills/blueking-chat-x/references/_index.md +153 -0
- package/skills/blueking-chat-x/references/components/activity-layout.md +134 -0
- package/skills/blueking-chat-x/references/components/activity-message.md +486 -0
- package/skills/blueking-chat-x/references/components/add-menu-btn.md +88 -0
- package/skills/blueking-chat-x/references/components/ai-image.md +230 -0
- package/skills/blueking-chat-x/references/components/ai-loading.md +131 -0
- package/skills/blueking-chat-x/references/components/ai-selection.md +439 -0
- package/skills/blueking-chat-x/references/components/ai-slash-input.md +102 -0
- package/skills/blueking-chat-x/references/components/animation-text.md +202 -0
- package/skills/blueking-chat-x/references/components/assistant-message.md +504 -0
- package/skills/blueking-chat-x/references/components/chat-container.md +912 -0
- package/skills/blueking-chat-x/references/components/chat-input.md +614 -0
- package/skills/blueking-chat-x/references/components/cite-content.md +142 -0
- package/skills/blueking-chat-x/references/components/code-content.md +211 -0
- package/skills/blueking-chat-x/references/components/collapsible-content.md +76 -0
- package/skills/blueking-chat-x/references/components/common-error-content.md +73 -0
- package/skills/blueking-chat-x/references/components/content-render.md +233 -0
- package/skills/blueking-chat-x/references/components/delete-tool.md +191 -0
- package/skills/blueking-chat-x/references/components/desc-panel.md +162 -0
- package/skills/blueking-chat-x/references/components/detail-section.md +91 -0
- package/skills/blueking-chat-x/references/components/execution-summary.md +150 -0
- package/skills/blueking-chat-x/references/components/file-artifact-panel.md +307 -0
- package/skills/blueking-chat-x/references/components/file-content.md +340 -0
- package/skills/blueking-chat-x/references/components/file-icon.md +109 -0
- package/skills/blueking-chat-x/references/components/file-upload-btn.md +162 -0
- package/skills/blueking-chat-x/references/components/flow-agent-content.md +266 -0
- package/skills/blueking-chat-x/references/components/flow-agent-node-detail.md +236 -0
- package/skills/blueking-chat-x/references/components/highlight-keyword.md +146 -0
- package/skills/blueking-chat-x/references/components/image-content.md +182 -0
- package/skills/blueking-chat-x/references/components/image-preview-group.md +184 -0
- package/skills/blueking-chat-x/references/components/image-preview.md +226 -0
- package/skills/blueking-chat-x/references/components/info-message.md +144 -0
- package/skills/blueking-chat-x/references/components/input-attachment.md +49 -0
- package/skills/blueking-chat-x/references/components/input-info-alert.md +42 -0
- package/skills/blueking-chat-x/references/components/input-menu-panel.md +162 -0
- package/skills/blueking-chat-x/references/components/interrupt-message.md +212 -0
- package/skills/blueking-chat-x/references/components/key-value-content.md +128 -0
- package/skills/blueking-chat-x/references/components/knowledge-rag-content.md +122 -0
- package/skills/blueking-chat-x/references/components/latex-content.md +200 -0
- package/skills/blueking-chat-x/references/components/loading-message.md +192 -0
- package/skills/blueking-chat-x/references/components/markdown-content.md +232 -0
- package/skills/blueking-chat-x/references/components/mention-tag.md +79 -0
- package/skills/blueking-chat-x/references/components/mention-text.md +83 -0
- package/skills/blueking-chat-x/references/components/mermaid-content.md +189 -0
- package/skills/blueking-chat-x/references/components/message-container.md +645 -0
- package/skills/blueking-chat-x/references/components/message-loading.md +118 -0
- package/skills/blueking-chat-x/references/components/message-render.md +327 -0
- package/skills/blueking-chat-x/references/components/message-time.md +177 -0
- package/skills/blueking-chat-x/references/components/message-tools.md +427 -0
- package/skills/blueking-chat-x/references/components/model-selector.md +157 -0
- package/skills/blueking-chat-x/references/components/preview-toolbar.md +42 -0
- package/skills/blueking-chat-x/references/components/questions-container.md +85 -0
- package/skills/blueking-chat-x/references/components/reasoning-message.md +232 -0
- package/skills/blueking-chat-x/references/components/reference-content.md +135 -0
- package/skills/blueking-chat-x/references/components/reference-doc-content.md +109 -0
- package/skills/blueking-chat-x/references/components/resource-icon.md +98 -0
- package/skills/blueking-chat-x/references/components/scroll-btn.md +159 -0
- package/skills/blueking-chat-x/references/components/selection-footer.md +78 -0
- package/skills/blueking-chat-x/references/components/selection-question.md +88 -0
- package/skills/blueking-chat-x/references/components/shortcut-btn.md +204 -0
- package/skills/blueking-chat-x/references/components/shortcut-btns.md +266 -0
- package/skills/blueking-chat-x/references/components/shortcut-render.md +424 -0
- package/skills/blueking-chat-x/references/components/simple-table.md +101 -0
- package/skills/blueking-chat-x/references/components/text-content.md +80 -0
- package/skills/blueking-chat-x/references/components/tool-approval-card.md +183 -0
- package/skills/blueking-chat-x/references/components/tool-btn.md +317 -0
- package/skills/blueking-chat-x/references/components/tool-message.md +235 -0
- package/skills/blueking-chat-x/references/components/toolcall-render.md +348 -0
- package/skills/blueking-chat-x/references/components/user-feedback.md +233 -0
- package/skills/blueking-chat-x/references/components/user-message.md +444 -0
- package/skills/blueking-chat-x/references/components/user-question-answered-card.md +104 -0
- package/skills/blueking-chat-x/references/components/user-question-card.md +231 -0
- package/skills/blueking-chat-x/references/components/user-question-choice.md +105 -0
- package/skills/blueking-chat-x/references/components/user-question-option.md +42 -0
- package/skills/blueking-chat-x/references/components/vnode-renderer.md +122 -0
- package/skills/blueking-chat-x/references/composables/use-animation-text.md +196 -0
- package/skills/blueking-chat-x/references/composables/use-artifact-preview.md +235 -0
- package/skills/blueking-chat-x/references/composables/use-clipboard.md +203 -0
- package/skills/blueking-chat-x/references/composables/use-command-selection.md +150 -0
- package/skills/blueking-chat-x/references/composables/use-container-scroll.md +57 -0
- package/skills/blueking-chat-x/references/composables/use-custom-tab.md +158 -0
- package/skills/blueking-chat-x/references/composables/use-flow-node-actions.md +164 -0
- package/skills/blueking-chat-x/references/composables/use-full-screen.md +112 -0
- package/skills/blueking-chat-x/references/composables/use-global-config.md +155 -0
- package/skills/blueking-chat-x/references/composables/use-input-mention.md +115 -0
- package/skills/blueking-chat-x/references/composables/use-menu-keydown.md +161 -0
- package/skills/blueking-chat-x/references/composables/use-message-group.md +244 -0
- package/skills/blueking-chat-x/references/composables/use-observer-visible-list.md +188 -0
- package/skills/blueking-chat-x/references/composables/use-parent-scrolling.md +46 -0
- package/skills/blueking-chat-x/references/directives/index.md +61 -0
- package/skills/blueking-chat-x/references/directives/overflow-tips.md +205 -0
- package/skills/blueking-chat-x/references/icons/index.md +185 -0
- package/skills/blueking-chat-x/references/plugins/index.md +56 -0
- package/skills/blueking-chat-x/references/plugins/markdown-container.md +55 -0
- package/skills/blueking-chat-x/references/plugins/markdown-latex.md +205 -0
- package/skills/blueking-chat-x/references/plugins/markdown-mermaid.md +247 -0
- package/skills/blueking-chat-x/references/theme/theme.md +423 -0
- package/skills/blueking-chat-x/references/types/constants.md +340 -0
- package/skills/blueking-chat-x/references/types/index.md +120 -0
- package/skills/blueking-chat-x/references/types/interrupt.md +379 -0
- package/skills/blueking-chat-x/references/types/messages.md +556 -0
- package/skills/blueking-chat-x/references/types/schema.md +91 -0
- package/skills/blueking-chat-x/references/utils/index.md +196 -0
- package/skills/blueking-chat-x/scripts/generate-references.mjs +536 -0
- package/dist/components/chat-input/ai-slash-editor/ai-slash-editor.vue.d.ts +0 -28
- package/dist/components/chat-input/ai-slash-editor/theme.d.ts +0 -24
- package/dist/mcp/generated/docs/ai-prompt-list.md +0 -45
- package/dist/mcp/generated/docs/ai-skill-list.md +0 -75
- package/dist/mcp/generated/docs/ai-slash-editor.md +0 -43
- package/dist/mcp/generated/docs/ai-slash-menu.md +0 -42
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# CiteContent 引用内容
|
|
2
|
+
|
|
3
|
+
> 能力域:内容渲染 | 未从包入口导出:内部组件,请通过上层组件使用 | since 1.0.0
|
|
4
|
+
|
|
5
|
+
渲染输入或消息中的引用片段。 源码位置:src/components/chat-content/cite-content/cite-content.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:chat-input(输入区展示待发送引用内容)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# CiteContent 引用内容
|
|
12
|
+
## 源码事实
|
|
13
|
+
|
|
14
|
+
- **源码位置**:`src/components/chat-content/cite-content/cite-content.vue`
|
|
15
|
+
- **能力域**:内容渲染
|
|
16
|
+
- **能力说明**:渲染输入或消息中的引用片段。
|
|
17
|
+
|
|
18
|
+
> **能力域**:内容渲染
|
|
19
|
+
|
|
20
|
+
展示被引用文本片段的紧凑条带组件。固定高度 28px,左侧引用图标 + 单行截断文本 + 可选关闭图标,背景灰色(`#f5f7fa`),hover 背景为 `#eaebf0`。
|
|
21
|
+
|
|
22
|
+
常见于两处:
|
|
23
|
+
|
|
24
|
+
- **`UserMessage`**:`property.extra.cite` 为字符串时,渲染在消息气泡上方
|
|
25
|
+
- **`ChatInput`**:通过 `v-model:cite` 绑定,渲染在输入框顶部,关闭后清空引用
|
|
26
|
+
|
|
27
|
+
## 组件结构
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
.ai-cite-content(flex,height: 28px,padding: 0 8px,gap: 4px,bg: #f5f7fa,hover: #eaebf0,border-radius: 4px,margin-bottom: 4px)
|
|
31
|
+
├── CiteIcon(14×14px,color: #979ba5,始终显示)
|
|
32
|
+
├── .ai-cite-content-text(flex: 1,单行截断,color: #979ba5,overflow: hidden,text-overflow: ellipsis)
|
|
33
|
+
│ {{ content }}(Vue 文本插值,XSS 安全)
|
|
34
|
+
└── CloseIcon(14×14px,color: #979ba5,v-if="onClose",hover: #4d4f56)
|
|
35
|
+
@click → onClose(content)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 基础用法
|
|
39
|
+
|
|
40
|
+
```vue
|
|
41
|
+
<template>
|
|
42
|
+
<CiteContent content="这是一段被引用的文本" />
|
|
43
|
+
</template>
|
|
44
|
+
|
|
45
|
+
<script setup lang="ts">
|
|
46
|
+
import { CiteContent } from '@blueking/chat-x';
|
|
47
|
+
</script>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 可关闭引用
|
|
51
|
+
|
|
52
|
+
传入 `onClose` 函数后,右侧显示关闭图标;点击时将当前 `content` 作为参数回传给 `onClose`:
|
|
53
|
+
|
|
54
|
+
```vue
|
|
55
|
+
<template>
|
|
56
|
+
<CiteContent
|
|
57
|
+
v-if="showCite"
|
|
58
|
+
content="这是一段可关闭的引用文本"
|
|
59
|
+
:on-close="handleClose"
|
|
60
|
+
/>
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
<script setup lang="ts">
|
|
64
|
+
import { CiteContent } from '@blueking/chat-x';
|
|
65
|
+
|
|
66
|
+
const handleClose = (content: string) => {
|
|
67
|
+
// content 即当前引用文本,可用于日志或状态清除
|
|
68
|
+
console.log('关闭引用:', content);
|
|
69
|
+
};
|
|
70
|
+
</script>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## 长文本截断
|
|
74
|
+
|
|
75
|
+
文本超出容器宽度时自动单行截断(`text-overflow: ellipsis`),始终保持 28px 高度不变形:
|
|
76
|
+
|
|
77
|
+
## 与 ChatInput 配合
|
|
78
|
+
|
|
79
|
+
`ChatInput` 通过 `v-model:cite` 内置了 `CiteContent`,当 `cite` 有值时自动渲染在输入框顶部(`input-header` slot 位置);用户点击关闭时,内部调用 `citeModel.value = ''` 清空引用:
|
|
80
|
+
|
|
81
|
+
```vue
|
|
82
|
+
<template>
|
|
83
|
+
<ChatInput
|
|
84
|
+
v-model="inputValue"
|
|
85
|
+
v-model:cite="citeText"
|
|
86
|
+
/>
|
|
87
|
+
</template>
|
|
88
|
+
|
|
89
|
+
<script setup lang="ts">
|
|
90
|
+
import { ref } from 'vue';
|
|
91
|
+
import { ChatInput } from '@blueking/chat-x';
|
|
92
|
+
|
|
93
|
+
const inputValue = ref('');
|
|
94
|
+
const citeText = ref('');
|
|
95
|
+
|
|
96
|
+
// 用户通过 AiSelection 划词后,将选中文本赋值给 citeText
|
|
97
|
+
// ChatInput 会自动在顶部显示 CiteContent,用户点击关闭时 citeText 自动清空
|
|
98
|
+
function onUserSelectText(selectedText: string) {
|
|
99
|
+
citeText.value = selectedText;
|
|
100
|
+
}
|
|
101
|
+
</script>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 与 UserMessage 配合
|
|
105
|
+
|
|
106
|
+
`UserMessage` 在 `property.extra.cite` 为字符串时,自动在气泡上方渲染 `CiteContent`(不带关闭按钮):
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
const message = {
|
|
110
|
+
role: 'user',
|
|
111
|
+
content: '这段代码有什么性能问题?',
|
|
112
|
+
property: {
|
|
113
|
+
extra: {
|
|
114
|
+
// 字符串类型 → 渲染 CiteContent(气泡外上方)
|
|
115
|
+
cite: 'for (let i = 0; i < arr.length; i++) {\n fetch(`/api/${arr[i]}`)\n}',
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## API
|
|
122
|
+
|
|
123
|
+
### Props
|
|
124
|
+
|
|
125
|
+
| 属性名 | 类型 | 必填 | 说明 |
|
|
126
|
+
| ------- | --------------------------- | ---- | --------------------------------------------------------- |
|
|
127
|
+
| content | `string` | ✓ | 引用的文本内容;使用 Vue 文本插值渲染,XSS 安全 |
|
|
128
|
+
| onClose | `(content: string) => void` | — | 关闭回调;传入后右侧显示关闭图标,点击时将 `content` 回传 |
|
|
129
|
+
|
|
130
|
+
> **XSS 安全**:`content` 通过 `{{ content }}` 文本插值渲染,不会执行 HTML 标签或脚本。
|
|
131
|
+
|
|
132
|
+
## 样式说明
|
|
133
|
+
|
|
134
|
+
| 元素 | 关键样式 |
|
|
135
|
+
| ------------------------ | --------------------------------------------------------------------------------------------------- |
|
|
136
|
+
| `.ai-cite-content` | `height: 28px`,`padding: 0 8px`,`background: #f5f7fa`,hover `#eaebf0`,`margin-bottom: 4px`(为下方内容留出间距) |
|
|
137
|
+
| `.ai-cite-content-text` | `flex: 1`,`white-space: nowrap`,`overflow: hidden`,`text-overflow: ellipsis`,`color: #979ba5` |
|
|
138
|
+
| `CiteIcon` / `CloseIcon` | `14×14px`,`color: #979ba5`;CloseIcon hover 变为 `#4d4f56` |
|
|
139
|
+
|
|
140
|
+
## 关联组件
|
|
141
|
+
|
|
142
|
+
- [ChatInput](/components/input/chat-input) — 引用区常见挂载位置
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# CodeContent 代码块
|
|
2
|
+
|
|
3
|
+
> 能力域:内容渲染 | 导入:`import { CodeContent } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
+
|
|
5
|
+
渲染 Markdown 代码块,支持高亮、复制和 header 插槽。 源码位置:src/components/markdown-token/code-content/code-content.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:markdown-content(解析 Markdown 后生成 fence token 并渲染本组件)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# CodeContent 代码块渲染
|
|
12
|
+
## 源码事实
|
|
13
|
+
|
|
14
|
+
- **源码位置**:`src/components/markdown-token/code-content/code-content.vue`
|
|
15
|
+
- **能力域**:内容渲染
|
|
16
|
+
- **能力说明**:渲染 Markdown 代码块,支持高亮、复制和 header 插槽。
|
|
17
|
+
|
|
18
|
+
> **能力域**:内容渲染
|
|
19
|
+
|
|
20
|
+
代码块渲染基础组件,专为 **Markdown 流式输出**设计。接收 `markdown-it` token 数组,基于 `highlight.js`(github-dark 主题)实现逐行语法高亮,顶部固定深色头部展示语言名和复制按钮。
|
|
21
|
+
|
|
22
|
+
## 组件结构
|
|
23
|
+
|
|
24
|
+
根类名为 **`.ai-code-content-wrapper`**:外层宽度、下边距以及 **`.code-content-header`**(深色顶栏)在任意父级下均生效。**代码区** `.hljs-pre`、行内高亮等样式选择器为 **`.ai-message-container .ai-code-content-wrapper`**,仅在消息列表(`MessageContainer` 根上的 `ai-message-container`)内与对话区一致。Wiki 与业务中若要完整还原代码区外观,请将 `CodeContent` 包在带 `ai-message-container` 类名的父节点内。
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
.ai-code-content-wrapper
|
|
28
|
+
├── .code-content-header(深色顶栏;不依赖 .ai-message-container)
|
|
29
|
+
│ ├── .code-header-language(token.info)
|
|
30
|
+
│ ├── slot#header({ language, token })
|
|
31
|
+
│ └── ToolBtn id="copy"
|
|
32
|
+
│
|
|
33
|
+
└── .hljs-pre(完整 padding / 背景 / code 字体:需父级为 .ai-message-container .ai-code-content-wrapper)
|
|
34
|
+
└── <code class="hljs language-{raw-info}">
|
|
35
|
+
├── v-for completedLines → <span class="code-line" />
|
|
36
|
+
└── v-if currentLineText → <span class="code-line current-line" />
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 基础用法
|
|
40
|
+
|
|
41
|
+
`token` 接收 `markdown-it` 解析生成的 token 数组,组件从中提取第一个 `fence` 或 `code_block` token 渲染:
|
|
42
|
+
|
|
43
|
+
```vue
|
|
44
|
+
<template>
|
|
45
|
+
<!-- 代码区 .hljs-pre 的完整样式依赖父级 .ai-message-container(与对话消息区一致);顶栏单独也可用 -->
|
|
46
|
+
<div class="ai-message-container">
|
|
47
|
+
<CodeContent
|
|
48
|
+
:token="codeTokens"
|
|
49
|
+
@mounted="handleMounted"
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<script setup lang="ts">
|
|
55
|
+
import { CodeContent } from '@blueking/chat-x';
|
|
56
|
+
import type { Token } from 'markdown-it';
|
|
57
|
+
|
|
58
|
+
const codeTokens: Token[] = [
|
|
59
|
+
{
|
|
60
|
+
type: 'fence',
|
|
61
|
+
tag: 'code',
|
|
62
|
+
info: 'typescript',
|
|
63
|
+
content: 'const greeting = "Hello, World!";\nconsole.log(greeting);',
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
const handleMounted = ({ el }: { el: HTMLElement | null }) => {
|
|
68
|
+
// el 是 <code> 元素的 DOM 引用(通过懒加载 getter 访问)
|
|
69
|
+
console.log('代码块已渲染:', el);
|
|
70
|
+
};
|
|
71
|
+
</script>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**TypeScript**
|
|
75
|
+
|
|
76
|
+
**Python**
|
|
77
|
+
|
|
78
|
+
**SQL**
|
|
79
|
+
|
|
80
|
+
## 流式渲染
|
|
81
|
+
|
|
82
|
+
组件的核心设计场景。流式输入时,每次 `token[].content` 追加新内容,只更新最后一行,已完成的行通过**内容比较复用缓存**,无需重新高亮:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
content 变化 → watch(immediate: true, deep: true) → processContent()
|
|
86
|
+
→ split('\n')
|
|
87
|
+
→ 除最后一行:与 completedLines 对比,内容未变则复用,否则重新 highlightLine
|
|
88
|
+
→ 最后一行:highlightLine 并赋值给 currentLineHtml(v-html 渲染)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**注意**:当 content 以 `\n` 结尾时,`split('\n')` 末尾为 `''`,`currentLineText = ''`,`.current-line` 元素不渲染(`v-if="currentLineText"`)。
|
|
92
|
+
|
|
93
|
+
```vue
|
|
94
|
+
<script setup lang="ts">
|
|
95
|
+
import { ref } from 'vue';
|
|
96
|
+
import { CodeContent } from '@blueking/chat-x';
|
|
97
|
+
|
|
98
|
+
const streamingTokens = ref([{ type: 'fence', tag: 'code', info: 'typescript', content: '' }]);
|
|
99
|
+
|
|
100
|
+
async function simulateStream() {
|
|
101
|
+
let content = '';
|
|
102
|
+
for (const char of fullCode) {
|
|
103
|
+
await new Promise(r => setTimeout(r, 20));
|
|
104
|
+
content += char;
|
|
105
|
+
// 每次只更新 content,token 数组引用可保持同一个对象(deep watch)
|
|
106
|
+
streamingTokens.value = [{ type: 'fence', tag: 'code', info: 'typescript', content }];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
</script>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## 语言识别
|
|
113
|
+
|
|
114
|
+
### 内置别名映射
|
|
115
|
+
|
|
116
|
+
组件在 `MarkdownLanguageMap` 中维护了 3 个常用别名,`info` 字段使用别名时自动映射:
|
|
117
|
+
|
|
118
|
+
| `info` 值 | 映射后 | 说明 |
|
|
119
|
+
| --------- | ------------ | ---- |
|
|
120
|
+
| `js` | `javascript` | — |
|
|
121
|
+
| `ts` | `typescript` | — |
|
|
122
|
+
| `py` | `python` | — |
|
|
123
|
+
|
|
124
|
+
### 解析优先级
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
1. MarkdownLanguageMap[info] → 尝试别名映射
|
|
128
|
+
2. hljs.getLanguage(mappedLang) → 检查 hljs 是否支持
|
|
129
|
+
3. 提取文件扩展名(如 "index.ts" → "ts")→ 再次查询 hljs
|
|
130
|
+
4. 均不匹配 → resolveLanguage 返回 null → 对内容进行 HTML 转义(非高亮)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
> **注意**:`code` 元素的 class 使用原始 `token.info`(`language-{info}`),不是解析后的语言名。即 `info: 'js'` → `class="language-js"`,但高亮时用 `javascript`。
|
|
134
|
+
|
|
135
|
+
### 未知语言(HTML 转义)
|
|
136
|
+
|
|
137
|
+
当语言无法识别时,内容经过 HTML 转义(`<` `>` `&` `"`)后直接渲染,不进行语法高亮:
|
|
138
|
+
|
|
139
|
+
### 无语言标识
|
|
140
|
+
|
|
141
|
+
`info` 为空字符串时,语言区域留空,内容同样走 HTML 转义路径:
|
|
142
|
+
|
|
143
|
+
## 高亮缓存
|
|
144
|
+
|
|
145
|
+
每行代码的高亮结果缓存在组件实例内部的 `Map<string, string>` 中(key 为 `"${lang}:${lineContent}"`),最大容量 500 条;超限后清除前 250 条(LRU 近似):
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const lineHighlightCache = new Map<string, string>();
|
|
149
|
+
const MAX_CACHE_SIZE = 500;
|
|
150
|
+
|
|
151
|
+
// 超限时清理前半部分
|
|
152
|
+
if (lineHighlightCache.size > MAX_CACHE_SIZE) {
|
|
153
|
+
const keys = Array.from(lineHighlightCache.keys()).slice(0, MAX_CACHE_SIZE / 2);
|
|
154
|
+
keys.forEach(k => lineHighlightCache.delete(k));
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## API
|
|
159
|
+
|
|
160
|
+
### Props
|
|
161
|
+
|
|
162
|
+
| 属性名 | 类型 | 必填 | 说明 |
|
|
163
|
+
| ------ | --------- | ---- | ------------------------------------------------------------------------ |
|
|
164
|
+
| token | `Token[]` | ✓ | markdown-it token 数组;组件提取其中第一个 `fence` 或 `code_block` token |
|
|
165
|
+
|
|
166
|
+
### Events
|
|
167
|
+
|
|
168
|
+
| 事件名 | 参数类型 | 触发时机 |
|
|
169
|
+
| ------- | ----------------------------- | --------------------------------------------------------------------------------- |
|
|
170
|
+
| mounted | `{ el: HTMLElement \| null }` | 每次 `token` 变化后 `nextTick` 完成时;`el` 为 `<code>` 元素引用(懒加载 getter) |
|
|
171
|
+
|
|
172
|
+
### Slots
|
|
173
|
+
|
|
174
|
+
| 插槽名 | 参数 | 说明 |
|
|
175
|
+
| ------ | -------------------------------------- | ------------------------------------------------------------------------------------------ |
|
|
176
|
+
| header | `{ language: string; token: Token[] }` | 代码块头部自定义内容区域,渲染在语言标签和复制按钮之间,可用于添加"插入"、"应用"等操作按钮 |
|
|
177
|
+
|
|
178
|
+
> **`mounted` 频率**:由于 `watch` 设置了 `immediate: true` 和 `deep: true`,每次 `token` 内容变化(包括初始化)都会触发 `mounted` 事件。
|
|
179
|
+
|
|
180
|
+
## Token 结构
|
|
181
|
+
|
|
182
|
+
组件从 token 数组中提取第一个匹配的 token:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// 组件接受的 token 格式(只使用这 3 个字段)
|
|
186
|
+
interface CodeToken {
|
|
187
|
+
type: 'fence' | 'code_block'; // 触发提取的条件
|
|
188
|
+
info: string; // 语言标识(如 'typescript'),显示在头部
|
|
189
|
+
content: string; // 代码内容(换行符 '\n' 分隔多行)
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
完整 Token 类型从 `markdown-it` 包引入:
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
import type { Token } from 'markdown-it';
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## 样式说明
|
|
200
|
+
|
|
201
|
+
| 区域 | 关键样式 |
|
|
202
|
+
| ----------------------- | ------------------------------------------------------------------------------------ |
|
|
203
|
+
| `.code-content-header` | `height: 40px`,`background: #2f333d`,`border: 1px solid #1a1a1a`,圆角仅顶部 `6px` |
|
|
204
|
+
| `.code-header-language` | `color: #999`,`font-size: 12px`,`margin-right: auto`(推复制按钮到右侧) |
|
|
205
|
+
| `.hljs-pre` | `background: #282c34`,`padding: 8px 16px`,`overflow-x: auto`,圆角仅底部 `6px` |
|
|
206
|
+
| `code` | `color: #abb2bf`,`font-size: 13px`,`line-height: 1.5`,等宽字体栈 |
|
|
207
|
+
| `.code-line` | `display: inline`(保持行内流式拼接) |
|
|
208
|
+
|
|
209
|
+
## 关联组件
|
|
210
|
+
|
|
211
|
+
- [MarkdownContent](/components/rendering/markdown-content) — 解析并传入 code fence token
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# CollapsibleContent 折叠内容
|
|
2
|
+
|
|
3
|
+
> 能力域:内容渲染 | 未从包入口导出:内部组件,请通过上层组件使用 | since 0.0.51
|
|
4
|
+
|
|
5
|
+
CollapsibleContent 用 ResizeObserver 持续测量插槽真实高度,超过 maxHeight(默认 200px)才折叠并显示切换按钮; 折叠通过外层 max-height + overflow hidden 实现,展开态可由 v-model:expanded 受控,便于「全部展开」这类批量操作。 源码位置:src/components/chat-content/collapsible-content/collapsible-content.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:user-message(用户消息正文超过 200px 时折叠)、activity-layout(活动消息的另一种折叠布局)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# CollapsibleContent 折叠内容
|
|
12
|
+
|
|
13
|
+
> **能力域**:内容渲染
|
|
14
|
+
|
|
15
|
+
## 源码事实
|
|
16
|
+
|
|
17
|
+
- **源码位置**:`src/components/chat-content/collapsible-content/collapsible-content.vue`
|
|
18
|
+
- **能力说明**:默认插槽内容高度超过 `maxHeight` 时折叠,并在下方渲染「显示更多 / 收起」;未超出时**不渲染**切换按钮。
|
|
19
|
+
- **切换按钮配色**:默认 `$color-text-secondary`(#979ba5),hover 转 `$color-text`(#4d4f56),箭头图标随展开态旋转。
|
|
20
|
+
|
|
21
|
+
## 实现要点
|
|
22
|
+
|
|
23
|
+
- **高度测量与折叠分离**:折叠由外层 `max-height` + `overflow: hidden` 实现,真实高度始终从内层测量容器读取,因此折叠状态不会污染测量结果。
|
|
24
|
+
- **持续跟踪高度**:内容可能因为图片加载、流式追加或窗口缩放而变高,用 `ResizeObserver` 持续观测而非只测一次;`ResizeObserver` 不可用时不折叠(降级为完整展示)。
|
|
25
|
+
- **展开态可受控**:`v-model:expanded` 允许外部驱动,便于实现「全部展开」;不绑定时组件内部自持。
|
|
26
|
+
|
|
27
|
+
## 用法
|
|
28
|
+
|
|
29
|
+
::: info 内部组件
|
|
30
|
+
本组件不在包入口导出,由消息组件内部使用。
|
|
31
|
+
:::
|
|
32
|
+
|
|
33
|
+
```vue
|
|
34
|
+
<template>
|
|
35
|
+
<CollapsibleContent :max-height="200">
|
|
36
|
+
<TextContent :content="content" />
|
|
37
|
+
</CollapsibleContent>
|
|
38
|
+
|
|
39
|
+
<!-- 外部受控展开态 -->
|
|
40
|
+
<CollapsibleContent v-model:expanded="allExpanded" :max-height="120">
|
|
41
|
+
<MarkdownContent :content="content" />
|
|
42
|
+
</CollapsibleContent>
|
|
43
|
+
</template>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**渲染效果**(阈值 120px,可用按钮切换展开态)
|
|
47
|
+
|
|
48
|
+
## API
|
|
49
|
+
|
|
50
|
+
### Props
|
|
51
|
+
|
|
52
|
+
| 属性名 | 类型 | 默认值 | 必填 | 说明 |
|
|
53
|
+
| --------- | -------- | ------ | ---- | ---------------------------------------------- |
|
|
54
|
+
| maxHeight | `number` | `200` | - | 折叠态下内容区最大高度(px),超出才出现按钮 |
|
|
55
|
+
| expanded | `boolean` | `false` | - | 展开态,支持 `v-model:expanded` |
|
|
56
|
+
|
|
57
|
+
### Emits
|
|
58
|
+
|
|
59
|
+
| 事件名 | 参数 | 触发时机 |
|
|
60
|
+
| --------------- | ------------------- | ------------------ |
|
|
61
|
+
| update:expanded | `(value: boolean)` | 点击切换按钮 |
|
|
62
|
+
|
|
63
|
+
### Slots
|
|
64
|
+
|
|
65
|
+
| 插槽名 | 说明 |
|
|
66
|
+
| ------- | ---------------- |
|
|
67
|
+
| default | 被折叠的内容 |
|
|
68
|
+
|
|
69
|
+
## 使用方
|
|
70
|
+
|
|
71
|
+
[UserMessage](/components/message/user-message) 用它把用户消息正文限制在 `CONST_USER_MESSAGE_MAX_HEIGHT`(200px)以内。
|
|
72
|
+
|
|
73
|
+
## 关联组件
|
|
74
|
+
|
|
75
|
+
- [UserMessage](/components/message/user-message) — 用户消息正文折叠
|
|
76
|
+
- [ActivityLayout](/components/helper/activity-layout) — 活动消息的折叠布局
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# CommonErrorContent 错误内容
|
|
2
|
+
|
|
3
|
+
> 能力域:内容渲染 | 导入:`import { commonErrorContent } from '@blueking/chat-x'` | since 1.0.0
|
|
4
|
+
|
|
5
|
+
展示统一错误提示内容。 源码位置:src/components/chat-content/common-error-content/common-error-content.vue。
|
|
6
|
+
|
|
7
|
+
**关联**:markdown-content(Markdown 渲染错误态展示)、reasoning-message(推理消息错误态展示)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# CommonErrorContent 通用错误内容
|
|
12
|
+
## 源码事实
|
|
13
|
+
|
|
14
|
+
- **源码位置**:`src/components/chat-content/common-error-content/common-error-content.vue`
|
|
15
|
+
- **能力域**:内容渲染
|
|
16
|
+
- **能力说明**:展示统一错误提示内容。
|
|
17
|
+
|
|
18
|
+
> **能力域**:内容渲染
|
|
19
|
+
|
|
20
|
+
错误状态消息渲染基础组件。红色 `ErrorIcon`(14×14px,绝对定位)+ 文本区域,`display: flex` 水平排列。
|
|
21
|
+
|
|
22
|
+
通常由上层组件在 `status === 'error'` 时自动渲染,无需手动使用。
|
|
23
|
+
|
|
24
|
+
## 组件结构
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
.ai-error-content(position: relative,display: flex,align-items: center)
|
|
28
|
+
├── ErrorIcon(position: absolute,top: 2px,left: 0,flex: 0 0 14px,14×14px,color: #ea3636)
|
|
29
|
+
└── .ai-error-content-text(flex: 1,margin-left: 20px,font-size: 12px,line-height: 20px,color: #4d4f56)
|
|
30
|
+
└── {{ content }}(Vue 文本插值,XSS 安全;content 为 undefined 时渲染空文本)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 基础用法
|
|
34
|
+
|
|
35
|
+
```vue
|
|
36
|
+
<template>
|
|
37
|
+
<CommonErrorContent content="请求失败,请稍后重试" />
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script setup lang="ts">
|
|
41
|
+
import { CommonErrorContent } from '@blueking/chat-x';
|
|
42
|
+
</script>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## 典型错误场景
|
|
46
|
+
|
|
47
|
+
## 不传 content
|
|
48
|
+
|
|
49
|
+
`content` 为可选,缺省时只渲染 `ErrorIcon`:
|
|
50
|
+
|
|
51
|
+
## 使用场景
|
|
52
|
+
|
|
53
|
+
组件库内部有两处自动使用:
|
|
54
|
+
|
|
55
|
+
| 使用方 | 触发条件 | 传入内容 |
|
|
56
|
+
| ------------------ | -------------------- | --------------------------------------------- |
|
|
57
|
+
| `MarkdownContent` | `status === 'error'` | `content`(字符串) |
|
|
58
|
+
| `ReasoningMessage` | `status === 'error'` | `content?.join('\n') \|\| ''`(数组转字符串) |
|
|
59
|
+
|
|
60
|
+
即 `AssistantMessage` / `ReasoningMessage` 在错误状态时,内容区域会自动替换为此组件,无需手动引入。
|
|
61
|
+
|
|
62
|
+
## API
|
|
63
|
+
|
|
64
|
+
### Props
|
|
65
|
+
|
|
66
|
+
| 属性名 | 类型 | 必填 | 说明 |
|
|
67
|
+
| ------- | -------- | ---- | --------------------------------------------------------------- |
|
|
68
|
+
| content | `string` | — | 错误提示文本;使用 Vue 文本插值渲染,XSS 安全;缺省时仅显示图标 |
|
|
69
|
+
|
|
70
|
+
## 关联组件
|
|
71
|
+
|
|
72
|
+
- [MarkdownContent](/components/rendering/markdown-content) — Markdown 错误态
|
|
73
|
+
- [ReasoningMessage](/components/message/reasoning-message) — 推理错误态
|