@ww-ai-lab/openclaw-office 2026.3.8 → 2026.3.18

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.
package/README.md CHANGED
@@ -33,19 +33,7 @@
33
33
 
34
34
  #### Demo Video
35
35
 
36
- <p align="center">
37
- <a href="https://www.youtube.com/watch?v=ACXSFTSlVLY">
38
- <img src="https://img.youtube.com/vi/ACXSFTSlVLY/maxresdefault.jpg" alt="OpenClaw Office Demo Video" width="100%" />
39
- </a>
40
- </p>
41
-
42
- <p align="center">
43
- ▶ Click the preview image above to play on YouTube
44
- </p>
45
-
46
- > GitHub sanitizes repository README content and does not allow embedded YouTube/iframe players, so the most reliable “preview + click-to-play” pattern is a linked video thumbnail.
47
-
48
- [Watch on YouTube](https://www.youtube.com/watch?v=ACXSFTSlVLY)
36
+ https://github.com/WW-AI-Lab/openclaw-office/raw/main/assets/iShot_2026-03-02_21.33.38.mp4
49
37
 
50
38
  ### Console
51
39
 
@@ -136,15 +124,6 @@ OPENCLAW_GATEWAY_TOKEN=<token> openclaw-office
136
124
  | `--host <host>` | Bind address | `0.0.0.0` |
137
125
  | `-h, --help` | Show help | — |
138
126
 
139
- The production server exposes Office publicly and proxies browser WebSocket traffic through the same origin path `/gateway-ws`. Its upstream Gateway address is resolved in this order:
140
-
141
- 1. `--gateway`
142
- 2. `OPENCLAW_GATEWAY_URL`
143
- 3. persisted Office config at `~/.openclaw/openclaw-office.json`
144
- 4. default `ws://localhost:18789`
145
-
146
- When `--gateway` or `OPENCLAW_GATEWAY_URL` is provided, Office automatically persists the value to `~/.openclaw/openclaw-office.json` for future restarts.
147
-
148
127
  > **Note:** This serves the pre-built production bundle. For development with hot reload, see [Development](#development) below.
149
128
 
150
129
  ---
@@ -159,10 +138,11 @@ pnpm install
159
138
 
160
139
  ### 2. Configure Gateway Connection
161
140
 
162
- Create a `.env.local` file (gitignored) with your Gateway token. `VITE_GATEWAY_URL` is optional and only needed if you want dev mode to proxy to a Gateway address other than the default `ws://localhost:18789`.
141
+ Create a `.env.local` file (gitignored) with your Gateway connection details:
163
142
 
164
143
  ```bash
165
144
  cat > .env.local << 'EOF'
145
+ VITE_GATEWAY_URL=ws://localhost:18789
166
146
  VITE_GATEWAY_TOKEN=<your-gateway-token>
167
147
  EOF
168
148
  ```
@@ -173,17 +153,20 @@ Get your Gateway token:
173
153
  openclaw config get gateway.auth.token
174
154
  ```
175
155
 
176
- ### 3. Enable Device Auth Bypass (Required)
156
+ ### 3. Browser Device Identity
157
+
158
+ OpenClaw Office now performs the same browser-side device identity signing flow as the built-in OpenClaw Control UI. In the common cases below, you should not need `gateway.controlUi.dangerouslyDisableDeviceAuth`:
177
159
 
178
- OpenClaw Office is a pure web application and cannot provide Ed25519 device identity signatures that Gateway 2026.2.15+ requires for operator scopes. You must configure the Gateway to bypass this requirement:
160
+ - OpenClaw Office opened on `http://localhost:*` or `http://127.0.0.1:*`
161
+ - OpenClaw Office served over HTTPS
162
+
163
+ If you open OpenClaw Office from a remote machine over plain HTTP, the browser may not expose `crypto.subtle`, so Gateway can still reject the connection. In that case, prefer HTTPS first. Only use the dangerous bypass as a temporary last resort:
179
164
 
180
165
  ```bash
181
166
  openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true
182
167
  ```
183
168
 
184
- **Restart the Gateway** after this configuration change.
185
-
186
- > **Security Note:** This bypass is intended for local development. In production, use a reverse proxy or other secure authentication mechanism.
169
+ If you change Gateway auth policy, restart Gateway afterward.
187
170
 
188
171
  ### 4. Start the Gateway
189
172
 
@@ -199,13 +182,14 @@ Ensure the OpenClaw Gateway is running on the configured address (default `local
199
182
  pnpm dev
200
183
  ```
201
184
 
202
- Open `http://localhost:5180` in your browser. In dev mode, the frontend always connects to the same-origin path `/gateway-ws`, and Vite proxies that path to the configured Gateway upstream (default `ws://localhost:18789`). `VITE_GATEWAY_URL` configures the proxy upstream and is not used as a browser-direct websocket URL.
185
+ Open `http://localhost:5180` in your browser.
203
186
 
204
187
  ### Environment Variables
205
188
 
206
189
  | Variable | Required | Default | Description |
207
190
  | -------------------- | ------------------------------------- | ---------------------- | ------------------------------------ |
208
- | `VITE_GATEWAY_URL` | No | `ws://localhost:18789` | Optional override for the dev proxy upstream Gateway address |
191
+ | `VITE_GATEWAY_URL` | No | `ws://localhost:18789` | Gateway WebSocket address |
192
+ | `VITE_GATEWAY_WS_PATH` | No | `/gateway-ws` | Browser-side reverse proxy WS path |
209
193
  | `VITE_GATEWAY_TOKEN` | Yes (when connecting to real Gateway) | — | Gateway auth token |
210
194
  | `VITE_MOCK` | No | `false` | Enable mock mode (no Gateway needed) |
211
195
 
package/README.zh.md CHANGED
@@ -33,19 +33,7 @@
33
33
 
34
34
  #### 演示视频
35
35
 
36
- <p align="center">
37
- <a href="https://www.youtube.com/watch?v=ACXSFTSlVLY">
38
- <img src="https://img.youtube.com/vi/ACXSFTSlVLY/maxresdefault.jpg" alt="OpenClaw Office 演示视频" width="100%" />
39
- </a>
40
- </p>
41
-
42
- <p align="center">
43
- ▶ 点击上方预览图即可跳转播放
44
- </p>
45
-
46
- > GitHub 会清洗仓库 README 内容,不允许真正内嵌 YouTube / iframe 播放器,所以最稳妥的实现方式就是“预览图 + 点击播放跳转”。
47
-
48
- [在 YouTube 观看](https://www.youtube.com/watch?v=ACXSFTSlVLY)
36
+ https://github.com/WW-AI-Lab/openclaw-office/raw/main/assets/iShot_2026-03-02_21.33.38.mp4
49
37
 
50
38
  ### 控制台
51
39
 
@@ -136,15 +124,6 @@ OPENCLAW_GATEWAY_TOKEN=<token> openclaw-office
136
124
  | `--host <host>` | 绑定地址 | `0.0.0.0` |
137
125
  | `-h, --help` | 显示帮助 | — |
138
126
 
139
- 生产服务端会对外暴露 Office,并通过同源路径 `/gateway-ws` 代理浏览器的 WebSocket 流量。其上游 Gateway 地址按以下优先级解析:
140
-
141
- 1. `--gateway`
142
- 2. `OPENCLAW_GATEWAY_URL`
143
- 3. Office 持久化配置 `~/.openclaw/openclaw-office.json`
144
- 4. 默认值 `ws://localhost:18789`
145
-
146
- 当提供 `--gateway` 或 `OPENCLAW_GATEWAY_URL` 时,Office 会自动将该值持久化到 `~/.openclaw/openclaw-office.json`,供后续重启复用。
147
-
148
127
  > **说明:** 此方式运行的是预构建的生产版本。如需热重载开发,请参见下方 [开发](#开发) 部分。
149
128
 
150
129
  ---
@@ -159,10 +138,11 @@ pnpm install
159
138
 
160
139
  ### 2. 配置 Gateway 连接
161
140
 
162
- 创建 `.env.local` 文件(已在 `.gitignore` 中,不会被提交),填入 Gateway token。`VITE_GATEWAY_URL` 是可选项,仅在你希望 dev 模式代理到非默认 `ws://localhost:18789` 地址时才需要填写:
141
+ 创建 `.env.local` 文件(已在 `.gitignore` 中,不会被提交),填入 Gateway 连接信息:
163
142
 
164
143
  ```bash
165
144
  cat > .env.local << 'EOF'
145
+ VITE_GATEWAY_URL=ws://localhost:18789
166
146
  VITE_GATEWAY_TOKEN=<你的 gateway token>
167
147
  EOF
168
148
  ```
@@ -173,17 +153,20 @@ EOF
173
153
  openclaw config get gateway.auth.token
174
154
  ```
175
155
 
176
- ### 3. 启用 Device Auth Bypass(必须)
156
+ ### 3. 浏览器 Device Identity
157
+
158
+ OpenClaw Office 现在会像 OpenClaw 内置 Control UI 一样,在浏览器侧完成 device identity 签名。以下常见场景通常**不再需要** `gateway.controlUi.dangerouslyDisableDeviceAuth`:
177
159
 
178
- OpenClaw Office 是纯 Web 应用,无法提供 Gateway 2026.2.15+ 要求的 Ed25519 device identity 签名。需要配置 Gateway 绕过此要求:
160
+ - `http://localhost:*` `http://127.0.0.1:*` 打开 OpenClaw Office
161
+ - 通过 HTTPS 访问 OpenClaw Office
162
+
163
+ 如果你是从远程机器通过纯 HTTP 访问,浏览器可能拿不到 `crypto.subtle`,Gateway 仍可能拒绝连接。此时应优先改用 HTTPS;只有在临时调试且确认风险的情况下,才建议使用危险 bypass:
179
164
 
180
165
  ```bash
181
166
  openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true
182
167
  ```
183
168
 
184
- 配置后需**重启 Gateway**。
185
-
186
- > **安全提示:** 此 bypass 配置仅建议在本地开发环境使用。生产环境应通过反向代理或其他安全机制处理认证。
169
+ 如果修改了 Gateway 认证策略,之后需要**重启 Gateway**。
187
170
 
188
171
  ### 4. 启动 Gateway
189
172
 
@@ -199,13 +182,14 @@ openclaw config set gateway.controlUi.dangerouslyDisableDeviceAuth true
199
182
  pnpm dev
200
183
  ```
201
184
 
202
- 在浏览器中打开 `http://localhost:5180`。在 dev 模式下,前端始终连接同源路径 `/gateway-ws`,再由 Vite 将该路径代理到配置的 Gateway 上游地址(默认 `ws://localhost:18789`)。`VITE_GATEWAY_URL` 仅用于配置代理上游,不会作为浏览器直连 WebSocket 地址使用。
185
+ 在浏览器中打开 `http://localhost:5180`。
203
186
 
204
187
  ### 环境变量
205
188
 
206
189
  | 变量 | 必须 | 默认值 | 说明 |
207
190
  | -------------------- | ------------------------- | ---------------------- | -------------------------------- |
208
- | `VITE_GATEWAY_URL` | 否 | `ws://localhost:18789` | 可选:覆盖 dev 代理的上游 Gateway 地址 |
191
+ | `VITE_GATEWAY_URL` | 否 | `ws://localhost:18789` | Gateway WebSocket 地址 |
192
+ | `VITE_GATEWAY_WS_PATH` | 否 | `/gateway-ws` | 浏览器侧反向代理 WS 路径 |
209
193
  | `VITE_GATEWAY_TOKEN` | 是(连接真实 Gateway 时) | — | Gateway 认证 token |
210
194
  | `VITE_MOCK` | 否 | `false` | 启用 Mock 模式(不需要 Gateway) |
211
195
 
@@ -1,31 +1,357 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import { createServer, request as httpRequest } from "node:http";
4
+ import { request as httpsRequest } from "node:https";
5
+ import { readFileSync } from "node:fs";
6
+ import { readFile, access } from "node:fs/promises";
7
+ import { resolve, join, extname } from "node:path";
3
8
  import { fileURLToPath } from "node:url";
4
- import { resolve } from "node:path";
5
- import {
6
- printHelp,
7
- resolveConfig,
8
- parseArgs,
9
- writePersistedOfficeConfig,
10
- } from "./openclaw-office-config.js";
11
- import { createOfficeServer, formatStartupSummary } from "./openclaw-office-server.js";
9
+ import { networkInterfaces, homedir } from "node:os";
12
10
 
13
11
  const __dirname = fileURLToPath(new URL(".", import.meta.url));
14
12
  const distDir = resolve(__dirname, "..", "dist");
15
13
 
16
- const args = parseArgs();
17
- if (args.help) {
18
- printHelp();
19
- process.exit(0);
14
+ const MIME_TYPES = {
15
+ ".html": "text/html; charset=utf-8",
16
+ ".js": "application/javascript; charset=utf-8",
17
+ ".css": "text/css; charset=utf-8",
18
+ ".json": "application/json; charset=utf-8",
19
+ ".svg": "image/svg+xml",
20
+ ".png": "image/png",
21
+ ".jpg": "image/jpeg",
22
+ ".jpeg": "image/jpeg",
23
+ ".gif": "image/gif",
24
+ ".ico": "image/x-icon",
25
+ ".woff": "font/woff",
26
+ ".woff2": "font/woff2",
27
+ ".ttf": "font/ttf",
28
+ ".webp": "image/webp",
29
+ ".glb": "model/gltf-binary",
30
+ ".gltf": "model/gltf+json",
31
+ };
32
+
33
+ // --- Argument parsing ---
34
+
35
+ function parseArgs() {
36
+ const args = process.argv.slice(2);
37
+ const result = { token: "", gatewayUrl: "", port: 0, host: "" };
38
+ for (let i = 0; i < args.length; i++) {
39
+ const arg = args[i];
40
+ const next = args[i + 1];
41
+ if ((arg === "--token" || arg === "-t") && next) {
42
+ result.token = next; i++;
43
+ } else if ((arg === "--gateway" || arg === "-g") && next) {
44
+ result.gatewayUrl = next; i++;
45
+ } else if ((arg === "--port" || arg === "-p") && next) {
46
+ result.port = parseInt(next, 10); i++;
47
+ } else if (arg === "--host" && next) {
48
+ result.host = next; i++;
49
+ } else if (arg === "--help" || arg === "-h") {
50
+ printHelp();
51
+ process.exit(0);
52
+ }
53
+ }
54
+ return result;
55
+ }
56
+
57
+ function printHelp() {
58
+ console.log(`
59
+ \x1b[36mOpenClaw Office\x1b[0m — Visual monitoring frontend for OpenClaw
60
+
61
+ \x1b[1mUsage:\x1b[0m
62
+ openclaw-office [options]
63
+
64
+ \x1b[1mOptions:\x1b[0m
65
+ -t, --token <token> Gateway auth token
66
+ -g, --gateway <url> Gateway WebSocket URL (default: ws://localhost:18789)
67
+ -p, --port <port> Server port (default: 5180, or PORT env)
68
+ --host <host> Bind address (default: 0.0.0.0)
69
+ -h, --help Show this help
70
+
71
+ \x1b[1mToken auto-detection:\x1b[0m
72
+ The token is resolved in this order:
73
+ 1. --token flag
74
+ 2. OPENCLAW_GATEWAY_TOKEN environment variable
75
+ 3. Auto-read from ~/.openclaw/openclaw.json
76
+
77
+ \x1b[1mExamples:\x1b[0m
78
+ openclaw-office
79
+ openclaw-office --token my-secret-token
80
+ openclaw-office --gateway ws://192.168.1.100:18789
81
+ PORT=3000 openclaw-office
82
+ `);
83
+ }
84
+
85
+ // --- Token auto-detection from openclaw config file ---
86
+
87
+ function readTokenFromConfig() {
88
+ const candidates = [
89
+ join(homedir(), ".openclaw", "openclaw.json"),
90
+ join(homedir(), ".clawdbot", "clawdbot.json"),
91
+ ];
92
+ for (const filePath of candidates) {
93
+ try {
94
+ const raw = readFileSync(filePath, "utf-8");
95
+ const config = JSON.parse(raw);
96
+ const token = config?.gateway?.auth?.token;
97
+ if (token && typeof token === "string" && token.length > 0) {
98
+ return { token, source: filePath };
99
+ }
100
+ } catch {
101
+ // file not found or parse error
102
+ }
103
+ }
104
+ return null;
105
+ }
106
+
107
+ // --- Config resolution ---
108
+
109
+ function resolveConfig() {
110
+ const args = parseArgs();
111
+
112
+ let token = "";
113
+ let tokenSource = "";
114
+
115
+ if (args.token) {
116
+ token = args.token;
117
+ tokenSource = "command line --token";
118
+ } else if (process.env.OPENCLAW_GATEWAY_TOKEN) {
119
+ token = process.env.OPENCLAW_GATEWAY_TOKEN;
120
+ tokenSource = "OPENCLAW_GATEWAY_TOKEN env";
121
+ } else {
122
+ const fromFile = readTokenFromConfig();
123
+ if (fromFile) {
124
+ token = fromFile.token;
125
+ tokenSource = fromFile.source;
126
+ }
127
+ }
128
+
129
+ const gatewayUrl = args.gatewayUrl || process.env.OPENCLAW_GATEWAY_URL || "ws://localhost:18789";
130
+ const port = args.port || parseInt(process.env.PORT || "5180", 10);
131
+ const host = args.host || process.env.HOST || "0.0.0.0";
132
+
133
+ return { token, tokenSource, gatewayUrl, port, host };
20
134
  }
21
135
 
136
+ // --- HTTP Server ---
137
+
22
138
  const config = resolveConfig();
23
- if (config.shouldPersistGatewayUrl) {
24
- writePersistedOfficeConfig(config.gatewayUrl, config.officeConfigPath);
139
+
140
+ const runtimeConfig = JSON.stringify({
141
+ gatewayUrl: config.gatewayUrl,
142
+ gatewayToken: config.token,
143
+ gatewayWsPath: "/gateway-ws",
144
+ });
145
+ const configScript = `<script>window.__OPENCLAW_CONFIG__=${runtimeConfig};</script>`;
146
+ const gatewayWsPrefixes = new Set(["/gateway-ws", "/api/gateway/ws"]);
147
+
148
+ async function tryReadFile(filePath) {
149
+ try {
150
+ await access(filePath);
151
+ return await readFile(filePath);
152
+ } catch {
153
+ return null;
154
+ }
155
+ }
156
+
157
+ let indexHtmlCache = null;
158
+
159
+ async function getIndexHtml() {
160
+ if (indexHtmlCache) return indexHtmlCache;
161
+ const raw = await readFile(join(distDir, "index.html"), "utf-8");
162
+ indexHtmlCache = raw.replace("</head>", `${configScript}\n</head>`);
163
+ return indexHtmlCache;
25
164
  }
26
165
 
27
- const { server } = createOfficeServer({ config, distDir });
166
+ function toHttpUrl(rawUrl) {
167
+ const url = new URL(rawUrl);
168
+ if (url.protocol === "ws:") {
169
+ url.protocol = "http:";
170
+ } else if (url.protocol === "wss:") {
171
+ url.protocol = "https:";
172
+ }
173
+ return url;
174
+ }
175
+
176
+ function serializeUpgradeResponse(res) {
177
+ const lines = [`HTTP/1.1 ${res.statusCode} ${res.statusMessage}`];
178
+ for (const [key, value] of Object.entries(res.headers)) {
179
+ if (Array.isArray(value)) {
180
+ for (const item of value) {
181
+ lines.push(`${key}: ${item}`);
182
+ }
183
+ } else if (typeof value !== "undefined") {
184
+ lines.push(`${key}: ${value}`);
185
+ }
186
+ }
187
+ lines.push("\r\n");
188
+ return lines.join("\r\n");
189
+ }
190
+
191
+ function writeSocketError(socket, statusCode, message) {
192
+ if (socket.destroyed) {
193
+ return;
194
+ }
195
+ socket.write(
196
+ `HTTP/1.1 ${statusCode} ${message}\r\nConnection: close\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: ${Buffer.byteLength(message)}\r\n\r\n${message}`,
197
+ );
198
+ socket.destroy();
199
+ }
200
+
201
+ function proxyWsUpgrade(req, downstreamSocket, downstreamHead) {
202
+ const upstreamUrl = toHttpUrl(config.gatewayUrl);
203
+ const headers = {
204
+ host: upstreamUrl.host,
205
+ connection: "Upgrade",
206
+ upgrade: "websocket",
207
+ origin: upstreamUrl.origin,
208
+ "sec-websocket-version": req.headers["sec-websocket-version"] || "13",
209
+ "sec-websocket-key": req.headers["sec-websocket-key"],
210
+ };
211
+ if (req.headers["sec-websocket-protocol"]) {
212
+ headers["sec-websocket-protocol"] = req.headers["sec-websocket-protocol"];
213
+ }
214
+
215
+ const doRequest = upstreamUrl.protocol === "https:" ? httpsRequest : httpRequest;
216
+ const upstreamReq = doRequest(upstreamUrl, { method: "GET", headers });
217
+ let settled = false;
218
+ let upgraded = false;
219
+
220
+ const fail = (statusCode, message) => {
221
+ if (settled) {
222
+ return;
223
+ }
224
+ settled = true;
225
+ writeSocketError(downstreamSocket, statusCode, message);
226
+ };
227
+
228
+ upstreamReq.on("upgrade", (upstreamRes, upstreamSocket, upstreamHead) => {
229
+ if (settled) {
230
+ upstreamSocket.destroy();
231
+ return;
232
+ }
233
+ settled = true;
234
+ upgraded = true;
235
+
236
+ if (downstreamSocket.destroyed) {
237
+ upstreamSocket.destroy();
238
+ return;
239
+ }
240
+
241
+ downstreamSocket.write(serializeUpgradeResponse(upstreamRes));
242
+
243
+ if (downstreamHead.length > 0) {
244
+ upstreamSocket.write(downstreamHead);
245
+ }
246
+ if (upstreamHead.length > 0) {
247
+ downstreamSocket.write(upstreamHead);
248
+ }
249
+
250
+ downstreamSocket.pipe(upstreamSocket, { end: false });
251
+ upstreamSocket.pipe(downstreamSocket, { end: false });
252
+
253
+ const closeBoth = () => {
254
+ if (!downstreamSocket.destroyed) {
255
+ downstreamSocket.destroy();
256
+ }
257
+ if (!upstreamSocket.destroyed) {
258
+ upstreamSocket.destroy();
259
+ }
260
+ };
261
+
262
+ downstreamSocket.on("error", closeBoth);
263
+ upstreamSocket.on("error", closeBoth);
264
+ downstreamSocket.on("close", closeBoth);
265
+ upstreamSocket.on("close", closeBoth);
266
+ });
267
+
268
+ upstreamReq.on("response", (upstreamRes) => {
269
+ upstreamRes.resume();
270
+ fail(upstreamRes.statusCode || 502, upstreamRes.statusMessage || "Bad Gateway");
271
+ });
272
+ upstreamReq.on("error", () => {
273
+ fail(502, "Bad Gateway");
274
+ });
275
+ downstreamSocket.on("error", () => {
276
+ if (!upgraded) {
277
+ upstreamReq.destroy();
278
+ }
279
+ });
280
+ downstreamSocket.on("close", () => {
281
+ if (!upgraded) {
282
+ upstreamReq.destroy();
283
+ }
284
+ });
285
+
286
+ upstreamReq.end();
287
+ }
288
+
289
+ const server = createServer(async (req, res) => {
290
+ const url = new URL(req.url || "/", `http://${req.headers.host}`);
291
+ const pathname = decodeURIComponent(url.pathname);
292
+
293
+ // Serve injected index.html for root and SPA routes
294
+ if (pathname === "/" || pathname === "/index.html") {
295
+ const html = await getIndexHtml();
296
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
297
+ res.end(html);
298
+ return;
299
+ }
300
+
301
+ // Try serving static file
302
+ const filePath = join(distDir, pathname);
303
+ const content = await tryReadFile(filePath);
304
+
305
+ if (content) {
306
+ const ext = extname(filePath).toLowerCase();
307
+ const mime = MIME_TYPES[ext] || "application/octet-stream";
308
+ res.writeHead(200, { "Content-Type": mime });
309
+ res.end(content);
310
+ return;
311
+ }
312
+
313
+ // SPA fallback for client-side routes
314
+ const html = await getIndexHtml();
315
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
316
+ res.end(html);
317
+ });
318
+
319
+ server.on("upgrade", (req, socket, head) => {
320
+ const pathname = new URL(req.url || "/", "http://localhost").pathname;
321
+ if (!gatewayWsPrefixes.has(pathname)) {
322
+ writeSocketError(socket, 404, "Not Found");
323
+ return;
324
+ }
325
+ proxyWsUpgrade(req, socket, head);
326
+ });
28
327
 
29
328
  server.listen(config.port, config.host, () => {
30
- console.log(formatStartupSummary(config));
329
+ console.log();
330
+ console.log(" \x1b[36m\u{1F3E2} OpenClaw Office\x1b[0m");
331
+ console.log();
332
+ console.log(` \x1b[32m\u{27A1}\x1b[0m Local: \x1b[36mhttp://localhost:${config.port}\x1b[0m`);
333
+ if (config.host === "0.0.0.0") {
334
+ const nets = networkInterfaces();
335
+ for (const name of Object.keys(nets)) {
336
+ for (const net of nets[name] || []) {
337
+ if (net.family === "IPv4" && !net.internal) {
338
+ console.log(` \x1b[32m\u{27A1}\x1b[0m Network: \x1b[36mhttp://${net.address}:${config.port}\x1b[0m`);
339
+ }
340
+ }
341
+ }
342
+ }
343
+ console.log();
344
+ console.log(` \x1b[32m\u{27A1}\x1b[0m Gateway: \x1b[33m${config.gatewayUrl}\x1b[0m`);
345
+ if (config.token) {
346
+ console.log(` \x1b[32m\u{2713}\x1b[0m Token: \x1b[32mloaded\x1b[0m \x1b[90m(from ${config.tokenSource})\x1b[0m`);
347
+ } else {
348
+ console.log(` \x1b[33m\u{26A0}\x1b[0m Token: \x1b[33mnot found\x1b[0m`);
349
+ console.log();
350
+ console.log(" \x1b[90mTo connect to Gateway, provide a token:\x1b[0m");
351
+ console.log(" \x1b[90m openclaw-office --token <your-token>\x1b[0m");
352
+ console.log(" \x1b[90m or install openclaw CLI and the token will be auto-detected\x1b[0m");
353
+ }
354
+ console.log();
355
+ console.log(" Press \x1b[1mCtrl+C\x1b[0m to stop");
356
+ console.log();
31
357
  });
@@ -1 +1 @@
1
- import{u as H,h as v,d as b,j as r}from"./index-QZYyP0qG.js";const N=10,d=24,x=10,u=14,w=[{max:0,color:"#f3f4f6"},{max:5,color:"#bbf7d0"},{max:10,color:"#4ade80"},{max:1/0,color:"#16a34a"}],D=[{max:0,color:"#1e293b"},{max:5,color:"#14532d"},{max:10,color:"#166534"},{max:1/0,color:"#22c55e"}];function E(c,i){const l=i?D:w;for(const s of l)if(c<=s.max)return s.color;return l[l.length-1].color}function M(c){const i=Date.now(),l=3600*1e3,s=new Map;for(const t of c){const a=t.timestamp,n=(i-a)/l;if(n<0||n>=d)continue;const m=23-Math.min(23,Math.floor(n));let o=s.get(t.agentId);o||(o={name:t.agentName,counts:Array.from({length:d},()=>0)},s.set(t.agentId,o)),m>=0&&m<d&&o.counts[m]++}return Array.from(s.entries()).map(([t,{name:a,counts:n}])=>({agentId:t,agentName:a,counts:n})).toSorted((t,a)=>{const n=t.counts.reduce((o,e)=>o+e,0);return a.counts.reduce((o,e)=>o+e,0)-n}).slice(0,N)}function O(){const{t:c}=H("panels"),i=v(e=>e.eventHistory),s=v(e=>e.theme)==="dark",[t,a]=b.useState(null),n=b.useMemo(()=>M(i),[i]);if(n.length===0)return r.jsx("div",{className:"flex h-48 items-center justify-center text-sm text-gray-500 dark:text-gray-400",children:c("common:empty.noActivityData")});const m=Date.now(),o=3600*1e3;return r.jsxs("div",{className:"relative",children:[r.jsx("svg",{width:d*x+60,height:N*u+24,className:"overflow-visible",children:n.map((e,f)=>r.jsxs("g",{children:[r.jsx("text",{x:0,y:f*u+u/2+4,fontSize:9,fill:s?"#e2e8f0":"#374151",children:e.agentName.length>10?`${e.agentName.slice(0,8)}…`:e.agentName}),e.counts.map((h,g)=>{const L=55+g*x,j=f*u+4,y=m-(d-g)*o,S=y+o,A=`${new Date(y).getHours()}:00-${new Date(S).getHours()}:00`;return r.jsx("rect",{x:L,y:j,width:x-1,height:u-1,fill:E(h,s),onMouseEnter:C=>{const p=C.target.getBoundingClientRect();a({agentName:e.agentName,hour:A,count:h,x:p.left,y:p.top})},onMouseLeave:()=>a(null)},g)})]},e.agentId))}),t&&r.jsxs("div",{className:"fixed z-10 rounded border border-gray-200 bg-white px-2 py-1 text-xs shadow dark:border-gray-700 dark:bg-gray-900 dark:text-gray-200",style:{left:t.x,top:t.y-32},children:[t.agentName," | ",t.hour," | ",t.count," ",c("activityHeatmap.eventsUnit")]})]})}export{O as ActivityHeatmap};
1
+ import{u as H,h as v,d as b,j as r}from"./index-WMjJihFL.js";const N=10,d=24,x=10,u=14,w=[{max:0,color:"#f3f4f6"},{max:5,color:"#bbf7d0"},{max:10,color:"#4ade80"},{max:1/0,color:"#16a34a"}],D=[{max:0,color:"#1e293b"},{max:5,color:"#14532d"},{max:10,color:"#166534"},{max:1/0,color:"#22c55e"}];function E(c,i){const l=i?D:w;for(const s of l)if(c<=s.max)return s.color;return l[l.length-1].color}function M(c){const i=Date.now(),l=3600*1e3,s=new Map;for(const t of c){const a=t.timestamp,n=(i-a)/l;if(n<0||n>=d)continue;const m=23-Math.min(23,Math.floor(n));let o=s.get(t.agentId);o||(o={name:t.agentName,counts:Array.from({length:d},()=>0)},s.set(t.agentId,o)),m>=0&&m<d&&o.counts[m]++}return Array.from(s.entries()).map(([t,{name:a,counts:n}])=>({agentId:t,agentName:a,counts:n})).toSorted((t,a)=>{const n=t.counts.reduce((o,e)=>o+e,0);return a.counts.reduce((o,e)=>o+e,0)-n}).slice(0,N)}function O(){const{t:c}=H("panels"),i=v(e=>e.eventHistory),s=v(e=>e.theme)==="dark",[t,a]=b.useState(null),n=b.useMemo(()=>M(i),[i]);if(n.length===0)return r.jsx("div",{className:"flex h-48 items-center justify-center text-sm text-gray-500 dark:text-gray-400",children:c("common:empty.noActivityData")});const m=Date.now(),o=3600*1e3;return r.jsxs("div",{className:"relative",children:[r.jsx("svg",{width:d*x+60,height:N*u+24,className:"overflow-visible",children:n.map((e,f)=>r.jsxs("g",{children:[r.jsx("text",{x:0,y:f*u+u/2+4,fontSize:9,fill:s?"#e2e8f0":"#374151",children:e.agentName.length>10?`${e.agentName.slice(0,8)}…`:e.agentName}),e.counts.map((h,g)=>{const L=55+g*x,j=f*u+4,y=m-(d-g)*o,S=y+o,A=`${new Date(y).getHours()}:00-${new Date(S).getHours()}:00`;return r.jsx("rect",{x:L,y:j,width:x-1,height:u-1,fill:E(h,s),onMouseEnter:C=>{const p=C.target.getBoundingClientRect();a({agentName:e.agentName,hour:A,count:h,x:p.left,y:p.top})},onMouseLeave:()=>a(null)},g)})]},e.agentId))}),t&&r.jsxs("div",{className:"fixed z-10 rounded border border-gray-200 bg-white px-2 py-1 text-xs shadow dark:border-gray-700 dark:bg-gray-900 dark:text-gray-200",style:{left:t.x,top:t.y-32},children:[t.agentName," | ",t.hour," | ",t.count," ",c("activityHeatmap.eventsUnit")]})]})}export{O as ActivityHeatmap};
@@ -1,4 +1,4 @@
1
- import{e as f,g as Ce,d as me,u as Qe,h as xe,j as S,i as Xe}from"./index-QZYyP0qG.js";import{c as I,f as A,H as Be,I as Ye,J as Fe,K as et,b as D,T as he,M as T,L as _,N as Ke,e as ye,h as Me,D as tt,C as rt,n as z,q as K,S as nt,A as it,d as at,k as Oe,l as ot,i as M,p as st,u as ct,G as lt,m as ee,j as ut,O as Ve,P as ft,Q as Y,U as Pe,z as pt,V as dt,R as vt,F as mt}from"./generateCategoricalChart-Onj3oDrM.js";var ht=["points","className","baseLinePoints","connectNulls"];function V(){return V=Object.assign?Object.assign.bind():function(r){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(r[t]=n[t])}return r},V.apply(this,arguments)}function yt(r,e){if(r==null)return{};var n=gt(r,e),t,i;if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(r);for(i=0;i<o.length;i++)t=o[i],!(e.indexOf(t)>=0)&&Object.prototype.propertyIsEnumerable.call(r,t)&&(n[t]=r[t])}return n}function gt(r,e){if(r==null)return{};var n={};for(var t in r)if(Object.prototype.hasOwnProperty.call(r,t)){if(e.indexOf(t)>=0)continue;n[t]=r[t]}return n}function ke(r){return Ot(r)||xt(r)||At(r)||bt()}function bt(){throw new TypeError(`Invalid attempt to spread non-iterable instance.
1
+ import{e as f,g as Ce,d as me,u as Qe,h as xe,j as S,i as Xe}from"./index-WMjJihFL.js";import{c as I,f as A,H as Be,I as Ye,J as Fe,K as et,b as D,T as he,M as T,L as _,N as Ke,e as ye,h as Me,D as tt,C as rt,n as z,q as K,S as nt,A as it,d as at,k as Oe,l as ot,i as M,p as st,u as ct,G as lt,m as ee,j as ut,O as Ve,P as ft,Q as Y,U as Pe,z as pt,V as dt,R as vt,F as mt}from"./generateCategoricalChart-DnxAF2gL.js";var ht=["points","className","baseLinePoints","connectNulls"];function V(){return V=Object.assign?Object.assign.bind():function(r){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(r[t]=n[t])}return r},V.apply(this,arguments)}function yt(r,e){if(r==null)return{};var n=gt(r,e),t,i;if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(r);for(i=0;i<o.length;i++)t=o[i],!(e.indexOf(t)>=0)&&Object.prototype.propertyIsEnumerable.call(r,t)&&(n[t]=r[t])}return n}function gt(r,e){if(r==null)return{};var n={};for(var t in r)if(Object.prototype.hasOwnProperty.call(r,t)){if(e.indexOf(t)>=0)continue;n[t]=r[t]}return n}function ke(r){return Ot(r)||xt(r)||At(r)||bt()}function bt(){throw new TypeError(`Invalid attempt to spread non-iterable instance.
2
2
  In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function At(r,e){if(r){if(typeof r=="string")return fe(r,e);var n=Object.prototype.toString.call(r).slice(8,-1);if(n==="Object"&&r.constructor&&(n=r.constructor.name),n==="Map"||n==="Set")return Array.from(r);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return fe(r,e)}}function xt(r){if(typeof Symbol<"u"&&r[Symbol.iterator]!=null||r["@@iterator"]!=null)return Array.from(r)}function Ot(r){if(Array.isArray(r))return fe(r)}function fe(r,e){(e==null||e>r.length)&&(e=r.length);for(var n=0,t=new Array(e);n<e;n++)t[n]=r[n];return t}var _e=function(e){return e&&e.x===+e.x&&e.y===+e.y},Pt=function(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:[],n=[[]];return e.forEach(function(t){_e(t)?n[n.length-1].push(t):n[n.length-1].length>0&&n.push([])}),_e(e[0])&&n[n.length-1].push(e[0]),n[n.length-1].length<=0&&(n=n.slice(0,-1)),n},U=function(e,n){var t=Pt(e);n&&(t=[t.reduce(function(o,a){return[].concat(ke(o),ke(a))},[])]);var i=t.map(function(o){return o.reduce(function(a,s,l){return"".concat(a).concat(l===0?"M":"L").concat(s.x,",").concat(s.y)},"")}).join("");return t.length===1?"".concat(i,"Z"):i},kt=function(e,n,t){var i=U(e,t);return"".concat(i.slice(-1)==="Z"?i.slice(0,-1):i,"L").concat(U(n.reverse(),t).slice(1))},_t=function(e){var n=e.points,t=e.className,i=e.baseLinePoints,o=e.connectNulls,a=yt(e,ht);if(!n||!n.length)return null;var s=I("recharts-polygon",t);if(i&&i.length){var l=a.stroke&&a.stroke!=="none",c=kt(n,i,o);return f.createElement("g",{className:s},f.createElement("path",V({},A(a,!0),{fill:c.slice(-1)==="Z"?a.fill:"none",stroke:"none",d:c})),l?f.createElement("path",V({},A(a,!0),{fill:"none",d:U(n,o)})):null,l?f.createElement("path",V({},A(a,!0),{fill:"none",d:U(i,o)})):null)}var p=U(n,o);return f.createElement("path",V({},A(a,!0),{fill:p.slice(-1)==="Z"?a.fill:"none",className:s,d:p}))},le,je;function jt(){if(je)return le;je=1;var r=Be(),e=Ye(),n=Fe();function t(i,o){return i&&i.length?r(i,n(o,2),e):void 0}return le=t,le}var wt=jt();const St=Ce(wt);var ue,we;function Tt(){if(we)return ue;we=1;var r=Be(),e=Fe(),n=et();function t(i,o){return i&&i.length?r(i,e(o,2),n):void 0}return ue=t,ue}var Et=Tt();const Rt=Ce(Et);var It=["cx","cy","angle","ticks","axisLine"],Lt=["ticks","tick","angle","tickFormatter","stroke"];function W(r){"@babel/helpers - typeof";return W=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},W(r)}function J(){return J=Object.assign?Object.assign.bind():function(r){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(r[t]=n[t])}return r},J.apply(this,arguments)}function Se(r,e){var n=Object.keys(r);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(r);e&&(t=t.filter(function(i){return Object.getOwnPropertyDescriptor(r,i).enumerable})),n.push.apply(n,t)}return n}function $(r){for(var e=1;e<arguments.length;e++){var n=arguments[e]!=null?arguments[e]:{};e%2?Se(Object(n),!0).forEach(function(t){ae(r,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(n)):Se(Object(n)).forEach(function(t){Object.defineProperty(r,t,Object.getOwnPropertyDescriptor(n,t))})}return r}function Te(r,e){if(r==null)return{};var n=$t(r,e),t,i;if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(r);for(i=0;i<o.length;i++)t=o[i],!(e.indexOf(t)>=0)&&Object.prototype.propertyIsEnumerable.call(r,t)&&(n[t]=r[t])}return n}function $t(r,e){if(r==null)return{};var n={};for(var t in r)if(Object.prototype.hasOwnProperty.call(r,t)){if(e.indexOf(t)>=0)continue;n[t]=r[t]}return n}function Nt(r,e){if(!(r instanceof e))throw new TypeError("Cannot call a class as a function")}function Ee(r,e){for(var n=0;n<e.length;n++){var t=e[n];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(r,ze(t.key),t)}}function Dt(r,e,n){return e&&Ee(r.prototype,e),n&&Ee(r,n),Object.defineProperty(r,"prototype",{writable:!1}),r}function Ct(r,e,n){return e=re(e),Bt(r,qe()?Reflect.construct(e,n||[],re(r).constructor):e.apply(r,n))}function Bt(r,e){if(e&&(W(e)==="object"||typeof e=="function"))return e;if(e!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return Ft(r)}function Ft(r){if(r===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return r}function qe(){try{var r=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(qe=function(){return!!r})()}function re(r){return re=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(n){return n.__proto__||Object.getPrototypeOf(n)},re(r)}function Kt(r,e){if(typeof e!="function"&&e!==null)throw new TypeError("Super expression must either be null or a function");r.prototype=Object.create(e&&e.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),Object.defineProperty(r,"prototype",{writable:!1}),e&&pe(r,e)}function pe(r,e){return pe=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,i){return t.__proto__=i,t},pe(r,e)}function ae(r,e,n){return e=ze(e),e in r?Object.defineProperty(r,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):r[e]=n,r}function ze(r){var e=Mt(r,"string");return W(e)=="symbol"?e:e+""}function Mt(r,e){if(W(r)!="object"||!r)return r;var n=r[Symbol.toPrimitive];if(n!==void 0){var t=n.call(r,e);if(W(t)!="object")return t;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(r)}var oe=(function(r){function e(){return Nt(this,e),Ct(this,e,arguments)}return Kt(e,r),Dt(e,[{key:"getTickValueCoord",value:function(t){var i=t.coordinate,o=this.props,a=o.angle,s=o.cx,l=o.cy;return T(s,l,i,a)}},{key:"getTickTextAnchor",value:function(){var t=this.props.orientation,i;switch(t){case"left":i="end";break;case"right":i="start";break;default:i="middle";break}return i}},{key:"getViewBox",value:function(){var t=this.props,i=t.cx,o=t.cy,a=t.angle,s=t.ticks,l=St(s,function(p){return p.coordinate||0}),c=Rt(s,function(p){return p.coordinate||0});return{cx:i,cy:o,startAngle:a,endAngle:a,innerRadius:c.coordinate||0,outerRadius:l.coordinate||0}}},{key:"renderAxisLine",value:function(){var t=this.props,i=t.cx,o=t.cy,a=t.angle,s=t.ticks,l=t.axisLine,c=Te(t,It),p=s.reduce(function(d,u){return[Math.min(d[0],u.coordinate),Math.max(d[1],u.coordinate)]},[1/0,-1/0]),v=T(i,o,p[0],a),y=T(i,o,p[1],a),x=$($($({},A(c,!1)),{},{fill:"none"},A(l,!1)),{},{x1:v.x,y1:v.y,x2:y.x,y2:y.y});return f.createElement("line",J({className:"recharts-polar-radius-axis-line"},x))}},{key:"renderTicks",value:function(){var t=this,i=this.props,o=i.ticks,a=i.tick,s=i.angle,l=i.tickFormatter,c=i.stroke,p=Te(i,Lt),v=this.getTickTextAnchor(),y=A(p,!1),x=A(a,!1),d=o.map(function(u,h){var g=t.getTickValueCoord(u),b=$($($($({textAnchor:v,transform:"rotate(".concat(90-s,", ").concat(g.x,", ").concat(g.y,")")},y),{},{stroke:"none",fill:c},x),{},{index:h},g),{},{payload:u});return f.createElement(_,J({className:I("recharts-polar-radius-axis-tick",Ke(a)),key:"tick-".concat(u.coordinate)},ye(t.props,u,h)),e.renderTickItem(a,b,l?l(u.value,h):u.value))});return f.createElement(_,{className:"recharts-polar-radius-axis-ticks"},d)}},{key:"render",value:function(){var t=this.props,i=t.ticks,o=t.axisLine,a=t.tick;return!i||!i.length?null:f.createElement(_,{className:I("recharts-polar-radius-axis",this.props.className)},o&&this.renderAxisLine(),a&&this.renderTicks(),Me.renderCallByParent(this.props,this.getViewBox()))}}],[{key:"renderTickItem",value:function(t,i,o){var a;return f.isValidElement(t)?a=f.cloneElement(t,i):D(t)?a=t(i):a=f.createElement(he,J({},i,{className:"recharts-polar-radius-axis-tick-value"}),o),a}}])})(me.PureComponent);ae(oe,"displayName","PolarRadiusAxis");ae(oe,"axisType","radiusAxis");ae(oe,"defaultProps",{type:"number",radiusAxisId:0,cx:0,cy:0,angle:0,orientation:"right",stroke:"#ccc",axisLine:!0,tick:!0,tickCount:5,allowDataOverflow:!1,scale:"auto",allowDuplicatedCategory:!0});function G(r){"@babel/helpers - typeof";return G=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},G(r)}function C(){return C=Object.assign?Object.assign.bind():function(r){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(r[t]=n[t])}return r},C.apply(this,arguments)}function Re(r,e){var n=Object.keys(r);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(r);e&&(t=t.filter(function(i){return Object.getOwnPropertyDescriptor(r,i).enumerable})),n.push.apply(n,t)}return n}function N(r){for(var e=1;e<arguments.length;e++){var n=arguments[e]!=null?arguments[e]:{};e%2?Re(Object(n),!0).forEach(function(t){se(r,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(n)):Re(Object(n)).forEach(function(t){Object.defineProperty(r,t,Object.getOwnPropertyDescriptor(n,t))})}return r}function Vt(r,e){if(!(r instanceof e))throw new TypeError("Cannot call a class as a function")}function Ie(r,e){for(var n=0;n<e.length;n++){var t=e[n];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(r,Ge(t.key),t)}}function qt(r,e,n){return e&&Ie(r.prototype,e),n&&Ie(r,n),Object.defineProperty(r,"prototype",{writable:!1}),r}function zt(r,e,n){return e=ne(e),Wt(r,We()?Reflect.construct(e,n||[],ne(r).constructor):e.apply(r,n))}function Wt(r,e){if(e&&(G(e)==="object"||typeof e=="function"))return e;if(e!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return Gt(r)}function Gt(r){if(r===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return r}function We(){try{var r=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(We=function(){return!!r})()}function ne(r){return ne=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(n){return n.__proto__||Object.getPrototypeOf(n)},ne(r)}function Ht(r,e){if(typeof e!="function"&&e!==null)throw new TypeError("Super expression must either be null or a function");r.prototype=Object.create(e&&e.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),Object.defineProperty(r,"prototype",{writable:!1}),e&&de(r,e)}function de(r,e){return de=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,i){return t.__proto__=i,t},de(r,e)}function se(r,e,n){return e=Ge(e),e in r?Object.defineProperty(r,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):r[e]=n,r}function Ge(r){var e=Zt(r,"string");return G(e)=="symbol"?e:e+""}function Zt(r,e){if(G(r)!="object"||!r)return r;var n=r[Symbol.toPrimitive];if(n!==void 0){var t=n.call(r,e);if(G(t)!="object")return t;throw new TypeError("@@toPrimitive must return a primitive value.")}return(e==="string"?String:Number)(r)}var Ut=Math.PI/180,Le=1e-5,ce=(function(r){function e(){return Vt(this,e),zt(this,e,arguments)}return Ht(e,r),qt(e,[{key:"getTickLineCoord",value:function(t){var i=this.props,o=i.cx,a=i.cy,s=i.radius,l=i.orientation,c=i.tickSize,p=c||8,v=T(o,a,s,t.coordinate),y=T(o,a,s+(l==="inner"?-1:1)*p,t.coordinate);return{x1:v.x,y1:v.y,x2:y.x,y2:y.y}}},{key:"getTickTextAnchor",value:function(t){var i=this.props.orientation,o=Math.cos(-t.coordinate*Ut),a;return o>Le?a=i==="outer"?"start":"end":o<-Le?a=i==="outer"?"end":"start":a="middle",a}},{key:"renderAxisLine",value:function(){var t=this.props,i=t.cx,o=t.cy,a=t.radius,s=t.axisLine,l=t.axisLineType,c=N(N({},A(this.props,!1)),{},{fill:"none"},A(s,!1));if(l==="circle")return f.createElement(tt,C({className:"recharts-polar-angle-axis-line"},c,{cx:i,cy:o,r:a}));var p=this.props.ticks,v=p.map(function(y){return T(i,o,a,y.coordinate)});return f.createElement(_t,C({className:"recharts-polar-angle-axis-line"},c,{points:v}))}},{key:"renderTicks",value:function(){var t=this,i=this.props,o=i.ticks,a=i.tick,s=i.tickLine,l=i.tickFormatter,c=i.stroke,p=A(this.props,!1),v=A(a,!1),y=N(N({},p),{},{fill:"none"},A(s,!1)),x=o.map(function(d,u){var h=t.getTickLineCoord(d),g=t.getTickTextAnchor(d),b=N(N(N({textAnchor:g},p),{},{stroke:"none",fill:c},v),{},{index:u,payload:d,x:h.x2,y:h.y2});return f.createElement(_,C({className:I("recharts-polar-angle-axis-tick",Ke(a)),key:"tick-".concat(d.coordinate)},ye(t.props,d,u)),s&&f.createElement("line",C({className:"recharts-polar-angle-axis-tick-line"},y,h)),a&&e.renderTickItem(a,b,l?l(d.value,u):d.value))});return f.createElement(_,{className:"recharts-polar-angle-axis-ticks"},x)}},{key:"render",value:function(){var t=this.props,i=t.ticks,o=t.radius,a=t.axisLine;return o<=0||!i||!i.length?null:f.createElement(_,{className:I("recharts-polar-angle-axis",this.props.className)},a&&this.renderAxisLine(),this.renderTicks())}}],[{key:"renderTickItem",value:function(t,i,o){var a;return f.isValidElement(t)?a=f.cloneElement(t,i):D(t)?a=t(i):a=f.createElement(he,C({},i,{className:"recharts-polar-angle-axis-tick-value"}),o),a}}])})(me.PureComponent);se(ce,"displayName","PolarAngleAxis");se(ce,"axisType","angleAxis");se(ce,"defaultProps",{type:"category",angleAxisId:0,scale:"auto",cx:0,cy:0,orientation:"outer",axisLine:!0,tickLine:!0,tickSize:8,tick:!0,hide:!1,allowDuplicatedCategory:!0});var te;function H(r){"@babel/helpers - typeof";return H=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(e){return typeof e}:function(e){return e&&typeof Symbol=="function"&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},H(r)}function q(){return q=Object.assign?Object.assign.bind():function(r){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(r[t]=n[t])}return r},q.apply(this,arguments)}function $e(r,e){var n=Object.keys(r);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(r);e&&(t=t.filter(function(i){return Object.getOwnPropertyDescriptor(r,i).enumerable})),n.push.apply(n,t)}return n}function m(r){for(var e=1;e<arguments.length;e++){var n=arguments[e]!=null?arguments[e]:{};e%2?$e(Object(n),!0).forEach(function(t){P(r,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(n)):$e(Object(n)).forEach(function(t){Object.defineProperty(r,t,Object.getOwnPropertyDescriptor(n,t))})}return r}function Jt(r,e){if(!(r instanceof e))throw new TypeError("Cannot call a class as a function")}function Ne(r,e){for(var n=0;n<e.length;n++){var t=e[n];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(r,Ze(t.key),t)}}function Qt(r,e,n){return e&&Ne(r.prototype,e),n&&Ne(r,n),Object.defineProperty(r,"prototype",{writable:!1}),r}function Xt(r,e,n){return e=ie(e),Yt(r,He()?Reflect.construct(e,n||[],ie(r).constructor):e.apply(r,n))}function Yt(r,e){if(e&&(H(e)==="object"||typeof e=="function"))return e;if(e!==void 0)throw new TypeError("Derived constructors may only return object or undefined");return er(r)}function er(r){if(r===void 0)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return r}function He(){try{var r=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch{}return(He=function(){return!!r})()}function ie(r){return ie=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(n){return n.__proto__||Object.getPrototypeOf(n)},ie(r)}function tr(r,e){if(typeof e!="function"&&e!==null)throw new TypeError("Super expression must either be null or a function");r.prototype=Object.create(e&&e.prototype,{constructor:{value:r,writable:!0,configurable:!0}}),Object.defineProperty(r,"prototype",{writable:!1}),e&&ve(r,e)}function ve(r,e){return ve=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,i){return t.__proto__=i,t},ve(r,e)}function P(r,e,n){return e=Ze(e),e in r?Object.defineProperty(r,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):r[e]=n,r}function Ze(r){var e=rr(r,"string");return H(e)=="symbol"?e:e+""}function rr(r,e){if(H(r)!="object"||!r)return r;var n=r[Symbol.toPrimitive];if(n!==void 0){var t=n.call(r,e);if(H(t)!="object")return t;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(r)}var E=(function(r){function e(n){var t;return Jt(this,e),t=Xt(this,e,[n]),P(t,"pieRef",null),P(t,"sectorRefs",[]),P(t,"id",ct("recharts-pie-")),P(t,"handleAnimationEnd",function(){var i=t.props.onAnimationEnd;t.setState({isAnimationFinished:!0}),D(i)&&i()}),P(t,"handleAnimationStart",function(){var i=t.props.onAnimationStart;t.setState({isAnimationFinished:!1}),D(i)&&i()}),t.state={isAnimationFinished:!n.isAnimationActive,prevIsAnimationActive:n.isAnimationActive,prevAnimationId:n.animationId,sectorToFocus:0},t}return tr(e,r),Qt(e,[{key:"isActiveIndex",value:function(t){var i=this.props.activeIndex;return Array.isArray(i)?i.indexOf(t)!==-1:t===i}},{key:"hasActiveIndex",value:function(){var t=this.props.activeIndex;return Array.isArray(t)?t.length!==0:t||t===0}},{key:"renderLabels",value:function(t){var i=this.props.isAnimationActive;if(i&&!this.state.isAnimationFinished)return null;var o=this.props,a=o.label,s=o.labelLine,l=o.dataKey,c=o.valueKey,p=A(this.props,!1),v=A(a,!1),y=A(s,!1),x=a&&a.offsetRadius||20,d=t.map(function(u,h){var g=(u.startAngle+u.endAngle)/2,b=T(u.cx,u.cy,u.outerRadius+x,g),k=m(m(m(m({},p),u),{},{stroke:"none"},v),{},{index:h,textAnchor:e.getTextAnchor(b.x,u.cx)},b),B=m(m(m(m({},p),u),{},{fill:"none",stroke:u.fill},y),{},{index:h,points:[T(u.cx,u.cy,u.outerRadius,g),b]}),j=l;return z(l)&&z(c)?j="value":z(l)&&(j=c),f.createElement(_,{key:"label-".concat(u.startAngle,"-").concat(u.endAngle,"-").concat(u.midAngle,"-").concat(h)},s&&e.renderLabelLineItem(s,B,"line"),e.renderLabelItem(a,k,K(u,j)))});return f.createElement(_,{className:"recharts-pie-labels"},d)}},{key:"renderSectorsStatically",value:function(t){var i=this,o=this.props,a=o.activeShape,s=o.blendStroke,l=o.inactiveShape;return t.map(function(c,p){if((c==null?void 0:c.startAngle)===0&&(c==null?void 0:c.endAngle)===0&&t.length!==1)return null;var v=i.isActiveIndex(p),y=l&&i.hasActiveIndex()?l:null,x=v?a:y,d=m(m({},c),{},{stroke:s?c.fill:c.stroke,tabIndex:-1});return f.createElement(_,q({ref:function(h){h&&!i.sectorRefs.includes(h)&&i.sectorRefs.push(h)},tabIndex:-1,className:"recharts-pie-sector"},ye(i.props,c,p),{key:"sector-".concat(c==null?void 0:c.startAngle,"-").concat(c==null?void 0:c.endAngle,"-").concat(c.midAngle,"-").concat(p)}),f.createElement(nt,q({option:x,isActive:v,shapeType:"sector"},d)))})}},{key:"renderSectorsWithAnimation",value:function(){var t=this,i=this.props,o=i.sectors,a=i.isAnimationActive,s=i.animationBegin,l=i.animationDuration,c=i.animationEasing,p=i.animationId,v=this.state,y=v.prevSectors,x=v.prevIsAnimationActive;return f.createElement(it,{begin:s,duration:l,isActive:a,easing:c,from:{t:0},to:{t:1},key:"pie-".concat(p,"-").concat(x),onAnimationStart:this.handleAnimationStart,onAnimationEnd:this.handleAnimationEnd},function(d){var u=d.t,h=[],g=o&&o[0],b=g.startAngle;return o.forEach(function(k,B){var j=y&&y[B],L=B>0?at(k,"paddingAngle",0):0;if(j){var Z=Oe(j.endAngle-j.startAngle,k.endAngle-k.startAngle),O=m(m({},k),{},{startAngle:b+L,endAngle:b+Z(u)+L});h.push(O),b=O.endAngle}else{var F=k.endAngle,w=k.startAngle,Q=Oe(0,F-w),X=Q(u),R=m(m({},k),{},{startAngle:b+L,endAngle:b+X+L});h.push(R),b=R.endAngle}}),f.createElement(_,null,t.renderSectorsStatically(h))})}},{key:"attachKeyboardHandlers",value:function(t){var i=this;t.onkeydown=function(o){if(!o.altKey)switch(o.key){case"ArrowLeft":{var a=++i.state.sectorToFocus%i.sectorRefs.length;i.sectorRefs[a].focus(),i.setState({sectorToFocus:a});break}case"ArrowRight":{var s=--i.state.sectorToFocus<0?i.sectorRefs.length-1:i.state.sectorToFocus%i.sectorRefs.length;i.sectorRefs[s].focus(),i.setState({sectorToFocus:s});break}case"Escape":{i.sectorRefs[i.state.sectorToFocus].blur(),i.setState({sectorToFocus:0});break}}}}},{key:"renderSectors",value:function(){var t=this.props,i=t.sectors,o=t.isAnimationActive,a=this.state.prevSectors;return o&&i&&i.length&&(!a||!ot(a,i))?this.renderSectorsWithAnimation():this.renderSectorsStatically(i)}},{key:"componentDidMount",value:function(){this.pieRef&&this.attachKeyboardHandlers(this.pieRef)}},{key:"render",value:function(){var t=this,i=this.props,o=i.hide,a=i.sectors,s=i.className,l=i.label,c=i.cx,p=i.cy,v=i.innerRadius,y=i.outerRadius,x=i.isAnimationActive,d=this.state.isAnimationFinished;if(o||!a||!a.length||!M(c)||!M(p)||!M(v)||!M(y))return null;var u=I("recharts-pie",s);return f.createElement(_,{tabIndex:this.props.rootTabIndex,className:u,ref:function(g){t.pieRef=g}},this.renderSectors(),l&&this.renderLabels(a),Me.renderCallByParent(this.props,null,!1),(!x||d)&&st.renderCallByParent(this.props,a,!1))}}],[{key:"getDerivedStateFromProps",value:function(t,i){return i.prevIsAnimationActive!==t.isAnimationActive?{prevIsAnimationActive:t.isAnimationActive,prevAnimationId:t.animationId,curSectors:t.sectors,prevSectors:[],isAnimationFinished:!0}:t.isAnimationActive&&t.animationId!==i.prevAnimationId?{prevAnimationId:t.animationId,curSectors:t.sectors,prevSectors:i.curSectors,isAnimationFinished:!0}:t.sectors!==i.curSectors?{curSectors:t.sectors,isAnimationFinished:!0}:null}},{key:"getTextAnchor",value:function(t,i){return t>i?"start":t<i?"end":"middle"}},{key:"renderLabelLineItem",value:function(t,i,o){if(f.isValidElement(t))return f.cloneElement(t,i);if(D(t))return t(i);var a=I("recharts-pie-label-line",typeof t!="boolean"?t.className:"");return f.createElement(rt,q({},i,{key:o,type:"linear",className:a}))}},{key:"renderLabelItem",value:function(t,i,o){if(f.isValidElement(t))return f.cloneElement(t,i);var a=o;if(D(t)&&(a=t(i),f.isValidElement(a)))return a;var s=I("recharts-pie-label-text",typeof t!="boolean"&&!D(t)?t.className:"");return f.createElement(he,q({},i,{alignmentBaseline:"middle",className:s}),a)}}])})(me.PureComponent);te=E;P(E,"displayName","Pie");P(E,"defaultProps",{stroke:"#fff",fill:"#808080",legendType:"rect",cx:"50%",cy:"50%",startAngle:0,endAngle:360,innerRadius:0,outerRadius:"80%",paddingAngle:0,labelLine:!0,hide:!1,minAngle:0,isAnimationActive:!lt.isSsr,animationBegin:400,animationDuration:1500,animationEasing:"ease",nameKey:"name",blendStroke:!1,rootTabIndex:0});P(E,"parseDeltaAngle",function(r,e){var n=ee(e-r),t=Math.min(Math.abs(e-r),360);return n*t});P(E,"getRealPieData",function(r){var e=r.data,n=r.children,t=A(r,!1),i=ut(n,Ve);return e&&e.length?e.map(function(o,a){return m(m(m({payload:o},t),o),i&&i[a]&&i[a].props)}):i&&i.length?i.map(function(o){return m(m({},t),o.props)}):[]});P(E,"parseCoordinateOfPie",function(r,e){var n=e.top,t=e.left,i=e.width,o=e.height,a=ft(i,o),s=t+Y(r.cx,i,i/2),l=n+Y(r.cy,o,o/2),c=Y(r.innerRadius,a,0),p=Y(r.outerRadius,a,a*.8),v=r.maxRadius||Math.sqrt(i*i+o*o)/2;return{cx:s,cy:l,innerRadius:c,outerRadius:p,maxRadius:v}});P(E,"getComposedData",function(r){var e=r.item,n=r.offset,t=e.type.defaultProps!==void 0?m(m({},e.type.defaultProps),e.props):e.props,i=te.getRealPieData(t);if(!i||!i.length)return null;var o=t.cornerRadius,a=t.startAngle,s=t.endAngle,l=t.paddingAngle,c=t.dataKey,p=t.nameKey,v=t.valueKey,y=t.tooltipType,x=Math.abs(t.minAngle),d=te.parseCoordinateOfPie(t,n),u=te.parseDeltaAngle(a,s),h=Math.abs(u),g=c;z(c)&&z(v)?(Pe(!1,`Use "dataKey" to specify the value of pie,
3
3
  the props "valueKey" will be deprecated in 1.1.0`),g="value"):z(c)&&(Pe(!1,`Use "dataKey" to specify the value of pie,
4
4
  the props "valueKey" will be deprecated in 1.1.0`),g=v);var b=i.filter(function(O){return K(O,g,0)!==0}).length,k=(h>=360?b:b-1)*l,B=h-b*x-k,j=i.reduce(function(O,F){var w=K(F,g,0);return O+(M(w)?w:0)},0),L;if(j>0){var Z;L=i.map(function(O,F){var w=K(O,g,0),Q=K(O,p,F),X=(M(w)?w:0)/j,R;F?R=Z.endAngle+ee(u)*l*(w!==0?1:0):R=a;var ge=R+ee(u)*((w!==0?x:0)+X*B),be=(R+ge)/2,Ae=(d.innerRadius+d.outerRadius)/2,Ue=[{name:Q,value:w,payload:O,dataKey:g,type:y}],Je=T(d.cx,d.cy,Ae,be);return Z=m(m(m({percent:X,cornerRadius:o,name:Q,tooltipPayload:Ue,midAngle:be,middleRadius:Ae,tooltipPosition:Je},O),d),{},{value:K(O,g),startAngle:R,endAngle:ge,payload:O,paddingAngle:ee(u)*l}),Z})}return m(m({},d),{},{sectors:L,data:i})});var nr=pt({chartName:"PieChart",GraphicalChild:E,validateTooltipEventTypes:["item"],defaultTooltipEventType:"item",legendContent:"children",axisComponents:[{axisType:"angleAxis",AxisComp:ce},{axisType:"radiusAxis",AxisComp:oe}],formatAxisMap:dt,defaultProps:{layout:"centric",startAngle:0,endAngle:360,cx:"50%",cy:"50%",innerRadius:0,outerRadius:"80%"}});function De(r){return r>=1e6?`${(r/1e6).toFixed(1)}M`:r>=1e3?`${(r/1e3).toFixed(1)}k`:String(r)}function or(){const{t:r}=Qe(),e=xe(a=>a.agentCosts),n=xe(a=>a.agents),t=Object.entries(e).filter(([,a])=>a>0),i=t.reduce((a,[,s])=>a+s,0);if(t.length===0)return S.jsx("div",{className:"flex h-24 items-center justify-center text-sm text-gray-500 dark:text-gray-400",children:r("empty.noCostData")});const o=t.map(([a,s])=>{var l;return{name:((l=n.get(a))==null?void 0:l.name)??a,agentId:a,value:s,color:Xe(a)}});return S.jsxs("div",{className:"relative h-[200px] w-full",children:[S.jsx(vt,{width:"100%",height:"100%",children:S.jsxs(nr,{children:[S.jsx(E,{data:o,dataKey:"value",nameKey:"name",cx:"50%",cy:"50%",innerRadius:50,outerRadius:80,paddingAngle:2,children:o.map((a,s)=>S.jsx(Ve,{fill:a.color},s))}),S.jsx(mt,{formatter:(a,s)=>{const l=typeof a=="number"?a:0,c=i>0?(l/i*100).toFixed(0):"0";return`${s}: ${De(l)} (${c}%)`}})]})}),S.jsx("div",{className:"absolute inset-0 flex items-center justify-center pointer-events-none",children:S.jsx("span",{className:"text-sm font-bold text-gray-700 dark:text-gray-300",children:De(i)})})]})}export{or as CostPieChart};
@@ -1 +1 @@
1
- import{u as S,h as g,d as M,j as d,S as k}from"./index-QZYyP0qG.js";const y=8,C=24,j=20,p=280;function T(l,n,s,f){const e=new Map,r=l.length;if(r===0)return e;for(let u=0;u<r;u++){const h=2*Math.PI*u/r-Math.PI/2;e.set(l[u].id,{x:n+f*Math.cos(h),y:s+f*Math.sin(h)})}return e}function w(l,n){if(n<=0)return y;const s=Math.min(l/n,1);return y+s*(C-y)}function E(){const{t:l}=S(),n=g(t=>t.agents),s=g(t=>t.links),f=g(t=>t.theme),[e,r]=M.useState(null),u=f==="dark",{topAgents:h,positions:x,maxToolCount:I}=M.useMemo(()=>{const t=Array.from(n.values()).toSorted((i,m)=>m.toolCallCount-i.toolCallCount).slice(0,j),o=Math.max(1,...t.map(i=>i.toolCallCount)),a=Math.min(80,Math.max(40,t.length*8)),c=T(t,p/2,p/2,a);return{topAgents:t,positions:c,maxToolCount:o}},[n]),v=M.useMemo(()=>{if(!e)return new Set;const t=new Set;for(const o of s)(o.sourceId===e||o.targetId===e)&&t.add(`${o.sourceId}-${o.targetId}`);return t},[s,e]);return h.length===0&&s.length===0?d.jsx("div",{className:"flex h-48 items-center justify-center text-sm text-gray-500 dark:text-gray-400",children:l("empty.noRelationData")}):d.jsxs("svg",{width:"100%",height:200,viewBox:`0 0 ${p} ${p}`,className:"overflow-visible",onMouseLeave:()=>r(null),children:[s.filter(t=>x.has(t.sourceId)&&x.has(t.targetId)).map(t=>{const o=x.get(t.sourceId),a=x.get(t.targetId),c=`${t.sourceId}-${t.targetId}`,i=v.has(c),m=Math.max(1,t.strength*3);return d.jsx("line",{x1:o.x,y1:o.y,x2:a.x,y2:a.y,stroke:i?"#3b82f6":"rgba(107,114,128,0.4)",strokeWidth:m},c)}),h.map(t=>{const o=x.get(t.id);if(!o)return null;const a=w(t.toolCallCount,I),c=e===t.id,i=c?1.2:1,m=k[t.status];return d.jsxs("g",{onMouseEnter:()=>r(t.id),onMouseLeave:()=>r(null),children:[d.jsx("circle",{cx:o.x,cy:o.y,r:a*i,fill:m,stroke:c?"#1e40af":"transparent",strokeWidth:2}),d.jsx("text",{x:o.x,y:o.y+a+10,textAnchor:"middle",fontSize:9,fill:u?"#e2e8f0":"#374151",children:t.name.length>8?`${t.name.slice(0,6)}…`:t.name})]},t.id)})]})}export{E as NetworkGraph};
1
+ import{u as S,h as g,d as M,j as d,S as k}from"./index-WMjJihFL.js";const y=8,C=24,j=20,p=280;function T(l,n,s,f){const e=new Map,r=l.length;if(r===0)return e;for(let u=0;u<r;u++){const h=2*Math.PI*u/r-Math.PI/2;e.set(l[u].id,{x:n+f*Math.cos(h),y:s+f*Math.sin(h)})}return e}function w(l,n){if(n<=0)return y;const s=Math.min(l/n,1);return y+s*(C-y)}function E(){const{t:l}=S(),n=g(t=>t.agents),s=g(t=>t.links),f=g(t=>t.theme),[e,r]=M.useState(null),u=f==="dark",{topAgents:h,positions:x,maxToolCount:I}=M.useMemo(()=>{const t=Array.from(n.values()).toSorted((i,m)=>m.toolCallCount-i.toolCallCount).slice(0,j),o=Math.max(1,...t.map(i=>i.toolCallCount)),a=Math.min(80,Math.max(40,t.length*8)),c=T(t,p/2,p/2,a);return{topAgents:t,positions:c,maxToolCount:o}},[n]),v=M.useMemo(()=>{if(!e)return new Set;const t=new Set;for(const o of s)(o.sourceId===e||o.targetId===e)&&t.add(`${o.sourceId}-${o.targetId}`);return t},[s,e]);return h.length===0&&s.length===0?d.jsx("div",{className:"flex h-48 items-center justify-center text-sm text-gray-500 dark:text-gray-400",children:l("empty.noRelationData")}):d.jsxs("svg",{width:"100%",height:200,viewBox:`0 0 ${p} ${p}`,className:"overflow-visible",onMouseLeave:()=>r(null),children:[s.filter(t=>x.has(t.sourceId)&&x.has(t.targetId)).map(t=>{const o=x.get(t.sourceId),a=x.get(t.targetId),c=`${t.sourceId}-${t.targetId}`,i=v.has(c),m=Math.max(1,t.strength*3);return d.jsx("line",{x1:o.x,y1:o.y,x2:a.x,y2:a.y,stroke:i?"#3b82f6":"rgba(107,114,128,0.4)",strokeWidth:m},c)}),h.map(t=>{const o=x.get(t.id);if(!o)return null;const a=w(t.toolCallCount,I),c=e===t.id,i=c?1.2:1,m=k[t.status];return d.jsxs("g",{onMouseEnter:()=>r(t.id),onMouseLeave:()=>r(null),children:[d.jsx("circle",{cx:o.x,cy:o.y,r:a*i,fill:m,stroke:c?"#1e40af":"transparent",strokeWidth:2}),d.jsx("text",{x:o.x,y:o.y+a+10,textAnchor:"middle",fontSize:9,fill:u?"#e2e8f0":"#374151",children:t.name.length>8?`${t.name.slice(0,6)}…`:t.name})]},t.id)})]})}export{E as NetworkGraph};