@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,114 @@
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.formatOpenAIResponse = exports.CustomMarkdown = exports.ReasoningCard = void 0;
7
+ const icons_1 = require("@ant-design/icons");
8
+ const antd_1 = require("antd");
9
+ const markdown_it_1 = __importDefault(require("markdown-it"));
10
+ const react_1 = __importDefault(require("react"));
11
+ const md = new markdown_it_1.default({
12
+ html: true,
13
+ breaks: true,
14
+ linkify: true,
15
+ typographer: true,
16
+ });
17
+ const ReasoningCard = ({ content }) => {
18
+ const { token } = antd_1.theme.useToken();
19
+ return (react_1.default.createElement(antd_1.Flex, { vertical: true, gap: 8 },
20
+ react_1.default.createElement(antd_1.Typography.Text, { type: "secondary", style: { fontSize: 12 } },
21
+ react_1.default.createElement(icons_1.RobotOutlined, { style: { marginRight: 4 } }),
22
+ " \u6DF1\u5EA6\u601D\u8003\u8FC7\u7A0B"),
23
+ react_1.default.createElement(antd_1.Card, { size: "small", style: {
24
+ backgroundColor: token.colorBgElevated,
25
+ border: `1px solid ${token.colorBorder}`,
26
+ borderRadius: 8,
27
+ } },
28
+ react_1.default.createElement(antd_1.Typography.Text, null, content))));
29
+ };
30
+ exports.ReasoningCard = ReasoningCard;
31
+ const CustomMarkdown = ({ content }) => {
32
+ const safeContent = (() => {
33
+ if (content === null || content === undefined) {
34
+ return "";
35
+ }
36
+ if (typeof content === "string") {
37
+ return content;
38
+ }
39
+ if (typeof content === "object" && content.content) {
40
+ return String(content.content);
41
+ }
42
+ try {
43
+ return JSON.stringify(content);
44
+ }
45
+ catch (e) {
46
+ return String(content);
47
+ }
48
+ })();
49
+ if (!safeContent || safeContent === "..." || safeContent.trim() === "") {
50
+ return react_1.default.createElement(antd_1.Typography.Text, { type: "secondary" }, "\u52A0\u8F7D\u4E2D...");
51
+ }
52
+ try {
53
+ return (react_1.default.createElement(antd_1.Typography, null,
54
+ react_1.default.createElement("div", { dangerouslySetInnerHTML: { __html: md.render(safeContent) } })));
55
+ }
56
+ catch (e) {
57
+ console.error("渲染Markdown失败:", e);
58
+ return react_1.default.createElement(antd_1.Typography.Text, null, safeContent);
59
+ }
60
+ };
61
+ exports.CustomMarkdown = CustomMarkdown;
62
+ const formatOpenAIResponse = (chunk) => {
63
+ try {
64
+ console.log("正在处理数据块:", chunk);
65
+ if (typeof chunk.data === "string") {
66
+ let dataContent = chunk.data;
67
+ if (dataContent.startsWith("data:")) {
68
+ dataContent = dataContent.substring(5).trim();
69
+ }
70
+ if (dataContent === " [DONE]") {
71
+ return null;
72
+ }
73
+ try {
74
+ let parsedData;
75
+ try {
76
+ parsedData = JSON.parse(dataContent);
77
+ }
78
+ catch (e) {
79
+ console.error("JSON解析失败", dataContent);
80
+ return { content: dataContent, reasoningContent: "", role: "assistant" };
81
+ }
82
+ if (parsedData.choices && parsedData.choices.length > 0) {
83
+ const choice = parsedData.choices[0];
84
+ if (choice.delta && (choice.delta.content !== undefined || choice.delta.reasoning_content !== undefined)) {
85
+ return {
86
+ content: choice.delta.content || "",
87
+ reasoningContent: choice.delta.reasoning_content || "",
88
+ role: parsedData.role || "assistant",
89
+ };
90
+ }
91
+ }
92
+ if (parsedData.content !== undefined || parsedData.reasoning_content !== undefined) {
93
+ return {
94
+ content: parsedData.content || "",
95
+ reasoningContent: parsedData.reasoning_content || "",
96
+ role: parsedData.role || "assistant",
97
+ };
98
+ }
99
+ console.log("未匹配任何已知数据格式,返回原始内容");
100
+ return { content: dataContent, reasoningContent: "", role: "assistant" };
101
+ }
102
+ catch (e) {
103
+ console.error("解析OpenAI格式数据失败:", e);
104
+ return { content: dataContent, reasoningContent: "", role: "assistant" };
105
+ }
106
+ }
107
+ return null;
108
+ }
109
+ catch (e) {
110
+ console.error("处理OpenAI响应时出错:", e);
111
+ return null;
112
+ }
113
+ };
114
+ exports.formatOpenAIResponse = formatOpenAIResponse;
@@ -0,0 +1,66 @@
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.LogPanel = void 0;
7
+ const antd_1 = require("antd");
8
+ const react_1 = __importDefault(require("react"));
9
+ const logger_service_1 = require("../services/logger-service");
10
+ const SystemLogs_1 = require("./SystemLogs");
11
+ const LogPanel = ({ open, activeTab, onTabChange, onClose, agentSimulatorInfo, height, debugStatus, }) => {
12
+ var _a, _b;
13
+ const { token } = antd_1.theme.useToken();
14
+ const getBaseUrl = (uri) => {
15
+ if (!uri)
16
+ return "";
17
+ try {
18
+ const url = new URL(uri);
19
+ return `${url.protocol}//${url.hostname}${url.port ? ":" + url.port : ""}`;
20
+ }
21
+ catch (_a) {
22
+ return "";
23
+ }
24
+ };
25
+ return (react_1.default.createElement(antd_1.Drawer, { placement: "bottom", open: open, onClose: onClose, height: height, mask: true, maskClosable: true, styles: {
26
+ body: { padding: 0, display: "flex", flexDirection: "column" },
27
+ header: { display: "none" },
28
+ }, destroyOnClose: false },
29
+ react_1.default.createElement("div", { style: {
30
+ borderBottom: `1px solid ${token.colorBorder}`,
31
+ backgroundColor: token.colorBgContainer,
32
+ } },
33
+ react_1.default.createElement(antd_1.Tabs, { activeKey: activeTab, onChange: onTabChange, type: "card", tabBarStyle: {
34
+ margin: 0,
35
+ padding: "0 16px",
36
+ marginBottom: 0,
37
+ }, animated: {
38
+ inkBar: true,
39
+ tabPane: false,
40
+ }, items: [
41
+ { key: "system", label: "系统日志" },
42
+ { key: "user", label: "用户日志" },
43
+ ] })),
44
+ react_1.default.createElement("div", { style: {
45
+ flex: 1,
46
+ overflow: "auto",
47
+ padding: "16px",
48
+ } },
49
+ activeTab === "system" &&
50
+ (agentSimulatorInfo ? (react_1.default.createElement(SystemLogs_1.SystemLogs, { baseUrl: getBaseUrl(agentSimulatorInfo.agentServerUrl), agentName: ((_a = agentSimulatorInfo.agentInfo) === null || _a === void 0 ? void 0 : _a.agent_name) || "未获取到Agent名称", debugStatus: debugStatus, isOpen: open, logType: logger_service_1.LogType.ACCESS })) : (react_1.default.createElement("div", { style: {
51
+ display: "flex",
52
+ alignItems: "center",
53
+ justifyContent: "center",
54
+ height: "200px",
55
+ color: token.colorTextSecondary,
56
+ } }, "Agent \u670D\u52A1\u672A\u8FDE\u63A5\uFF0C\u65E0\u6CD5\u83B7\u53D6\u7CFB\u7EDF\u65E5\u5FD7"))),
57
+ activeTab === "user" &&
58
+ (agentSimulatorInfo ? (react_1.default.createElement(SystemLogs_1.SystemLogs, { baseUrl: getBaseUrl(agentSimulatorInfo.agentServerUrl), agentName: ((_b = agentSimulatorInfo.agentInfo) === null || _b === void 0 ? void 0 : _b.agent_name) || "未获取到Agent名称", debugStatus: debugStatus, isOpen: open, logType: logger_service_1.LogType.USERCODE })) : (react_1.default.createElement("div", { style: {
59
+ display: "flex",
60
+ alignItems: "center",
61
+ justifyContent: "center",
62
+ height: "200px",
63
+ color: token.colorTextSecondary,
64
+ } }, "Agent \u670D\u52A1\u672A\u8FDE\u63A5\uFF0C\u65E0\u6CD5\u83B7\u53D6\u7528\u6237\u65E5\u5FD7"))))));
65
+ };
66
+ exports.LogPanel = LogPanel;
@@ -0,0 +1,404 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.SystemLogs = exports.AgentType = void 0;
16
+ const antd_1 = require("antd");
17
+ const react_1 = __importDefault(require("react"));
18
+ const react_2 = require("react");
19
+ const logger_service_1 = require("../services/logger-service");
20
+ var AgentType;
21
+ (function (AgentType) {
22
+ AgentType["AI_SDK_REQUEST_START"] = "AI_SDK_REQUEST_START";
23
+ AgentType["AI_SDK_REQUEST_SUCCESS"] = "AI_SDK_REQUEST_SUCCESS";
24
+ AgentType["AI_SDK_REQUEST_ERROR"] = "AI_SDK_REQUEST_ERROR";
25
+ AgentType["AI_SDK_CREATE_MODEL"] = "AI_SDK_CREATE_MODEL";
26
+ AgentType["AI_SDK_CREATE_RECORD_PAIR"] = "AI_SDK_CREATE_RECORD_PAIR";
27
+ AgentType["AI_SDK_GET_HISTORY_MESSAGES"] = "AI_SDK_GET_HISTORY_MESSAGES";
28
+ AgentType["AI_SDK_GET_CONVERSATIONS"] = "AI_SDK_GET_CONVERSATIONS";
29
+ AgentType["SERVER_REQUEST_START"] = "SERVER_REQUEST_START";
30
+ AgentType["SERVER_REQUEST_END"] = "SERVER_REQUEST_END";
31
+ })(AgentType || (exports.AgentType = AgentType = {}));
32
+ const SystemLogs = ({ baseUrl, agentName, debugStatus, isOpen = false, logType = logger_service_1.LogType.ACCESS, }) => {
33
+ const { token } = antd_1.theme.useToken();
34
+ const [logs, setLogs] = (0, react_2.useState)([]);
35
+ const [expandedLogs, setExpandedLogs] = (0, react_2.useState)(new Set());
36
+ const loggerService = (0, react_2.useMemo)(() => new logger_service_1.LoggerService({ baseUrl }), [baseUrl]);
37
+ const highlightKeywords = (text) => {
38
+ const keywords = [
39
+ "getHistoryMessages",
40
+ "createRecordPair",
41
+ "getConversations",
42
+ "AI_SDK_REQUEST_START",
43
+ "AI_SDK_REQUEST_SUCCESS",
44
+ "AI_SDK_REQUEST_ERROR",
45
+ "AI_SDK_CREATE_MODEL",
46
+ "AI_SDK_CREATE_RECORD_PAIR",
47
+ "AI_SDK_GET_HISTORY_MESSAGES",
48
+ "AI_SDK_GET_CONVERSATIONS",
49
+ "SERVER_REQUEST_START",
50
+ "SERVER_REQUEST_END",
51
+ ];
52
+ const regex = new RegExp(`(${keywords.join("|")})`, "gi");
53
+ const parts = text.split(regex);
54
+ return parts.map((part, index) => {
55
+ if (keywords.some((keyword) => keyword.toLowerCase() === part.toLowerCase())) {
56
+ return (react_1.default.createElement("span", { key: index, style: {
57
+ fontWeight: "bold",
58
+ color: "#ffa940",
59
+ background: "rgba(255, 169, 64, 0.1)",
60
+ padding: "0 2px",
61
+ borderRadius: "2px",
62
+ } }, part));
63
+ }
64
+ return react_1.default.createElement("span", { key: index }, part);
65
+ });
66
+ };
67
+ const getStatusStyle = (status) => {
68
+ if (status >= 500) {
69
+ return { color: "#ff4d4f", fontWeight: "bold" };
70
+ }
71
+ else if (status >= 400) {
72
+ return { color: "#faad14", fontWeight: "bold" };
73
+ }
74
+ else if (status >= 300) {
75
+ return { color: "#1890ff" };
76
+ }
77
+ else if (status >= 200) {
78
+ return { color: "#52c41a", fontWeight: "bold" };
79
+ }
80
+ return {};
81
+ };
82
+ const formatLogEntry = (entry) => {
83
+ var _a;
84
+ const timestamp = new Date(entry["@timestamp"]).toLocaleTimeString();
85
+ const level = entry.level.toUpperCase();
86
+ try {
87
+ const detail = JSON.parse(entry.message);
88
+ let logMessage = `[${timestamp}] [${level}] ${(detail === null || detail === void 0 ? void 0 : detail.url) || (detail === null || detail === void 0 ? void 0 : detail.eventId) || "unknown"}`;
89
+ if (entry.source === "remote") {
90
+ if (detail.type === "FRAMEWORK_EVENT") {
91
+ const scene = detail.scene || "unknown";
92
+ const statusSpan = detail.status ? (react_1.default.createElement("span", { style: getStatusStyle(detail.status) },
93
+ " (",
94
+ detail.status,
95
+ ")")) : null;
96
+ logMessage = (react_1.default.createElement(react_2.Fragment, null,
97
+ `[${timestamp}] [${(_a = detail.eventId) === null || _a === void 0 ? void 0 : _a.slice(-8)}] [${level}] ${scene}`,
98
+ statusSpan));
99
+ }
100
+ else if (detail.type === "HTTP_ACCESS") {
101
+ const scene = detail.scene || "unknown";
102
+ const method = detail.method || "unknown";
103
+ const url = detail.url || "unknown";
104
+ const statusSpan = detail.status ? (react_1.default.createElement("span", { style: getStatusStyle(detail.status) },
105
+ " (",
106
+ detail.status,
107
+ ")")) : null;
108
+ const durationText = detail.duration ? ` - ${detail.duration}` : "";
109
+ logMessage = (react_1.default.createElement(react_2.Fragment, null,
110
+ `[${timestamp}] ${detail.eventId ? `[${detail.eventId.slice(-8)}]` : ""} [${level}] ${scene} ${method} ${url}`,
111
+ statusSpan,
112
+ durationText));
113
+ }
114
+ }
115
+ else {
116
+ logMessage = `[${timestamp}] ${detail.eventId ? `[${detail.eventId.slice(-8)}]` : ""} [${level}] ${(detail === null || detail === void 0 ? void 0 : detail.msg) || "unknown"}`;
117
+ }
118
+ return typeof logMessage === "string" ? highlightKeywords(logMessage) : logMessage;
119
+ }
120
+ catch (_b) {
121
+ return `[${timestamp}] [${level}] ${entry.message}`;
122
+ }
123
+ };
124
+ const formatDetailedInfo = (entry) => {
125
+ try {
126
+ const detail = JSON.parse(entry.message);
127
+ const details = [];
128
+ if (detail.type === "FRAMEWORK_EVENT" || detail.type === "HTTP_ACCESS") {
129
+ if (detail.scene)
130
+ details.push(react_1.default.createElement("div", { key: "scene" },
131
+ react_1.default.createElement("strong", null, "Scene:"),
132
+ " ",
133
+ detail.scene));
134
+ if (detail.method)
135
+ details.push(react_1.default.createElement("div", { key: "method" },
136
+ react_1.default.createElement("strong", null, "Method:"),
137
+ " ",
138
+ detail.method));
139
+ if (detail.url)
140
+ details.push(react_1.default.createElement("div", { key: "url" },
141
+ react_1.default.createElement("strong", null, "URL:"),
142
+ " ",
143
+ detail.url));
144
+ if (detail.modelName)
145
+ details.push(react_1.default.createElement("div", { key: "model" },
146
+ react_1.default.createElement("strong", null, "Model:"),
147
+ " ",
148
+ detail.modelName));
149
+ if (detail.status)
150
+ details.push(react_1.default.createElement("div", { key: "status" },
151
+ react_1.default.createElement("strong", null, "Status:"),
152
+ " ",
153
+ react_1.default.createElement("span", { style: getStatusStyle(detail.status) }, detail.status)));
154
+ if (detail.duration)
155
+ details.push(react_1.default.createElement("div", { key: "duration" },
156
+ react_1.default.createElement("strong", null, "Duration:"),
157
+ " ",
158
+ detail.duration));
159
+ if (detail.ip)
160
+ details.push(react_1.default.createElement("div", { key: "ip" },
161
+ react_1.default.createElement("strong", null, "IP:"),
162
+ " ",
163
+ detail.ip));
164
+ }
165
+ if (detail.error)
166
+ details.push(react_1.default.createElement("div", { key: "error" },
167
+ react_1.default.createElement("strong", null, "Error:"),
168
+ " ",
169
+ react_1.default.createElement("span", { style: { color: "#ff4d4f" } }, detail.error)));
170
+ if (detail.stack)
171
+ details.push(react_1.default.createElement("div", { key: "stack" },
172
+ react_1.default.createElement("strong", null, "Stack Trace:"),
173
+ react_1.default.createElement("pre", { style: { margin: 0, whiteSpace: "pre-wrap" } }, detail.stack)));
174
+ if (detail.headers)
175
+ details.push(react_1.default.createElement("div", { key: "headers" },
176
+ react_1.default.createElement("strong", null, "Headers:"),
177
+ react_1.default.createElement("pre", { style: { margin: 0 } }, JSON.stringify(detail.headers, null, 2))));
178
+ if (detail.data)
179
+ details.push(react_1.default.createElement("div", { key: "data" },
180
+ react_1.default.createElement("strong", null, "Data:"),
181
+ react_1.default.createElement("pre", { style: { margin: 0 } }, JSON.stringify(detail.data, null, 2))));
182
+ if (detail.eventId)
183
+ details.push(react_1.default.createElement("div", { key: "eventId" },
184
+ react_1.default.createElement("strong", null, "Event ID:"),
185
+ " ",
186
+ detail.eventId));
187
+ return details;
188
+ }
189
+ catch (_a) {
190
+ return [entry.message];
191
+ }
192
+ };
193
+ const hasDetailedInfo = (entry) => {
194
+ const detail = JSON.parse(entry.message);
195
+ return !!((detail.headers && Object.keys(detail.headers).length > 0) ||
196
+ detail.data ||
197
+ detail.error ||
198
+ detail.stack ||
199
+ (detail.eventId && detail.eventId !== "unknown"));
200
+ };
201
+ const toggleExpanded = (index) => {
202
+ const newExpanded = new Set(expandedLogs);
203
+ if (newExpanded.has(index)) {
204
+ newExpanded.delete(index);
205
+ }
206
+ else {
207
+ newExpanded.add(index);
208
+ }
209
+ setExpandedLogs(newExpanded);
210
+ };
211
+ const getLogStyle = (entry) => {
212
+ const baseStyle = {
213
+ margin: "2px 0",
214
+ padding: "2px 0",
215
+ };
216
+ switch (entry.level) {
217
+ case "error":
218
+ return Object.assign(Object.assign({}, baseStyle), { color: "#ff4d4f", fontWeight: "bold" });
219
+ case "warn":
220
+ return Object.assign(Object.assign({}, baseStyle), { color: "#faad14", fontWeight: "bold" });
221
+ case "info":
222
+ return Object.assign(Object.assign({}, baseStyle), { color: "#1890ff" });
223
+ case "debug":
224
+ return Object.assign(Object.assign({}, baseStyle), { color: "#8c8c8c" });
225
+ default:
226
+ return Object.assign(Object.assign({}, baseStyle), { color: "#8c8c8c" });
227
+ }
228
+ };
229
+ const fetchLogs = () => __awaiter(void 0, void 0, void 0, function* () {
230
+ if (debugStatus !== "normal") {
231
+ return;
232
+ }
233
+ try {
234
+ const response = yield loggerService.getLogs(logType);
235
+ if (response.success && response.data.length > 0) {
236
+ setLogs((prevLogs) => {
237
+ const localLogs = prevLogs.filter((log) => log.source === "local");
238
+ const prevRemoteLogs = prevLogs.filter((log) => log.source === "remote");
239
+ const newRemoteLogs = response.data.map((log) => (Object.assign(Object.assign({}, log), { source: "remote" })));
240
+ const allRemoteLogs = [...prevRemoteLogs, ...newRemoteLogs];
241
+ const uniqueRemoteLogs = allRemoteLogs.reduce((acc, current) => {
242
+ const existingLog = acc.find((log) => log.id === current.id);
243
+ if (!existingLog) {
244
+ acc.push(current);
245
+ }
246
+ return acc;
247
+ }, []);
248
+ return [...localLogs, ...uniqueRemoteLogs];
249
+ });
250
+ }
251
+ }
252
+ catch (error) {
253
+ console.error("Failed to fetch logs:", error);
254
+ const errorLog = {
255
+ "@timestamp": new Date().toISOString(),
256
+ level: "error",
257
+ eventId: "",
258
+ message: JSON.stringify({ msg: `日志获取失败: ${error.message}` }),
259
+ source: "local",
260
+ };
261
+ setLogs((prevLogs) => [...prevLogs, errorLog]);
262
+ }
263
+ });
264
+ (0, react_2.useEffect)(() => {
265
+ const initialLogs = [
266
+ logType === logger_service_1.LogType.USERCODE
267
+ ? {
268
+ "@timestamp": new Date().toISOString(),
269
+ level: "system",
270
+ eventId: "",
271
+ message: JSON.stringify({ msg: `👤 用户日志拉取成功 ${new Date().toLocaleString()}` }),
272
+ source: "local",
273
+ }
274
+ : {
275
+ "@timestamp": new Date().toISOString(),
276
+ level: "system",
277
+ eventId: "",
278
+ message: JSON.stringify({ msg: `🖥️ 系统日志拉取成功 ${new Date().toLocaleString()}` }),
279
+ source: "local",
280
+ },
281
+ {
282
+ "@timestamp": new Date().toISOString(),
283
+ level: "system",
284
+ eventId: "",
285
+ message: JSON.stringify({ msg: `Agent服务地址: ${baseUrl}` }),
286
+ source: "local",
287
+ },
288
+ {
289
+ "@timestamp": new Date().toISOString(),
290
+ level: "system",
291
+ eventId: "",
292
+ message: JSON.stringify({ msg: `Agent '${agentName}' 已加载` }),
293
+ source: "local",
294
+ },
295
+ ];
296
+ setLogs(initialLogs);
297
+ fetchLogs();
298
+ const intervalId = setInterval(fetchLogs, 5000);
299
+ return () => {
300
+ clearInterval(intervalId);
301
+ };
302
+ }, [baseUrl, agentName, loggerService, debugStatus]);
303
+ (0, react_2.useEffect)(() => {
304
+ if (isOpen) {
305
+ fetchLogs();
306
+ }
307
+ }, [isOpen]);
308
+ (0, react_2.useEffect)(() => {
309
+ const statusLog = {
310
+ "@timestamp": new Date().toISOString(),
311
+ level: debugStatus === "normal" ? "system" : "warn",
312
+ eventId: "",
313
+ message: JSON.stringify({ msg: `调试状态变更: ${debugStatus}` }),
314
+ source: "local",
315
+ };
316
+ setLogs((prevLogs) => [...prevLogs, statusLog]);
317
+ }, [debugStatus]);
318
+ const formatUserLogDetailedInfo = (entry) => {
319
+ try {
320
+ const detail = JSON.parse(entry.message);
321
+ const details = [];
322
+ if (detail.eventId)
323
+ details.push(react_1.default.createElement("div", { key: "eventId" },
324
+ react_1.default.createElement("strong", null, "Event ID:"),
325
+ " ",
326
+ detail.eventId));
327
+ if (detail.requestId)
328
+ details.push(react_1.default.createElement("div", { key: "requestId" },
329
+ react_1.default.createElement("strong", null, "Request ID:"),
330
+ " ",
331
+ detail.requestId));
332
+ if (detail.scene)
333
+ details.push(react_1.default.createElement("div", { key: "scene" },
334
+ react_1.default.createElement("strong", null, "Scene:"),
335
+ " ",
336
+ detail.scene));
337
+ if (Array.isArray(detail.logs)) {
338
+ details.push(react_1.default.createElement("div", { key: "logs-title" },
339
+ react_1.default.createElement("strong", null, "Logs:")));
340
+ detail.logs.forEach((log, idx) => {
341
+ var _a;
342
+ details.push(react_1.default.createElement("div", { key: `log-${idx}`, style: { marginLeft: "10px" } },
343
+ react_1.default.createElement("div", null, `[${((_a = log.level) === null || _a === void 0 ? void 0 : _a.toUpperCase()) || "LOG"}] ${log["@timestamp"] || ""}`),
344
+ log.caller && react_1.default.createElement("div", null,
345
+ "\u00A0\u00A0Caller: ",
346
+ log.caller),
347
+ log.content && react_1.default.createElement("div", null,
348
+ "\u00A0\u00A0Content: ",
349
+ log.content)));
350
+ });
351
+ }
352
+ return details;
353
+ }
354
+ catch (e) {
355
+ return [entry.message];
356
+ }
357
+ };
358
+ return (react_1.default.createElement("div", { className: "system-logs", style: { height: "100%", backgroundColor: token.colorBgElevated } },
359
+ react_1.default.createElement("div", { className: "logs-content", style: { height: "100%", margin: 0 } },
360
+ debugStatus !== "normal" && (react_1.default.createElement("div", { style: {
361
+ background: "rgba(250, 173, 20, 0.1)",
362
+ color: "#faad14",
363
+ padding: "8px 16px",
364
+ borderBottom: "1px solid #333",
365
+ fontSize: "13px",
366
+ } }, "\u26A0\uFE0F \u8C03\u8BD5\u72B6\u6001\u5F02\u5E38\uFF0C\u65E5\u5FD7\u83B7\u53D6\u5DF2\u6682\u505C")),
367
+ react_1.default.createElement("div", { style: {
368
+ color: "#d4d4d4",
369
+ fontSize: 15,
370
+ margin: 0,
371
+ padding: 16,
372
+ height: debugStatus !== "normal" ? "calc(100% - 40px)" : "100%",
373
+ boxSizing: "border-box",
374
+ fontFamily: "Menlo, Monaco, Consolas, monospace",
375
+ overflow: "auto",
376
+ } }, logs.map((entry, index) => {
377
+ const isExpanded = expandedLogs.has(index);
378
+ const hasDetails = hasDetailedInfo(entry);
379
+ return (react_1.default.createElement("div", { key: index, style: { marginBottom: "4px" } },
380
+ react_1.default.createElement("div", { style: Object.assign(Object.assign({}, getLogStyle(entry)), { display: "flex", alignItems: "center", cursor: hasDetails ? "pointer" : "default" }), onClick: () => hasDetails && toggleExpanded(index) },
381
+ hasDetails && (react_1.default.createElement("span", { style: {
382
+ marginRight: "6px",
383
+ color: "#8c8c8c",
384
+ fontSize: "12px",
385
+ transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)",
386
+ transition: "transform 0.2s ease",
387
+ userSelect: "none",
388
+ } }, "\u25B6")),
389
+ react_1.default.createElement("div", { style: { flex: 1 } }, formatLogEntry(entry))),
390
+ hasDetails && isExpanded && (react_1.default.createElement("div", { style: {
391
+ marginLeft: hasDetails ? "18px" : "0",
392
+ marginTop: "4px",
393
+ padding: "8px 12px",
394
+ background: "rgba(255, 255, 255, 0.05)",
395
+ borderLeft: "3px solid #1890ff",
396
+ borderRadius: "0 4px 4px 0",
397
+ fontSize: "13px",
398
+ color: "#a3a3a3",
399
+ whiteSpace: "pre-wrap",
400
+ wordBreak: "break-all",
401
+ } }, logType === logger_service_1.LogType.USERCODE ? formatUserLogDetailedInfo(entry) : formatDetailedInfo(entry)))));
402
+ })))));
403
+ };
404
+ exports.SystemLogs = SystemLogs;