@scenemesh/entity-engine-aimodule 1.0.0

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 (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +854 -0
  3. package/dist/ai-core-LBGYFGOK.mjs +17 -0
  4. package/dist/ai-core-LBGYFGOK.mjs.map +1 -0
  5. package/dist/ai-core-UGJWSCQN.js +17 -0
  6. package/dist/ai-core-UGJWSCQN.js.map +1 -0
  7. package/dist/ai-core-manager-B3Z34RHA.mjs +9 -0
  8. package/dist/ai-core-manager-B3Z34RHA.mjs.map +1 -0
  9. package/dist/ai-core-manager-W7SSDCG5.js +9 -0
  10. package/dist/ai-core-manager-W7SSDCG5.js.map +1 -0
  11. package/dist/ai-embeddings-5ED5LDXX.mjs +17 -0
  12. package/dist/ai-embeddings-5ED5LDXX.mjs.map +1 -0
  13. package/dist/ai-embeddings-WCXZMMTZ.js +17 -0
  14. package/dist/ai-embeddings-WCXZMMTZ.js.map +1 -0
  15. package/dist/ai-form-renderer-24IWNMX5.js +233 -0
  16. package/dist/ai-form-renderer-24IWNMX5.js.map +1 -0
  17. package/dist/ai-form-renderer-BORQABF2.mjs +233 -0
  18. package/dist/ai-form-renderer-BORQABF2.mjs.map +1 -0
  19. package/dist/ai-provider-3PSCVEEN.mjs +17 -0
  20. package/dist/ai-provider-3PSCVEEN.mjs.map +1 -0
  21. package/dist/ai-provider-WMPMVZFL.js +17 -0
  22. package/dist/ai-provider-WMPMVZFL.js.map +1 -0
  23. package/dist/ai-renderer-7WGGWH5D.mjs +134 -0
  24. package/dist/ai-renderer-7WGGWH5D.mjs.map +1 -0
  25. package/dist/ai-renderer-OILYWAJV.js +134 -0
  26. package/dist/ai-renderer-OILYWAJV.js.map +1 -0
  27. package/dist/ai-settings-DGCFPK3U.js +15 -0
  28. package/dist/ai-settings-DGCFPK3U.js.map +1 -0
  29. package/dist/ai-settings-DTXEAB64.mjs +15 -0
  30. package/dist/ai-settings-DTXEAB64.mjs.map +1 -0
  31. package/dist/ai-structured-EGZ26ZS4.mjs +13 -0
  32. package/dist/ai-structured-EGZ26ZS4.mjs.map +1 -0
  33. package/dist/ai-structured-N2FZLO4A.js +13 -0
  34. package/dist/ai-structured-N2FZLO4A.js.map +1 -0
  35. package/dist/ai-tools-B3R77HZ3.js +19 -0
  36. package/dist/ai-tools-B3R77HZ3.js.map +1 -0
  37. package/dist/ai-tools-JAPVYQGE.mjs +19 -0
  38. package/dist/ai-tools-JAPVYQGE.mjs.map +1 -0
  39. package/dist/ai.module-GAHVCBTP.js +7 -0
  40. package/dist/ai.module-GAHVCBTP.js.map +1 -0
  41. package/dist/ai.module-TTPMTPB3.mjs +7 -0
  42. package/dist/ai.module-TTPMTPB3.mjs.map +1 -0
  43. package/dist/chunk-25C2NRSD.mjs +611 -0
  44. package/dist/chunk-25C2NRSD.mjs.map +1 -0
  45. package/dist/chunk-4JQ7UOXH.js +427 -0
  46. package/dist/chunk-4JQ7UOXH.js.map +1 -0
  47. package/dist/chunk-6IUKES2L.js +290 -0
  48. package/dist/chunk-6IUKES2L.js.map +1 -0
  49. package/dist/chunk-COWPK7XN.mjs +834 -0
  50. package/dist/chunk-COWPK7XN.mjs.map +1 -0
  51. package/dist/chunk-CTEXPMVZ.js +512 -0
  52. package/dist/chunk-CTEXPMVZ.js.map +1 -0
  53. package/dist/chunk-DXQTHA75.js +573 -0
  54. package/dist/chunk-DXQTHA75.js.map +1 -0
  55. package/dist/chunk-DZFQ6I23.js +72 -0
  56. package/dist/chunk-DZFQ6I23.js.map +1 -0
  57. package/dist/chunk-J323UTPE.mjs +650 -0
  58. package/dist/chunk-J323UTPE.mjs.map +1 -0
  59. package/dist/chunk-LHNNALVF.js +834 -0
  60. package/dist/chunk-LHNNALVF.js.map +1 -0
  61. package/dist/chunk-O7SZSMXV.js +1621 -0
  62. package/dist/chunk-O7SZSMXV.js.map +1 -0
  63. package/dist/chunk-OTNOFOVW.js +650 -0
  64. package/dist/chunk-OTNOFOVW.js.map +1 -0
  65. package/dist/chunk-PRIGZEI4.mjs +72 -0
  66. package/dist/chunk-PRIGZEI4.mjs.map +1 -0
  67. package/dist/chunk-SBSZ3IPB.mjs +573 -0
  68. package/dist/chunk-SBSZ3IPB.mjs.map +1 -0
  69. package/dist/chunk-SXPA6SSD.mjs +1621 -0
  70. package/dist/chunk-SXPA6SSD.mjs.map +1 -0
  71. package/dist/chunk-T5A4KAVS.mjs +512 -0
  72. package/dist/chunk-T5A4KAVS.mjs.map +1 -0
  73. package/dist/chunk-TDRKKUNT.mjs +357 -0
  74. package/dist/chunk-TDRKKUNT.mjs.map +1 -0
  75. package/dist/chunk-TJFNODPE.js +357 -0
  76. package/dist/chunk-TJFNODPE.js.map +1 -0
  77. package/dist/chunk-V2SSI3SL.mjs +427 -0
  78. package/dist/chunk-V2SSI3SL.mjs.map +1 -0
  79. package/dist/chunk-X42L6MTY.mjs +290 -0
  80. package/dist/chunk-X42L6MTY.mjs.map +1 -0
  81. package/dist/chunk-YSVMY77H.js +611 -0
  82. package/dist/chunk-YSVMY77H.js.map +1 -0
  83. package/dist/core-ANYRS6EF.mjs +73 -0
  84. package/dist/core-ANYRS6EF.mjs.map +1 -0
  85. package/dist/core-K5K34DCS.js +73 -0
  86. package/dist/core-K5K34DCS.js.map +1 -0
  87. package/dist/core-index.d.mts +1668 -0
  88. package/dist/core-index.d.ts +1668 -0
  89. package/dist/core-index.js +101 -0
  90. package/dist/core-index.js.map +1 -0
  91. package/dist/core-index.mjs +101 -0
  92. package/dist/core-index.mjs.map +1 -0
  93. package/dist/index.d.mts +2911 -0
  94. package/dist/index.d.ts +2911 -0
  95. package/dist/index.js +1177 -0
  96. package/dist/index.js.map +1 -0
  97. package/dist/index.mjs +1177 -0
  98. package/dist/index.mjs.map +1 -0
  99. package/dist/tools-352X7A6X.mjs +366 -0
  100. package/dist/tools-352X7A6X.mjs.map +1 -0
  101. package/dist/tools-YLEX6GNO.js +366 -0
  102. package/dist/tools-YLEX6GNO.js.map +1 -0
  103. package/dist/ui-index.d.mts +627 -0
  104. package/dist/ui-index.d.ts +627 -0
  105. package/dist/ui-index.js +2354 -0
  106. package/dist/ui-index.js.map +1 -0
  107. package/dist/ui-index.mjs +2353 -0
  108. package/dist/ui-index.mjs.map +1 -0
  109. package/package.json +105 -0
@@ -0,0 +1,1621 @@
1
+ // src/components/ChatDialog/ChatDialog.tsx
2
+ import { motion, AnimatePresence } from "framer-motion";
3
+ import React, { useRef, useState, useEffect, useCallback } from "react";
4
+ import {
5
+ X,
6
+ Send,
7
+ Square,
8
+ Paperclip,
9
+ AlertCircle,
10
+ SparklesIcon
11
+ } from "lucide-react";
12
+ import { Box as Box2, Text as Text2, Badge as Badge2, Group as Group2, Paper as Paper2, Stack as Stack2, Title, Button, Textarea, ActionIcon, ScrollArea } from "@mantine/core";
13
+
14
+ // src/hooks/useChat.ts
15
+ import { useChat as useAIChat } from "@ai-sdk/react";
16
+ var useChat = useAIChat;
17
+
18
+ // src/components/MessageBubble/MessageBubble.tsx
19
+ import { Box, Text, Badge, Group, Paper, Stack } from "@mantine/core";
20
+
21
+ // src/components/DynamicUI/EntityEngineDynamicComponents.tsx
22
+ import { EntityViewContainer } from "@scenemesh/entity-engine";
23
+ import { jsx, jsxs } from "react/jsx-runtime";
24
+ var DynamicEntityGridComponent = ({
25
+ modelName = "",
26
+ displayMode = "table",
27
+ toolName,
28
+ _renderHint
29
+ }) => {
30
+ if (!modelName) {
31
+ return /* @__PURE__ */ jsxs("div", { style: {
32
+ padding: "1rem",
33
+ border: "1px solid #e2e8f0",
34
+ borderRadius: "0.5rem",
35
+ backgroundColor: "#f8fafc"
36
+ }, children: [
37
+ /* @__PURE__ */ jsxs("h4", { children: [
38
+ "\u26A0\uFE0F ",
39
+ toolName,
40
+ " \u9519\u8BEF"
41
+ ] }),
42
+ /* @__PURE__ */ jsx("p", { children: "\u7F3A\u5C11\u5FC5\u9700\u7684 modelName \u53C2\u6570" })
43
+ ] });
44
+ }
45
+ return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
46
+ EntityViewContainer,
47
+ {
48
+ modelName,
49
+ viewType: "grid",
50
+ behavior: { mode: "display" },
51
+ viewOptions: {
52
+ mode: displayMode,
53
+ hideToolbar: false,
54
+ hideEditColumn: false,
55
+ hidePagination: false
56
+ }
57
+ }
58
+ ) });
59
+ };
60
+ var DynamicEntityFormComponent = ({
61
+ modelName = "",
62
+ baseObjectId,
63
+ mode = "display",
64
+ toCreating = false,
65
+ toolName
66
+ }) => {
67
+ if (!modelName) {
68
+ return /* @__PURE__ */ jsxs("div", { style: {
69
+ padding: "1rem",
70
+ border: "1px solid #e2e8f0",
71
+ borderRadius: "0.5rem",
72
+ backgroundColor: "#f8fafc"
73
+ }, children: [
74
+ /* @__PURE__ */ jsxs("h4", { children: [
75
+ "\u26A0\uFE0F ",
76
+ toolName,
77
+ " \u9519\u8BEF"
78
+ ] }),
79
+ /* @__PURE__ */ jsx("p", { children: "\u7F3A\u5C11\u5FC5\u9700\u7684 modelName \u53C2\u6570" })
80
+ ] });
81
+ }
82
+ return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
83
+ EntityViewContainer,
84
+ {
85
+ modelName,
86
+ viewType: "form",
87
+ baseObjectId,
88
+ behavior: {
89
+ mode,
90
+ toCreating
91
+ }
92
+ }
93
+ ) });
94
+ };
95
+ var DynamicEntityKanbanComponent = ({
96
+ modelName = "",
97
+ toolName,
98
+ _renderHint
99
+ }) => {
100
+ if (!modelName) {
101
+ return /* @__PURE__ */ jsxs("div", { style: {
102
+ padding: "1rem",
103
+ border: "1px solid #e2e8f0",
104
+ borderRadius: "0.5rem",
105
+ backgroundColor: "#f8fafc"
106
+ }, children: [
107
+ /* @__PURE__ */ jsxs("h4", { children: [
108
+ "\u26A0\uFE0F ",
109
+ toolName,
110
+ " \u9519\u8BEF"
111
+ ] }),
112
+ /* @__PURE__ */ jsx("p", { children: "\u7F3A\u5C11\u5FC5\u9700\u7684 modelName \u53C2\u6570" })
113
+ ] });
114
+ }
115
+ return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
116
+ EntityViewContainer,
117
+ {
118
+ modelName,
119
+ viewType: "kanban",
120
+ behavior: { mode: "display" },
121
+ viewOptions: {
122
+ hideToolbar: false,
123
+ hideEditColumn: false,
124
+ hidePagination: false
125
+ }
126
+ }
127
+ ) });
128
+ };
129
+ var DynamicEntityDashboardComponent = ({
130
+ modelName = "",
131
+ toolName,
132
+ _renderHint
133
+ }) => {
134
+ if (!modelName) {
135
+ return /* @__PURE__ */ jsxs("div", { style: {
136
+ padding: "1rem",
137
+ border: "1px solid #e2e8f0",
138
+ borderRadius: "0.5rem",
139
+ backgroundColor: "#f8fafc"
140
+ }, children: [
141
+ /* @__PURE__ */ jsxs("h4", { children: [
142
+ "\u26A0\uFE0F ",
143
+ toolName,
144
+ " \u9519\u8BEF"
145
+ ] }),
146
+ /* @__PURE__ */ jsx("p", { children: "\u7F3A\u5C11\u5FC5\u9700\u7684 modelName \u53C2\u6570" })
147
+ ] });
148
+ }
149
+ return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
150
+ EntityViewContainer,
151
+ {
152
+ modelName,
153
+ viewType: "dashboard",
154
+ behavior: { mode: "display" },
155
+ viewOptions: {
156
+ hideToolbar: false,
157
+ hideEditColumn: false,
158
+ hidePagination: false
159
+ }
160
+ }
161
+ ) });
162
+ };
163
+ var DynamicEntityMastailComponent = ({
164
+ modelName = "",
165
+ baseObjectId,
166
+ toolName,
167
+ _renderHint
168
+ }) => {
169
+ if (!modelName) {
170
+ return /* @__PURE__ */ jsxs("div", { style: {
171
+ padding: "1rem",
172
+ border: "1px solid #e2e8f0",
173
+ borderRadius: "0.5rem",
174
+ backgroundColor: "#f8fafc"
175
+ }, children: [
176
+ /* @__PURE__ */ jsxs("h4", { children: [
177
+ "\u26A0\uFE0F ",
178
+ toolName,
179
+ " \u9519\u8BEF"
180
+ ] }),
181
+ /* @__PURE__ */ jsx("p", { children: "\u7F3A\u5C11\u5FC5\u9700\u7684 modelName \u53C2\u6570" })
182
+ ] });
183
+ }
184
+ return /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
185
+ EntityViewContainer,
186
+ {
187
+ modelName,
188
+ viewType: "mastail",
189
+ baseObjectId,
190
+ behavior: { mode: "display" },
191
+ viewOptions: {
192
+ hideToolbar: false,
193
+ hideEditColumn: false,
194
+ hidePagination: false
195
+ }
196
+ }
197
+ ) });
198
+ };
199
+ var DynamicErrorDisplayComponent = ({
200
+ toolName,
201
+ error,
202
+ errorDetails,
203
+ errorType,
204
+ executedAt,
205
+ _renderHint
206
+ }) => /* @__PURE__ */ jsxs("div", { style: {
207
+ padding: "1rem",
208
+ backgroundColor: "#fee2e2",
209
+ border: "1px solid #fecaca",
210
+ borderRadius: "0.5rem",
211
+ color: "#dc2626",
212
+ margin: "0.5rem 0"
213
+ }, children: [
214
+ /* @__PURE__ */ jsxs("div", { style: { fontWeight: "500", marginBottom: "0.5rem" }, children: [
215
+ "\u274C ",
216
+ toolName,
217
+ " \u6267\u884C\u5931\u8D25"
218
+ ] }),
219
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, fontSize: "0.875rem" }, children: error }),
220
+ errorDetails && /* @__PURE__ */ jsxs("details", { style: { marginTop: "0.5rem" }, children: [
221
+ /* @__PURE__ */ jsx("summary", { style: { cursor: "pointer", fontSize: "0.875rem" }, children: "\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F" }),
222
+ /* @__PURE__ */ jsx("pre", { style: {
223
+ marginTop: "0.25rem",
224
+ fontSize: "0.75rem",
225
+ backgroundColor: "#fef2f2",
226
+ padding: "0.5rem",
227
+ borderRadius: "0.25rem",
228
+ overflow: "auto",
229
+ whiteSpace: "pre-wrap"
230
+ }, children: errorDetails })
231
+ ] }),
232
+ executedAt && /* @__PURE__ */ jsxs("div", { style: {
233
+ fontSize: "0.75rem",
234
+ color: "#991b1b",
235
+ marginTop: "0.5rem",
236
+ opacity: 0.8
237
+ }, children: [
238
+ "\u6267\u884C\u65F6\u95F4: ",
239
+ new Date(executedAt).toLocaleString()
240
+ ] })
241
+ ] });
242
+ var ENTITY_DYNAMIC_COMPONENTS = {
243
+ "DynamicDataTable": DynamicEntityGridComponent,
244
+ "DynamicDataGrid": DynamicEntityGridComponent,
245
+ "DynamicDataList": DynamicEntityGridComponent,
246
+ "DynamicEntityForm": DynamicEntityFormComponent,
247
+ "DynamicEntityKanban": DynamicEntityKanbanComponent,
248
+ "DynamicEntityDashboard": DynamicEntityDashboardComponent,
249
+ "DynamicEntityMastail": DynamicEntityMastailComponent,
250
+ "DynamicErrorDisplay": DynamicErrorDisplayComponent
251
+ };
252
+
253
+ // src/components/DynamicUI/DynamicToolRenderer.tsx
254
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
255
+ function DynamicToolRenderer({ toolName, input, output, state }) {
256
+ switch (state) {
257
+ case "input-streaming":
258
+ return /* @__PURE__ */ jsxs2("div", { style: { padding: "0.75rem", background: "#f8fafc", borderRadius: "0.5rem", border: "1px solid #e2e8f0" }, children: [
259
+ /* @__PURE__ */ jsxs2("div", { style: { fontWeight: "500", marginBottom: "0.25rem" }, children: [
260
+ "\u26A1 ",
261
+ toolName,
262
+ " - \u51C6\u5907\u4E2D..."
263
+ ] }),
264
+ /* @__PURE__ */ jsx2("div", { style: { fontSize: "0.875rem", color: "#64748b" }, children: "\u6B63\u5728\u89E3\u6790\u5DE5\u5177\u53C2\u6570..." })
265
+ ] });
266
+ case "input-available":
267
+ return /* @__PURE__ */ jsxs2("div", { style: { padding: "0.75rem", background: "#fef3c7", borderRadius: "0.5rem", border: "1px solid #f59e0b" }, children: [
268
+ /* @__PURE__ */ jsxs2("div", { style: { fontWeight: "500", marginBottom: "0.25rem" }, children: [
269
+ "\u{1F527} ",
270
+ toolName,
271
+ " - \u6267\u884C\u4E2D"
272
+ ] }),
273
+ /* @__PURE__ */ jsxs2("div", { style: { fontSize: "0.875rem", color: "#92400e" }, children: [
274
+ input?.modelName && `\u67E5\u8BE2\u6A21\u578B\uFF1A${input.modelName}`,
275
+ input?.displayMode && ` | \u663E\u793A\u6A21\u5F0F\uFF1A${input.displayMode}`
276
+ ] })
277
+ ] });
278
+ case "output-available":
279
+ return /* @__PURE__ */ jsx2(
280
+ DynamicOutputRenderer,
281
+ {
282
+ toolName,
283
+ input,
284
+ output
285
+ }
286
+ );
287
+ case "output-error":
288
+ return /* @__PURE__ */ jsxs2("div", { style: {
289
+ padding: "1rem",
290
+ background: "#fee2e2",
291
+ borderRadius: "0.5rem",
292
+ border: "1px solid #fecaca",
293
+ color: "#dc2626"
294
+ }, children: [
295
+ /* @__PURE__ */ jsxs2("div", { style: { fontWeight: "500", marginBottom: "0.5rem" }, children: [
296
+ "\u274C ",
297
+ toolName,
298
+ " \u6267\u884C\u5931\u8D25"
299
+ ] }),
300
+ /* @__PURE__ */ jsx2("p", { style: { margin: 0 }, children: output?.error || "\u672A\u77E5\u9519\u8BEF" }),
301
+ output?.errorDetails && /* @__PURE__ */ jsxs2("details", { style: { marginTop: "0.5rem" }, children: [
302
+ /* @__PURE__ */ jsx2("summary", { style: { cursor: "pointer" }, children: "\u8BE6\u7EC6\u4FE1\u606F" }),
303
+ /* @__PURE__ */ jsx2("p", { style: { marginTop: "0.25rem", fontSize: "0.875rem" }, children: output.errorDetails })
304
+ ] })
305
+ ] });
306
+ default:
307
+ return /* @__PURE__ */ jsxs2("div", { style: { padding: "0.75rem", background: "#f1f5f9", borderRadius: "0.5rem" }, children: [
308
+ /* @__PURE__ */ jsxs2("h4", { children: [
309
+ "\u{1F527} ",
310
+ toolName
311
+ ] }),
312
+ /* @__PURE__ */ jsxs2("p", { children: [
313
+ "\u672A\u77E5\u72B6\u6001: ",
314
+ state
315
+ ] })
316
+ ] });
317
+ }
318
+ }
319
+ function DynamicOutputRenderer({ toolName, input, output }) {
320
+ const renderHint = output?._renderHint;
321
+ const componentType = renderHint?.componentType;
322
+ const displayMode = input?.displayMode || output?.displayMode;
323
+ let selectedComponentType;
324
+ if (componentType && componentType in ENTITY_DYNAMIC_COMPONENTS) {
325
+ selectedComponentType = componentType;
326
+ } else {
327
+ switch (displayMode) {
328
+ case "table":
329
+ selectedComponentType = "DynamicDataTable";
330
+ break;
331
+ case "list":
332
+ selectedComponentType = "DynamicDataGrid";
333
+ break;
334
+ case "grid":
335
+ selectedComponentType = "DynamicDataGrid";
336
+ break;
337
+ case "form":
338
+ selectedComponentType = "DynamicEntityForm";
339
+ break;
340
+ case "kanban":
341
+ selectedComponentType = "DynamicEntityKanban";
342
+ break;
343
+ case "dashboard":
344
+ selectedComponentType = "DynamicEntityDashboard";
345
+ break;
346
+ case "mastail":
347
+ selectedComponentType = "DynamicEntityMastail";
348
+ break;
349
+ default:
350
+ if (input?.baseObjectId || output?.baseObjectId) {
351
+ selectedComponentType = "DynamicEntityForm";
352
+ } else {
353
+ selectedComponentType = "DynamicDataGrid";
354
+ }
355
+ }
356
+ }
357
+ const SelectedComponent = ENTITY_DYNAMIC_COMPONENTS[selectedComponentType];
358
+ const componentProps = {
359
+ toolName,
360
+ modelName: input?.modelName || output?.modelName,
361
+ displayMode: displayMode || "table",
362
+ data: output?.data,
363
+ totalCount: output?.totalCount,
364
+ pagination: output?.pagination,
365
+ query: output?.query || {
366
+ sortBy: input?.sortBy,
367
+ filters: input?.filters
368
+ },
369
+ baseObjectId: input?.baseObjectId,
370
+ mode: input?.mode === "create" ? "edit" : input?.mode || "display",
371
+ toCreating: input?.mode === "create",
372
+ executedAt: output?.executedAt,
373
+ toolCallId: output?.toolCallId,
374
+ _renderHint: renderHint
375
+ };
376
+ if (selectedComponentType === "DynamicErrorDisplay") {
377
+ componentProps.error = output?.error || "Unknown error";
378
+ componentProps.errorDetails = output?.errorDetails || renderHint?.errorDetails;
379
+ componentProps.errorType = output?.errorType || renderHint?.errorType || "unknown";
380
+ }
381
+ return /* @__PURE__ */ jsxs2("div", { style: { margin: "0.5rem 0" }, children: [
382
+ /* @__PURE__ */ jsxs2("div", { style: {
383
+ fontWeight: "500",
384
+ marginBottom: "0.75rem",
385
+ padding: "0.5rem",
386
+ background: "#f0f9ff",
387
+ borderRadius: "0.375rem",
388
+ border: "1px solid #e0f2fe"
389
+ }, children: [
390
+ "\u{1F527} ",
391
+ toolName,
392
+ " \u7ED3\u679C",
393
+ output?.executedAt && /* @__PURE__ */ jsx2("span", { style: {
394
+ fontSize: "0.75rem",
395
+ color: "#64748b",
396
+ marginLeft: "0.5rem"
397
+ }, children: new Date(output.executedAt).toLocaleString() })
398
+ ] }),
399
+ /* @__PURE__ */ jsx2(SelectedComponent, { ...componentProps })
400
+ ] });
401
+ }
402
+
403
+ // src/components/GenerativeUI/PrebuiltComponents.tsx
404
+ import { EntityViewContainer as EntityViewContainer2 } from "@scenemesh/entity-engine";
405
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
406
+ var WeatherComponent = ({
407
+ temperature = 0,
408
+ weather = "",
409
+ location = "",
410
+ humidity,
411
+ windSpeed
412
+ }) => (
413
+ // <div style={{
414
+ // background: 'linear-gradient(135deg, #74b9ff 0%, #0984e3 100%)',
415
+ // color: 'white',
416
+ // padding: '1.5rem',
417
+ // borderRadius: '0.75rem',
418
+ // margin: '0.5rem 0',
419
+ // boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)'
420
+ // }}>
421
+ // <div style={{ display: 'flex', alignItems: 'center', marginBottom: '0.5rem' }}>
422
+ // <span style={{ fontSize: '1.5rem', marginRight: '0.5rem' }}>🌤️</span>
423
+ // <h3 style={{ margin: 0, fontSize: '1.25rem' }}>{location}</h3>
424
+ // </div>
425
+ // <p style={{ margin: '0.25rem 0', fontSize: '1rem' }}>{weather}</p>
426
+ // <p style={{ margin: '0.25rem 0', fontSize: '1.5rem', fontWeight: 'bold' }}>{temperature}°C</p>
427
+ // {humidity && <p style={{ margin: '0.25rem 0', fontSize: '0.875rem' }}>湿度: {humidity}%</p>}
428
+ // {windSpeed && <p style={{ margin: '0.25rem 0', fontSize: '0.875rem' }}>风速: {windSpeed} km/h</p>}
429
+ // </div>
430
+ /* @__PURE__ */ jsx3(EntityViewContainer2, { modelName: "product", viewType: "grid", behavior: { mode: "edit" } })
431
+ );
432
+ var LocationComponent = ({
433
+ city = "",
434
+ country = "",
435
+ province = "",
436
+ coordinates,
437
+ timezone = "",
438
+ population,
439
+ area
440
+ }) => /* @__PURE__ */ jsxs3("div", { style: {
441
+ background: "linear-gradient(135deg, #fd79a8 0%, #e84393 100%)",
442
+ color: "white",
443
+ padding: "1.5rem",
444
+ borderRadius: "0.75rem",
445
+ margin: "0.5rem 0",
446
+ boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)"
447
+ }, children: [
448
+ /* @__PURE__ */ jsxs3("div", { style: { display: "flex", alignItems: "center", marginBottom: "0.5rem" }, children: [
449
+ /* @__PURE__ */ jsx3("span", { style: { fontSize: "1.5rem", marginRight: "0.5rem" }, children: "\u{1F4CD}" }),
450
+ /* @__PURE__ */ jsx3("h3", { style: { margin: 0, fontSize: "1.25rem" }, children: city })
451
+ ] }),
452
+ province && /* @__PURE__ */ jsxs3("p", { style: { margin: "0.25rem 0", fontSize: "1rem" }, children: [
453
+ province,
454
+ ", ",
455
+ country
456
+ ] }),
457
+ coordinates && /* @__PURE__ */ jsxs3("p", { style: { margin: "0.25rem 0", fontSize: "0.875rem" }, children: [
458
+ "\u5750\u6807: ",
459
+ coordinates.lat.toFixed(4),
460
+ ", ",
461
+ coordinates.lng.toFixed(4)
462
+ ] }),
463
+ timezone && /* @__PURE__ */ jsxs3("p", { style: { margin: "0.25rem 0", fontSize: "0.875rem" }, children: [
464
+ "\u65F6\u533A: ",
465
+ timezone
466
+ ] }),
467
+ population && /* @__PURE__ */ jsxs3("p", { style: { margin: "0.25rem 0", fontSize: "0.875rem" }, children: [
468
+ "\u4EBA\u53E3: ",
469
+ population.toLocaleString(),
470
+ "\u4E07\u4EBA"
471
+ ] }),
472
+ area && /* @__PURE__ */ jsxs3("p", { style: { margin: "0.25rem 0", fontSize: "0.875rem" }, children: [
473
+ "\u9762\u79EF: ",
474
+ area.toLocaleString(),
475
+ " km\xB2"
476
+ ] })
477
+ ] });
478
+ var CodeExecutionComponent = ({
479
+ code = "",
480
+ language = "javascript",
481
+ output = "",
482
+ status = "success"
483
+ }) => /* @__PURE__ */ jsxs3("div", { style: {
484
+ background: "#f8fafc",
485
+ border: "1px solid #e2e8f0",
486
+ borderRadius: "0.75rem",
487
+ margin: "0.5rem 0",
488
+ overflow: "hidden"
489
+ }, children: [
490
+ /* @__PURE__ */ jsxs3("div", { style: {
491
+ background: "#334155",
492
+ color: "white",
493
+ padding: "0.75rem 1rem",
494
+ fontSize: "0.875rem",
495
+ display: "flex",
496
+ alignItems: "center"
497
+ }, children: [
498
+ /* @__PURE__ */ jsx3("span", { style: { marginRight: "0.5rem" }, children: "\u{1F4BB}" }),
499
+ /* @__PURE__ */ jsxs3("span", { children: [
500
+ "\u4EE3\u7801\u6267\u884C (",
501
+ language,
502
+ ")"
503
+ ] }),
504
+ /* @__PURE__ */ jsx3("span", { style: {
505
+ marginLeft: "auto",
506
+ fontSize: "0.75rem",
507
+ color: status === "success" ? "#10b981" : status === "error" ? "#ef4444" : "#f59e0b"
508
+ }, children: status === "success" ? "\u2705 \u6210\u529F" : status === "error" ? "\u274C \u9519\u8BEF" : "\u23F3 \u8FD0\u884C\u4E2D" })
509
+ ] }),
510
+ code && /* @__PURE__ */ jsx3("div", { style: { padding: "1rem" }, children: /* @__PURE__ */ jsx3("pre", { style: {
511
+ background: "#1e293b",
512
+ color: "#e2e8f0",
513
+ padding: "1rem",
514
+ borderRadius: "0.5rem",
515
+ fontSize: "0.875rem",
516
+ overflow: "auto",
517
+ margin: "0 0 1rem 0"
518
+ }, children: code }) }),
519
+ output && /* @__PURE__ */ jsxs3("div", { style: { padding: "0 1rem 1rem" }, children: [
520
+ /* @__PURE__ */ jsx3("h4", { style: { margin: "0 0 0.5rem 0", fontSize: "0.875rem", color: "#64748b" }, children: "\u8F93\u51FA:" }),
521
+ /* @__PURE__ */ jsx3("pre", { style: {
522
+ background: status === "error" ? "#fef2f2" : "#f0f9ff",
523
+ color: status === "error" ? "#dc2626" : "#0f172a",
524
+ padding: "1rem",
525
+ borderRadius: "0.5rem",
526
+ fontSize: "0.875rem",
527
+ overflow: "auto",
528
+ margin: 0,
529
+ border: `1px solid ${status === "error" ? "#fecaca" : "#e0f2fe"}`
530
+ }, children: output })
531
+ ] })
532
+ ] });
533
+
534
+ // src/components/MessageBubble/MessageBubble.tsx
535
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
536
+ var ReasoningDisplay = ({ reasoning, step }) => /* @__PURE__ */ jsxs4(
537
+ Paper,
538
+ {
539
+ p: "sm",
540
+ withBorder: true,
541
+ style: {
542
+ backgroundColor: "var(--mantine-color-yellow-0)",
543
+ borderColor: "var(--mantine-color-yellow-2)",
544
+ borderLeft: "3px solid var(--mantine-color-yellow-4)"
545
+ },
546
+ children: [
547
+ /* @__PURE__ */ jsxs4(Text, { size: "xs", fw: 500, c: "var(--mantine-color-yellow-8)", mb: 4, children: [
548
+ "\u{1F4AD} ",
549
+ step ? `Step ${step}:` : "Reasoning:"
550
+ ] }),
551
+ /* @__PURE__ */ jsx4(Text, { size: "xs", c: "var(--mantine-color-gray-7)", style: { lineHeight: 1.3 }, children: reasoning })
552
+ ]
553
+ }
554
+ );
555
+ var FileDisplay = ({ file }) => {
556
+ if (!file) return null;
557
+ return /* @__PURE__ */ jsx4(
558
+ Paper,
559
+ {
560
+ p: "sm",
561
+ withBorder: true,
562
+ style: {
563
+ backgroundColor: "var(--mantine-color-gray-0)",
564
+ borderColor: "var(--mantine-color-gray-3)"
565
+ },
566
+ children: /* @__PURE__ */ jsxs4(Group, { gap: "xs", align: "center", children: [
567
+ /* @__PURE__ */ jsx4(
568
+ Box,
569
+ {
570
+ w: 24,
571
+ h: 24,
572
+ bg: "var(--mantine-color-gray-1)",
573
+ style: {
574
+ borderRadius: "4px",
575
+ display: "flex",
576
+ alignItems: "center",
577
+ justifyContent: "center",
578
+ fontSize: "12px"
579
+ },
580
+ children: "\u{1F4CE}"
581
+ }
582
+ ),
583
+ /* @__PURE__ */ jsxs4(Box, { style: { flex: 1 }, children: [
584
+ /* @__PURE__ */ jsx4(Text, { size: "xs", fw: 500, c: "var(--mantine-color-gray-8)", children: file.name || "File" }),
585
+ file.size && /* @__PURE__ */ jsxs4(Text, { size: "xs", c: "var(--mantine-color-gray-6)", children: [
586
+ Math.round(file.size / 1024),
587
+ "KB"
588
+ ] }),
589
+ file.url && /* @__PURE__ */ jsx4(
590
+ Text,
591
+ {
592
+ size: "xs",
593
+ component: "a",
594
+ href: file.url,
595
+ target: "_blank",
596
+ rel: "noopener noreferrer",
597
+ c: "var(--mantine-color-blue-6)",
598
+ td: "none",
599
+ style: { cursor: "pointer" },
600
+ children: "View File"
601
+ }
602
+ )
603
+ ] })
604
+ ] })
605
+ }
606
+ );
607
+ };
608
+ function MessageBubble({
609
+ message,
610
+ showAvatar = false,
611
+ // 不再使用头像
612
+ showTimestamp = true,
613
+ onToolResult,
614
+ enableReasoning = true,
615
+ enableGenerativeUI = true,
616
+ showReasoningByDefault = false
617
+ }) {
618
+ const isUser = message.role === "user";
619
+ return /* @__PURE__ */ jsxs4(Stack, { gap: "xs", mb: "md", style: { width: "100%" }, children: [
620
+ /* @__PURE__ */ jsxs4(
621
+ Group,
622
+ {
623
+ gap: "xs",
624
+ align: "center",
625
+ justify: isUser ? "flex-end" : "flex-start",
626
+ children: [
627
+ /* @__PURE__ */ jsx4(
628
+ Badge,
629
+ {
630
+ variant: "light",
631
+ color: isUser ? "blue" : "gray",
632
+ size: "xs",
633
+ radius: "sm",
634
+ children: isUser ? "You" : "AI"
635
+ }
636
+ ),
637
+ showTimestamp && /* @__PURE__ */ jsx4(Text, { size: "xs", c: "var(--mantine-color-gray-5)", children: (/* @__PURE__ */ new Date()).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) })
638
+ ]
639
+ }
640
+ ),
641
+ /* @__PURE__ */ jsx4(
642
+ Box,
643
+ {
644
+ style: {
645
+ width: "100%",
646
+ display: "flex",
647
+ justifyContent: isUser ? "flex-end" : "flex-start"
648
+ },
649
+ children: /* @__PURE__ */ jsx4(
650
+ Box,
651
+ {
652
+ style: {
653
+ maxWidth: "100%",
654
+ width: isUser ? "fit-content" : "100%"
655
+ },
656
+ children: message.parts.map((part, index) => {
657
+ if (part.type === "text") {
658
+ return /* @__PURE__ */ jsx4(
659
+ Text,
660
+ {
661
+ size: "sm",
662
+ style: {
663
+ lineHeight: 1.5,
664
+ whiteSpace: "pre-wrap",
665
+ wordBreak: "break-word",
666
+ textAlign: isUser ? "right" : "left"
667
+ },
668
+ c: "var(--mantine-color-text)",
669
+ children: part.text
670
+ },
671
+ index
672
+ );
673
+ }
674
+ if (part.type === "file") {
675
+ return /* @__PURE__ */ jsx4(FileDisplay, { file: part }, index);
676
+ }
677
+ if (part.type === "data") {
678
+ if (part.data?.type === "reasoning" && enableReasoning) {
679
+ return /* @__PURE__ */ jsx4(
680
+ ReasoningDisplay,
681
+ {
682
+ reasoning: part.data.content,
683
+ step: part.data.step
684
+ },
685
+ index
686
+ );
687
+ }
688
+ return null;
689
+ }
690
+ if (part.type === "tool-getWeather") {
691
+ switch (part.state) {
692
+ case "input-streaming":
693
+ return /* @__PURE__ */ jsx4(Text, { size: "xs", c: "var(--mantine-color-gray-6)", children: "Preparing weather request..." }, index);
694
+ case "input-available":
695
+ return /* @__PURE__ */ jsxs4(Text, { size: "xs", c: "var(--mantine-color-gray-6)", children: [
696
+ "Getting weather for ",
697
+ part.input?.location,
698
+ "..."
699
+ ] }, index);
700
+ case "output-available": {
701
+ if (onToolResult) {
702
+ onToolResult({
703
+ toolName: "getWeather",
704
+ input: part.input,
705
+ output: part.output,
706
+ state: part.state
707
+ });
708
+ }
709
+ const rawData = part.output.data || part.output;
710
+ const weatherData = {
711
+ ...rawData,
712
+ weather: rawData.condition || rawData.weather
713
+ };
714
+ return /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsx4(WeatherComponent, { ...weatherData }) }, index);
715
+ }
716
+ case "output-error":
717
+ return /* @__PURE__ */ jsx4(Paper, { p: "sm", withBorder: true, style: {
718
+ backgroundColor: "var(--mantine-color-red-0)",
719
+ borderColor: "var(--mantine-color-red-2)",
720
+ borderLeft: "3px solid var(--mantine-color-red-4)"
721
+ }, children: /* @__PURE__ */ jsxs4(Text, { size: "xs", c: "var(--mantine-color-red-8)", children: [
722
+ "\u274C Weather Error: ",
723
+ part.errorText
724
+ ] }) }, index);
725
+ default:
726
+ return null;
727
+ }
728
+ }
729
+ if (part.type === "tool-getLocation") {
730
+ switch (part.state) {
731
+ case "input-streaming":
732
+ return /* @__PURE__ */ jsx4(Text, { size: "xs", c: "var(--mantine-color-gray-6)", children: "Preparing location request..." }, index);
733
+ case "input-available":
734
+ return /* @__PURE__ */ jsxs4(Text, { size: "xs", c: "var(--mantine-color-gray-6)", children: [
735
+ "Getting location for ",
736
+ part.input?.city,
737
+ "..."
738
+ ] }, index);
739
+ case "output-available": {
740
+ if (onToolResult) {
741
+ onToolResult({
742
+ toolName: "getLocation",
743
+ input: part.input,
744
+ output: part.output,
745
+ state: part.state
746
+ });
747
+ }
748
+ const locationData = part.output.data || part.output;
749
+ return /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsx4(LocationComponent, { ...locationData }) }, index);
750
+ }
751
+ case "output-error":
752
+ return /* @__PURE__ */ jsx4(Paper, { p: "sm", withBorder: true, style: {
753
+ backgroundColor: "var(--mantine-color-red-0)",
754
+ borderColor: "var(--mantine-color-red-2)",
755
+ borderLeft: "3px solid var(--mantine-color-red-4)"
756
+ }, children: /* @__PURE__ */ jsxs4(Text, { size: "xs", c: "var(--mantine-color-red-8)", children: [
757
+ "\u274C Location Error: ",
758
+ part.errorText
759
+ ] }) }, index);
760
+ default:
761
+ return null;
762
+ }
763
+ }
764
+ if (part.type === "tool-displayWeather") {
765
+ switch (part.state) {
766
+ case "input-streaming":
767
+ return /* @__PURE__ */ jsx4(Text, { size: "xs", c: "var(--mantine-color-gray-6)", children: "Preparing weather display..." }, index);
768
+ case "input-available":
769
+ return /* @__PURE__ */ jsxs4(Text, { size: "xs", c: "var(--mantine-color-gray-6)", children: [
770
+ "Loading weather display for ",
771
+ part.input?.location,
772
+ "..."
773
+ ] }, index);
774
+ case "output-available":
775
+ return /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsx4(WeatherComponent, { ...part.output }) }, index);
776
+ case "output-error":
777
+ return /* @__PURE__ */ jsx4(Paper, { p: "sm", withBorder: true, style: {
778
+ backgroundColor: "var(--mantine-color-red-0)",
779
+ borderColor: "var(--mantine-color-red-2)",
780
+ borderLeft: "3px solid var(--mantine-color-red-4)"
781
+ }, children: /* @__PURE__ */ jsxs4(Text, { size: "xs", c: "var(--mantine-color-red-8)", children: [
782
+ "\u274C Weather Display Error: ",
783
+ part.errorText
784
+ ] }) }, index);
785
+ default:
786
+ return null;
787
+ }
788
+ }
789
+ if (part.type === "tool-executeCode") {
790
+ switch (part.state) {
791
+ case "input-streaming":
792
+ return /* @__PURE__ */ jsx4(Text, { size: "xs", c: "var(--mantine-color-gray-6)", children: "Preparing code execution..." }, index);
793
+ case "input-available":
794
+ return /* @__PURE__ */ jsx4(Text, { size: "xs", c: "var(--mantine-color-gray-6)", children: "Executing code..." }, index);
795
+ case "output-available":
796
+ if (onToolResult) {
797
+ onToolResult({
798
+ toolName: "executeCode",
799
+ input: part.input,
800
+ output: part.output,
801
+ state: part.state
802
+ });
803
+ }
804
+ return /* @__PURE__ */ jsx4("div", { children: /* @__PURE__ */ jsx4(CodeExecutionComponent, { ...part.output }) }, index);
805
+ case "output-error":
806
+ return /* @__PURE__ */ jsx4(Paper, { p: "sm", withBorder: true, style: {
807
+ backgroundColor: "var(--mantine-color-red-0)",
808
+ borderColor: "var(--mantine-color-red-2)",
809
+ borderLeft: "3px solid var(--mantine-color-red-4)"
810
+ }, children: /* @__PURE__ */ jsxs4(Text, { size: "xs", c: "var(--mantine-color-red-8)", children: [
811
+ "\u274C Code Execution Error: ",
812
+ part.errorText
813
+ ] }) }, index);
814
+ default:
815
+ return null;
816
+ }
817
+ }
818
+ if (part.type === "dynamic-tool") {
819
+ return /* @__PURE__ */ jsx4(
820
+ DynamicToolRenderer,
821
+ {
822
+ toolName: part.toolName,
823
+ input: part.input,
824
+ output: part.output,
825
+ state: part.state
826
+ },
827
+ index
828
+ );
829
+ }
830
+ if (part.type === "tool-result") {
831
+ return /* @__PURE__ */ jsxs4(Paper, { p: "sm", withBorder: true, style: {
832
+ backgroundColor: "var(--mantine-color-blue-0)",
833
+ borderColor: "var(--mantine-color-blue-2)",
834
+ borderLeft: "3px solid var(--mantine-color-blue-4)"
835
+ }, children: [
836
+ /* @__PURE__ */ jsx4(Text, { size: "xs", fw: 500, c: "var(--mantine-color-blue-8)", mb: 4, children: "\u{1F527} Tool Result" }),
837
+ /* @__PURE__ */ jsx4(Text, { component: "pre", size: "xs", style: {
838
+ fontFamily: "monospace",
839
+ margin: 0,
840
+ lineHeight: 1.3,
841
+ overflow: "auto"
842
+ }, c: "var(--mantine-color-gray-7)", children: JSON.stringify(part.result, null, 2) })
843
+ ] }, index);
844
+ }
845
+ return null;
846
+ })
847
+ }
848
+ )
849
+ }
850
+ )
851
+ ] });
852
+ }
853
+
854
+ // src/utils/theme.ts
855
+ var aiThemeColors = {
856
+ // 主要文本颜色 - 使用 Mantine CSS 变量
857
+ primaryText: "var(--mantine-color-text)",
858
+ // 主要文本颜色,自动适配主题
859
+ secondaryText: "var(--mantine-color-dimmed)",
860
+ // 次要文本颜色
861
+ headingText: "var(--mantine-color-text)",
862
+ // 标题文本颜色
863
+ // 语义化文本颜色 - 优化深色模式
864
+ mutedText: "var(--mantine-color-dimmed)",
865
+ // 静音文本,使用dimmed确保深色模式协调
866
+ placeholderText: "var(--mantine-color-placeholder)",
867
+ // 占位符文本
868
+ // 状态颜色 - 使用 Mantine 预定义颜色
869
+ success: "var(--mantine-color-green-filled)",
870
+ warning: "var(--mantine-color-yellow-filled)",
871
+ error: "var(--mantine-color-red-filled)",
872
+ info: "var(--mantine-color-blue-filled)",
873
+ // 浅色状态颜色(用于背景)- 深色模式自动适配
874
+ successLight: "var(--mantine-color-green-light)",
875
+ warningLight: "var(--mantine-color-yellow-light)",
876
+ errorLight: "var(--mantine-color-red-light)",
877
+ infoLight: "var(--mantine-color-blue-light)",
878
+ // 背景颜色 - 深色模式自动切换
879
+ bodyBackground: "var(--mantine-color-body)",
880
+ // 主体背景
881
+ cardBackground: "var(--mantine-color-default)",
882
+ // 卡片背景,使用default确保深色模式协调
883
+ paperBackground: "var(--mantine-color-default)",
884
+ // 纸张背景
885
+ codeBackground: "var(--mantine-color-default)",
886
+ // 代码背景,深色模式下自动变深
887
+ // 边框和分隔线 - 深色模式自动适配
888
+ border: "var(--mantine-color-default-border)",
889
+ // 默认边框
890
+ borderLight: "var(--mantine-color-default-border)",
891
+ // 统一使用default-border
892
+ divider: "var(--mantine-color-default-border)",
893
+ // 分隔线
894
+ // 交互状态 - 深色模式友好
895
+ hoverBackground: "var(--mantine-color-default-hover)",
896
+ // 悬浮背景,深色模式自动调整
897
+ selectedBackground: "var(--mantine-color-blue-light)",
898
+ // 选中背景 - 使用蓝色,深色模式下更清晰
899
+ selectedText: "var(--mantine-color-blue-filled)",
900
+ // 选中文本 - 使用蓝色,深色模式下更清晰
901
+ // 输入组件 - 深色模式协调
902
+ inputBackground: "var(--mantine-color-default)",
903
+ // 输入框背景
904
+ inputBorder: "var(--mantine-color-default-border)",
905
+ // 输入框边框
906
+ inputPlaceholder: "var(--mantine-color-placeholder)"
907
+ // 输入框占位符
908
+ };
909
+ function getThemedTextProps(variant = "primary") {
910
+ switch (variant) {
911
+ case "primary":
912
+ return { c: aiThemeColors.primaryText };
913
+ case "secondary":
914
+ return { c: aiThemeColors.secondaryText };
915
+ case "heading":
916
+ return { c: aiThemeColors.headingText, fw: 600 };
917
+ case "muted":
918
+ return { c: "var(--mantine-color-gray-6)" };
919
+ // 深色模式下更清晰
920
+ case "subtitle":
921
+ return { c: "var(--mantine-color-gray-7)", fw: 500 };
922
+ case "caption":
923
+ return { c: "var(--mantine-color-gray-6)" };
924
+ case "success":
925
+ return { c: aiThemeColors.success };
926
+ case "warning":
927
+ return { c: aiThemeColors.warning };
928
+ case "error":
929
+ return { c: aiThemeColors.error };
930
+ case "info":
931
+ return { c: aiThemeColors.info };
932
+ default:
933
+ return { c: aiThemeColors.primaryText };
934
+ }
935
+ }
936
+ var componentStyles = {
937
+ // 共享基础样式
938
+ cardBackground: aiThemeColors.cardBackground,
939
+ // 聊天对话框样式 - 深色模式优化
940
+ chatDialog: {
941
+ titleColor: aiThemeColors.headingText,
942
+ descriptionColor: aiThemeColors.secondaryText,
943
+ cardBackground: aiThemeColors.cardBackground,
944
+ border: aiThemeColors.border
945
+ },
946
+ // 消息气泡样式
947
+ messageBubble: {
948
+ userBackground: "var(--mantine-color-blue-filled)",
949
+ userText: "var(--mantine-color-white)",
950
+ aiBackground: aiThemeColors.cardBackground,
951
+ aiText: aiThemeColors.primaryText,
952
+ border: aiThemeColors.border
953
+ },
954
+ // 文件查看器样式
955
+ fileViewer: {
956
+ background: aiThemeColors.cardBackground,
957
+ border: aiThemeColors.borderLight,
958
+ text: aiThemeColors.primaryText
959
+ },
960
+ // 代码背景
961
+ codeBackground: aiThemeColors.codeBackground,
962
+ // 工具栏样式
963
+ toolbar: {
964
+ background: aiThemeColors.bodyBackground,
965
+ border: aiThemeColors.border,
966
+ text: aiThemeColors.primaryText
967
+ },
968
+ // 状态样式配置 - 深色模式完美适配
969
+ status: {
970
+ error: {
971
+ background: "var(--mantine-color-red-light)",
972
+ border: "var(--mantine-color-red-outline)",
973
+ text: "var(--mantine-color-red-light-color)",
974
+ textSecondary: "var(--mantine-color-red-light-color)",
975
+ textLight: "var(--mantine-color-red-light-color)",
976
+ icon: "var(--mantine-color-red-light-color)",
977
+ progressColor: "red"
978
+ },
979
+ warning: {
980
+ background: "var(--mantine-color-yellow-light)",
981
+ border: "var(--mantine-color-yellow-outline)",
982
+ text: "var(--mantine-color-yellow-light-color)",
983
+ textSecondary: "var(--mantine-color-yellow-light-color)",
984
+ textLight: "var(--mantine-color-yellow-light-color)",
985
+ icon: "var(--mantine-color-yellow-light-color)",
986
+ progressColor: "yellow"
987
+ },
988
+ success: {
989
+ background: "var(--mantine-color-green-light)",
990
+ border: "var(--mantine-color-green-outline)",
991
+ text: "var(--mantine-color-green-light-color)",
992
+ textSecondary: "var(--mantine-color-green-light-color)",
993
+ textLight: "var(--mantine-color-green-light-color)",
994
+ icon: "var(--mantine-color-green-light-color)",
995
+ progressColor: "green"
996
+ },
997
+ info: {
998
+ background: "var(--mantine-color-blue-light)",
999
+ border: "var(--mantine-color-blue-outline)",
1000
+ text: "var(--mantine-color-blue-light-color)",
1001
+ textSecondary: "var(--mantine-color-blue-light-color)",
1002
+ textLight: "var(--mantine-color-blue-light-color)",
1003
+ icon: "var(--mantine-color-blue-light-color)",
1004
+ progressColor: "blue"
1005
+ }
1006
+ },
1007
+ // 文字颜色标准化系统 - 深色模式优化
1008
+ text: {
1009
+ // 主要文字级别
1010
+ primary: aiThemeColors.primaryText,
1011
+ // 主标题、重要内容
1012
+ heading: aiThemeColors.headingText,
1013
+ // 页面标题、section标题
1014
+ subtitle: "var(--mantine-color-gray-7)",
1015
+ // 副标题,清晰但次要
1016
+ // 次要文字级别
1017
+ secondary: aiThemeColors.secondaryText,
1018
+ // 正文内容
1019
+ caption: "var(--mantine-color-gray-6)",
1020
+ // 说明文字,比dimmed更清晰
1021
+ label: "var(--mantine-color-gray-7)",
1022
+ // 标签文字
1023
+ // 弱化文字级别
1024
+ muted: "var(--mantine-color-gray-6)",
1025
+ // 静音文字,深色模式优化
1026
+ placeholder: aiThemeColors.placeholderText,
1027
+ // 占位符文字
1028
+ disabled: "var(--mantine-color-gray-5)",
1029
+ // 禁用状态文字
1030
+ // 状态文字
1031
+ success: aiThemeColors.success,
1032
+ warning: aiThemeColors.warning,
1033
+ error: aiThemeColors.error,
1034
+ info: aiThemeColors.info
1035
+ }
1036
+ };
1037
+
1038
+ // src/components/ChatDialog/ChatDialog.tsx
1039
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1040
+ function ChatDialog({
1041
+ chatOptions = {},
1042
+ title = "AI Assistant",
1043
+ description = "Chat with your AI assistant",
1044
+ open = false,
1045
+ onOpenChange,
1046
+ placeholder = "Type your message here...",
1047
+ className,
1048
+ showHeader = true,
1049
+ allowFileUpload = true,
1050
+ acceptedFileTypes = ["image/*", "text/*", "application/pdf"],
1051
+ maxFileSize = 10 * 1024 * 1024,
1052
+ // 10MB
1053
+ messageRenderer,
1054
+ theme = "system",
1055
+ // 新增的增强功能选项
1056
+ enableReasoning = true,
1057
+ enableGenerativeUI = true,
1058
+ showReasoningByDefault = false
1059
+ }) {
1060
+ const [frontendToolStatus, setFrontendToolStatus] = useState({
1061
+ isProcessing: false,
1062
+ currentTool: void 0,
1063
+ processedTools: /* @__PURE__ */ new Set()
1064
+ // 防止重复处理
1065
+ });
1066
+ const handleError = useCallback((err) => {
1067
+ console.error("ChatDialog useChat error:", err);
1068
+ let friendlyError = err;
1069
+ const originalMessage = err.message || "Unknown occurred";
1070
+ if (originalMessage.includes("<!DOCTYPE") || originalMessage.includes("<html>") || originalMessage.includes("<body>")) {
1071
+ friendlyError = new Error("AI\u670D\u52A1\u8FDE\u63A5\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u670D\u52A1\u5668\u662F\u5426\u6B63\u5728\u8FD0\u884C");
1072
+ friendlyError.name = err.name;
1073
+ } else if (originalMessage.includes("fetch") || originalMessage.includes("NetworkError") || originalMessage.includes("Failed to fetch")) {
1074
+ friendlyError = new Error("AI\u670D\u52A1\u8FDE\u63A5\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5");
1075
+ friendlyError.name = err.name;
1076
+ } else if (originalMessage.includes("404") || originalMessage.includes("Not Found")) {
1077
+ friendlyError = new Error("AI API\u7AEF\u70B9\u672A\u627E\u5230\uFF0C\u8BF7\u786E\u4FDDAI\u670D\u52A1\u5668\u6B63\u5728\u8FD0\u884C\u5E76\u4E14\u7AEF\u70B9\u914D\u7F6E\u6B63\u786E");
1078
+ friendlyError.name = err.name;
1079
+ } else if (originalMessage.includes("ECONNREFUSED") || originalMessage.includes("Connection refused")) {
1080
+ friendlyError = new Error("AI\u670D\u52A1\u5668\u8FDE\u63A5\u88AB\u62D2\u7EDD");
1081
+ friendlyError.name = err.name;
1082
+ }
1083
+ chatOptions.onError?.(friendlyError);
1084
+ }, [chatOptions]);
1085
+ const {
1086
+ messages,
1087
+ status,
1088
+ error,
1089
+ sendMessage,
1090
+ stop,
1091
+ clearError,
1092
+ resumeStream,
1093
+ addToolResult,
1094
+ setMessages
1095
+ } = useChat({
1096
+ // Use standard properties from chatOptions
1097
+ ...chatOptions,
1098
+ // Standard onFinish callback
1099
+ onFinish: (options) => {
1100
+ setTimeout(() => {
1101
+ inputRef.current?.focus();
1102
+ }, 100);
1103
+ chatOptions.onFinish?.(options);
1104
+ },
1105
+ onError: handleError,
1106
+ // Standard onToolCall - for listening only, no return value
1107
+ onToolCall: chatOptions.onToolCall
1108
+ });
1109
+ useEffect(() => {
1110
+ const handleFrontendToolCall = async (toolName, input2) => {
1111
+ const frontendToolNames = [
1112
+ "recordGetValues",
1113
+ "recordSetValues",
1114
+ "recordGetFieldInfo",
1115
+ "recordResetForm",
1116
+ "recordValidateForm"
1117
+ ];
1118
+ if (!frontendToolNames.includes(toolName)) {
1119
+ return;
1120
+ }
1121
+ setFrontendToolStatus((prev) => ({
1122
+ ...prev,
1123
+ isProcessing: true,
1124
+ currentTool: toolName
1125
+ }));
1126
+ const waitId = `frontend-${toolName}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
1127
+ try {
1128
+ if (window.__ENTITY_ENGINE_AI_BRIDGE__) {
1129
+ const result = await window.__ENTITY_ENGINE_AI_BRIDGE__.executeViewControllerTool(
1130
+ toolName,
1131
+ input2 || {}
1132
+ );
1133
+ const finalResult = typeof result === "string" ? result : JSON.stringify(result, null, 2);
1134
+ await fetch("/api/ee/servlet/ai/frontend-tool-result", {
1135
+ method: "POST",
1136
+ headers: {
1137
+ "Content-Type": "application/json"
1138
+ },
1139
+ body: JSON.stringify({
1140
+ waitId: `frontend-${toolName}`,
1141
+ // 简化waitId匹配
1142
+ result: finalResult,
1143
+ timestamp: Date.now()
1144
+ })
1145
+ });
1146
+ }
1147
+ } catch (_error) {
1148
+ await fetch("/api/ee/servlet/ai/frontend-tool-result", {
1149
+ method: "POST",
1150
+ headers: {
1151
+ "Content-Type": "application/json"
1152
+ },
1153
+ body: JSON.stringify({
1154
+ waitId: `frontend-${toolName}`,
1155
+ error: error.message,
1156
+ timestamp: Date.now()
1157
+ })
1158
+ });
1159
+ } finally {
1160
+ setFrontendToolStatus((prev) => ({
1161
+ ...prev,
1162
+ isProcessing: false,
1163
+ currentTool: void 0
1164
+ }));
1165
+ }
1166
+ };
1167
+ window.__FRONTEND_TOOL_HANDLER__ = handleFrontendToolCall;
1168
+ return () => {
1169
+ if (window.__FRONTEND_TOOL_HANDLER__) {
1170
+ delete window.__FRONTEND_TOOL_HANDLER__;
1171
+ }
1172
+ };
1173
+ }, []);
1174
+ const [input, setInput] = useState("");
1175
+ const [attachedFiles, setAttachedFiles] = useState([]);
1176
+ const inputRef = useRef(null);
1177
+ const fileInputRef = useRef(null);
1178
+ const messagesEndRef = useRef(null);
1179
+ useEffect(() => {
1180
+ if (messagesEndRef.current) {
1181
+ messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
1182
+ }
1183
+ }, [messages, status]);
1184
+ useEffect(() => {
1185
+ if (open && inputRef.current) {
1186
+ const timer = setTimeout(() => {
1187
+ inputRef.current?.focus();
1188
+ }, 100);
1189
+ return () => clearTimeout(timer);
1190
+ }
1191
+ return void 0;
1192
+ }, [open]);
1193
+ const handleFormSubmit = useCallback((e) => {
1194
+ e.preventDefault();
1195
+ if (!input.trim() && attachedFiles.length === 0) return;
1196
+ if (status === "streaming") return;
1197
+ try {
1198
+ if (attachedFiles.length > 0) {
1199
+ sendMessage({
1200
+ text: input.trim(),
1201
+ files: attachedFiles
1202
+ });
1203
+ } else {
1204
+ sendMessage({
1205
+ text: input.trim()
1206
+ });
1207
+ }
1208
+ setInput("");
1209
+ setAttachedFiles([]);
1210
+ if (fileInputRef.current) {
1211
+ fileInputRef.current.value = "";
1212
+ }
1213
+ } catch (sendError) {
1214
+ console.error("Failed to send message:", sendError);
1215
+ }
1216
+ }, [input, attachedFiles, status, sendMessage]);
1217
+ const handleFileUpload = useCallback((e) => {
1218
+ const files = e.target.files;
1219
+ if (!files) return;
1220
+ const newFiles = [];
1221
+ Array.from(files).forEach((file, index) => {
1222
+ if (file.size > maxFileSize) {
1223
+ return;
1224
+ }
1225
+ const isAccepted = acceptedFileTypes.some((type) => {
1226
+ if (type.endsWith("/*")) {
1227
+ return file.type.startsWith(type.slice(0, -1));
1228
+ }
1229
+ return file.type === type;
1230
+ });
1231
+ if (!isAccepted) {
1232
+ return;
1233
+ }
1234
+ const fileUrl = URL.createObjectURL(file);
1235
+ newFiles.push({
1236
+ type: "file",
1237
+ filename: file.name,
1238
+ mediaType: file.type,
1239
+ url: fileUrl
1240
+ });
1241
+ });
1242
+ setAttachedFiles((prev) => [...prev, ...newFiles]);
1243
+ }, [maxFileSize, acceptedFileTypes]);
1244
+ const removeFile = useCallback((index) => {
1245
+ setAttachedFiles((prev) => {
1246
+ const newFiles = prev.slice();
1247
+ URL.revokeObjectURL(newFiles[index].url);
1248
+ newFiles.splice(index, 1);
1249
+ return newFiles;
1250
+ });
1251
+ }, []);
1252
+ const handleKeyPress = useCallback((e) => {
1253
+ if (e.key === "Enter" && !e.shiftKey) {
1254
+ e.preventDefault();
1255
+ handleFormSubmit(e);
1256
+ }
1257
+ }, [handleFormSubmit]);
1258
+ const isLoading = status === "streaming" || status === "submitted";
1259
+ const canSend = !isLoading && (input.trim() || attachedFiles.length > 0);
1260
+ return /* @__PURE__ */ jsxs5(
1261
+ Box2,
1262
+ {
1263
+ style: {
1264
+ height: "100%",
1265
+ width: "100%",
1266
+ display: "flex",
1267
+ flexDirection: "column",
1268
+ position: "relative",
1269
+ zIndex: "auto",
1270
+ minHeight: 0,
1271
+ overflow: "hidden",
1272
+ background: `
1273
+ radial-gradient(
1274
+ circle at 85% 85%,
1275
+ rgba(34, 139, 230, 0.18) 0%,
1276
+ rgba(34, 139, 230, 0.09) 25%,
1277
+ rgba(34, 139, 230, 0.03) 50%,
1278
+ rgba(255, 255, 255, 1) 75%
1279
+ )
1280
+ `
1281
+ },
1282
+ children: [
1283
+ showHeader && /* @__PURE__ */ jsx5(
1284
+ Paper2,
1285
+ {
1286
+ p: "lg",
1287
+ bg: "white",
1288
+ radius: 0,
1289
+ style: {
1290
+ position: "sticky",
1291
+ top: 0,
1292
+ zIndex: 100
1293
+ },
1294
+ children: /* @__PURE__ */ jsxs5(Group2, { justify: "space-between", align: "center", style: { width: "100%" }, children: [
1295
+ /* @__PURE__ */ jsxs5(Group2, { gap: "md", style: { flex: 1 }, children: [
1296
+ /* @__PURE__ */ jsx5(
1297
+ Box2,
1298
+ {
1299
+ style: {
1300
+ width: "40px",
1301
+ height: "40px",
1302
+ borderRadius: "8px",
1303
+ display: "flex",
1304
+ alignItems: "center",
1305
+ justifyContent: "center",
1306
+ boxShadow: "0 2px 8px rgba(25, 118, 210, 0.3)"
1307
+ },
1308
+ children: /* @__PURE__ */ jsx5(SparklesIcon, { size: 24, color: "#1976d2" })
1309
+ }
1310
+ ),
1311
+ /* @__PURE__ */ jsxs5("div", { children: [
1312
+ /* @__PURE__ */ jsx5(Title, { order: 4, c: "var(--mantine-color-gray-9)", mb: 2, children: title }),
1313
+ /* @__PURE__ */ jsxs5(Group2, { gap: "xs", align: "center", children: [
1314
+ /* @__PURE__ */ jsx5(
1315
+ Badge2,
1316
+ {
1317
+ size: "xs",
1318
+ color: error ? "red" : "green",
1319
+ variant: "light",
1320
+ leftSection: /* @__PURE__ */ jsx5(Box2, { w: 6, h: 6, bg: error ? "red" : "green", style: { borderRadius: "50%" } }),
1321
+ children: error ? "Offline" : "Online"
1322
+ }
1323
+ ),
1324
+ description && /* @__PURE__ */ jsx5(Text2, { size: "xs", c: "var(--mantine-color-gray-6)", children: description })
1325
+ ] })
1326
+ ] })
1327
+ ] }),
1328
+ /* @__PURE__ */ jsx5(
1329
+ ActionIcon,
1330
+ {
1331
+ variant: "subtle",
1332
+ color: "gray",
1333
+ size: "lg",
1334
+ onClick: () => onOpenChange?.(false),
1335
+ "aria-label": "\u5173\u95ED\u5BF9\u8BDD\u6846",
1336
+ style: { flexShrink: 0 },
1337
+ children: /* @__PURE__ */ jsx5(X, { size: 18 })
1338
+ }
1339
+ )
1340
+ ] })
1341
+ }
1342
+ ),
1343
+ /* @__PURE__ */ jsx5(ScrollArea, { style: { flex: 1 }, p: "xl", children: /* @__PURE__ */ jsxs5(Stack2, { gap: "md", maw: "none", w: "100%", children: [
1344
+ /* @__PURE__ */ jsx5(AnimatePresence, { mode: "popLayout", children: messages.map((message, index) => /* @__PURE__ */ jsx5(
1345
+ motion.div,
1346
+ {
1347
+ initial: { opacity: 0, y: 20 },
1348
+ animate: { opacity: 1, y: 0 },
1349
+ exit: { opacity: 0, y: -20 },
1350
+ transition: { duration: 0.3, delay: index * 0.1 },
1351
+ children: messageRenderer ? React.createElement(messageRenderer, { message }) : /* @__PURE__ */ jsx5(
1352
+ MessageBubble,
1353
+ {
1354
+ message,
1355
+ showAvatar: true,
1356
+ showTimestamp: true,
1357
+ enableReasoning,
1358
+ enableGenerativeUI,
1359
+ showReasoningByDefault
1360
+ }
1361
+ )
1362
+ },
1363
+ message.id
1364
+ )) }),
1365
+ isLoading && /* @__PURE__ */ jsx5(
1366
+ motion.div,
1367
+ {
1368
+ initial: { opacity: 0 },
1369
+ animate: { opacity: 1 },
1370
+ children: /* @__PURE__ */ jsxs5(Group2, { gap: "sm", justify: "space-between", children: [
1371
+ /* @__PURE__ */ jsxs5(Group2, { gap: "sm", children: [
1372
+ /* @__PURE__ */ jsxs5(Group2, { gap: "xs", children: [
1373
+ /* @__PURE__ */ jsx5(Box2, { w: 8, h: 8, bg: "gray.4", style: { borderRadius: "50%", animation: "bounce 1s infinite" } }),
1374
+ /* @__PURE__ */ jsx5(Box2, { w: 8, h: 8, bg: "gray.4", style: { borderRadius: "50%", animation: "bounce 1s infinite 0.1s" } }),
1375
+ /* @__PURE__ */ jsx5(Box2, { w: 8, h: 8, bg: "gray.4", style: { borderRadius: "50%", animation: "bounce 1s infinite 0.2s" } })
1376
+ ] }),
1377
+ /* @__PURE__ */ jsx5(Text2, { size: "sm", ...getThemedTextProps("muted"), children: "AI is thinking..." })
1378
+ ] }),
1379
+ /* @__PURE__ */ jsx5(
1380
+ ActionIcon,
1381
+ {
1382
+ variant: "subtle",
1383
+ color: "red",
1384
+ onClick: stop,
1385
+ size: "sm",
1386
+ children: /* @__PURE__ */ jsx5(Square, { size: 16 })
1387
+ }
1388
+ )
1389
+ ] })
1390
+ }
1391
+ ),
1392
+ /* @__PURE__ */ jsx5("div", { ref: messagesEndRef })
1393
+ ] }) }),
1394
+ error && /* @__PURE__ */ jsx5(
1395
+ motion.div,
1396
+ {
1397
+ initial: { opacity: 0, height: 0 },
1398
+ animate: { opacity: 1, height: "auto" },
1399
+ style: { margin: "1rem" },
1400
+ children: /* @__PURE__ */ jsx5(
1401
+ Paper2,
1402
+ {
1403
+ p: "md",
1404
+ style: {
1405
+ backgroundColor: componentStyles.status.error.background,
1406
+ borderLeft: `4px solid ${componentStyles.status.error.border}`
1407
+ },
1408
+ children: /* @__PURE__ */ jsxs5(Group2, { align: "flex-start", gap: "sm", children: [
1409
+ /* @__PURE__ */ jsx5(AlertCircle, { size: 20, color: componentStyles.status.error.text }),
1410
+ /* @__PURE__ */ jsxs5(Box2, { style: { flex: 1 }, children: [
1411
+ /* @__PURE__ */ jsx5(Text2, { size: "sm", fw: 500, c: componentStyles.status.error.text, children: "Connection Error" }),
1412
+ /* @__PURE__ */ jsx5(Text2, { size: "sm", c: componentStyles.status.error.text, mt: "xs", children: error.message }),
1413
+ /* @__PURE__ */ jsxs5(Group2, { gap: "sm", mt: "md", children: [
1414
+ /* @__PURE__ */ jsx5(
1415
+ Button,
1416
+ {
1417
+ size: "xs",
1418
+ variant: "light",
1419
+ color: "red",
1420
+ onClick: () => clearError(),
1421
+ children: "Dismiss"
1422
+ }
1423
+ ),
1424
+ /* @__PURE__ */ jsx5(
1425
+ Button,
1426
+ {
1427
+ size: "xs",
1428
+ variant: "light",
1429
+ color: "blue",
1430
+ onClick: () => resumeStream(),
1431
+ children: "Retry Connection"
1432
+ }
1433
+ )
1434
+ ] })
1435
+ ] })
1436
+ ] })
1437
+ }
1438
+ )
1439
+ }
1440
+ ),
1441
+ attachedFiles.length > 0 && /* @__PURE__ */ jsxs5(
1442
+ Paper2,
1443
+ {
1444
+ p: "lg",
1445
+ shadow: "xs",
1446
+ style: {
1447
+ borderTop: "1px solid var(--mantine-color-gray-2)",
1448
+ backgroundColor: "var(--mantine-color-gray-0)"
1449
+ },
1450
+ children: [
1451
+ /* @__PURE__ */ jsx5(Text2, { size: "sm", fw: 500, c: "var(--mantine-color-gray-7)", mb: "md", children: "\u{1F4CE} \u9644\u4EF6\u9884\u89C8" }),
1452
+ /* @__PURE__ */ jsx5(Group2, { gap: "md", wrap: "wrap", children: attachedFiles.map((file, index) => /* @__PURE__ */ jsx5(
1453
+ Paper2,
1454
+ {
1455
+ p: "sm",
1456
+ shadow: "xs",
1457
+ withBorder: true,
1458
+ style: {
1459
+ maxWidth: "280px",
1460
+ backgroundColor: "white",
1461
+ position: "relative"
1462
+ },
1463
+ children: /* @__PURE__ */ jsxs5(Group2, { gap: "sm", align: "center", children: [
1464
+ /* @__PURE__ */ jsx5(
1465
+ Box2,
1466
+ {
1467
+ w: 32,
1468
+ h: 32,
1469
+ bg: "var(--mantine-color-blue-light)",
1470
+ style: {
1471
+ borderRadius: "6px",
1472
+ display: "flex",
1473
+ alignItems: "center",
1474
+ justifyContent: "center"
1475
+ },
1476
+ children: /* @__PURE__ */ jsx5(Paperclip, { size: 16, color: "var(--mantine-color-blue-6)" })
1477
+ }
1478
+ ),
1479
+ /* @__PURE__ */ jsxs5(Box2, { style: { flex: 1, minWidth: 0 }, children: [
1480
+ /* @__PURE__ */ jsx5(Text2, { size: "sm", fw: 500, truncate: true, c: "var(--mantine-color-gray-8)", children: file.filename }),
1481
+ /* @__PURE__ */ jsx5(Text2, { size: "xs", c: "var(--mantine-color-gray-6)", children: file.mediaType })
1482
+ ] }),
1483
+ /* @__PURE__ */ jsx5(
1484
+ ActionIcon,
1485
+ {
1486
+ variant: "subtle",
1487
+ color: "red",
1488
+ size: "sm",
1489
+ onClick: () => removeFile(index),
1490
+ style: { flexShrink: 0 },
1491
+ children: /* @__PURE__ */ jsx5(X, { size: 14 })
1492
+ }
1493
+ )
1494
+ ] })
1495
+ },
1496
+ `${file.filename}-${index}`
1497
+ )) })
1498
+ ]
1499
+ }
1500
+ ),
1501
+ /* @__PURE__ */ jsx5(
1502
+ Paper2,
1503
+ {
1504
+ p: "lg",
1505
+ shadow: "md",
1506
+ style: {
1507
+ borderTop: "1px solid var(--mantine-color-gray-2)",
1508
+ backgroundColor: "white",
1509
+ position: "sticky",
1510
+ bottom: 0,
1511
+ zIndex: 50
1512
+ },
1513
+ children: /* @__PURE__ */ jsx5("form", { onSubmit: handleFormSubmit, children: /* @__PURE__ */ jsxs5(Stack2, { gap: "sm", children: [
1514
+ /* @__PURE__ */ jsxs5(Group2, { align: "center", gap: "md", children: [
1515
+ allowFileUpload && /* @__PURE__ */ jsxs5(Box2, { children: [
1516
+ /* @__PURE__ */ jsx5(
1517
+ "input",
1518
+ {
1519
+ ref: fileInputRef,
1520
+ type: "file",
1521
+ multiple: true,
1522
+ accept: acceptedFileTypes.join(","),
1523
+ onChange: handleFileUpload,
1524
+ style: { display: "none" }
1525
+ }
1526
+ ),
1527
+ /* @__PURE__ */ jsx5(
1528
+ ActionIcon,
1529
+ {
1530
+ variant: "light",
1531
+ color: "gray",
1532
+ size: "lg",
1533
+ onClick: () => fileInputRef.current?.click(),
1534
+ disabled: isLoading,
1535
+ style: {
1536
+ border: "2px solid var(--mantine-color-gray-3)",
1537
+ backgroundColor: "var(--mantine-color-gray-0)",
1538
+ transition: "all 0.2s ease"
1539
+ },
1540
+ children: /* @__PURE__ */ jsx5(Paperclip, { size: 20 })
1541
+ }
1542
+ )
1543
+ ] }),
1544
+ /* @__PURE__ */ jsx5(Box2, { style: { flex: 1 }, children: /* @__PURE__ */ jsx5(
1545
+ Textarea,
1546
+ {
1547
+ ref: inputRef,
1548
+ value: input,
1549
+ onChange: (e) => setInput(e.target.value),
1550
+ onKeyDown: handleKeyPress,
1551
+ placeholder,
1552
+ disabled: isLoading,
1553
+ minRows: 1,
1554
+ maxRows: 4,
1555
+ autosize: true,
1556
+ variant: "filled",
1557
+ styles: {
1558
+ input: {
1559
+ backgroundColor: "var(--mantine-color-gray-0)",
1560
+ border: "2px solid var(--mantine-color-gray-2)",
1561
+ borderRadius: "12px",
1562
+ padding: "12px 16px",
1563
+ fontSize: "14px",
1564
+ lineHeight: "1.4",
1565
+ transition: "all 0.2s ease",
1566
+ "&:focus": {
1567
+ backgroundColor: "white",
1568
+ borderColor: "var(--mantine-color-blue-4)",
1569
+ boxShadow: "0 0 0 3px var(--mantine-color-blue-1)"
1570
+ },
1571
+ "&::placeholder": {
1572
+ color: "var(--mantine-color-gray-5)"
1573
+ }
1574
+ }
1575
+ }
1576
+ }
1577
+ ) }),
1578
+ /* @__PURE__ */ jsx5(
1579
+ ActionIcon,
1580
+ {
1581
+ type: "submit",
1582
+ disabled: !canSend,
1583
+ size: "lg",
1584
+ variant: "filled",
1585
+ style: {
1586
+ background: canSend ? "linear-gradient(45deg, var(--mantine-color-blue-6), var(--mantine-color-blue-5))" : "var(--mantine-color-gray-4)",
1587
+ color: "white",
1588
+ border: "none",
1589
+ borderRadius: "12px",
1590
+ boxShadow: canSend ? "0 4px 12px var(--mantine-color-blue-2)" : "none",
1591
+ transform: canSend ? "scale(1)" : "scale(0.95)",
1592
+ transition: "all 0.2s ease",
1593
+ cursor: canSend ? "pointer" : "not-allowed",
1594
+ "&:hover": canSend ? {
1595
+ transform: "scale(1.05)",
1596
+ boxShadow: "0 6px 16px var(--mantine-color-blue-3)"
1597
+ } : {}
1598
+ },
1599
+ children: /* @__PURE__ */ jsx5(Send, { size: 20 })
1600
+ }
1601
+ )
1602
+ ] }),
1603
+ input.length > 0 && /* @__PURE__ */ jsxs5(Group2, { justify: "space-between", align: "center", children: [
1604
+ /* @__PURE__ */ jsx5(Text2, { size: "xs", c: "var(--mantine-color-gray-6)", children: isLoading ? "AI\u6B63\u5728\u56DE\u590D..." : "Enter\u53D1\u9001\uFF0CShift+Enter\u6362\u884C" }),
1605
+ /* @__PURE__ */ jsxs5(Text2, { size: "xs", c: "var(--mantine-color-gray-5)", children: [
1606
+ input.length,
1607
+ "/2000"
1608
+ ] })
1609
+ ] })
1610
+ ] }) })
1611
+ }
1612
+ )
1613
+ ]
1614
+ }
1615
+ );
1616
+ }
1617
+
1618
+ export {
1619
+ ChatDialog
1620
+ };
1621
+ //# sourceMappingURL=chunk-SXPA6SSD.mjs.map