@vectorx/agent-simulator 0.1.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 (67) hide show
  1. package/README.md +76 -0
  2. package/bin/agent.js +55 -0
  3. package/lib/index.js +5 -0
  4. package/lib/simulator.js +224 -0
  5. package/lib/types.js +2 -0
  6. package/lib/utils.js +7 -0
  7. package/lib/webview-ui/Agent.js +16 -0
  8. package/lib/webview-ui/App.js +359 -0
  9. package/lib/webview-ui/ErrorBoundary.js +57 -0
  10. package/lib/webview-ui/components/KnowledgeBaseSearchBlock.js +62 -0
  11. package/lib/webview-ui/components/KnowledgeBaseSearchResult.js +37 -0
  12. package/lib/webview-ui/components/MarkdownRenderer.js +27 -0
  13. package/lib/webview-ui/components/MessageRenderer.js +36 -0
  14. package/lib/webview-ui/components/ThinkingBlock.js +105 -0
  15. package/lib/webview-ui/components/ToolUseBlock.js +20 -0
  16. package/lib/webview-ui/components/ToolUseBlockHeader.js +48 -0
  17. package/lib/webview-ui/components/index.js +23 -0
  18. package/lib/webview-ui/constants.js +24 -0
  19. package/lib/webview-ui/contexts/ThemeContext.js +50 -0
  20. package/lib/webview-ui/hooks/useAgentStatus.js +96 -0
  21. package/lib/webview-ui/index.js +17 -0
  22. package/lib/webview-ui/services/agent-service.js +33 -0
  23. package/lib/webview-ui/services/logger-service.js +51 -0
  24. package/lib/webview-ui/styles/copilot.js +118 -0
  25. package/lib/webview-ui/styles/workarea.js +72 -0
  26. package/lib/webview-ui/types/index.js +2 -0
  27. package/lib/webview-ui/types.js +2 -0
  28. package/lib/webview-ui/widgets/BubbleComponents.js +114 -0
  29. package/lib/webview-ui/widgets/LogPanel.js +66 -0
  30. package/lib/webview-ui/widgets/SystemLogs.js +404 -0
  31. package/lib/webview-ui/widgets/ToolBar.js +109 -0
  32. package/lib/webview-ui/widgets/index.js +20 -0
  33. package/package.json +79 -0
  34. package/public/assets/index-j_rEEDWU.js +93 -0
  35. package/public/assets/main.js +580 -0
  36. package/public/assets/style.css +1 -0
  37. package/public/index.html +15 -0
  38. package/types/index.d.ts +3 -0
  39. package/types/simulator.d.ts +15 -0
  40. package/types/types.d.ts +6 -0
  41. package/types/utils.d.ts +1 -0
  42. package/types/webview-ui/Agent.d.ts +3 -0
  43. package/types/webview-ui/App.d.ts +3 -0
  44. package/types/webview-ui/ErrorBoundary.d.ts +18 -0
  45. package/types/webview-ui/components/KnowledgeBaseSearchBlock.d.ts +19 -0
  46. package/types/webview-ui/components/KnowledgeBaseSearchResult.d.ts +8 -0
  47. package/types/webview-ui/components/MarkdownRenderer.d.ts +6 -0
  48. package/types/webview-ui/components/MessageRenderer.d.ts +6 -0
  49. package/types/webview-ui/components/ThinkingBlock.d.ts +7 -0
  50. package/types/webview-ui/components/ToolUseBlock.d.ts +9 -0
  51. package/types/webview-ui/components/ToolUseBlockHeader.d.ts +9 -0
  52. package/types/webview-ui/components/index.d.ts +7 -0
  53. package/types/webview-ui/constants.d.ts +17 -0
  54. package/types/webview-ui/contexts/ThemeContext.d.ts +11 -0
  55. package/types/webview-ui/hooks/useAgentStatus.d.ts +11 -0
  56. package/types/webview-ui/index.d.ts +2 -0
  57. package/types/webview-ui/services/agent-service.d.ts +27 -0
  58. package/types/webview-ui/services/logger-service.d.ts +29 -0
  59. package/types/webview-ui/styles/copilot.d.ts +13 -0
  60. package/types/webview-ui/styles/workarea.d.ts +10 -0
  61. package/types/webview-ui/types/index.d.ts +20 -0
  62. package/types/webview-ui/types.d.ts +48 -0
  63. package/types/webview-ui/widgets/BubbleComponents.d.ts +12 -0
  64. package/types/webview-ui/widgets/LogPanel.d.ts +14 -0
  65. package/types/webview-ui/widgets/SystemLogs.d.ts +23 -0
  66. package/types/webview-ui/widgets/ToolBar.d.ts +13 -0
  67. package/types/webview-ui/widgets/index.d.ts +4 -0
@@ -0,0 +1,359 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const icons_1 = require("@ant-design/icons");
37
+ const icons_2 = require("@ant-design/icons");
38
+ const x_1 = require("@ant-design/x");
39
+ const antd_1 = require("antd");
40
+ const antd_2 = require("antd");
41
+ const react_1 = __importStar(require("react"));
42
+ const Agent_1 = require("./Agent");
43
+ const ErrorBoundary_1 = require("./ErrorBoundary");
44
+ const components_1 = require("./components");
45
+ const constants_1 = require("./constants");
46
+ const ThemeContext_1 = require("./contexts/ThemeContext");
47
+ const useAgentStatus_1 = require("./hooks/useAgentStatus");
48
+ const copilot_1 = require("./styles/copilot");
49
+ const workarea_1 = require("./styles/workarea");
50
+ const widgets_1 = require("./widgets");
51
+ const LogPanel_1 = require("./widgets/LogPanel");
52
+ const ChatAgent = ({ agentSimulatorInfo, onMessageUpdate, onRequestStart, onRequestEnd, onUserSubmit, onCancel, }) => {
53
+ const abortController = (0, react_1.useRef)(null);
54
+ const [agent] = (0, x_1.useXAgent)({
55
+ baseURL: (0, Agent_1.getSendMessageUri)(agentSimulatorInfo),
56
+ });
57
+ const handleUserSubmit = (0, react_1.useCallback)((val, messages) => {
58
+ const userMessage = {
59
+ id: `user-${Date.now()}`,
60
+ role: "user",
61
+ content: val,
62
+ isThinking: false,
63
+ isTimeout: false,
64
+ isInterrupted: false,
65
+ isUiDiscard: false,
66
+ uiTimeStr: new Date().toLocaleTimeString(),
67
+ type: "answer",
68
+ };
69
+ const newMessages = [...messages, userMessage];
70
+ onMessageUpdate(newMessages);
71
+ onRequestStart();
72
+ agent.request({
73
+ msg: val,
74
+ history: [],
75
+ }, {
76
+ onUpdate: (chunk) => {
77
+ try {
78
+ if (chunk === null || chunk === void 0 ? void 0 : chunk.data) {
79
+ const data = typeof chunk.data === "string" ? chunk.data : chunk.data.toString();
80
+ if (data.endsWith("[DONE]")) {
81
+ return;
82
+ }
83
+ let message;
84
+ try {
85
+ message = JSON.parse(data);
86
+ }
87
+ catch (parseError) {
88
+ console.error("Failed to parse message data:", parseError);
89
+ return;
90
+ }
91
+ if (!message || typeof message !== "object") {
92
+ console.warn("Invalid message object:", message);
93
+ return;
94
+ }
95
+ const msgType = message.choices[0].message.type;
96
+ const currentText = message.choices[0].message.content || "";
97
+ const currentReasoning = message.choices[0].message.reasoning_content || "";
98
+ const messageId = message.id;
99
+ onMessageUpdate((prev) => {
100
+ const newMessages = [...prev];
101
+ let existingIndex = newMessages.findIndex((msg) => msg.id === messageId);
102
+ if (existingIndex === -1) {
103
+ const newMessage = {
104
+ id: messageId,
105
+ role: "assistant",
106
+ content: "",
107
+ reasoningContent: "",
108
+ isThinking: true,
109
+ isTimeout: false,
110
+ isInterrupted: false,
111
+ isUiDiscard: false,
112
+ uiTimeStr: new Date().toLocaleTimeString(),
113
+ type: "thinking",
114
+ cards: [],
115
+ timestamp: Date.now(),
116
+ };
117
+ newMessages.push(newMessage);
118
+ existingIndex = newMessages.length - 1;
119
+ }
120
+ const existingMessage = newMessages[existingIndex];
121
+ const updatedMessage = Object.assign({}, existingMessage);
122
+ updatedMessage.reasoningContent = (updatedMessage.reasoningContent || "") + currentReasoning;
123
+ updatedMessage.isThinking = !!currentReasoning;
124
+ if (msgType === "answer") {
125
+ updatedMessage.content = (updatedMessage.content || "") + currentText;
126
+ updatedMessage.type = "answer";
127
+ }
128
+ else if ([
129
+ "function_call",
130
+ "function_call_response",
131
+ "knowledge_base_search",
132
+ "knowledge_base_search_response",
133
+ ].includes(msgType)) {
134
+ const cards = updatedMessage.cards ? [...updatedMessage.cards] : [];
135
+ const existingCardIndex = cards.findIndex((card) => card.type === msgType);
136
+ const newCard = {
137
+ type: msgType,
138
+ content: currentText,
139
+ };
140
+ if (existingCardIndex !== -1) {
141
+ cards[existingCardIndex].content += currentText;
142
+ }
143
+ else {
144
+ cards.push(newCard);
145
+ }
146
+ updatedMessage.cards = cards;
147
+ if (existingMessage.type === "thinking") {
148
+ updatedMessage.type = msgType;
149
+ }
150
+ }
151
+ newMessages[existingIndex] = updatedMessage;
152
+ return newMessages;
153
+ });
154
+ }
155
+ }
156
+ catch (error) {
157
+ console.error("Transform message error:", error);
158
+ }
159
+ },
160
+ onSuccess: () => {
161
+ onMessageUpdate((prev) => {
162
+ return prev.map((msg) => (Object.assign(Object.assign({}, msg), { isThinking: false })));
163
+ });
164
+ onRequestEnd();
165
+ },
166
+ onError: (error) => {
167
+ console.error("Request error:", error);
168
+ onMessageUpdate((prev) => {
169
+ const newMessages = [...prev];
170
+ const lastMessageIndex = newMessages.length - 1;
171
+ if (lastMessageIndex >= 0 && newMessages[lastMessageIndex].isThinking) {
172
+ newMessages[lastMessageIndex] = Object.assign(Object.assign({}, newMessages[lastMessageIndex]), { content: error.name === "AbortError" ? "请求已取消" : "请求失败,请重试!", isThinking: false });
173
+ }
174
+ return newMessages;
175
+ });
176
+ onRequestEnd();
177
+ },
178
+ onStream: (controller) => {
179
+ abortController.current = controller;
180
+ },
181
+ });
182
+ }, [agent, onMessageUpdate, onRequestStart, onRequestEnd]);
183
+ const handleCancel = (0, react_1.useCallback)(() => {
184
+ var _a;
185
+ (_a = abortController.current) === null || _a === void 0 ? void 0 : _a.abort();
186
+ }, []);
187
+ react_1.default.useEffect(() => {
188
+ onUserSubmit(handleUserSubmit);
189
+ onCancel(handleCancel);
190
+ }, [handleUserSubmit, handleCancel, onUserSubmit, onCancel]);
191
+ return react_1.default.createElement("div", { style: { display: "none" } });
192
+ };
193
+ const Copilot = () => {
194
+ const { isDark } = (0, ThemeContext_1.useThemeHook)();
195
+ const { token } = antd_1.theme.useToken();
196
+ const { styles } = (0, copilot_1.useCopilotStyle)();
197
+ const attachmentsRef = (0, react_1.useRef)(null);
198
+ const chatUserSubmitRef = (0, react_1.useRef)(null);
199
+ const chatCancelRef = (0, react_1.useRef)(null);
200
+ const [attachmentsOpen, setAttachmentsOpen] = (0, react_1.useState)(false);
201
+ const [files, setFiles] = (0, react_1.useState)([]);
202
+ const [inputValue, setInputValue] = (0, react_1.useState)("");
203
+ const [messages, setMessages] = (0, react_1.useState)([]);
204
+ const [loading, setLoading] = (0, react_1.useState)(false);
205
+ const { agentSimulatorInfo, debugStatus, isConnecting, retryConnection } = (0, useAgentStatus_1.useAgentStatus)();
206
+ const [showSystemLogs, setShowSystemLogs] = (0, react_1.useState)(false);
207
+ const [activeLogTab, setActiveLogTab] = (0, react_1.useState)("system");
208
+ const handleClearChat = () => {
209
+ setMessages([]);
210
+ };
211
+ const handleToggleLogs = () => setShowSystemLogs((v) => !v);
212
+ const canSendMessage = agentSimulatorInfo && debugStatus === "normal";
213
+ const getDisabledReason = () => {
214
+ if (!agentSimulatorInfo) {
215
+ return "服务断开,无法发送消息";
216
+ }
217
+ if (debugStatus !== "normal") {
218
+ return "调试状态异常,无法发送消息";
219
+ }
220
+ return "";
221
+ };
222
+ const handleUserSubmit = (val) => {
223
+ if (!canSendMessage) {
224
+ antd_2.message.warning(getDisabledReason());
225
+ return;
226
+ }
227
+ if (chatUserSubmitRef.current) {
228
+ chatUserSubmitRef.current(val, messages);
229
+ }
230
+ };
231
+ const handleCancel = () => {
232
+ if (chatCancelRef.current) {
233
+ chatCancelRef.current();
234
+ }
235
+ };
236
+ const onPasteFile = (_, files) => {
237
+ var _a;
238
+ for (const file of files) {
239
+ (_a = attachmentsRef.current) === null || _a === void 0 ? void 0 : _a.upload(file);
240
+ }
241
+ setAttachmentsOpen(true);
242
+ };
243
+ const chatList = (react_1.default.createElement("div", { className: styles.chatList, style: { display: "flex", flexDirection: "column" } }, (messages === null || messages === void 0 ? void 0 : messages.length) ? (react_1.default.createElement(x_1.Bubble.List, { style: { height: "100%", padding: "12px 16px" }, items: messages.map((item) => {
244
+ return {
245
+ content: item.content,
246
+ role: item.role,
247
+ messageRender: () => (item.role === "user" ? item.content : react_1.default.createElement(components_1.MessageRenderer, { message: item })),
248
+ };
249
+ }), roles: {
250
+ assistant: {
251
+ placement: "start",
252
+ loadingRender: () => (react_1.default.createElement(antd_2.Space, null,
253
+ react_1.default.createElement(antd_2.Spin, { size: "small" }),
254
+ "Custom loading...")),
255
+ avatar: {
256
+ icon: react_1.default.createElement(icons_2.AliwangwangFilled, null),
257
+ style: { background: token.colorInfoText },
258
+ },
259
+ styles: {
260
+ content: {
261
+ backgroundColor: "transparent",
262
+ padding: 0,
263
+ },
264
+ },
265
+ },
266
+ user: {
267
+ placement: "start",
268
+ avatar: {
269
+ icon: react_1.default.createElement(icons_2.UserOutlined, null),
270
+ style: {
271
+ background: token.colorSuccessText,
272
+ },
273
+ },
274
+ },
275
+ } })) : (react_1.default.createElement(react_1.default.Fragment, null,
276
+ react_1.default.createElement(x_1.Welcome, { variant: "borderless", title: "\uD83D\uDC4B Hello, \u5C0F\u7A0B\u5E8F\u5F00\u653E\u5E73\u53F0\u667A\u80FD\u4F53\u8C03\u8BD5\u5668", description: "\u63D0\u4F9B Agent \u8C03\u8BD5\u6A21\u62DF\u529F\u80FD", className: styles.chatWelcome, style: {
277
+ backgroundImage: isDark
278
+ ? "linear-gradient(97deg, rgba(90,196,255,0.12) 0%, rgba(174,136,255,0.12) 100%)"
279
+ : "linear-gradient(97deg, #f2f9fe 0%, #f7f3ff 100%)",
280
+ } }),
281
+ react_1.default.createElement(x_1.Prompts, { vertical: true, title: "\u6211\u53EF\u4EE5\u5E2E\u52A9\u4F60\uFF1A", items: constants_1.MOCK_QUESTIONS.map((i) => ({
282
+ key: i,
283
+ description: i,
284
+ })), onItemClick: (info) => { var _a; return handleUserSubmit((_a = info === null || info === void 0 ? void 0 : info.data) === null || _a === void 0 ? void 0 : _a.description); }, style: {
285
+ marginInline: 16,
286
+ }, styles: {
287
+ title: { fontSize: 14 },
288
+ } })))));
289
+ const sendHeader = (react_1.default.createElement(x_1.Sender.Header, { title: "Upload File", styles: { content: { padding: 0 } }, open: attachmentsOpen, onOpenChange: setAttachmentsOpen, forceRender: true },
290
+ react_1.default.createElement(x_1.Attachments, { ref: attachmentsRef, beforeUpload: () => false, items: files, onChange: ({ fileList }) => setFiles(fileList), placeholder: (type) => type === "drop"
291
+ ? { title: "Drop file here" }
292
+ : {
293
+ icon: react_1.default.createElement(icons_1.CloudUploadOutlined, null),
294
+ title: "Upload files",
295
+ description: "Click or drag files to this area to upload",
296
+ } })));
297
+ const chatSender = (react_1.default.createElement("div", { className: styles.chatSend, style: {
298
+ background: token.colorBgContainer,
299
+ borderTop: `1px solid ${token.colorBorder}`,
300
+ borderRadius: 0,
301
+ padding: "16px 20px",
302
+ } },
303
+ react_1.default.createElement(x_1.Suggestion, { items: constants_1.MOCK_SUGGESTIONS, onSelect: (itemVal) => setInputValue(`[${itemVal}]:`) }, ({ onTrigger, onKeyDown }) => (react_1.default.createElement(x_1.Sender, { loading: loading, value: inputValue, disabled: !canSendMessage, onChange: (v) => {
304
+ onTrigger(v === "/");
305
+ setInputValue(v);
306
+ }, onSubmit: () => {
307
+ handleUserSubmit(inputValue);
308
+ setInputValue("");
309
+ }, onCancel: handleCancel, allowSpeech: true, placeholder: !canSendMessage ? getDisabledReason() : "Ask or input / use skills", onKeyDown: onKeyDown, header: sendHeader, prefix: react_1.default.createElement(antd_2.Button, { type: "text", icon: react_1.default.createElement(icons_1.PaperClipOutlined, { style: { fontSize: 18 } }), onClick: () => setAttachmentsOpen(!attachmentsOpen), disabled: !canSendMessage }), onPasteFile: onPasteFile, actions: (_, info) => {
310
+ const { SendButton, LoadingButton, SpeechButton } = info.components;
311
+ return (react_1.default.createElement("div", { style: {
312
+ display: "flex",
313
+ alignItems: "center",
314
+ gap: 4,
315
+ } },
316
+ react_1.default.createElement(SpeechButton, { className: styles.speechButton, disabled: !canSendMessage }),
317
+ loading ? (react_1.default.createElement(LoadingButton, { type: "default" })) : (react_1.default.createElement(SendButton, { type: "primary", disabled: !canSendMessage }))));
318
+ } })))));
319
+ return (react_1.default.createElement("div", { className: styles.copilotChat, style: {
320
+ background: token.colorBgContainer,
321
+ minHeight: "100vh",
322
+ borderRadius: 0,
323
+ boxShadow: "none",
324
+ padding: 0,
325
+ border: `1px solid ${token.colorBorder}`,
326
+ } },
327
+ react_1.default.createElement(widgets_1.ToolBar, { agentSimulatorInfo: agentSimulatorInfo, debugStatus: debugStatus, showSystemLogs: showSystemLogs, isConnecting: isConnecting, onRetryConnection: retryConnection, onClearChat: handleClearChat, onToggleLogs: handleToggleLogs }),
328
+ react_1.default.createElement(LogPanel_1.LogPanel, { open: showSystemLogs, activeTab: activeLogTab, onTabChange: setActiveLogTab, onClose: () => setShowSystemLogs(false), agentSimulatorInfo: agentSimulatorInfo, height: constants_1.LOG_PANEL_HEIGHT, debugStatus: debugStatus }),
329
+ chatList,
330
+ chatSender,
331
+ agentSimulatorInfo && (react_1.default.createElement(ChatAgent, { agentSimulatorInfo: agentSimulatorInfo, onMessageUpdate: setMessages, onRequestStart: () => setLoading(true), onRequestEnd: () => setLoading(false), onUserSubmit: (fn) => {
332
+ chatUserSubmitRef.current = fn;
333
+ }, onCancel: (fn) => {
334
+ chatCancelRef.current = fn;
335
+ } }))));
336
+ };
337
+ const CopilotSimulator = () => {
338
+ const { styles: workareaStyles } = (0, workarea_1.useWorkareaStyle)();
339
+ const getIsDarkFromQuery = () => {
340
+ const params = new URLSearchParams(window.location.search);
341
+ return params.get("isDark") ? params.get("isDark") === "true" : false;
342
+ };
343
+ const initIsDarkMode = getIsDarkFromQuery();
344
+ const [darkMode, setDarkMode] = (0, react_1.useState)(initIsDarkMode);
345
+ if (typeof require === "function") {
346
+ const { ipcRenderer } = require("electron");
347
+ ipcRenderer.on("setTheme", (event, isDark) => {
348
+ setDarkMode(isDark);
349
+ });
350
+ }
351
+ return (react_1.default.createElement(ThemeContext_1.ThemeProvider, { isDark: darkMode },
352
+ react_1.default.createElement(antd_1.ConfigProvider, { theme: {
353
+ algorithm: darkMode ? antd_1.theme.darkAlgorithm : antd_1.theme.defaultAlgorithm,
354
+ } },
355
+ react_1.default.createElement(ErrorBoundary_1.ErrorBoundary, null,
356
+ react_1.default.createElement("div", { className: workareaStyles.copilotWrapper },
357
+ react_1.default.createElement(Copilot, null))))));
358
+ };
359
+ exports.default = CopilotSimulator;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ErrorBoundary = void 0;
7
+ const icons_1 = require("@ant-design/icons");
8
+ const antd_1 = require("antd");
9
+ const react_1 = __importDefault(require("react"));
10
+ const { useToken } = antd_1.theme;
11
+ const { Paragraph, Text } = antd_1.Typography;
12
+ function ErrorDisplay({ error }) {
13
+ const { token } = useToken();
14
+ return (react_1.default.createElement("div", { style: {
15
+ padding: "20px",
16
+ minHeight: "100vh",
17
+ display: "flex",
18
+ flexDirection: "column",
19
+ justifyContent: "center",
20
+ alignItems: "center",
21
+ background: token.colorBgContainer,
22
+ } },
23
+ react_1.default.createElement(antd_1.Result, { status: "error", title: "\u667A\u80FD\u4F53\u6A21\u62DF\u5668\u52A0\u8F7D\u5931\u8D25", subTitle: "\u8BF7\u68C0\u67E5\u4EE5\u4E0B\u9519\u8BEF\u4FE1\u606F\uFF0C\u7136\u540E\u91CD\u8BD5", extra: [
24
+ react_1.default.createElement(antd_1.Button, { type: "primary", key: "reload", icon: react_1.default.createElement(icons_1.ReloadOutlined, null), onClick: () => window.location.reload() }, "\u91CD\u8BD5"),
25
+ ] },
26
+ react_1.default.createElement("div", { className: "desc" },
27
+ react_1.default.createElement(Paragraph, null,
28
+ react_1.default.createElement(Text, { strong: true, style: {
29
+ fontSize: 16,
30
+ color: token.colorText,
31
+ } }, "\u53D1\u751F\u4E86\u4EE5\u4E0B\u9519\u8BEF\uFF1A")),
32
+ error && (react_1.default.createElement(Paragraph, null,
33
+ react_1.default.createElement(icons_1.CloseCircleOutlined, { style: {
34
+ color: token.colorError,
35
+ marginRight: 8,
36
+ } }),
37
+ react_1.default.createElement(Text, { code: true, style: { color: token.colorTextSecondary } }, (error === null || error === void 0 ? void 0 : error.message) || `${error}` || "错误信息为空")))))));
38
+ }
39
+ class ErrorBoundary extends react_1.default.Component {
40
+ constructor(props) {
41
+ super(props);
42
+ this.state = { hasError: false };
43
+ }
44
+ static getDerivedStateFromError(error) {
45
+ return { hasError: true, error };
46
+ }
47
+ componentDidCatch(error, errorInfo) {
48
+ console.error("ErrorBoundary caught an error:", error, errorInfo);
49
+ }
50
+ render() {
51
+ if (this.state.hasError) {
52
+ return react_1.default.createElement(ErrorDisplay, { error: this.state.error });
53
+ }
54
+ return this.props.children;
55
+ }
56
+ }
57
+ exports.ErrorBoundary = ErrorBoundary;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.KnowledgeBaseSearchBlock = void 0;
7
+ const icons_1 = require("@ant-design/icons");
8
+ const antd_style_1 = require("antd-style");
9
+ const react_1 = __importDefault(require("react"));
10
+ const react_2 = require("react");
11
+ const _1 = require(".");
12
+ const useStyles = (0, antd_style_1.createStyles)(({ token, css }) => ({
13
+ block: css `
14
+ border: 1px solid ${token.colorBorderSecondary};
15
+ border-radius: 8px;
16
+ background: ${token.colorBgLayout};
17
+ overflow: hidden;
18
+ `,
19
+ body: css `
20
+ padding: 12px;
21
+ font-size: 13px;
22
+ `,
23
+ query: css `
24
+ color: ${token.colorText};
25
+ margin-bottom: 4px;
26
+ `,
27
+ kbId: css `
28
+ color: ${token.colorTextTertiary};
29
+ font-family: ${token.fontFamilyCode};
30
+ `,
31
+ param: css `
32
+ margin-top: 4px;
33
+ color: ${token.colorTextTertiary};
34
+ font-family: ${token.fontFamilyCode};
35
+ `,
36
+ noResult: css `
37
+ color: ${token.colorTextSecondary};
38
+ `,
39
+ }));
40
+ const KnowledgeBaseSearchBlock = ({ query, knowledge_base_id, score_threshold, knowledge_search_mode, chunks, isResponse, reason_msg, has_result, }) => {
41
+ const [isExpanded, setIsExpanded] = (0, react_2.useState)(true);
42
+ const { styles } = useStyles();
43
+ const headerText = isResponse ? "知识库检索结果(检索到 " + ((chunks === null || chunks === void 0 ? void 0 : chunks.length) || 0) + " 条)" : "知识库检索";
44
+ const icon = react_1.default.createElement(icons_1.SearchOutlined, null);
45
+ return (react_1.default.createElement("div", { className: styles.block, style: { width: "100%" } },
46
+ react_1.default.createElement(_1.ToolUseBlockHeader, { toolName: headerText, isExpanded: isExpanded, onToggleExpand: () => setIsExpanded(!isExpanded), icon: icon }),
47
+ isExpanded && (react_1.default.createElement("div", { className: styles.body }, !isResponse ? (react_1.default.createElement("div", null,
48
+ react_1.default.createElement("div", { className: styles.query },
49
+ "\u67E5\u8BE2: \"",
50
+ query,
51
+ "\""),
52
+ react_1.default.createElement("div", { className: styles.kbId },
53
+ "\u77E5\u8BC6\u5E93ID: ",
54
+ knowledge_base_id || "N/A"),
55
+ knowledge_search_mode && react_1.default.createElement("div", { className: styles.param },
56
+ "\u68C0\u7D22\u6A21\u5F0F: ",
57
+ knowledge_search_mode),
58
+ score_threshold !== undefined && react_1.default.createElement("div", { className: styles.param },
59
+ "\u9608\u503C: ",
60
+ score_threshold))) : (react_1.default.createElement("div", null, has_result && (chunks === null || chunks === void 0 ? void 0 : chunks.length) ? (chunks.map((chunk, index) => react_1.default.createElement(_1.KnowledgeBaseSearchResult, Object.assign({ key: chunk.id || index }, chunk)))) : (react_1.default.createElement("div", { className: styles.noResult }, reason_msg || "未找到相关内容"))))))));
61
+ };
62
+ exports.KnowledgeBaseSearchBlock = KnowledgeBaseSearchBlock;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.KnowledgeBaseSearchResult = void 0;
7
+ const antd_style_1 = require("antd-style");
8
+ const react_1 = __importDefault(require("react"));
9
+ const useStyles = (0, antd_style_1.createStyles)(({ token, css }) => ({
10
+ result: css `
11
+ border: 1px solid ${token.colorBorderSecondary};
12
+ border-radius: 6px;
13
+ padding: 12px;
14
+ background: ${token.colorBgContainer};
15
+ margin-bottom: 8px;
16
+ font-size: 13px;
17
+ `,
18
+ detail: css `
19
+ color: ${token.colorTextSecondary};
20
+ white-space: pre-wrap;
21
+ word-break: break-word;
22
+ margin-bottom: 8px;
23
+ `,
24
+ score: css `
25
+ color: ${token.colorTextTertiary};
26
+ font-size: 12px;
27
+ `,
28
+ }));
29
+ const KnowledgeBaseSearchResult = ({ score, detail }) => {
30
+ const { styles } = useStyles();
31
+ return (react_1.default.createElement("div", { className: styles.result },
32
+ react_1.default.createElement("div", { className: styles.detail }, detail),
33
+ react_1.default.createElement("div", { className: styles.score },
34
+ "\u76F8\u5173\u6027\u5206\u6570: ",
35
+ score.toFixed(4))));
36
+ };
37
+ exports.KnowledgeBaseSearchResult = KnowledgeBaseSearchResult;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MarkdownRenderer = void 0;
7
+ const antd_1 = require("antd");
8
+ const antd_style_1 = require("antd-style");
9
+ const markdown_it_1 = __importDefault(require("markdown-it"));
10
+ const react_1 = __importDefault(require("react"));
11
+ const react_2 = require("react");
12
+ const copilot_1 = require("../styles/copilot");
13
+ const md = (0, markdown_it_1.default)({ html: true, breaks: true });
14
+ const useStyles = (0, antd_style_1.createStyles)(({ token, css }) => ({
15
+ markdownContent: css `
16
+ transition: opacity 0.2s ease-in-out;
17
+ opacity: 1;
18
+ `,
19
+ }));
20
+ const MarkdownRenderer = ({ content }) => {
21
+ const { styles } = useStyles();
22
+ const { styles: copilotStyles } = (0, copilot_1.useCopilotStyle)();
23
+ const html = (0, react_2.useMemo)(() => md.render(content), [content]);
24
+ return (react_1.default.createElement(antd_1.Typography, null,
25
+ react_1.default.createElement("div", { className: `markdown-content ${copilotStyles.markdownContent} ${styles.markdownContent}`, dangerouslySetInnerHTML: { __html: html } })));
26
+ };
27
+ exports.MarkdownRenderer = MarkdownRenderer;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MessageRenderer = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const _1 = require(".");
9
+ const cardComponentMap = {
10
+ knowledge_base_search: _1.KnowledgeBaseSearchBlock,
11
+ knowledge_base_search_response: (props) => react_1.default.createElement(_1.KnowledgeBaseSearchBlock, Object.assign({}, props, { isResponse: true })),
12
+ function_call: _1.ToolUseBlock,
13
+ function_call_response: (props) => react_1.default.createElement(_1.ToolUseBlock, Object.assign({}, props, { isResponse: true })),
14
+ };
15
+ const MessageRenderer = ({ message }) => {
16
+ const { cards, reasoningContent, content } = message;
17
+ return (react_1.default.createElement("div", { style: { display: "flex", flexDirection: "column", gap: "10px" } }, cards === null || cards === void 0 ? void 0 :
18
+ cards.map((card, index) => {
19
+ const CardComponent = cardComponentMap[card.type];
20
+ if (!CardComponent) {
21
+ console.warn(`No component found for card type: ${card.type}`);
22
+ return null;
23
+ }
24
+ let cardContent;
25
+ try {
26
+ cardContent = JSON.parse(card.content);
27
+ }
28
+ catch (e) {
29
+ cardContent = { content: card.content };
30
+ }
31
+ return react_1.default.createElement(CardComponent, Object.assign({ key: index }, cardContent));
32
+ }),
33
+ reasoningContent && react_1.default.createElement(_1.ThinkingBlock, { message: message }),
34
+ content && react_1.default.createElement(_1.MarkdownRenderer, { content: content })));
35
+ };
36
+ exports.MessageRenderer = MessageRenderer;