@infinilabs/ai-chat 0.0.0 → 0.0.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 (119) hide show
  1. package/README.md +310 -56
  2. package/dist/_baseUniq-BFn6cCm9.js +152 -0
  3. package/dist/_baseUniq-nfJyj2zU.cjs +151 -0
  4. package/dist/arc-BWSMkwk2.cjs +130 -0
  5. package/dist/arc-DODeX7B9.js +131 -0
  6. package/dist/architecture-U656AL7Q-B4C0nw6C.js +5 -0
  7. package/dist/architecture-U656AL7Q-CVURQXwt.cjs +5 -0
  8. package/dist/architectureDiagram-VXUJARFQ-2UbdzpNz.cjs +8681 -0
  9. package/dist/architectureDiagram-VXUJARFQ-NCVmzKuE.js +8681 -0
  10. package/dist/blockDiagram-VD42YOAC-B3yCPK1N.cjs +3606 -0
  11. package/dist/blockDiagram-VD42YOAC-C4FsmQfk.js +3606 -0
  12. package/dist/c4Diagram-YG6GDRKO-ATyoKzFV.js +2481 -0
  13. package/dist/c4Diagram-YG6GDRKO-COwVcHWj.cjs +2481 -0
  14. package/dist/channel-2Y73gsu9.cjs +6 -0
  15. package/dist/channel-oB8MffQV.js +7 -0
  16. package/dist/chunk-4BX2VUAB-C3diNHZw.cjs +15 -0
  17. package/dist/chunk-4BX2VUAB-sd2zFBFz.js +16 -0
  18. package/dist/chunk-55IACEB6-6ohTnYE3.js +13 -0
  19. package/dist/chunk-55IACEB6-T-CzlJke.cjs +12 -0
  20. package/dist/chunk-B4BG7PRW-B1zqG62l.cjs +1825 -0
  21. package/dist/chunk-B4BG7PRW-E1dti26Y.js +1826 -0
  22. package/dist/chunk-DI55MBZ5-Dk0kfYBV.cjs +1914 -0
  23. package/dist/chunk-DI55MBZ5-DpHw-vMw.js +1915 -0
  24. package/dist/chunk-FMBD7UC4-B1vXpasq.js +19 -0
  25. package/dist/chunk-FMBD7UC4-CShN9-qf.cjs +18 -0
  26. package/dist/chunk-QN33PNHL-Cw7FG91D.js +24 -0
  27. package/dist/chunk-QN33PNHL-DJi1fhak.cjs +23 -0
  28. package/dist/chunk-QZHKN3VN-BweiBR9P.js +17 -0
  29. package/dist/chunk-QZHKN3VN-DfUW_gDw.cjs +16 -0
  30. package/dist/chunk-TZMSLE5B-DY2Kbag4.cjs +107 -0
  31. package/dist/chunk-TZMSLE5B-ZQ2Esoix.js +108 -0
  32. package/dist/classDiagram-2ON5EDUG-D2tIbkjc.js +19 -0
  33. package/dist/classDiagram-2ON5EDUG-DRhRmkUb.cjs +19 -0
  34. package/dist/classDiagram-v2-WZHVMYZB-D2tIbkjc.js +19 -0
  35. package/dist/classDiagram-v2-WZHVMYZB-DRhRmkUb.cjs +19 -0
  36. package/dist/clone-BMkj3yun.cjs +7 -0
  37. package/dist/clone-ChHXIoR6.js +8 -0
  38. package/dist/cose-bilkent-S5V4N54A-BXnWH5Od.cjs +4942 -0
  39. package/dist/cose-bilkent-S5V4N54A-D15BmpCb.js +4942 -0
  40. package/dist/cytoscape.esm-BfvZ3QT_.js +30239 -0
  41. package/dist/cytoscape.esm-D8IBYQeQ.cjs +30238 -0
  42. package/dist/dagre-6UL2VRFP-DGQ6TW_g.cjs +693 -0
  43. package/dist/dagre-6UL2VRFP-WmhUYWg8.js +693 -0
  44. package/dist/defaultLocale-DVr69WTU.js +206 -0
  45. package/dist/defaultLocale-DwYGIg9G.cjs +203 -0
  46. package/dist/diagram-PSM6KHXK-DSfHBoUT.js +845 -0
  47. package/dist/diagram-PSM6KHXK-J4qyGeN7.cjs +845 -0
  48. package/dist/diagram-QEK2KX5R-D96wT5cH.cjs +300 -0
  49. package/dist/diagram-QEK2KX5R-I_nyexpY.js +300 -0
  50. package/dist/diagram-S2PKOQOG-BC_WyKEe.cjs +210 -0
  51. package/dist/diagram-S2PKOQOG-aooXSMNo.js +210 -0
  52. package/dist/erDiagram-Q2GNP2WA-DQ8Lquay.cjs +1158 -0
  53. package/dist/erDiagram-Q2GNP2WA-DWF8e6EL.js +1158 -0
  54. package/dist/flowDiagram-NV44I4VS-CM9c4F1o.js +2331 -0
  55. package/dist/flowDiagram-NV44I4VS-DpYNkyM2.cjs +2331 -0
  56. package/dist/ganttDiagram-JELNMOA3-CAsoD6rZ.js +3679 -0
  57. package/dist/ganttDiagram-JELNMOA3-DfKahpj4.cjs +3679 -0
  58. package/dist/gitGraph-F6HP7TQM-BX2fz4_i.js +5 -0
  59. package/dist/gitGraph-F6HP7TQM-DRkGg4T1.cjs +5 -0
  60. package/dist/gitGraphDiagram-NY62KEGX-PXpI94u6.js +1203 -0
  61. package/dist/gitGraphDiagram-NY62KEGX-YhnKpooH.cjs +1203 -0
  62. package/dist/graph-BvxpI7Xc.js +596 -0
  63. package/dist/graph-CI_TWBSn.cjs +595 -0
  64. package/dist/index-BctLGjTK.cjs +120500 -0
  65. package/dist/index-CjSgoo1P.js +120485 -0
  66. package/dist/index.cjs +19 -0
  67. package/dist/index.js +12 -19961
  68. package/dist/info-NVLQJR56-BGbTE7dw.cjs +5 -0
  69. package/dist/info-NVLQJR56-DRxIh-N8.js +5 -0
  70. package/dist/infoDiagram-WHAUD3N6-BB2Bnbnh.cjs +31 -0
  71. package/dist/infoDiagram-WHAUD3N6-D_RrgwxS.js +31 -0
  72. package/dist/init-DevvdK2U.cjs +15 -0
  73. package/dist/init-ZxktEp_H.js +16 -0
  74. package/dist/journeyDiagram-XKPGCS4Q-BJjXlMIj.js +1254 -0
  75. package/dist/journeyDiagram-XKPGCS4Q-BcBLsfI9.cjs +1254 -0
  76. package/dist/kanban-definition-3W4ZIXB7-0wwNBZ93.js +1047 -0
  77. package/dist/kanban-definition-3W4ZIXB7-CaY0q4j9.cjs +1047 -0
  78. package/dist/katex-BhpYeT3b.cjs +14523 -0
  79. package/dist/katex-ei8sH3Uy.js +14524 -0
  80. package/dist/layout-CcghncRv.js +2183 -0
  81. package/dist/layout-CvwzED_C.cjs +2182 -0
  82. package/dist/linear-CYow-mAK.cjs +339 -0
  83. package/dist/linear-D_gKQzVp.js +340 -0
  84. package/dist/mermaid-parser.core-CzmkR-3i.cjs +18703 -0
  85. package/dist/mermaid-parser.core-DCMDT-Cp.js +18704 -0
  86. package/dist/min-BBp7Smma.js +41 -0
  87. package/dist/min-Gu1I_bJ9.cjs +40 -0
  88. package/dist/mindmap-definition-VGOIOE7T-D16Pp1u5.cjs +1126 -0
  89. package/dist/mindmap-definition-VGOIOE7T-PjSLRtz4.js +1126 -0
  90. package/dist/ordinal-CxptdPJm.js +76 -0
  91. package/dist/ordinal-D7sQNqXZ.cjs +75 -0
  92. package/dist/packet-BFZMPI3H-BvdogPiS.js +5 -0
  93. package/dist/packet-BFZMPI3H-C7pOHUWY.cjs +5 -0
  94. package/dist/pie-7BOR55EZ-D-DxSHbP.cjs +5 -0
  95. package/dist/pie-7BOR55EZ-DEWJe4Xn.js +5 -0
  96. package/dist/pieDiagram-ADFJNKIX-CoDddKZl.js +237 -0
  97. package/dist/pieDiagram-ADFJNKIX-DjN4DU9l.cjs +237 -0
  98. package/dist/quadrantDiagram-AYHSOK5B-BZOg0JMm.js +1335 -0
  99. package/dist/quadrantDiagram-AYHSOK5B-DXjTSOL4.cjs +1335 -0
  100. package/dist/radar-NHE76QYJ-BrnDXy9q.cjs +5 -0
  101. package/dist/radar-NHE76QYJ-C2WmPmJ4.js +5 -0
  102. package/dist/requirementDiagram-UZGBJVZJ-CCW1O1xH.js +1161 -0
  103. package/dist/requirementDiagram-UZGBJVZJ-e5F3-dDI.cjs +1161 -0
  104. package/dist/sankeyDiagram-TZEHDZUN-BaGzCxTp.js +1193 -0
  105. package/dist/sankeyDiagram-TZEHDZUN-DtIvOvVI.cjs +1193 -0
  106. package/dist/sequenceDiagram-WL72ISMW-0vFhYnxn.cjs +3874 -0
  107. package/dist/sequenceDiagram-WL72ISMW-DL3B7U56.js +3874 -0
  108. package/dist/stateDiagram-FKZM4ZOC-CXW608BR.cjs +447 -0
  109. package/dist/stateDiagram-FKZM4ZOC-Ddw6HxPD.js +447 -0
  110. package/dist/stateDiagram-v2-4FDKWEC3-DZCkQKmp.js +19 -0
  111. package/dist/stateDiagram-v2-4FDKWEC3-DefWUbvq.cjs +19 -0
  112. package/dist/timeline-definition-IT6M3QCI-C3TfA9lE.cjs +1222 -0
  113. package/dist/timeline-definition-IT6M3QCI-DiS88lUo.js +1222 -0
  114. package/dist/treemap-KMMF4GRG-Bl-H6j2c.cjs +5 -0
  115. package/dist/treemap-KMMF4GRG-DGGr_R9A.js +5 -0
  116. package/dist/xychartDiagram-PRI3JC2R-BrOwRjfF.js +1886 -0
  117. package/dist/xychartDiagram-PRI3JC2R-CM06DttH.cjs +1886 -0
  118. package/package.json +22 -11
  119. package/dist/index.css +0 -1582
package/README.md CHANGED
@@ -1,81 +1,335 @@
1
1
  # @infinilabs/ai-chat
2
2
 
3
- 这是一个 AI Chat 组件库,用于在 React 应用中集成 AI 聊天功能。
3
+ 一个「开箱即用」的 AI Chat 组件库,用于在 React 应用中快速集成带有:
4
4
 
5
- ## 项目简介
5
+ - 会话历史列表(选择、重命名、删除、刷新、搜索)
6
+ - 小助手列表(选择、翻页、搜索)
7
+ - AI 聊天区域(支持流式回答、思考过程展示、引用来源等)
6
8
 
7
- 1. 项目是 pnpm 项目,执行命令需要用 pnpm
8
- 2. 项目是 AI Chat 组件库,最后是需要 pnpm build 之后部署发布 npm 库的
9
+ ---
9
10
 
10
- ## 对外的参数
11
+ ## 安装与构建
12
+
13
+ - 项目使用 pnpm 进行依赖管理和构建。
14
+ - 最终以 npm 包形式对外发布。
15
+
16
+ ```bash
17
+ pnpm add @infinilabs/ai-chat
18
+ ```
19
+
20
+ ### Peer Dependencies
21
+
22
+ 在使用本组件库之前,请确保你的项目中安装了以下依赖(通常这些也是你项目的基础依赖):
23
+
24
+ - `react` >= 18.3.1
25
+ - `react-dom` >= 18.3.1
26
+ - `antd` >= 6
27
+
28
+ 本包默认内置:
29
+
30
+ - React 组件 + Zustand 状态管理
31
+ - Tailwind v4 + 一套内置样式(JS 自动注入,无需手动引入 CSS)
32
+ - `react-i18next` 国际化配置(中英文文案)
33
+ - 依赖 `antd` 的 `message` 组件做操作反馈
34
+ - `axios`, `dayjs`, `lucide-react` 等工具库
35
+
36
+ 开发与构建:
37
+
38
+ ```bash
39
+ pnpm dev # 本地开发预览
40
+ pnpm build # 构建 npm 产物(dist)
41
+ pnpm lint # 代码检查
42
+ ```
43
+
44
+ ---
45
+
46
+ ## 导出组件一览
47
+
48
+ 1. `Chat`:核心 AI 聊天区域(流式回答、思考过程、引用文档等)。
49
+ 2. `History`:会话历史列表(选择、重命名、删除、刷新、搜索)。
50
+ 3. `AssistantList`:小助手选择列表(支持翻页、搜索、限制 ID)。
51
+ 4. `ChatInput`:独立输入框组件(高级用法,可单独组合 UI)。
52
+
53
+ 通常推荐的组合方式是:左侧 `AssistantList + History`,右侧 `Chat`。
54
+
55
+ ---
56
+
57
+ ## 快速开始示例
58
+
59
+ 一个最小可用的布局示例(假设你已经在后端实现了对应的接口,见后文「后端接口约定」):
60
+
61
+ ```tsx
62
+ import { useRef } from "react";
63
+ import {
64
+ Chat,
65
+ History,
66
+ AssistantList,
67
+ } from "@infinilabs/ai-chat";
68
+
69
+ // Chat 组件内部的 ref 方法定义(仅类型示意,见下文详细说明)
70
+ interface ChatAIRef {
71
+ init: (params: { message?: string; attachments?: string[] }) => void;
72
+ cancelChat: () => void;
73
+ clearChat: () => void;
74
+ }
75
+
76
+ function AIChatApp() {
77
+ const chatRef = useRef<ChatAIRef | null>(null);
78
+
79
+ const BaseUrl = "https://your-api-endpoint.example.com";
80
+ const Token = "your-api-token";
81
+
82
+ return (
83
+ <div className="flex h-full">
84
+ <div className="w-72 border-r flex flex-col gap-3 p-3">
85
+ <AssistantList BaseUrl={BaseUrl} Token={Token} />
86
+ <History BaseUrl={BaseUrl} Token={Token} />
87
+ </div>
88
+
89
+ <div className="flex-1 flex flex-col p-3">
90
+ <Chat ref={chatRef} BaseUrl={BaseUrl} />
91
+ </div>
92
+ </div>
93
+ );
94
+ }
95
+ ```
96
+
97
+ 要点说明:
98
+
99
+ - 必须提供后端 HTTP 地址 `BaseUrl`,用于请求 `/chat/*`、`/assistant/*` 等接口。
100
+ - 如果后端需要鉴权,可以通过 `Token` 传入 `History`(下文有解释)。
101
+ - `Chat` 组件通过 `ref` 暴露方法来发送消息、取消对话等。
102
+ - 历史、助手列表和 Chat 使用一个共享的 Zustand store 做状态同步。
103
+
104
+ ---
105
+
106
+ ## Chat 组件
107
+
108
+ ### Props 定义
11
109
 
12
- 1. 需要获取历史数据的方法,支持组件内部调用获取数据
13
110
  ```ts
14
- const [_error, res] = await Get(`/chat/_history`, {
15
- from: 0,
16
- size: 100,
17
- });
111
+ interface ChatAIProps {
112
+ BaseUrl: string;
113
+ Token?: string;
114
+ formatUrl?: (data: IChunkData) => string;
115
+ locale?: string;
116
+ t?: TFunction;
117
+ }
18
118
  ```
19
- 2. 需要删除历史记录的方法,支持组件内部调用操作数据
20
- 3. 需要获取小助手列表数据的方法,支持组件内部调用获取数据
21
- 4. 需要创建新的会话的方法,支持组件内部调用获取第一次聊天的数据
119
+
22
120
  ```ts
23
- await streamPost({
24
- url: "/chat/_create",
25
- body: { message },
26
- queryParams,
27
- onMessage: (line) => {
28
- // console.log("⏳", line);
29
- handleChatCreateStreamMessage(line);
30
- // append to chat box
31
- },
32
- });
121
+ export interface IChunkData {
122
+ message_chunk?: string;
123
+ [key: string]: unknown;
124
+ }
33
125
  ```
34
- 5. 需要继续聊天的方法,支持组件内部调用获取继续聊天的数据
126
+
127
+ ### 必填 / 选填一览
128
+
129
+ | Prop | 是否必填 | 类型 | 说明 |
130
+ |-----------|----------|-----------------------------------|------|
131
+ | `BaseUrl` | 必填 | `string` | 后端服务基础地址,例如 `https://api.example.com`。用于文件访问等。网络请求本身通过 localStorage 中的配置读取,见「后端接口约定」。 |
132
+ | `Token` | 选填 | `string` | 预留的鉴权 Token。当前版本主要通过 `History` 组件统一写入 localStorage 中的 `headers`,供所有请求复用。 |
133
+ | `formatUrl` | 选填 | `(data: IChunkData) => string` | 用于把引用文档等 chunk 数据转换为链接地址,传递给底层 `@infinilabs/chat-message`。 |
134
+ | `locale` | 选填 | `string` | 语言标识(如 `"en"`、`"zh"`)。不传时使用 `react-i18next` 默认语言。 |
135
+ | `t` | 选填 | `TFunction` | 自定义翻译函数;不传时使用组件内部的 `useTranslation`。 |
136
+
137
+ 注意:
138
+
139
+ - `BaseUrl` 目前主要用接口请求,可以知道使用的哪个 coco-server 服务。
140
+
141
+ ### Ref 方法
142
+
35
143
  ```ts
36
- await streamPost({
37
- url: `/chat/${newChat?._id}/_chat`,
38
- body: { message },
39
- queryParams,
40
- onMessage: (line) => {
41
- // console.log("line", line);
42
- handleChatCreateStreamMessage(line);
43
- // append to chat box
44
- },
45
- });
144
+ export interface SendMessageParams {
145
+ message?: string;
146
+ attachments?: string[];
147
+ }
148
+
149
+ export interface ChatAIRef {
150
+ init: (params: SendMessageParams) => void;
151
+ cancelChat: () => void;
152
+ clearChat: () => void;
153
+ onSelectChat: (chat: Chat) => void;
154
+ }
46
155
  ```
47
- 6. 需要取消聊天的方法,支持组件内部调用取消聊天
156
+
157
+ 方法说明:
158
+
159
+ | 方法名 | 参数 | 说明 |
160
+ |----------------|------------------------------|------|
161
+ | `init` | `SendMessageParams` | 发送一条消息:如果当前还没有会话,则创建新会话并调用 `/chat/_create`;如果有正在使用的会话,则调用 `/chat/{chatId}/_chat`。 |
162
+ | `cancelChat` | 无 | 取消当前正在进行的回答,内部会请求 `/chat/{chatId}/_cancel?message_id={curId}`,并重置流式状态。 |
163
+ | `clearChat` | 无 | 清空当前激活会话,在有 `_id` 时会调用 `/chat/{chatId}/_close`,然后清空 `activeChat`。 |
164
+ | `onSelectChat` | `chat: Chat` | 手动选择一个会话作为当前会话。内部会自动拉取该会话的历史记录。 |
165
+
166
+ `Chat` 内部使用了多个 Hook 来处理流式 chunk、思考过程、工具调用等(`useMessageChunkData`、`useMessageHandler`),并把这些数据传给 `ChatContent` 再由 `@infinilabs/chat-message` 渲染。
167
+
168
+ ---
169
+
170
+ ## History 组件
171
+
172
+ ### Props 定义
173
+
48
174
  ```ts
49
- const [_error, res] = await Post(
50
- `/chat/${activeChat?._id}/_cancel?message_id=${curIdRef.current}`,
51
- undefined
52
- );
175
+ interface HistoryProps {
176
+ BaseUrl: string;
177
+ Token?: string;
178
+ locale?: string;
179
+ t?: TFunction;
180
+ }
53
181
  ```
54
- 7. 需要每个聊天会话都有历史记录,历史记录包含用户输入和小助手回复
182
+
183
+ ### 功能与行为
184
+
185
+ - 初始化时根据 `BaseUrl`、`Token` 写入:
186
+ - `localStorage["app-store"] = { state: { endpoint_http: BaseUrl } }`
187
+ - `localStorage["headers"] = { "X-API-TOKEN": Token }`(仅当传入 `Token` 时)
188
+ - 使用 `GET /chat/_history` 拉取会话列表并写入 Zustand store:
189
+ - 默认请求参数:`{ from: 0, size: 100, keyword }`
190
+ - 当没有当前激活会话时,会自动选中第一条。
191
+ - 渲染内部的 `HistoryList`,支持:
192
+ - 搜索(关键字筛选)
193
+ - 手动刷新
194
+ - 选择会话
195
+ - 重命名会话(`PUT /chat/{chatId}`)
196
+ - 删除会话(`DELETE /chat/{chatId}`)
197
+
198
+ ### 使用示例
199
+
200
+ ```tsx
201
+ import { History } from "@infinilabs/ai-chat";
202
+
203
+ function Sidebar() {
204
+ return (
205
+ <History
206
+ BaseUrl="https://api.example.com"
207
+ Token="your-api-token"
208
+ locale="zh"
209
+ />
210
+ );
211
+ }
212
+ ```
213
+
214
+ 推荐做法:
215
+
216
+ - 统一通过 `History` 组件初始化 `BaseUrl` 和 `Token`,后续所有 `Get` / `Post` / `streamPost` 请求都会复用这两个配置。
217
+
218
+ ---
219
+
220
+ ## AssistantList 组件
221
+
222
+ ### Props 定义
223
+
55
224
  ```ts
56
- const [_error, res] = await Get(`/chat/${chat?._id}/_history`, {
57
- from: 0,
58
- size: 1000,
59
- });
60
- response = res;
225
+ interface AssistantListProps {
226
+ BaseUrl: string;
227
+ Token?: string;
228
+ assistantIDs?: string[];
229
+ locale?: string;
230
+ t?: TFunction;
231
+ }
232
+ ```
233
+
234
+ 注意:当前实现中,`BaseUrl`、`Token` 同样依赖 `axiosRequest.ts` 中从 localStorage 读取的配置,因此实际生效的仍然是 `History` 写入的值;在布局中同时使用 `History` 和 `AssistantList` 即可。
235
+
236
+ ### 功能与行为
237
+
238
+ - 使用 `POST /assistant/_search` 获取小助手列表,支持:
239
+ - 分页:`current`(页码)、`pageSize`(每页数量,默认 10)
240
+ - 搜索:`keyword`
241
+ - 过滤:`ids`(通过 `assistantIDs` 传入一组助手 ID)
242
+ - 将获取到的助手列表写入 Zustand store。
243
+ - 当列表不为空且当前没有已选助手时,自动选择第一条。
244
+ - 支持滚动加载更多(触底 + `hasMore` 控制)。
245
+ - UI 方面:
246
+ - 顶部按钮显示当前助手 name 与 icon。
247
+ - 点击后浮层中展示搜索输入框 + 列表,可切换助手。
248
+
249
+ ### 使用示例
250
+
251
+ ```tsx
252
+ import { AssistantList } from "@infinilabs/ai-chat";
253
+
254
+ function AssistantSelector() {
255
+ return (
256
+ <AssistantList
257
+ BaseUrl="https://api.example.com"
258
+ Token="your-api-token"
259
+ assistantIDs={["assistant-1", "assistant-2"]}
260
+ locale="zh"
261
+ />
262
+ );
263
+ }
61
264
  ```
62
- 8. 需要打开聊天会话的方法,支持组件内部调用打开聊天会话
265
+
266
+ `Chat` 组件在创建新会话时,会从 store 中读取当前助手的 `_id`,并作为 `assistant_id` 写入 `/chat/_create` 请求体。
267
+
268
+ ---
269
+
270
+ ## ChatInput 组件(可选)
271
+
272
+ 该组件内部已被 `Chat` 使用,一般不需要单独使用。如果你希望自定义布局、只复用输入框,可以单独引入:
273
+
63
274
  ```ts
64
- const [_error, res] = await Post(`/chat/${chat?._id}/_open`, {});
65
- response = res;
275
+ interface ChatInputProps {
276
+ onSend: (params: SendMessageParams) => void;
277
+ disabled: boolean;
278
+ isChatMode: boolean;
279
+ inputValue: string;
280
+ changeInput: (val: string) => void;
281
+ isDeepThinkActive: boolean;
282
+ setIsDeepThinkActive: () => void;
283
+ chatPlaceholder?: string;
284
+ searchPlaceholder?: string;
285
+ returnToInputShortcut?: string; // 默认 "i"
286
+ }
66
287
  ```
67
- 9. 需要关闭聊天会话的方法,支持组件内部调用关闭聊天会话
288
+
289
+ 特性:
290
+
291
+ - 自动高度 textarea。
292
+ - 支持 Enter 发送、Shift+Enter 换行。
293
+ - 支持「按 i 聚焦输入框」的快捷键提示。
294
+ - 底部附加一些模式切换、深度思考开关等控制按钮。
295
+
296
+ ---
297
+
298
+ ## 类型定义汇总
299
+
68
300
  ```ts
69
- const [_error, res] = await Post(`/chat/${chat?._id}/_close`, {});
70
- response = res;
301
+ export interface ChatMessageSource {
302
+ type: string;
303
+ assistant_id?: string;
304
+ message: string;
305
+ question?: string;
306
+ [key: string]: unknown;
307
+ }
308
+
309
+ export interface ChatMessageItem {
310
+ _id: string;
311
+ _source: ChatMessageSource;
312
+ }
313
+
314
+ export interface Chat {
315
+ _id: string;
316
+ messages?: ChatMessageItem[];
317
+ _source?: {
318
+ id?: string;
319
+ [key: string]: unknown;
320
+ };
321
+ }
71
322
  ```
72
323
 
73
- ## 包含组件
324
+ 你可以在自己的代码中根据需要复制这些接口,用于约束后端返回的数据结构。
325
+
326
+ ---
74
327
 
75
- 1. 独立历史列表组件(支持选择、重命名、删除、刷新、搜索)
76
- 2. 独立小助手列表组件(支持选择、翻页、搜索)
77
- 3. 独立 AI Chat 聊天组件(组件会话渲染 采用 "@infinilabs/chat-message": "workspace:*" 这个组件)
328
+ ## 小结与推荐接入方式
78
329
 
79
- 外部用户使用的时候,可以自由拼装,自己根据需要选择使用哪个组件。
330
+ 1. 在应用中引入 `AssistantList`、`History`、`Chat` 三个组件,组成完整的 AI Chat 页面。
331
+ 2. 使用 `History` 组件统一配置 `BaseUrl`、`Token`,确保所有请求都能访问到后端。
332
+ 3. 如需手动发送消息或控制对话流程,可以通过 `Chat` 的 `ref` 调用 `init`、`cancelChat`、`clearChat` 等方法。
333
+ 4. 如需深度定制 UI,仅复用其中部分组件(例如只用 `Chat` 或 `ChatInput`),也完全支持。
80
334
 
81
335
 
@@ -0,0 +1,152 @@
1
+ import { aO as Symbol$1, aH as isArray, aP as isArguments, aQ as arrayPush, aJ as identity, aE as baseEach, aR as arrayFilter, aG as baseIteratee, aS as Set, aT as setToArray, aU as SetCache, aV as cacheHas } from "./index-CjSgoo1P.js";
2
+ function noop() {
3
+ }
4
+ function arrayEach(array, iteratee) {
5
+ var index = -1, length = array == null ? 0 : array.length;
6
+ while (++index < length) {
7
+ if (iteratee(array[index], index, array) === false) {
8
+ break;
9
+ }
10
+ }
11
+ return array;
12
+ }
13
+ function baseFindIndex(array, predicate, fromIndex, fromRight) {
14
+ var length = array.length, index = fromIndex + -1;
15
+ while (++index < length) {
16
+ if (predicate(array[index], index, array)) {
17
+ return index;
18
+ }
19
+ }
20
+ return -1;
21
+ }
22
+ function baseIsNaN(value) {
23
+ return value !== value;
24
+ }
25
+ function strictIndexOf(array, value, fromIndex) {
26
+ var index = fromIndex - 1, length = array.length;
27
+ while (++index < length) {
28
+ if (array[index] === value) {
29
+ return index;
30
+ }
31
+ }
32
+ return -1;
33
+ }
34
+ function baseIndexOf(array, value, fromIndex) {
35
+ return value === value ? strictIndexOf(array, value, fromIndex) : baseFindIndex(array, baseIsNaN, fromIndex);
36
+ }
37
+ function arrayIncludes(array, value) {
38
+ var length = array == null ? 0 : array.length;
39
+ return !!length && baseIndexOf(array, value, 0) > -1;
40
+ }
41
+ var spreadableSymbol = Symbol$1 ? Symbol$1.isConcatSpreadable : void 0;
42
+ function isFlattenable(value) {
43
+ return isArray(value) || isArguments(value) || !!(spreadableSymbol && value && value[spreadableSymbol]);
44
+ }
45
+ function baseFlatten(array, depth, predicate, isStrict, result) {
46
+ var index = -1, length = array.length;
47
+ predicate || (predicate = isFlattenable);
48
+ result || (result = []);
49
+ while (++index < length) {
50
+ var value = array[index];
51
+ if (predicate(value)) {
52
+ {
53
+ arrayPush(result, value);
54
+ }
55
+ } else if (!isStrict) {
56
+ result[result.length] = value;
57
+ }
58
+ }
59
+ return result;
60
+ }
61
+ function arrayReduce(array, iteratee, accumulator, initAccum) {
62
+ var index = -1, length = array == null ? 0 : array.length;
63
+ if (initAccum && length) {
64
+ accumulator = array[++index];
65
+ }
66
+ while (++index < length) {
67
+ accumulator = iteratee(accumulator, array[index], index, array);
68
+ }
69
+ return accumulator;
70
+ }
71
+ function castFunction(value) {
72
+ return typeof value == "function" ? value : identity;
73
+ }
74
+ function forEach(collection, iteratee) {
75
+ var func = isArray(collection) ? arrayEach : baseEach;
76
+ return func(collection, castFunction(iteratee));
77
+ }
78
+ function baseFilter(collection, predicate) {
79
+ var result = [];
80
+ baseEach(collection, function(value, index, collection2) {
81
+ if (predicate(value, index, collection2)) {
82
+ result.push(value);
83
+ }
84
+ });
85
+ return result;
86
+ }
87
+ function filter(collection, predicate) {
88
+ var func = isArray(collection) ? arrayFilter : baseFilter;
89
+ return func(collection, baseIteratee(predicate));
90
+ }
91
+ function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
92
+ eachFunc(collection, function(value, index, collection2) {
93
+ accumulator = initAccum ? (initAccum = false, value) : iteratee(accumulator, value, index, collection2);
94
+ });
95
+ return accumulator;
96
+ }
97
+ function reduce(collection, iteratee, accumulator) {
98
+ var func = isArray(collection) ? arrayReduce : baseReduce, initAccum = arguments.length < 3;
99
+ return func(collection, baseIteratee(iteratee), accumulator, initAccum, baseEach);
100
+ }
101
+ var INFINITY = 1 / 0;
102
+ var createSet = !(Set && 1 / setToArray(new Set([, -0]))[1] == INFINITY) ? noop : function(values) {
103
+ return new Set(values);
104
+ };
105
+ var LARGE_ARRAY_SIZE = 200;
106
+ function baseUniq(array, iteratee, comparator) {
107
+ var index = -1, includes = arrayIncludes, length = array.length, isCommon = true, result = [], seen = result;
108
+ if (length >= LARGE_ARRAY_SIZE) {
109
+ var set = iteratee ? null : createSet(array);
110
+ if (set) {
111
+ return setToArray(set);
112
+ }
113
+ isCommon = false;
114
+ includes = cacheHas;
115
+ seen = new SetCache();
116
+ } else {
117
+ seen = iteratee ? [] : result;
118
+ }
119
+ outer:
120
+ while (++index < length) {
121
+ var value = array[index], computed = iteratee ? iteratee(value) : value;
122
+ value = value !== 0 ? value : 0;
123
+ if (isCommon && computed === computed) {
124
+ var seenIndex = seen.length;
125
+ while (seenIndex--) {
126
+ if (seen[seenIndex] === computed) {
127
+ continue outer;
128
+ }
129
+ }
130
+ if (iteratee) {
131
+ seen.push(computed);
132
+ }
133
+ result.push(value);
134
+ } else if (!includes(seen, computed, comparator)) {
135
+ if (seen !== result) {
136
+ seen.push(computed);
137
+ }
138
+ result.push(value);
139
+ }
140
+ }
141
+ return result;
142
+ }
143
+ export {
144
+ arrayEach as a,
145
+ baseFlatten as b,
146
+ baseUniq as c,
147
+ forEach as d,
148
+ baseFindIndex as e,
149
+ filter as f,
150
+ castFunction as g,
151
+ reduce as r
152
+ };
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ const index = require("./index-BctLGjTK.cjs");
3
+ function noop() {
4
+ }
5
+ function arrayEach(array, iteratee) {
6
+ var index2 = -1, length = array == null ? 0 : array.length;
7
+ while (++index2 < length) {
8
+ if (iteratee(array[index2], index2, array) === false) {
9
+ break;
10
+ }
11
+ }
12
+ return array;
13
+ }
14
+ function baseFindIndex(array, predicate, fromIndex, fromRight) {
15
+ var length = array.length, index2 = fromIndex + -1;
16
+ while (++index2 < length) {
17
+ if (predicate(array[index2], index2, array)) {
18
+ return index2;
19
+ }
20
+ }
21
+ return -1;
22
+ }
23
+ function baseIsNaN(value) {
24
+ return value !== value;
25
+ }
26
+ function strictIndexOf(array, value, fromIndex) {
27
+ var index2 = fromIndex - 1, length = array.length;
28
+ while (++index2 < length) {
29
+ if (array[index2] === value) {
30
+ return index2;
31
+ }
32
+ }
33
+ return -1;
34
+ }
35
+ function baseIndexOf(array, value, fromIndex) {
36
+ return value === value ? strictIndexOf(array, value, fromIndex) : baseFindIndex(array, baseIsNaN, fromIndex);
37
+ }
38
+ function arrayIncludes(array, value) {
39
+ var length = array == null ? 0 : array.length;
40
+ return !!length && baseIndexOf(array, value, 0) > -1;
41
+ }
42
+ var spreadableSymbol = index.Symbol ? index.Symbol.isConcatSpreadable : void 0;
43
+ function isFlattenable(value) {
44
+ return index.isArray(value) || index.isArguments(value) || !!(spreadableSymbol && value && value[spreadableSymbol]);
45
+ }
46
+ function baseFlatten(array, depth, predicate, isStrict, result) {
47
+ var index$1 = -1, length = array.length;
48
+ predicate || (predicate = isFlattenable);
49
+ result || (result = []);
50
+ while (++index$1 < length) {
51
+ var value = array[index$1];
52
+ if (predicate(value)) {
53
+ {
54
+ index.arrayPush(result, value);
55
+ }
56
+ } else if (!isStrict) {
57
+ result[result.length] = value;
58
+ }
59
+ }
60
+ return result;
61
+ }
62
+ function arrayReduce(array, iteratee, accumulator, initAccum) {
63
+ var index2 = -1, length = array == null ? 0 : array.length;
64
+ if (initAccum && length) {
65
+ accumulator = array[++index2];
66
+ }
67
+ while (++index2 < length) {
68
+ accumulator = iteratee(accumulator, array[index2], index2, array);
69
+ }
70
+ return accumulator;
71
+ }
72
+ function castFunction(value) {
73
+ return typeof value == "function" ? value : index.identity;
74
+ }
75
+ function forEach(collection, iteratee) {
76
+ var func = index.isArray(collection) ? arrayEach : index.baseEach;
77
+ return func(collection, castFunction(iteratee));
78
+ }
79
+ function baseFilter(collection, predicate) {
80
+ var result = [];
81
+ index.baseEach(collection, function(value, index2, collection2) {
82
+ if (predicate(value, index2, collection2)) {
83
+ result.push(value);
84
+ }
85
+ });
86
+ return result;
87
+ }
88
+ function filter(collection, predicate) {
89
+ var func = index.isArray(collection) ? index.arrayFilter : baseFilter;
90
+ return func(collection, index.baseIteratee(predicate));
91
+ }
92
+ function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
93
+ eachFunc(collection, function(value, index2, collection2) {
94
+ accumulator = initAccum ? (initAccum = false, value) : iteratee(accumulator, value, index2, collection2);
95
+ });
96
+ return accumulator;
97
+ }
98
+ function reduce(collection, iteratee, accumulator) {
99
+ var func = index.isArray(collection) ? arrayReduce : baseReduce, initAccum = arguments.length < 3;
100
+ return func(collection, index.baseIteratee(iteratee), accumulator, initAccum, index.baseEach);
101
+ }
102
+ var INFINITY = 1 / 0;
103
+ var createSet = !(index.Set && 1 / index.setToArray(new index.Set([, -0]))[1] == INFINITY) ? noop : function(values) {
104
+ return new index.Set(values);
105
+ };
106
+ var LARGE_ARRAY_SIZE = 200;
107
+ function baseUniq(array, iteratee, comparator) {
108
+ var index$1 = -1, includes = arrayIncludes, length = array.length, isCommon = true, result = [], seen = result;
109
+ if (length >= LARGE_ARRAY_SIZE) {
110
+ var set = iteratee ? null : createSet(array);
111
+ if (set) {
112
+ return index.setToArray(set);
113
+ }
114
+ isCommon = false;
115
+ includes = index.cacheHas;
116
+ seen = new index.SetCache();
117
+ } else {
118
+ seen = iteratee ? [] : result;
119
+ }
120
+ outer:
121
+ while (++index$1 < length) {
122
+ var value = array[index$1], computed = iteratee ? iteratee(value) : value;
123
+ value = value !== 0 ? value : 0;
124
+ if (isCommon && computed === computed) {
125
+ var seenIndex = seen.length;
126
+ while (seenIndex--) {
127
+ if (seen[seenIndex] === computed) {
128
+ continue outer;
129
+ }
130
+ }
131
+ if (iteratee) {
132
+ seen.push(computed);
133
+ }
134
+ result.push(value);
135
+ } else if (!includes(seen, computed, comparator)) {
136
+ if (seen !== result) {
137
+ seen.push(computed);
138
+ }
139
+ result.push(value);
140
+ }
141
+ }
142
+ return result;
143
+ }
144
+ exports.arrayEach = arrayEach;
145
+ exports.baseFindIndex = baseFindIndex;
146
+ exports.baseFlatten = baseFlatten;
147
+ exports.baseUniq = baseUniq;
148
+ exports.castFunction = castFunction;
149
+ exports.filter = filter;
150
+ exports.forEach = forEach;
151
+ exports.reduce = reduce;