@szjy/ai-coms 0.1.7 → 0.1.8

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 CHANGED
@@ -1,6 +1,8 @@
1
1
  ## @szjy/ai-coms — Vue3 AI 聊天组件库
2
2
 
3
- 一个基于 Vue 3 与 Element Plus 的即插即用 AI 对话组件(SzAiChat)。支持多家大模型流式对话(Spark、Ollama、SiliconFlow、Kimi Moonshot、DashScope、数智建管等),内置消息面板、Markdown 渲染与高亮、流式增量显示、复制等常用能力,帮助你在业务系统中快速集成 AI 助手。
3
+ 一个基于 Vue 3 与 Element Plus 的即插即用 AI 对话组件(SzAiChat)。支持多家大模型流式对话(Spark、Ollama、SiliconFlow、Kimi Moonshot、DashScope、数智建管、Dify OpenAI 兼容等),内置消息面板、Markdown 渲染与高亮、流式增量显示、复制、消息后处理(messagePostRender)与路由链接渲染(routeLinkRender)等常用能力,帮助你在业务系统中快速集成 AI 助手。
4
+
5
+ > 当前版本:`0.1.8`
4
6
 
5
7
  ### 适用场景
6
8
  - 企业 Web 系统内嵌 AI 助手(客服、知识问答、项目辅助)
@@ -10,9 +12,10 @@
10
12
 
11
13
  ### 亮点
12
14
  - 统一组件:提供 `SzAiChat` 组件与安装器 `create`,一行注册、开箱即用。
13
- - 多模型接入:内置多种大模型接入方法与流式解析器,轻松切换。
15
+ - 多模型接入:内置多种大模型接入方法与流式解析器,通过 `llmName` 属性或 `?llmName=` 参数轻松切换。
14
16
  - 体验完善:欢迎页、快捷提问、消息气泡、Markdown 渲染、复制、抽屉模式切换。
15
- - 友好扩展:将流解析、API 调用、渲染拆分,方便替换与扩展。
17
+ - 消息后处理:通过 `messagePostRender` 回调在消息渲染完成后自定义处理 DOM,内置 `routeLinkRender` 支持 `#router:xxx#` 路由链接渲染。
18
+ - 友好扩展:将流解析、API 调用、渲染拆分,`extraConfig` 支持供应商级参数透传,方便替换与扩展。
16
19
 
17
20
 
18
21
  ---
@@ -20,15 +23,21 @@
20
23
  ### 目录结构说明
21
24
  ```text
22
25
  ai-coms/
23
- ├─ index.ts # 库入口:导出组件与安装器
26
+ ├─ index.ts # 库入口:导出组件、安装器与自定义渲染器
24
27
  ├─ vite.config.mts # Vite 构建配置(库模式)
25
28
  ├─ package.json # 包信息、脚本与依赖
29
+ ├─ docs/
30
+ │ └─ message-post-render.md # messagePostRender 与 routeLinkRender 使用教程
26
31
  ├─ public/ # 静态资源(图片、脚本、svg)
27
32
  │ ├─ images/ # 组件使用的图片与图标
28
33
  │ └─ scripts/ai/ # markdown-it 与 highlight.js 静态脚本
29
34
  ├─ packages/
30
35
  │ ├─ api/ai.ts # 多家大模型的流式请求封装(Fetch + SSE/JSON)
31
- │ ├─ common/utils/ # 通用工具(剪贴板、URL、loader 等)
36
+ │ ├─ common/
37
+ │ │ ├─ utils/ # 通用工具(剪贴板、URL、loader 等)
38
+ │ │ └─ custom-render/ # 自定义消息渲染器
39
+ │ │ ├─ index.ts # 出口汇总
40
+ │ │ └─ routeLinkRender.ts # #router:xxx# 路由链接渲染器
32
41
  │ └─ components/
33
42
  │ ├─ components.ts # 组件出口汇总(当前导出 AiChat)
34
43
  │ ├─ installer.ts # 全量安装器,循环注册所有导出的组件
@@ -49,7 +58,9 @@ ai-coms/
49
58
  └─ examples/ # 运行示例(Vite)
50
59
  ├─ main.ts # 示例入口,注册 Element Plus 与组件
51
60
  ├─ App.vue # 示例页面,包含 Tab 与 AiChat 使用
52
- └─ components/AiChatTab.vue # 组件使用样例(token/identifier/baseUrl 传参)
61
+ └─ components/
62
+ ├─ AiChatTab.vue # 组件使用样例(token/identifier/baseUrl 传参)
63
+ └─ DifyOpenAIChatTab.vue # Dify OpenAI 兼容 provider 使用样例
53
64
  ```
54
65
 
55
66
  模块依赖与调用流向(简化):
@@ -77,7 +88,7 @@ graph TD
77
88
 
78
89
  运行所需依赖(节选,详见 package.json):
79
90
  - 生产依赖:`vue@^3.4.21`、`element-plus@2.7.1`、`aa-loader@^0.1.5`
80
- - 开发依赖:`vite`、`@vitejs/plugin-vue`、`vite-plugin-dts`、`typescript`、`vue-tsc`、`sass/less` 等
91
+ - 开发依赖:`vite@^5`、`@vitejs/plugin-vue`、`@vitejs/plugin-vue-jsx`、`vite-plugin-dts`、`vite-plugin-svg-icons`、`unplugin-icons` + `@iconify-json/mdi`(示例用 `~icons/mdi`)、`unplugin-vue-components`、`typescript`、`vue-tsc`、`sass/less` 等
81
92
 
82
93
  浏览器兼容:现代浏览器(需支持 ReadableStream/TransformStream 的流式能力;如需更广兼容度请添加 Polyfill)。
83
94
 
@@ -140,13 +151,34 @@ app.use(ElementPlus).use(szAIKits).mount('#app')
140
151
  在页面中引入:
141
152
  ```vue
142
153
  <template>
143
- <sz-ai-chat :token="token" :identifier="identifier" :baseUrl="baseUrl" :title="'数智AI助理'" />
154
+ <sz-ai-chat
155
+ :token="token"
156
+ :identifier="identifier"
157
+ :baseUrl="baseUrl"
158
+ :title="'数智AI助理'"
159
+ llmName="szjy"
160
+ :messagePostRender="handleMessagePostRender"
161
+ :extraConfig="{ projectId: 26 }"
162
+ />
144
163
  <!-- 右下角悬浮按钮点击后弹出对话面板 -->
145
- <!-- 可通过 ?llmName=szjy 切换默认大模型(支持 standard/spark/ollama3/siliconflow/moonshot/dashscope/szjy) -->
164
+ <!-- 可通过 llmName 属性或 ?llmName=szjy 切换默认大模型 -->
165
+ <!-- 支持 standard/spark/ollama3/siliconflow/moonshot/dashscope/szjy/dify-openai -->
146
166
  <!-- e.g. http://localhost:8810/?llmName=spark -->
147
167
  </template>
148
168
  ```
149
169
 
170
+ 组件 Props:
171
+
172
+ | 属性 | 类型 | 默认值 | 说明 |
173
+ |---|---|---|---|
174
+ | token | string | `''` | 大模型 API 的鉴权 token |
175
+ | identifier | string | `''` | 项目/租户标识符(数智建管、Dify 等使用) |
176
+ | baseUrl | string | `''` | 自定义接口前缀(数智建管、Dify 等使用) |
177
+ | title | string | `'数智AI助理'` | 对话面板标题 |
178
+ | llmName | string | `'szjy'` | 大模型名称,对应 `LLMTypes` 中的 `modelName` |
179
+ | messagePostRender | Function | `null` | 消息渲染完成后的回调 `(container, textContent) => void` |
180
+ | extraConfig | Object | `{}` | 额外配置参数,透传给供应商 API(如 `{ projectId }`、`{ authToken }`) |
181
+
150
182
  主要功能:
151
183
  - 悬浮入口与关闭:右下角按钮打开对话,悬浮关闭按钮隐藏组件。
152
184
  - 欢迎页与快捷提问:无对话时显示欢迎与常见问题,点击自动填充发送。
@@ -181,20 +213,34 @@ sequenceDiagram
181
213
  ### API 接口文档(前端调用封装)
182
214
  文件:`packages/api/ai.ts`(基于浏览器 `fetch`,返回 `Promise<Response>`,调用处继续基于 `Response.body` 进行流式读取)
183
215
 
184
- 公共说明:所有接口均使用 `POST`,默认 `stream: true`,对于需要鉴权的接口通过 `Authorization: Bearer <token>` 头传递。
216
+ 公共说明:所有接口均使用 `POST`,默认 `stream: true`,对于需要鉴权的接口通过 `Authorization: Bearer <token>` 头传递。所有函数签名统一为 `(text, token, identifier, baseUrl, extraConfig)`,未使用的参数可留空。
185
217
 
186
218
  | 函数名 | 说明 | 请求路径 | 认证 | 主要参数 | 备注 |
187
219
  |---|---|---|---|---|---|
220
+ | createDifyOpenAIStylized(text, token, identifier, baseUrl, extraConfig) | Dify(OpenAI 兼容) | `${ensureFullURL(baseUrl)}/v1/chat/completions` | Bearer(authToken) | text, token, identifier, baseUrl, extraConfig | 请求体含 `inputs.token`、`inputs.projectCode`,`extraConfig.authToken` 为 Dify 应用密钥,`extraConfig.projectId` 可选 |
188
221
  | createOllama3Stylized(text) | 本地 Ollama3 | `http://localhost:11434/api/chat` | 否 | text | 模型固定 `llama3` |
189
- | createSparkStylized(text, token) | 科大讯飞 Spark | `${location.origin}/spark/v1/chat/completions` | Bearer | text, token | SSE `data:` JSON |
222
+ | createSparkStylized(text, token) | 科大讯飞 Spark | `${location.origin}/spark/v1/chat/completions` | Bearer | text, token | SSE `data:` JSON 行,模型 `generalv4.0Ultra` |
190
223
  | createSiliconFlowStylized(text, token) | SiliconFlow | `${location.origin}/siliconflow/v1/chat/completions` | Bearer | text, token | 兼容 OpenAI 接口格式 |
191
224
  | createKimiMoonshotStylized(text, token) | Moonshot | `${location.origin}/moonshot/v1/chat/completions` | Bearer | text, token | 提供 system 提示 |
192
225
  | createDashScopeStylized(text, token) | 通义千问 | `${location.origin}/dashscope/compatible-mode/v1/chat/completions` | Bearer | text, token | 兼容 OpenAI 路径 |
193
226
  | createSZJYStylized(text, token, identifier, baseUrl) | 数智建管 | `${ensureFullURL(baseUrl)}/support/${identifier}/a` | Bearer | text, token, identifier, baseUrl | 业务网关需配置 |
194
227
 
228
+ 大模型映射(`LLMTypes`,`packages/components/AiChat/src/transform/index.ts`):
229
+
230
+ | modelName | label | api |
231
+ |---|---|---|
232
+ | standard | 模拟数据模型 | null(本地模拟,不发起请求) |
233
+ | spark | Spark 星火大模型 | createSparkStylized |
234
+ | ollama3 | Ollama 3 大模型 | createOllama3Stylized |
235
+ | siliconflow | SiliconFlow 硅基流动大模型 | createSiliconFlowStylized |
236
+ | moonshot | Kimi Moonshot 月之暗面大模型 | createKimiMoonshotStylized |
237
+ | dashscope | 通义千问大模型 | createDashScopeStylized |
238
+ | szjy | 数智建管大模型 | createSZJYStylized |
239
+ | dify-openai | Dify (OpenAI 兼容) | createDifyOpenAIStylized |
240
+
195
241
  流解析器(`packages/components/AiChat/src/transform/index.ts`):
196
242
  - `splitStream('\n')` 将 `ReadableStream<string>` 按行切分,兼容 `SSE data:` 与直接 JSON 片段。
197
- - `transformStreamValue` 针对各模型对单行数据进行解析,统一返回 `{ content, done }`。
243
+ - `transformStreamValue` 针对各模型对单行数据进行解析,统一返回 `{ content, done }`;`dify-openai`、`siliconflow`、`moonshot`、`dashscope`、`szjy` 均复用 `spark` 的 OpenAI 兼容解析逻辑。
198
244
 
199
245
  在组件中,`createAssistantWriterStylized` 会把 `Response.body` 管道化为可读 `reader`,再交给 `Previewer` 逐步渲染。
200
246
 
@@ -202,12 +248,60 @@ sequenceDiagram
202
248
  ---
203
249
 
204
250
  ### 配置与扩展
205
- - 切换默认模型:在地址栏加上 `?llmName=<name>`(支持:`standard`、`spark`、`ollama3`、`siliconflow`、`moonshot`、`dashscope`、`szjy`)。
251
+ - 切换默认模型:使用 `llmName` 属性,或在地址栏加上 `?llmName=<name>`(支持:`standard`、`spark`、`ollama3`、`siliconflow`、`moonshot`、`dashscope`、`szjy`、`dify-openai`)。
252
+ - 供应商参数透传:通过 `extraConfig` 传入供应商级配置(如 Dify 的 `authToken`、`projectId`)。
253
+ - 消息后处理:通过 `messagePostRender` 回调在消息渲染完成后自定义处理 DOM(详见下节)。
206
254
  - 自定义图标:`SvgIcon` 支持传入绝对路径或 `/images/svg/*.svg`,颜色通过滤镜近似实现。
207
255
  - 组件前缀:`packages/components/contants.ts` 中 `COMP_PREFIX = 'Sz'`,通过 `create({ componentPrefix })` 可定制。
208
256
  - 版本常量:`VERSION` 注入自 `package.json`,在 Vite 中以 `__PKG_VERSION__` 注入。
209
257
 
210
258
 
259
+ ---
260
+
261
+ ### 消息后处理与路由链接渲染
262
+ 组件提供 `messagePostRender` 回调,在每条 AI 消息**流式输出完成、DOM 更新后**触发一次,可用于自定义处理渲染后的内容(高亮关键词、埋点、插入自定义元素等)。
263
+
264
+ ```ts
265
+ // 函数签名
266
+ messagePostRender?: (container: HTMLElement, textContent: string) => void
267
+ ```
268
+
269
+ 库内置了 `routeLinkRender`(从 `@szjy/ai-coms` 导出),可将 AI 输出中的 `#router:xxx#` 标记自动渲染为可点击的路由链接:
270
+
271
+ ```vue
272
+ <template>
273
+ <sz-ai-chat :token="token" :messagePostRender="handleMessagePostRender" />
274
+ </template>
275
+
276
+ <script setup lang="ts">
277
+ import { routeLinkRender } from '@szjy/ai-coms'
278
+ import { useRouter } from 'vue-router'
279
+
280
+ const router = useRouter()
281
+
282
+ const handleMessagePostRender = (container: HTMLElement, textContent: string) => {
283
+ routeLinkRender(container, textContent, {
284
+ onRouteClick: (routeName, queryParams) => {
285
+ const routeData = router.resolve({ name: routeName, query: queryParams })
286
+ window.open(routeData.href, '_blank')
287
+ },
288
+ // 可选:自定义链接样式(会与默认样式合并)
289
+ linkStyle: { color: '#536fec', fontWeight: 'bold', textDecoration: 'underline' }
290
+ })
291
+ }
292
+ </script>
293
+ ```
294
+
295
+ 支持的标记格式:
296
+
297
+ | 格式 | 说明 |
298
+ |---|---|
299
+ | `#router:routeName#` | 简单路由,只有路由名 |
300
+ | `#router:routeName?a=1&b=2#` | 带查询参数的路由,`?` 后解析为 `queryParams` 对象 |
301
+
302
+ > 完整教程见 [`docs/message-post-render.md`](docs/message-post-render.md)。
303
+
304
+
211
305
  ---
212
306
 
213
307
  ### 项目维护规范
@@ -253,6 +347,14 @@ sequenceDiagram
253
347
  - 可能原因:未将其外部化。
254
348
  - 解决:本库构建已在 `vite.config.mts` 配置 `external`,作为使用方请在你的应用构建中确保仅引用一次依赖。
255
349
 
350
+ 6) 使用 Dify(OpenAI 兼容)报鉴权错误或提示缺少 authToken
351
+ - 可能原因:未通过 `extraConfig.authToken` 传入 Dify 应用密钥(`app-xxx`),此时会回退到内网默认值并在控制台报错。
352
+ - 解决:在 `<sz-ai-chat>` 传入 `:extraConfig="{ authToken: 'app-xxx', projectId: 26 }"`,并确认 `baseUrl` 指向 Dify 实例地址。
353
+
354
+ 7) `#router:xxx#` 链接未渲染或点击无跳转
355
+ - 可能原因:未绑定 `messagePostRender`,或未在 `routeLinkRender` 的 `onRouteClick` 中实现跳转逻辑。
356
+ - 解决:参考「消息后处理与路由链接渲染」一节绑定回调;`#` 为分隔符,路由名与参数不能包含 `#`。
357
+
256
358
 
257
359
  ---
258
360
 
@@ -268,6 +370,7 @@ sequenceDiagram
268
370
  - Moonshot API:`https://platform.moonshot.cn/`
269
371
  - DashScope(通义千问):`https://dashscope.aliyun.com/`
270
372
  - SiliconFlow:`https://docs.siliconflow.cn/`
373
+ - Dify(OpenAI 兼容接口):`https://docs.dify.ai/`
271
374
  - 科大讯飞 Spark(参考其服务端/网关说明)
272
375
 
273
376