@huyooo/ai-chat-frontend-react 0.2.14 → 0.2.16

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 (76) hide show
  1. package/dist/index.css +0 -1
  2. package/dist/index.js +1 -5418
  3. package/package.json +4 -5
  4. package/dist/index.css.map +0 -1
  5. package/dist/index.js.map +0 -1
  6. package/src/adapter.ts +0 -68
  7. package/src/components/ChatPanel.tsx +0 -553
  8. package/src/components/common/ConfirmDialog.css +0 -136
  9. package/src/components/common/ConfirmDialog.tsx +0 -91
  10. package/src/components/common/CopyButton.css +0 -22
  11. package/src/components/common/CopyButton.tsx +0 -46
  12. package/src/components/common/IndexingSettings.css +0 -207
  13. package/src/components/common/IndexingSettings.tsx +0 -398
  14. package/src/components/common/SettingsPanel.css +0 -337
  15. package/src/components/common/SettingsPanel.tsx +0 -215
  16. package/src/components/common/Toast.css +0 -50
  17. package/src/components/common/Toast.tsx +0 -38
  18. package/src/components/common/ToggleSwitch.css +0 -52
  19. package/src/components/common/ToggleSwitch.tsx +0 -20
  20. package/src/components/header/ChatHeader.css +0 -285
  21. package/src/components/header/ChatHeader.tsx +0 -376
  22. package/src/components/input/AtFilePicker.css +0 -147
  23. package/src/components/input/AtFilePicker.tsx +0 -519
  24. package/src/components/input/ChatInput.css +0 -283
  25. package/src/components/input/ChatInput.tsx +0 -575
  26. package/src/components/input/DropdownSelector.css +0 -231
  27. package/src/components/input/DropdownSelector.tsx +0 -333
  28. package/src/components/input/ImagePreviewModal.css +0 -124
  29. package/src/components/input/ImagePreviewModal.tsx +0 -118
  30. package/src/components/input/at-views/AtBranchView.tsx +0 -34
  31. package/src/components/input/at-views/AtBrowserView.tsx +0 -34
  32. package/src/components/input/at-views/AtChatsView.tsx +0 -34
  33. package/src/components/input/at-views/AtDocsView.tsx +0 -34
  34. package/src/components/input/at-views/AtFilesView.tsx +0 -168
  35. package/src/components/input/at-views/AtTerminalsView.tsx +0 -34
  36. package/src/components/input/at-views/AtViewStyles.css +0 -143
  37. package/src/components/input/at-views/index.ts +0 -9
  38. package/src/components/message/ContentRenderer.css +0 -9
  39. package/src/components/message/MessageBubble.css +0 -193
  40. package/src/components/message/MessageBubble.tsx +0 -240
  41. package/src/components/message/PartsRenderer.css +0 -12
  42. package/src/components/message/PartsRenderer.tsx +0 -168
  43. package/src/components/message/WelcomeMessage.css +0 -221
  44. package/src/components/message/WelcomeMessage.tsx +0 -93
  45. package/src/components/message/parts/CollapsibleCard.css +0 -80
  46. package/src/components/message/parts/CollapsibleCard.tsx +0 -80
  47. package/src/components/message/parts/ErrorPart.css +0 -9
  48. package/src/components/message/parts/ErrorPart.tsx +0 -40
  49. package/src/components/message/parts/ImagePart.css +0 -49
  50. package/src/components/message/parts/ImagePart.tsx +0 -54
  51. package/src/components/message/parts/SearchPart.css +0 -44
  52. package/src/components/message/parts/SearchPart.tsx +0 -63
  53. package/src/components/message/parts/TextPart.css +0 -579
  54. package/src/components/message/parts/TextPart.tsx +0 -213
  55. package/src/components/message/parts/ThinkingPart.css +0 -9
  56. package/src/components/message/parts/ThinkingPart.tsx +0 -48
  57. package/src/components/message/parts/ToolCallPart.css +0 -246
  58. package/src/components/message/parts/ToolCallPart.tsx +0 -289
  59. package/src/components/message/parts/ToolResultPart.css +0 -67
  60. package/src/components/message/parts/index.ts +0 -13
  61. package/src/components/message/parts/visual-predicate.ts +0 -43
  62. package/src/components/message/parts/visual-render.ts +0 -19
  63. package/src/components/message/parts/visual.ts +0 -12
  64. package/src/components/message/welcome-types.ts +0 -46
  65. package/src/context/AutoRunConfigContext.tsx +0 -13
  66. package/src/context/ChatAdapterContext.tsx +0 -8
  67. package/src/context/ChatInputContext.tsx +0 -40
  68. package/src/context/RenderersContext.tsx +0 -35
  69. package/src/hooks/useChat.ts +0 -1569
  70. package/src/hooks/useImageUpload.ts +0 -345
  71. package/src/hooks/useVoiceInput.ts +0 -454
  72. package/src/hooks/useVoiceToTextInput.ts +0 -87
  73. package/src/index.ts +0 -151
  74. package/src/styles.css +0 -330
  75. package/src/types/index.ts +0 -196
  76. package/src/utils/fileIcon.ts +0 -49
package/src/styles.css DELETED
@@ -1,330 +0,0 @@
1
- /**
2
- * AI Chat 全局样式
3
- * 仅包含 CSS 变量和 ChatPanel 基础布局
4
- */
5
-
6
- /* 导入 Markdown / Mermaid 等共享渲染样式(与 vue 版本保持一致) */
7
- @import "@huyooo/ai-chat-shared/styles";
8
-
9
- /**
10
- * 主题协议(跨项目统一):
11
- * - 使用 document.documentElement 的 data-theme = light | dark
12
- * - 默认跟随系统 prefers-color-scheme
13
- * - 组件内部继续使用 --chat-*(ai-chat 自己维护配色,避免被宿主 token “染色”)
14
- */
15
-
16
- /* 默认:浅色 */
17
- :root {
18
- color-scheme: light;
19
-
20
- /* ai-chat 专用变量(保持兼容) */
21
- /* Cursor 官网(Light)白色主题:暖白底 + 橙色强调 */
22
- --chat-bg: #f7f7f4;
23
- /* header 与主背景同步,用底部分割线表达层级 */
24
- --chat-header-bg: var(--chat-bg);
25
- --chat-input-bg: #f0efeb;
26
- --chat-dropdown-bg: #f2f1ed;
27
- --chat-muted: #ebeae5;
28
- --chat-muted-hover: #e6e5e0;
29
- --chat-border: #26251e1a;
30
- --chat-text: #26251eeb;
31
- --chat-text-strong: #26251e;
32
- --chat-text-muted: #26251e99;
33
- /* 主色:light/dark 保持一致(蓝) */
34
- --chat-primary: #54a9ff;
35
- /* hover:比主色更深一档,保持可感知的交互反馈 */
36
- --chat-primary-hover: #2f90ff;
37
- --chat-destructive: #cf2d56;
38
- --chat-destructive-hover: #b3003f;
39
- --chat-success: #1f8a65;
40
- --chat-code-bg: #f2f1ed;
41
- --chat-code-text: #26251eeb;
42
- --chat-scrollbar: rgba(38, 37, 30, 0.2);
43
- --chat-scrollbar-hover: rgba(38, 37, 30, 0.3);
44
- /* 悬浮圆形按钮(如 scroll-to-bottom)在浅色下更像 macOS:白底+阴影 */
45
- --chat-fab-bg: #ffffff;
46
- --chat-fab-bg-hover: var(--chat-input-bg);
47
- --chat-fab-shadow: 0 10px 24px rgba(0, 0, 0, 0.12);
48
-
49
- /* 代码高亮 - GitHub Light 风格 */
50
- --chat-hljs-keyword: #cf222e;
51
- --chat-hljs-built-in: #953800;
52
- --chat-hljs-type: #953800;
53
- --chat-hljs-function: #8250df;
54
- --chat-hljs-string: #0a3069;
55
- --chat-hljs-number: #0550ae;
56
- --chat-hljs-literal: #0550ae;
57
- --chat-hljs-comment: #6e7781;
58
- --chat-hljs-variable: #953800;
59
- --chat-hljs-attr: #0550ae;
60
- --chat-hljs-property: #116329;
61
- --chat-hljs-operator: #cf222e;
62
- --chat-hljs-punctuation: #24292f;
63
- --chat-hljs-params: #24292f;
64
- --chat-hljs-regexp: #116329;
65
- --chat-hljs-selector: #116329;
66
- --chat-hljs-tag: #116329;
67
- --chat-hljs-name: #116329;
68
- --chat-hljs-deletion: #82071e;
69
- --chat-hljs-deletion-bg: rgba(255, 129, 130, 0.15);
70
- --chat-hljs-addition: #116329;
71
- --chat-hljs-addition-bg: rgba(46, 160, 67, 0.15);
72
- --chat-hljs-meta: #6e7781;
73
- --chat-hljs-link: #0a3069;
74
- --chat-hljs-symbol: #0550ae;
75
- --chat-hljs-subst: #24292f;
76
- --chat-hljs-section: #0550ae;
77
- --chat-hljs-bullet: #953800;
78
- }
79
-
80
- /* 默认跟随系统暗色 */
81
- @media (prefers-color-scheme: dark) {
82
- :root {
83
- color-scheme: dark;
84
- /* 旧版暗色(深灰底:你更喜欢的观感) */
85
- --chat-bg: #1e1e1e;
86
- --chat-header-bg: #1e1e1e;
87
- --chat-input-bg: #2d2d2d;
88
- --chat-dropdown-bg: #252526;
89
- --chat-muted: #2d2d2d;
90
- --chat-muted-hover: #3c3c3c;
91
- --chat-border: #333;
92
- --chat-text: #ccc;
93
- --chat-text-strong: #fff;
94
- --chat-text-muted: #888;
95
- /* 主色:light/dark 保持一致(蓝) */
96
- --chat-primary: #54a9ff;
97
- --chat-primary-hover: #2f90ff;
98
- --chat-destructive: #cf2d56;
99
- --chat-destructive-hover: #e33b67;
100
- --chat-success: #1f8a65;
101
- --chat-code-bg: #1f2937;
102
- --chat-code-text: #e5e7eb;
103
- --chat-scrollbar: rgba(255, 255, 255, 0.2);
104
- --chat-scrollbar-hover: rgba(255, 255, 255, 0.3);
105
- /* 暗色下保持融入背景 */
106
- --chat-fab-bg: var(--chat-muted);
107
- --chat-fab-bg-hover: var(--chat-muted-hover);
108
- --chat-fab-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
109
-
110
- /* 代码高亮 - GitHub Dark 风格 */
111
- --chat-hljs-keyword: #ff7b72;
112
- --chat-hljs-built-in: #ffa657;
113
- --chat-hljs-type: #ffa657;
114
- --chat-hljs-function: #d2a8ff;
115
- --chat-hljs-string: #a5d6ff;
116
- --chat-hljs-number: #79c0ff;
117
- --chat-hljs-literal: #79c0ff;
118
- --chat-hljs-comment: #8b949e;
119
- --chat-hljs-variable: #ffa657;
120
- --chat-hljs-attr: #79c0ff;
121
- --chat-hljs-property: #7ee787;
122
- --chat-hljs-operator: #ff7b72;
123
- --chat-hljs-punctuation: #e6edf3;
124
- --chat-hljs-params: #e6edf3;
125
- --chat-hljs-regexp: #7ee787;
126
- --chat-hljs-selector: #7ee787;
127
- --chat-hljs-tag: #7ee787;
128
- --chat-hljs-name: #7ee787;
129
- --chat-hljs-deletion: #ffa198;
130
- --chat-hljs-deletion-bg: rgba(248, 81, 73, 0.15);
131
- --chat-hljs-addition: #7ee787;
132
- --chat-hljs-addition-bg: rgba(46, 160, 67, 0.15);
133
- --chat-hljs-meta: #8b949e;
134
- --chat-hljs-link: #a5d6ff;
135
- --chat-hljs-symbol: #79c0ff;
136
- --chat-hljs-subst: #e6edf3;
137
- --chat-hljs-section: #79c0ff;
138
- --chat-hljs-bullet: #ffa657;
139
- }
140
- }
141
-
142
- /* 显式浅色/暗色覆盖系统 */
143
- :root[data-theme="light"] {
144
- color-scheme: light;
145
- /* 显式 light 必须覆盖 prefers-color-scheme: dark 的变量 */
146
- --chat-bg: #f7f7f4;
147
- --chat-header-bg: var(--chat-bg);
148
- --chat-input-bg: #f0efeb;
149
- --chat-dropdown-bg: #f2f1ed;
150
- --chat-muted: #ebeae5;
151
- --chat-muted-hover: #e6e5e0;
152
- --chat-border: #26251e1a;
153
- --chat-text: #26251eeb;
154
- --chat-text-strong: #26251e;
155
- --chat-text-muted: #26251e99;
156
- --chat-primary: #54a9ff;
157
- --chat-primary-hover: #2f90ff;
158
- --chat-destructive: #cf2d56;
159
- --chat-destructive-hover: #b3003f;
160
- --chat-success: #1f8a65;
161
- --chat-code-bg: #f2f1ed;
162
- --chat-code-text: #26251eeb;
163
- --chat-scrollbar: rgba(38, 37, 30, 0.2);
164
- --chat-scrollbar-hover: rgba(38, 37, 30, 0.3);
165
- --chat-fab-bg: #ffffff;
166
- --chat-fab-bg-hover: var(--chat-input-bg);
167
- --chat-fab-shadow: 0 10px 24px rgba(0, 0, 0, 0.12);
168
-
169
- /* 代码高亮 - GitHub Light 风格 */
170
- --chat-hljs-keyword: #cf222e;
171
- --chat-hljs-built-in: #953800;
172
- --chat-hljs-type: #953800;
173
- --chat-hljs-function: #8250df;
174
- --chat-hljs-string: #0a3069;
175
- --chat-hljs-number: #0550ae;
176
- --chat-hljs-literal: #0550ae;
177
- --chat-hljs-comment: #6e7781;
178
- --chat-hljs-variable: #953800;
179
- --chat-hljs-attr: #0550ae;
180
- --chat-hljs-property: #116329;
181
- --chat-hljs-operator: #cf222e;
182
- --chat-hljs-punctuation: #24292f;
183
- --chat-hljs-params: #24292f;
184
- --chat-hljs-regexp: #116329;
185
- --chat-hljs-selector: #116329;
186
- --chat-hljs-tag: #116329;
187
- --chat-hljs-name: #116329;
188
- --chat-hljs-deletion: #82071e;
189
- --chat-hljs-deletion-bg: rgba(255, 129, 130, 0.15);
190
- --chat-hljs-addition: #116329;
191
- --chat-hljs-addition-bg: rgba(46, 160, 67, 0.15);
192
- --chat-hljs-meta: #6e7781;
193
- --chat-hljs-link: #0a3069;
194
- --chat-hljs-symbol: #0550ae;
195
- --chat-hljs-subst: #24292f;
196
- --chat-hljs-section: #0550ae;
197
- --chat-hljs-bullet: #953800;
198
- }
199
-
200
- :root[data-theme="dark"] {
201
- color-scheme: dark;
202
- /* 旧版暗色(深灰底:你更喜欢的观感) */
203
- --chat-bg: #1e1e1e;
204
- --chat-header-bg: #1e1e1e;
205
- --chat-input-bg: #2d2d2d;
206
- --chat-dropdown-bg: #252526;
207
- --chat-muted: #2d2d2d;
208
- --chat-muted-hover: #3c3c3c;
209
- --chat-border: #333;
210
- --chat-text: #ccc;
211
- --chat-text-strong: #fff;
212
- --chat-text-muted: #888;
213
- /* 主色:light/dark 保持一致(蓝) */
214
- --chat-primary: #54a9ff;
215
- --chat-primary-hover: #2f90ff;
216
- --chat-destructive: #cf2d56;
217
- --chat-destructive-hover: #e33b67;
218
- --chat-success: #1f8a65;
219
- --chat-code-bg: #1f2937;
220
- --chat-code-text: #e5e7eb;
221
- --chat-scrollbar: rgba(255, 255, 255, 0.2);
222
- --chat-scrollbar-hover: rgba(255, 255, 255, 0.3);
223
- --chat-fab-bg: var(--chat-muted);
224
- --chat-fab-bg-hover: var(--chat-muted-hover);
225
- --chat-fab-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
226
-
227
- /* 代码高亮 - GitHub Dark 风格 */
228
- --chat-hljs-keyword: #ff7b72;
229
- --chat-hljs-built-in: #ffa657;
230
- --chat-hljs-type: #ffa657;
231
- --chat-hljs-function: #d2a8ff;
232
- --chat-hljs-string: #a5d6ff;
233
- --chat-hljs-number: #79c0ff;
234
- --chat-hljs-literal: #79c0ff;
235
- --chat-hljs-comment: #8b949e;
236
- --chat-hljs-variable: #ffa657;
237
- --chat-hljs-attr: #79c0ff;
238
- --chat-hljs-property: #7ee787;
239
- --chat-hljs-operator: #ff7b72;
240
- --chat-hljs-punctuation: #e6edf3;
241
- --chat-hljs-params: #e6edf3;
242
- --chat-hljs-regexp: #7ee787;
243
- --chat-hljs-selector: #7ee787;
244
- --chat-hljs-tag: #7ee787;
245
- --chat-hljs-name: #7ee787;
246
- --chat-hljs-deletion: #ffa198;
247
- --chat-hljs-deletion-bg: rgba(248, 81, 73, 0.15);
248
- --chat-hljs-addition: #7ee787;
249
- --chat-hljs-addition-bg: rgba(46, 160, 67, 0.15);
250
- --chat-hljs-meta: #8b949e;
251
- --chat-hljs-link: #a5d6ff;
252
- --chat-hljs-symbol: #79c0ff;
253
- --chat-hljs-subst: #e6edf3;
254
- --chat-hljs-section: #79c0ff;
255
- --chat-hljs-bullet: #ffa657;
256
- }
257
-
258
- /* 统一滚动条样式 - 任何需要自定义滚动条的元素添加此类 */
259
- .chat-scrollbar::-webkit-scrollbar {
260
- width: 6px;
261
- }
262
-
263
- .chat-scrollbar::-webkit-scrollbar-track {
264
- background: transparent;
265
- }
266
-
267
- .chat-scrollbar::-webkit-scrollbar-thumb {
268
- background: var(--chat-scrollbar, rgba(255, 255, 255, 0.2));
269
- border-radius: 3px;
270
- }
271
-
272
- .chat-scrollbar::-webkit-scrollbar-thumb:hover {
273
- background: var(--chat-scrollbar-hover, rgba(255, 255, 255, 0.3));
274
- }
275
-
276
- /* ChatPanel 基础布局 */
277
- .chat-panel {
278
- display: flex;
279
- flex-direction: column;
280
- width: 100%;
281
- height: 100%;
282
- background: var(--chat-bg, #1e1e1e);
283
- overflow: hidden;
284
- }
285
-
286
- .messages-wrapper {
287
- flex: 1;
288
- min-height: 0;
289
- position: relative;
290
- display: flex;
291
- flex-direction: column;
292
- }
293
-
294
- .messages-container {
295
- flex: 1;
296
- min-height: 0;
297
- overflow-y: auto;
298
- padding: 12px;
299
- scroll-behavior: smooth;
300
- display: flex;
301
- flex-direction: column;
302
- gap: 8px;
303
- }
304
-
305
- /* 滚动到底部按钮 */
306
- .scroll-to-bottom-btn {
307
- position: absolute;
308
- bottom: 16px;
309
- right: 16px;
310
- display: flex;
311
- align-items: center;
312
- justify-content: center;
313
- width: 32px;
314
- height: 32px;
315
- border-radius: 50%;
316
- background: var(--chat-fab-bg, var(--chat-muted));
317
- border: 1px solid var(--chat-border);
318
- color: var(--chat-text-muted);
319
- cursor: pointer;
320
- transition: all 0.2s ease;
321
- box-shadow: var(--chat-fab-shadow, 0 2px 8px rgba(0, 0, 0, 0.3));
322
- z-index: 10;
323
- pointer-events: auto;
324
- }
325
-
326
- .scroll-to-bottom-btn:hover {
327
- background: var(--chat-fab-bg-hover, var(--chat-muted-hover));
328
- color: var(--chat-text);
329
- transform: scale(1.1);
330
- }
@@ -1,196 +0,0 @@
1
- /**
2
- * AI Chat 前端类型定义
3
- * 核心类型从 bridge-electron 导出,保持类型一致性
4
- *
5
- * 架构:消息内容使用 ContentPart 数组,支持流式渲染和自定义 UI
6
- */
7
-
8
- // 从 bridge-electron 导入类型
9
- import type {
10
- ChatMode as ChatModeType,
11
- ThinkingMode as ThinkingModeType,
12
- SessionRecord as SessionRecordType,
13
- MessageRecord as MessageRecordType,
14
- ModelOption as ModelOptionType,
15
- ProviderType as ProviderTypeType,
16
- } from '@huyooo/ai-chat-bridge-electron/renderer'
17
-
18
- // 重新导出核心类型
19
- export type ChatMode = ChatModeType
20
- export type ThinkingMode = ThinkingModeType
21
- export type SessionRecord = SessionRecordType
22
- export type MessageRecord = MessageRecordType
23
- export type ModelOption = ModelOptionType
24
- export type ProviderType = ProviderTypeType
25
-
26
- // ==================== Content Part 类型 ====================
27
- //
28
- // 架构说明:
29
- // 1. 内置类型:text, code, thinking, search, tool_call, image, error
30
- // 2. 扩展类型:weather, stock 等业务类型(通过 partRenderers 注册渲染器)
31
- // 3. 工具执行完成后,如果定义了 resultType,直接生成对应类型的 Part(如 weather)
32
- // 4. 前端通过 partRenderers 统一渲染所有 Part 类型
33
-
34
- /** 搜索结果 */
35
- export interface SearchResult {
36
- title: string
37
- url: string
38
- snippet: string
39
- }
40
-
41
- /** 文本内容 Part */
42
- export interface TextPart {
43
- type: 'text'
44
- text: string
45
- }
46
-
47
- /** 代码块 Part(从 text 中解析,或直接返回)*/
48
- export interface CodePart {
49
- type: 'code'
50
- content: string
51
- language?: string
52
- }
53
-
54
- /** 思考过程 Part */
55
- export interface ThinkingPart {
56
- type: 'thinking'
57
- text: string
58
- status: 'running' | 'done'
59
- duration?: number // 秒
60
- }
61
-
62
- /** 搜索 Part */
63
- export interface SearchPart {
64
- type: 'search'
65
- query?: string
66
- results?: SearchResult[]
67
- status: 'running' | 'done'
68
- }
69
-
70
- /** 工具调用 Part(仅展示执行过程,结果由具体类型 Part 渲染)*/
71
- export interface ToolCallPart {
72
- type: 'tool_call'
73
- id: string
74
- name: string
75
- args?: Record<string, unknown>
76
- status: 'pending' | 'running' | 'done' | 'error' | 'cancelled' | 'skipped'
77
- // 注意:不再有 result 字段,结果由工具的 resultType 指定的 Part 类型渲染
78
- /** 工具执行输出(用于 execute_command 等需要展示 stdout/stderr 的工具) */
79
- output?: {
80
- stdout?: string
81
- stderr?: string
82
- }
83
- }
84
-
85
- /** 图片 Part */
86
- export interface ImagePart {
87
- type: 'image'
88
- url: string
89
- }
90
-
91
- /** 错误 Part */
92
- export interface ErrorPart {
93
- type: 'error'
94
- message: string
95
- category?: string
96
- retryable?: boolean
97
- }
98
-
99
- // ==================== 扩展 Part 类型(业务类型)====================
100
-
101
- /** 天气 Part(由 get_weather 工具生成)*/
102
- export interface WeatherPart {
103
- type: 'weather'
104
- city: string
105
- temperature: number
106
- condition: string
107
- humidity: number
108
- wind: string
109
- reportTime?: string
110
- province?: string
111
- }
112
-
113
- /** 自定义 Part 基础接口(用于扩展)*/
114
- export interface CustomPart {
115
- type: string
116
- [key: string]: unknown
117
- }
118
-
119
- /** 内置 Part 联合类型 */
120
- export type BuiltinPart =
121
- | TextPart
122
- | CodePart
123
- | ThinkingPart
124
- | SearchPart
125
- | ToolCallPart
126
- | ImagePart
127
- | ErrorPart
128
-
129
- /** 内容 Part 联合类型(包含内置和扩展类型)*/
130
- export type ContentPart = BuiltinPart | WeatherPart | CustomPart
131
-
132
- /** 内置 Part 类型字符串 */
133
- export type BuiltinPartType = BuiltinPart['type']
134
-
135
- /** 内容 Part 类型字符串 */
136
- export type ContentPartType = string
137
-
138
- /** 步骤折叠模式 */
139
- export type StepsExpandedType = 'open' | 'close' | 'auto'
140
-
141
- // ==================== 消息类型 ====================
142
-
143
- /** 错误详情(结构化错误信息) */
144
- export interface ErrorDetails {
145
- category?: string
146
- message: string
147
- code?: string
148
- statusCode?: number
149
- retryable?: boolean
150
- retryAfter?: number
151
- }
152
-
153
- /** 聊天消息(前端显示用)- 新架构:基于 parts 数组 */
154
- export interface ChatMessage {
155
- id: string
156
- role: 'user' | 'assistant'
157
- /** 内容 parts 数组 - 核心渲染数据 */
158
- parts: ContentPart[]
159
- /** 生成此消息时使用的模型 */
160
- model?: string
161
- /** 生成此消息时使用的模式 (ask/agent) */
162
- mode?: string
163
- /** 生成此消息时是否启用 web 搜索 */
164
- webSearchEnabled?: boolean
165
- /** 生成此消息时是否启用深度思考 */
166
- thinkingEnabled?: boolean
167
- /** 用户上传的图片(仅用户消息) */
168
- images?: string[]
169
- /** 是否正在加载 */
170
- loading?: boolean
171
- /** 是否已复制 */
172
- copied?: boolean
173
- /** 消息时间戳 */
174
- timestamp?: number
175
- /** 错误详情(如果有错误) */
176
- error?: ErrorDetails
177
- /** 是否被用户中止 */
178
- aborted?: boolean
179
- }
180
-
181
- /** 获取消息的纯文本内容(用于复制、保存等) */
182
- export function getMessageText(message: ChatMessage): string {
183
- return message.parts
184
- .filter((p): p is TextPart => p.type === 'text')
185
- .map(p => p.text)
186
- .join('')
187
- }
188
-
189
- /** 输入区配置快照(用于历史回溯/重发) */
190
- export interface ChatInputOptions {
191
- mode: ChatMode
192
- model: string
193
- webSearchEnabled: boolean
194
- thinkingEnabled: boolean
195
- }
196
-
@@ -1,49 +0,0 @@
1
- /**
2
- * 根据文件名或路径获取对应的图标
3
- */
4
- export function getFileIcon(nameOrPath: string): string {
5
- const name = basename(nameOrPath).toLowerCase();
6
- const ext = name.includes('.') ? name.slice(name.lastIndexOf('.')) : '';
7
-
8
- if (ext === '.vue') return 'vscode-icons:file-type-vue';
9
- if (ext === '.tsx') return 'vscode-icons:file-type-reactts';
10
- if (ext === '.jsx') return 'vscode-icons:file-type-reactjs';
11
- if (ext === '.ts') return 'vscode-icons:file-type-typescript';
12
- if (ext === '.js') return 'vscode-icons:file-type-js';
13
- if (ext === '.css') return 'vscode-icons:file-type-css';
14
- if (ext === '.scss' || ext === '.sass') return 'vscode-icons:file-type-scss';
15
- if (ext === '.less') return 'vscode-icons:file-type-less';
16
- if (ext === '.json') return 'vscode-icons:file-type-json';
17
- if (ext === '.yaml' || ext === '.yml') return 'vscode-icons:file-type-yaml';
18
- if (ext === '.xml') return 'vscode-icons:file-type-xml';
19
- if (ext === '.md') return 'vscode-icons:file-type-markdown';
20
- if (ext === '.txt') return 'vscode-icons:file-type-text';
21
- if (['.png', '.jpg', '.jpeg', '.gif', '.webp', '.svg', '.ico'].includes(ext)) {
22
- return 'vscode-icons:file-type-image';
23
- }
24
- if (ext === '.html' || ext === '.htm') return 'vscode-icons:file-type-html';
25
- if (ext === '.py') return 'vscode-icons:file-type-python';
26
- if (ext === '.go') return 'vscode-icons:file-type-go';
27
- if (ext === '.rs') return 'vscode-icons:file-type-rust';
28
- if (ext === '.sh' || ext === '.bash' || ext === '.zsh') return 'vscode-icons:file-type-shell';
29
-
30
- return 'lucide:file';
31
- }
32
-
33
- /**
34
- * 获取路径的文件名部分
35
- */
36
- export function basename(p: string): string {
37
- const normalized = p.replace(/\\/g, '/');
38
- const idx = normalized.lastIndexOf('/');
39
- return idx >= 0 ? normalized.slice(idx + 1) || normalized : normalized;
40
- }
41
-
42
- /**
43
- * 获取路径的目录部分
44
- */
45
- export function dirname(p: string): string {
46
- const normalized = p.replace(/\\/g, '/');
47
- const idx = normalized.lastIndexOf('/');
48
- return idx > 0 ? normalized.slice(0, idx) : '';
49
- }