@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,17 @@
1
+ import {
2
+ AISDKIntegration,
3
+ ai_core_default,
4
+ generateText,
5
+ smoothStream,
6
+ streamText,
7
+ tool
8
+ } from "./chunk-X42L6MTY.mjs";
9
+ export {
10
+ AISDKIntegration,
11
+ ai_core_default as default,
12
+ generateText,
13
+ smoothStream,
14
+ streamText,
15
+ tool
16
+ };
17
+ //# sourceMappingURL=ai-core-LBGYFGOK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,17 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+ var _chunk6IUKES2Ljs = require('./chunk-6IUKES2L.js');
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+ exports.AISDKIntegration = _chunk6IUKES2Ljs.AISDKIntegration; exports.default = _chunk6IUKES2Ljs.ai_core_default; exports.generateText = _chunk6IUKES2Ljs.generateText; exports.smoothStream = _chunk6IUKES2Ljs.smoothStream; exports.streamText = _chunk6IUKES2Ljs.streamText; exports.tool = _chunk6IUKES2Ljs.tool;
17
+ //# sourceMappingURL=ai-core-UGJWSCQN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/shixin/dev/workspaces/scenemesh-projects/scenemesh-platform-workbench5/packages/entity-engine-aimodule/dist/ai-core-UGJWSCQN.js"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACA;AACA;AACA;AACF,qTAAC","file":"/Users/shixin/dev/workspaces/scenemesh-projects/scenemesh-platform-workbench5/packages/entity-engine-aimodule/dist/ai-core-UGJWSCQN.js"}
@@ -0,0 +1,9 @@
1
+ import {
2
+ AICoreManager,
3
+ ai_core_manager_default
4
+ } from "./chunk-T5A4KAVS.mjs";
5
+ export {
6
+ AICoreManager,
7
+ ai_core_manager_default as default
8
+ };
9
+ //# sourceMappingURL=ai-core-manager-B3Z34RHA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,9 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+ var _chunkCTEXPMVZjs = require('./chunk-CTEXPMVZ.js');
5
+
6
+
7
+
8
+ exports.AICoreManager = _chunkCTEXPMVZjs.AICoreManager; exports.default = _chunkCTEXPMVZjs.ai_core_manager_default;
9
+ //# sourceMappingURL=ai-core-manager-W7SSDCG5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/shixin/dev/workspaces/scenemesh-projects/scenemesh-platform-workbench5/packages/entity-engine-aimodule/dist/ai-core-manager-W7SSDCG5.js"],"names":[],"mappings":"AAAA;AACE;AACA;AACF,sDAA4B;AAC5B;AACE;AACA;AACF,mHAAC","file":"/Users/shixin/dev/workspaces/scenemesh-projects/scenemesh-platform-workbench5/packages/entity-engine-aimodule/dist/ai-core-manager-W7SSDCG5.js"}
@@ -0,0 +1,17 @@
1
+ import {
2
+ AIEmbeddingsIntegration,
3
+ SupportedEmbeddingModels,
4
+ ai_embeddings_default,
5
+ cosineSimilarity,
6
+ embed,
7
+ embedMany
8
+ } from "./chunk-TDRKKUNT.mjs";
9
+ export {
10
+ AIEmbeddingsIntegration,
11
+ SupportedEmbeddingModels,
12
+ cosineSimilarity,
13
+ ai_embeddings_default as default,
14
+ embed,
15
+ embedMany
16
+ };
17
+ //# sourceMappingURL=ai-embeddings-5ED5LDXX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,17 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+ var _chunkTJFNODPEjs = require('./chunk-TJFNODPE.js');
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+ exports.AIEmbeddingsIntegration = _chunkTJFNODPEjs.AIEmbeddingsIntegration; exports.SupportedEmbeddingModels = _chunkTJFNODPEjs.SupportedEmbeddingModels; exports.cosineSimilarity = _chunkTJFNODPEjs.cosineSimilarity; exports.default = _chunkTJFNODPEjs.ai_embeddings_default; exports.embed = _chunkTJFNODPEjs.embed; exports.embedMany = _chunkTJFNODPEjs.embedMany;
17
+ //# sourceMappingURL=ai-embeddings-WCXZMMTZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/shixin/dev/workspaces/scenemesh-projects/scenemesh-platform-workbench5/packages/entity-engine-aimodule/dist/ai-embeddings-WCXZMMTZ.js"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACF,sDAA4B;AAC5B;AACE;AACA;AACA;AACA;AACA;AACA;AACF,yWAAC","file":"/Users/shixin/dev/workspaces/scenemesh-projects/scenemesh-platform-workbench5/packages/entity-engine-aimodule/dist/ai-embeddings-WCXZMMTZ.js"}
@@ -0,0 +1,233 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
+
3
+ var _chunkO7SZSMXVjs = require('./chunk-O7SZSMXV.js');
4
+
5
+ // src/entity-module/renderers/ai-form-renderer.tsx
6
+ var _ai = require('ai');
7
+ var _lucidereact = require('lucide-react');
8
+ var _core = require('@mantine/core');
9
+ var _hooks = require('@mantine/hooks');
10
+ var _react = require('react');
11
+ var _entityengine = require('@scenemesh/entity-engine');
12
+ var _jsxruntime = require('react/jsx-runtime');
13
+ function EntityAIFormComp(_props) {
14
+ const engine = _entityengine.useEntityEngine.call(void 0, );
15
+ const model = _props.model;
16
+ const viewdata = _props.viewData;
17
+ const viewId = _optionalChain([_props, 'access', _ => _.additionalProps, 'optionalAccess', _2 => _2.viewId]);
18
+ const vc = engine.componentRegistry.getViewController(void 0, void 0, viewId);
19
+ const { width } = _hooks.useViewportSize.call(void 0, );
20
+ const [drawerOpened, setDrawerOpened] = _react.useState.call(void 0, false);
21
+ const getDrawerSize = _react.useCallback.call(void 0, () => {
22
+ if (width <= 768) return "80%";
23
+ if (width <= 1024) return "40%";
24
+ return "30%";
25
+ }, [width]);
26
+ const handleOpenAI = () => {
27
+ setDrawerOpened(true);
28
+ };
29
+ const handleClose = _react.useCallback.call(void 0, () => {
30
+ setDrawerOpened(false);
31
+ }, []);
32
+ const executeViewControllerTool = _react.useCallback.call(void 0, async (toolName, input) => {
33
+ if (!vc) {
34
+ throw new Error("\u6CA1\u6709\u53EF\u7528\u7684\u89C6\u56FE\u63A7\u5236\u5668");
35
+ }
36
+ const operationMap = {
37
+ "recordGetValues": "record.getValues",
38
+ "recordSetValues": "record.setValues",
39
+ "recordGetFieldInfo": "record.getFieldInfo",
40
+ "recordResetForm": "record.resetForm",
41
+ "recordValidateForm": "record.validateForm"
42
+ };
43
+ if (toolName === "recordSetValues") {
44
+ if (input.values) {
45
+ const fieldNames = Object.keys(input.values);
46
+ const actualFields = await vc.invoke("record.getFieldInfo", {});
47
+ if (actualFields && Array.isArray(actualFields)) {
48
+ const realFieldNames = actualFields.map((field) => _optionalChain([field, 'access', _3 => _3._field, 'optionalAccess', _4 => _4.name])).filter(Boolean);
49
+ const invalidFields = fieldNames.filter((name) => !realFieldNames.includes(name));
50
+ if (invalidFields.length > 0) {
51
+ const validValues = {};
52
+ Object.entries(input.values).forEach(([key, value]) => {
53
+ if (realFieldNames.includes(key)) {
54
+ validValues[key] = value;
55
+ }
56
+ });
57
+ if (Object.keys(validValues).length > 0) {
58
+ input.values = validValues;
59
+ } else {
60
+ return `Field name error! You used invalid field names.
61
+
62
+ Invalid fields: [${invalidFields.join(", ")}]
63
+ Correct field names: [${realFieldNames.join(", ")}]
64
+
65
+ \u8BF7\u91CD\u65B0\u8C03\u7528recordSetValues\uFF0C\u4F7F\u7528\u6B63\u786E\u7684\u5B57\u6BB5\u540D:
66
+ \u793A\u4F8B: recordSetValues({"values": {"${realFieldNames[0]}": "\u4EA7\u54C1\u503C", "${realFieldNames.slice(1, 3).join('": "\u503C", "')}": "\u503C"}})
67
+
68
+ \u91CD\u8981\u63D0\u9192: \u5FC5\u987B\u4F7F\u7528recordGetFieldInfo\u8FD4\u56DE\u7684\u786E\u5207\u5B57\u6BB5\u540D\uFF0C\u4E0D\u80FD\u731C\u6D4B\u6216\u7FFB\u8BD1\u5B57\u6BB5\u540D\uFF01`;
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ const operation = operationMap[toolName];
75
+ if (!operation) {
76
+ throw new Error(`\u672A\u77E5\u7684\u5DE5\u5177: ${toolName}`);
77
+ }
78
+ const result = await vc.invoke(operation, input);
79
+ return typeof result === "string" ? result : JSON.stringify(result, null, 2);
80
+ }, [vc]);
81
+ _react.useEffect.call(void 0, () => {
82
+ if (typeof window !== "undefined") {
83
+ window.__ENTITY_ENGINE_AI_BRIDGE__ = {
84
+ executeViewControllerTool
85
+ };
86
+ window.resolveFrontendTool = (waitId, result) => {
87
+ fetch("/api/ee/servlet/ai/frontend-tool-result", {
88
+ method: "POST",
89
+ headers: {
90
+ "Content-Type": "application/json"
91
+ },
92
+ body: JSON.stringify({
93
+ waitId,
94
+ result,
95
+ timestamp: Date.now()
96
+ })
97
+ }).then((response) => {
98
+ if (!response.ok) {
99
+ console.error("Failed to send tool result");
100
+ }
101
+ }).catch((error) => {
102
+ console.error("Failed to send tool result:", error);
103
+ });
104
+ };
105
+ window.rejectFrontendTool = (waitId, error) => {
106
+ fetch("/api/ee/servlet/ai/frontend-tool-result", {
107
+ method: "POST",
108
+ headers: {
109
+ "Content-Type": "application/json"
110
+ },
111
+ body: JSON.stringify({
112
+ waitId,
113
+ error,
114
+ timestamp: Date.now()
115
+ })
116
+ }).catch((networkError) => {
117
+ });
118
+ };
119
+ return () => {
120
+ if (window.__ENTITY_ENGINE_AI_BRIDGE__) {
121
+ delete window.__ENTITY_ENGINE_AI_BRIDGE__;
122
+ }
123
+ if (window.resolveFrontendTool) {
124
+ delete window.resolveFrontendTool;
125
+ }
126
+ if (window.rejectFrontendTool) {
127
+ delete window.rejectFrontendTool;
128
+ }
129
+ };
130
+ }
131
+ return () => {
132
+ };
133
+ }, [executeViewControllerTool]);
134
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
135
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
136
+ _core.Button,
137
+ {
138
+ leftSection: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.SparklesIcon, { size: 20 }),
139
+ onClick: handleOpenAI,
140
+ disabled: !vc,
141
+ variant: "light",
142
+ children: "\u667A\u80FD\u586B\u8868"
143
+ }
144
+ ),
145
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
146
+ _core.Drawer,
147
+ {
148
+ opened: drawerOpened,
149
+ onClose: handleClose,
150
+ position: "right",
151
+ withOverlay: false,
152
+ closeOnClickOutside: false,
153
+ closeOnEscape: true,
154
+ zIndex: 9999999,
155
+ withCloseButton: false,
156
+ transitionProps: {
157
+ transition: "slide-left",
158
+ duration: 200,
159
+ timingFunction: "ease-out"
160
+ },
161
+ styles: {
162
+ content: {
163
+ height: "100vh",
164
+ borderRadius: 0,
165
+ display: "flex",
166
+ flexDirection: "column",
167
+ boxShadow: "-4px 0 20px rgba(0, 0, 0, 0.1)"
168
+ },
169
+ body: {
170
+ height: "100vh",
171
+ padding: 0,
172
+ overflow: "hidden",
173
+ flex: 1,
174
+ display: "flex",
175
+ flexDirection: "column"
176
+ }
177
+ },
178
+ size: getDrawerSize(),
179
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
180
+ _chunkO7SZSMXVjs.ChatDialog,
181
+ {
182
+ title: "AI\u52A9\u624B",
183
+ description: `scenemesh ai ${vc ? `\u2022 ${vc.viewType}\u89C6\u56FE` : ""}`,
184
+ open: true,
185
+ onOpenChange: (open) => {
186
+ if (!open) {
187
+ handleClose();
188
+ }
189
+ },
190
+ placeholder: "\u8F93\u5165\u60A8\u7684\u95EE\u9898\u6216\u9700\u6C42...",
191
+ showHeader: true,
192
+ allowFileUpload: true,
193
+ acceptedFileTypes: ["image/*", "text/*", "application/pdf", "application/json"],
194
+ maxFileSize: 10 * 1024 * 1024,
195
+ theme: "system",
196
+ chatOptions: {
197
+ id: "ai-assistant-chat",
198
+ transport: new (0, _ai.DefaultChatTransport)({
199
+ api: "/api/ee/servlet/ai/chat"
200
+ }),
201
+ onFinish: (options) => {
202
+ },
203
+ onError: (error) => {
204
+ if (error.message.includes("AI\u670D\u52A1\u8FDE\u63A5\u5931\u8D25")) {
205
+ console.error("AI service connection failed:", error);
206
+ }
207
+ },
208
+ // Tool call listener - calls ChatDialog's frontend tool handler
209
+ onToolCall: async ({ toolCall }) => {
210
+ const toolInput = toolCall.args || toolCall.input || toolCall.parameters || {};
211
+ if (typeof window.__FRONTEND_TOOL_HANDLER__ === "function") {
212
+ setTimeout(() => {
213
+ window.__FRONTEND_TOOL_HANDLER__(toolCall.toolName, toolInput);
214
+ }, 0);
215
+ }
216
+ }
217
+ }
218
+ }
219
+ )
220
+ }
221
+ )
222
+ ] });
223
+ }
224
+ var EntityEngineAIFormRenderer = {
225
+ name: "view-form-tool-1",
226
+ slotName: "view-form-tool",
227
+ disabled: false,
228
+ renderer: (props) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EntityAIFormComp, { ...props })
229
+ };
230
+
231
+
232
+ exports.EntityEngineAIFormRenderer = EntityEngineAIFormRenderer;
233
+ //# sourceMappingURL=ai-form-renderer-24IWNMX5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/shixin/dev/workspaces/scenemesh-projects/scenemesh-platform-workbench5/packages/entity-engine-aimodule/dist/ai-form-renderer-24IWNMX5.js","../src/entity-module/renderers/ai-form-renderer.tsx"],"names":[],"mappings":"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","file":"/Users/shixin/dev/workspaces/scenemesh-projects/scenemesh-platform-workbench5/packages/entity-engine-aimodule/dist/ai-form-renderer-24IWNMX5.js","sourcesContent":[null,"// 'use client' directive is added by tsup banner\n\nimport type { IEntityView, IEntityModel, IEntityNamedRenderer } from '@scenemesh/entity-engine';\n\nimport { DefaultChatTransport } from 'ai';\nimport { SparklesIcon } from 'lucide-react';\nimport { Button, Drawer } from '@mantine/core';\nimport { useViewportSize } from '@mantine/hooks';\nimport { useState, useEffect, useCallback } from 'react';\nimport { useEntityEngine } from '@scenemesh/entity-engine';\n\nimport { ChatDialog } from '../../components';\n\n\nfunction EntityAIFormComp(_props: any) {\n const engine = useEntityEngine();\n const model = _props.model as IEntityModel;\n const viewdata = _props.viewData as IEntityView;\n const viewId = _props.additionalProps?.viewId;\n const vc = engine.componentRegistry.getViewController(undefined, undefined, viewId);\n \n const { width } = useViewportSize();\n const [drawerOpened, setDrawerOpened] = useState(false);\n\n // Responsive size calculation\n const getDrawerSize = useCallback(() => {\n if (width <= 768) return '80%';\n if (width <= 1024) return '40%';\n return '30%';\n }, [width]);\n\n const handleOpenAI = () => {\n setDrawerOpened(true);\n };\n\n const handleClose = useCallback(() => {\n setDrawerOpened(false);\n }, []);\n\n // Frontend tool executor - executes view controller operations directly in frontend\n const executeViewControllerTool = useCallback(async (toolName: string, input: any): Promise<string> => {\n \n if (!vc) {\n throw new Error('没有可用的视图控制器');\n }\n\n // 解析工具名称到视图控制器操作\n const operationMap: Record<string, string> = {\n 'recordGetValues': 'record.getValues',\n 'recordSetValues': 'record.setValues',\n 'recordGetFieldInfo': 'record.getFieldInfo',\n 'recordResetForm': 'record.resetForm',\n 'recordValidateForm': 'record.validateForm',\n };\n\n // Validate field names and record actual set values\n if (toolName === 'recordSetValues') {\n if (input.values) {\n const fieldNames = Object.keys(input.values);\n \n // 获取当前表单实际的字段名\n const actualFields = await vc.invoke('record.getFieldInfo', {});\n if (actualFields && Array.isArray(actualFields)) {\n const realFieldNames = actualFields.map((field: any) => field._field?.name).filter(Boolean);\n \n // 检查字段名是否匹配\n const invalidFields = fieldNames.filter(name => !realFieldNames.includes(name));\n if (invalidFields.length > 0) {\n \n // 过滤掉无效字段,只设置有效字段\n const validValues: Record<string, any> = {};\n Object.entries(input.values).forEach(([key, value]) => {\n if (realFieldNames.includes(key)) {\n validValues[key] = value;\n }\n });\n \n if (Object.keys(validValues).length > 0) {\n // 更新input.values为只包含有效字段\n input.values = validValues;\n } else {\n // 🚨 返回详细错误信息,包含准确字段名,让AI重新调用\n return `Field name error! You used invalid field names.\\n\\nInvalid fields: [${invalidFields.join(', ')}]\\nCorrect field names: [${realFieldNames.join(', ')}]\n\n请重新调用recordSetValues,使用正确的字段名:\n示例: recordSetValues({\"values\": {\"${realFieldNames[0]}\": \"产品值\", \"${realFieldNames.slice(1, 3).join('\": \"值\", \"')}\": \"值\"}})\n\n重要提醒: 必须使用recordGetFieldInfo返回的确切字段名,不能猜测或翻译字段名!`;\n }\n }\n }\n }\n }\n\n const operation = operationMap[toolName];\n if (!operation) {\n throw new Error(`未知的工具: ${toolName}`);\n }\n\n const result = await vc.invoke(operation, input);\n \n // 返回字符串结果供AI使用\n return typeof result === 'string' ? result : JSON.stringify(result, null, 2);\n }, [vc]);\n\n // 🌉 注册全局前端工具桥接和HTTP通信\n useEffect(() => {\n if (typeof window !== 'undefined') {\n window.__ENTITY_ENGINE_AI_BRIDGE__ = {\n executeViewControllerTool\n };\n\n // Setup frontend to backend HTTP communication bridge\n window.resolveFrontendTool = (waitId: string, result: string) => {\n \n // 通过HTTP POST发送结果给后端\n fetch('/api/ee/servlet/ai/frontend-tool-result', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n waitId,\n result,\n timestamp: Date.now()\n })\n }).then(response => {\n if (!response.ok) {\n console.error('Failed to send tool result');\n }\n }).catch(error => {\n console.error('Failed to send tool result:', error);\n });\n };\n \n window.rejectFrontendTool = (waitId: string, error: string) => {\n \n fetch('/api/ee/servlet/ai/frontend-tool-result', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n waitId,\n error,\n timestamp: Date.now()\n })\n }).catch(networkError => {\n });\n };\n\n return () => {\n if (window.__ENTITY_ENGINE_AI_BRIDGE__) {\n delete (window as any).__ENTITY_ENGINE_AI_BRIDGE__;\n }\n if ((window as any).resolveFrontendTool) {\n delete (window as any).resolveFrontendTool;\n }\n if ((window as any).rejectFrontendTool) {\n delete (window as any).rejectFrontendTool;\n }\n };\n }\n return () =>{}\n }, [executeViewControllerTool]);\n\n\n return (\n <>\n <Button \n leftSection={<SparklesIcon size={20} />} \n onClick={handleOpenAI}\n disabled={!vc}\n variant='light'\n >\n 智能填表\n </Button>\n\n <Drawer\n opened={drawerOpened}\n onClose={handleClose}\n position=\"right\"\n withOverlay={false}\n closeOnClickOutside={false}\n closeOnEscape\n zIndex={9999999}\n withCloseButton={false}\n transitionProps={{\n transition: 'slide-left',\n duration: 200,\n timingFunction: 'ease-out',\n }}\n styles={{\n content: {\n height: '100vh',\n borderRadius: 0,\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '-4px 0 20px rgba(0, 0, 0, 0.1)',\n },\n body: {\n height: '100vh',\n padding: 0,\n overflow: 'hidden',\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n }\n }}\n size={getDrawerSize()}\n >\n {/* Pass viewController directly to ChatDialog */}\n <ChatDialog\n title=\"AI助手\"\n description={`scenemesh ai ${vc ? `• ${vc.viewType}视图` : ''}`}\n open\n onOpenChange={(open) => {\n if (!open) {\n handleClose();\n }\n }}\n placeholder=\"输入您的问题或需求...\"\n showHeader\n allowFileUpload\n acceptedFileTypes={['image/*', 'text/*', 'application/pdf', 'application/json']}\n maxFileSize={10 * 1024 * 1024} // 10MB\n theme=\"system\"\n // Mixed tool configuration - backend tools + frontend tool interception\n chatOptions={{\n id: 'ai-assistant-chat',\n transport: new DefaultChatTransport({\n api: '/api/ee/servlet/ai/chat',\n }),\n onFinish: (options) => {\n // Standard AI SDK onFinish callback\n },\n onError: (error) => {\n if (error.message.includes('AI服务连接失败')) {\n console.error('AI service connection failed:', error);\n }\n },\n // Tool call listener - calls ChatDialog's frontend tool handler\n onToolCall: async ({ toolCall }: { toolCall: any }) => {\n \n // Try different parameter fields\n const toolInput = toolCall.args || toolCall.input || toolCall.parameters || {};\n \n \n // Call ChatDialog's frontend tool handler\n if (typeof (window as any).__FRONTEND_TOOL_HANDLER__ === 'function') {\n \n // 异步调用,不阻塞AI SDK\n setTimeout(() => {\n (window as any).__FRONTEND_TOOL_HANDLER__(toolCall.toolName, toolInput);\n }, 0);\n }\n },\n }}\n />\n </Drawer>\n </>\n );\n}\n\nexport const EntityEngineAIFormRenderer: IEntityNamedRenderer = {\n name: 'view-form-tool-1',\n slotName: 'view-form-tool',\n disabled: false,\n renderer: (props) => <EntityAIFormComp {...props} />,\n};"]}
@@ -0,0 +1,233 @@
1
+ import {
2
+ ChatDialog
3
+ } from "./chunk-SXPA6SSD.mjs";
4
+
5
+ // src/entity-module/renderers/ai-form-renderer.tsx
6
+ import { DefaultChatTransport } from "ai";
7
+ import { SparklesIcon } from "lucide-react";
8
+ import { Button, Drawer } from "@mantine/core";
9
+ import { useViewportSize } from "@mantine/hooks";
10
+ import { useState, useEffect, useCallback } from "react";
11
+ import { useEntityEngine } from "@scenemesh/entity-engine";
12
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
+ function EntityAIFormComp(_props) {
14
+ const engine = useEntityEngine();
15
+ const model = _props.model;
16
+ const viewdata = _props.viewData;
17
+ const viewId = _props.additionalProps?.viewId;
18
+ const vc = engine.componentRegistry.getViewController(void 0, void 0, viewId);
19
+ const { width } = useViewportSize();
20
+ const [drawerOpened, setDrawerOpened] = useState(false);
21
+ const getDrawerSize = useCallback(() => {
22
+ if (width <= 768) return "80%";
23
+ if (width <= 1024) return "40%";
24
+ return "30%";
25
+ }, [width]);
26
+ const handleOpenAI = () => {
27
+ setDrawerOpened(true);
28
+ };
29
+ const handleClose = useCallback(() => {
30
+ setDrawerOpened(false);
31
+ }, []);
32
+ const executeViewControllerTool = useCallback(async (toolName, input) => {
33
+ if (!vc) {
34
+ throw new Error("\u6CA1\u6709\u53EF\u7528\u7684\u89C6\u56FE\u63A7\u5236\u5668");
35
+ }
36
+ const operationMap = {
37
+ "recordGetValues": "record.getValues",
38
+ "recordSetValues": "record.setValues",
39
+ "recordGetFieldInfo": "record.getFieldInfo",
40
+ "recordResetForm": "record.resetForm",
41
+ "recordValidateForm": "record.validateForm"
42
+ };
43
+ if (toolName === "recordSetValues") {
44
+ if (input.values) {
45
+ const fieldNames = Object.keys(input.values);
46
+ const actualFields = await vc.invoke("record.getFieldInfo", {});
47
+ if (actualFields && Array.isArray(actualFields)) {
48
+ const realFieldNames = actualFields.map((field) => field._field?.name).filter(Boolean);
49
+ const invalidFields = fieldNames.filter((name) => !realFieldNames.includes(name));
50
+ if (invalidFields.length > 0) {
51
+ const validValues = {};
52
+ Object.entries(input.values).forEach(([key, value]) => {
53
+ if (realFieldNames.includes(key)) {
54
+ validValues[key] = value;
55
+ }
56
+ });
57
+ if (Object.keys(validValues).length > 0) {
58
+ input.values = validValues;
59
+ } else {
60
+ return `Field name error! You used invalid field names.
61
+
62
+ Invalid fields: [${invalidFields.join(", ")}]
63
+ Correct field names: [${realFieldNames.join(", ")}]
64
+
65
+ \u8BF7\u91CD\u65B0\u8C03\u7528recordSetValues\uFF0C\u4F7F\u7528\u6B63\u786E\u7684\u5B57\u6BB5\u540D:
66
+ \u793A\u4F8B: recordSetValues({"values": {"${realFieldNames[0]}": "\u4EA7\u54C1\u503C", "${realFieldNames.slice(1, 3).join('": "\u503C", "')}": "\u503C"}})
67
+
68
+ \u91CD\u8981\u63D0\u9192: \u5FC5\u987B\u4F7F\u7528recordGetFieldInfo\u8FD4\u56DE\u7684\u786E\u5207\u5B57\u6BB5\u540D\uFF0C\u4E0D\u80FD\u731C\u6D4B\u6216\u7FFB\u8BD1\u5B57\u6BB5\u540D\uFF01`;
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+ const operation = operationMap[toolName];
75
+ if (!operation) {
76
+ throw new Error(`\u672A\u77E5\u7684\u5DE5\u5177: ${toolName}`);
77
+ }
78
+ const result = await vc.invoke(operation, input);
79
+ return typeof result === "string" ? result : JSON.stringify(result, null, 2);
80
+ }, [vc]);
81
+ useEffect(() => {
82
+ if (typeof window !== "undefined") {
83
+ window.__ENTITY_ENGINE_AI_BRIDGE__ = {
84
+ executeViewControllerTool
85
+ };
86
+ window.resolveFrontendTool = (waitId, result) => {
87
+ fetch("/api/ee/servlet/ai/frontend-tool-result", {
88
+ method: "POST",
89
+ headers: {
90
+ "Content-Type": "application/json"
91
+ },
92
+ body: JSON.stringify({
93
+ waitId,
94
+ result,
95
+ timestamp: Date.now()
96
+ })
97
+ }).then((response) => {
98
+ if (!response.ok) {
99
+ console.error("Failed to send tool result");
100
+ }
101
+ }).catch((error) => {
102
+ console.error("Failed to send tool result:", error);
103
+ });
104
+ };
105
+ window.rejectFrontendTool = (waitId, error) => {
106
+ fetch("/api/ee/servlet/ai/frontend-tool-result", {
107
+ method: "POST",
108
+ headers: {
109
+ "Content-Type": "application/json"
110
+ },
111
+ body: JSON.stringify({
112
+ waitId,
113
+ error,
114
+ timestamp: Date.now()
115
+ })
116
+ }).catch((networkError) => {
117
+ });
118
+ };
119
+ return () => {
120
+ if (window.__ENTITY_ENGINE_AI_BRIDGE__) {
121
+ delete window.__ENTITY_ENGINE_AI_BRIDGE__;
122
+ }
123
+ if (window.resolveFrontendTool) {
124
+ delete window.resolveFrontendTool;
125
+ }
126
+ if (window.rejectFrontendTool) {
127
+ delete window.rejectFrontendTool;
128
+ }
129
+ };
130
+ }
131
+ return () => {
132
+ };
133
+ }, [executeViewControllerTool]);
134
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
135
+ /* @__PURE__ */ jsx(
136
+ Button,
137
+ {
138
+ leftSection: /* @__PURE__ */ jsx(SparklesIcon, { size: 20 }),
139
+ onClick: handleOpenAI,
140
+ disabled: !vc,
141
+ variant: "light",
142
+ children: "\u667A\u80FD\u586B\u8868"
143
+ }
144
+ ),
145
+ /* @__PURE__ */ jsx(
146
+ Drawer,
147
+ {
148
+ opened: drawerOpened,
149
+ onClose: handleClose,
150
+ position: "right",
151
+ withOverlay: false,
152
+ closeOnClickOutside: false,
153
+ closeOnEscape: true,
154
+ zIndex: 9999999,
155
+ withCloseButton: false,
156
+ transitionProps: {
157
+ transition: "slide-left",
158
+ duration: 200,
159
+ timingFunction: "ease-out"
160
+ },
161
+ styles: {
162
+ content: {
163
+ height: "100vh",
164
+ borderRadius: 0,
165
+ display: "flex",
166
+ flexDirection: "column",
167
+ boxShadow: "-4px 0 20px rgba(0, 0, 0, 0.1)"
168
+ },
169
+ body: {
170
+ height: "100vh",
171
+ padding: 0,
172
+ overflow: "hidden",
173
+ flex: 1,
174
+ display: "flex",
175
+ flexDirection: "column"
176
+ }
177
+ },
178
+ size: getDrawerSize(),
179
+ children: /* @__PURE__ */ jsx(
180
+ ChatDialog,
181
+ {
182
+ title: "AI\u52A9\u624B",
183
+ description: `scenemesh ai ${vc ? `\u2022 ${vc.viewType}\u89C6\u56FE` : ""}`,
184
+ open: true,
185
+ onOpenChange: (open) => {
186
+ if (!open) {
187
+ handleClose();
188
+ }
189
+ },
190
+ placeholder: "\u8F93\u5165\u60A8\u7684\u95EE\u9898\u6216\u9700\u6C42...",
191
+ showHeader: true,
192
+ allowFileUpload: true,
193
+ acceptedFileTypes: ["image/*", "text/*", "application/pdf", "application/json"],
194
+ maxFileSize: 10 * 1024 * 1024,
195
+ theme: "system",
196
+ chatOptions: {
197
+ id: "ai-assistant-chat",
198
+ transport: new DefaultChatTransport({
199
+ api: "/api/ee/servlet/ai/chat"
200
+ }),
201
+ onFinish: (options) => {
202
+ },
203
+ onError: (error) => {
204
+ if (error.message.includes("AI\u670D\u52A1\u8FDE\u63A5\u5931\u8D25")) {
205
+ console.error("AI service connection failed:", error);
206
+ }
207
+ },
208
+ // Tool call listener - calls ChatDialog's frontend tool handler
209
+ onToolCall: async ({ toolCall }) => {
210
+ const toolInput = toolCall.args || toolCall.input || toolCall.parameters || {};
211
+ if (typeof window.__FRONTEND_TOOL_HANDLER__ === "function") {
212
+ setTimeout(() => {
213
+ window.__FRONTEND_TOOL_HANDLER__(toolCall.toolName, toolInput);
214
+ }, 0);
215
+ }
216
+ }
217
+ }
218
+ }
219
+ )
220
+ }
221
+ )
222
+ ] });
223
+ }
224
+ var EntityEngineAIFormRenderer = {
225
+ name: "view-form-tool-1",
226
+ slotName: "view-form-tool",
227
+ disabled: false,
228
+ renderer: (props) => /* @__PURE__ */ jsx(EntityAIFormComp, { ...props })
229
+ };
230
+ export {
231
+ EntityEngineAIFormRenderer
232
+ };
233
+ //# sourceMappingURL=ai-form-renderer-BORQABF2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/entity-module/renderers/ai-form-renderer.tsx"],"sourcesContent":["// 'use client' directive is added by tsup banner\n\nimport type { IEntityView, IEntityModel, IEntityNamedRenderer } from '@scenemesh/entity-engine';\n\nimport { DefaultChatTransport } from 'ai';\nimport { SparklesIcon } from 'lucide-react';\nimport { Button, Drawer } from '@mantine/core';\nimport { useViewportSize } from '@mantine/hooks';\nimport { useState, useEffect, useCallback } from 'react';\nimport { useEntityEngine } from '@scenemesh/entity-engine';\n\nimport { ChatDialog } from '../../components';\n\n\nfunction EntityAIFormComp(_props: any) {\n const engine = useEntityEngine();\n const model = _props.model as IEntityModel;\n const viewdata = _props.viewData as IEntityView;\n const viewId = _props.additionalProps?.viewId;\n const vc = engine.componentRegistry.getViewController(undefined, undefined, viewId);\n \n const { width } = useViewportSize();\n const [drawerOpened, setDrawerOpened] = useState(false);\n\n // Responsive size calculation\n const getDrawerSize = useCallback(() => {\n if (width <= 768) return '80%';\n if (width <= 1024) return '40%';\n return '30%';\n }, [width]);\n\n const handleOpenAI = () => {\n setDrawerOpened(true);\n };\n\n const handleClose = useCallback(() => {\n setDrawerOpened(false);\n }, []);\n\n // Frontend tool executor - executes view controller operations directly in frontend\n const executeViewControllerTool = useCallback(async (toolName: string, input: any): Promise<string> => {\n \n if (!vc) {\n throw new Error('没有可用的视图控制器');\n }\n\n // 解析工具名称到视图控制器操作\n const operationMap: Record<string, string> = {\n 'recordGetValues': 'record.getValues',\n 'recordSetValues': 'record.setValues',\n 'recordGetFieldInfo': 'record.getFieldInfo',\n 'recordResetForm': 'record.resetForm',\n 'recordValidateForm': 'record.validateForm',\n };\n\n // Validate field names and record actual set values\n if (toolName === 'recordSetValues') {\n if (input.values) {\n const fieldNames = Object.keys(input.values);\n \n // 获取当前表单实际的字段名\n const actualFields = await vc.invoke('record.getFieldInfo', {});\n if (actualFields && Array.isArray(actualFields)) {\n const realFieldNames = actualFields.map((field: any) => field._field?.name).filter(Boolean);\n \n // 检查字段名是否匹配\n const invalidFields = fieldNames.filter(name => !realFieldNames.includes(name));\n if (invalidFields.length > 0) {\n \n // 过滤掉无效字段,只设置有效字段\n const validValues: Record<string, any> = {};\n Object.entries(input.values).forEach(([key, value]) => {\n if (realFieldNames.includes(key)) {\n validValues[key] = value;\n }\n });\n \n if (Object.keys(validValues).length > 0) {\n // 更新input.values为只包含有效字段\n input.values = validValues;\n } else {\n // 🚨 返回详细错误信息,包含准确字段名,让AI重新调用\n return `Field name error! You used invalid field names.\\n\\nInvalid fields: [${invalidFields.join(', ')}]\\nCorrect field names: [${realFieldNames.join(', ')}]\n\n请重新调用recordSetValues,使用正确的字段名:\n示例: recordSetValues({\"values\": {\"${realFieldNames[0]}\": \"产品值\", \"${realFieldNames.slice(1, 3).join('\": \"值\", \"')}\": \"值\"}})\n\n重要提醒: 必须使用recordGetFieldInfo返回的确切字段名,不能猜测或翻译字段名!`;\n }\n }\n }\n }\n }\n\n const operation = operationMap[toolName];\n if (!operation) {\n throw new Error(`未知的工具: ${toolName}`);\n }\n\n const result = await vc.invoke(operation, input);\n \n // 返回字符串结果供AI使用\n return typeof result === 'string' ? result : JSON.stringify(result, null, 2);\n }, [vc]);\n\n // 🌉 注册全局前端工具桥接和HTTP通信\n useEffect(() => {\n if (typeof window !== 'undefined') {\n window.__ENTITY_ENGINE_AI_BRIDGE__ = {\n executeViewControllerTool\n };\n\n // Setup frontend to backend HTTP communication bridge\n window.resolveFrontendTool = (waitId: string, result: string) => {\n \n // 通过HTTP POST发送结果给后端\n fetch('/api/ee/servlet/ai/frontend-tool-result', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n waitId,\n result,\n timestamp: Date.now()\n })\n }).then(response => {\n if (!response.ok) {\n console.error('Failed to send tool result');\n }\n }).catch(error => {\n console.error('Failed to send tool result:', error);\n });\n };\n \n window.rejectFrontendTool = (waitId: string, error: string) => {\n \n fetch('/api/ee/servlet/ai/frontend-tool-result', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n waitId,\n error,\n timestamp: Date.now()\n })\n }).catch(networkError => {\n });\n };\n\n return () => {\n if (window.__ENTITY_ENGINE_AI_BRIDGE__) {\n delete (window as any).__ENTITY_ENGINE_AI_BRIDGE__;\n }\n if ((window as any).resolveFrontendTool) {\n delete (window as any).resolveFrontendTool;\n }\n if ((window as any).rejectFrontendTool) {\n delete (window as any).rejectFrontendTool;\n }\n };\n }\n return () =>{}\n }, [executeViewControllerTool]);\n\n\n return (\n <>\n <Button \n leftSection={<SparklesIcon size={20} />} \n onClick={handleOpenAI}\n disabled={!vc}\n variant='light'\n >\n 智能填表\n </Button>\n\n <Drawer\n opened={drawerOpened}\n onClose={handleClose}\n position=\"right\"\n withOverlay={false}\n closeOnClickOutside={false}\n closeOnEscape\n zIndex={9999999}\n withCloseButton={false}\n transitionProps={{\n transition: 'slide-left',\n duration: 200,\n timingFunction: 'ease-out',\n }}\n styles={{\n content: {\n height: '100vh',\n borderRadius: 0,\n display: 'flex',\n flexDirection: 'column',\n boxShadow: '-4px 0 20px rgba(0, 0, 0, 0.1)',\n },\n body: {\n height: '100vh',\n padding: 0,\n overflow: 'hidden',\n flex: 1,\n display: 'flex',\n flexDirection: 'column',\n }\n }}\n size={getDrawerSize()}\n >\n {/* Pass viewController directly to ChatDialog */}\n <ChatDialog\n title=\"AI助手\"\n description={`scenemesh ai ${vc ? `• ${vc.viewType}视图` : ''}`}\n open\n onOpenChange={(open) => {\n if (!open) {\n handleClose();\n }\n }}\n placeholder=\"输入您的问题或需求...\"\n showHeader\n allowFileUpload\n acceptedFileTypes={['image/*', 'text/*', 'application/pdf', 'application/json']}\n maxFileSize={10 * 1024 * 1024} // 10MB\n theme=\"system\"\n // Mixed tool configuration - backend tools + frontend tool interception\n chatOptions={{\n id: 'ai-assistant-chat',\n transport: new DefaultChatTransport({\n api: '/api/ee/servlet/ai/chat',\n }),\n onFinish: (options) => {\n // Standard AI SDK onFinish callback\n },\n onError: (error) => {\n if (error.message.includes('AI服务连接失败')) {\n console.error('AI service connection failed:', error);\n }\n },\n // Tool call listener - calls ChatDialog's frontend tool handler\n onToolCall: async ({ toolCall }: { toolCall: any }) => {\n \n // Try different parameter fields\n const toolInput = toolCall.args || toolCall.input || toolCall.parameters || {};\n \n \n // Call ChatDialog's frontend tool handler\n if (typeof (window as any).__FRONTEND_TOOL_HANDLER__ === 'function') {\n \n // 异步调用,不阻塞AI SDK\n setTimeout(() => {\n (window as any).__FRONTEND_TOOL_HANDLER__(toolCall.toolName, toolInput);\n }, 0);\n }\n },\n }}\n />\n </Drawer>\n </>\n );\n}\n\nexport const EntityEngineAIFormRenderer: IEntityNamedRenderer = {\n name: 'view-form-tool-1',\n slotName: 'view-form-tool',\n disabled: false,\n renderer: (props) => <EntityAIFormComp {...props} />,\n};"],"mappings":"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","names":[]}