@tonyclaw/agent-inspector 3.0.19 → 3.0.21

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 (42) hide show
  1. package/.output/cli.js +2 -2
  2. package/.output/nitro.json +1 -1
  3. package/.output/public/assets/{CompareDrawer-DR3WgrId.js → CompareDrawer-BhQ8UZBt.js} +1 -1
  4. package/.output/public/assets/{ProxyViewerContainer-B7PZaz5j.js → ProxyViewerContainer-GpMPUmJQ.js} +30 -30
  5. package/.output/public/assets/{ReplayDialog-Bt9jgdvJ.js → ReplayDialog-CqUvVWFk.js} +1 -1
  6. package/.output/public/assets/{RequestAnatomy-C-4630lw.js → RequestAnatomy-DU8c0Ysb.js} +1 -1
  7. package/.output/public/assets/{ResponseView-f_JrN1iQ.js → ResponseView-Ce2JAKBf.js} +2 -2
  8. package/.output/public/assets/{StreamingChunkSequence-D8dBm1d8.js → StreamingChunkSequence-DvMcBgID.js} +1 -1
  9. package/.output/public/assets/{_sessionId-CtoSDXDC.js → _sessionId-BeinzuQZ.js} +1 -1
  10. package/.output/public/assets/{index-B-rVc2xu.js → index-BMVjOrho.js} +2 -2
  11. package/.output/public/assets/{index-BtCnkWve.js → index-Cu0STzXy.js} +1 -1
  12. package/.output/public/assets/{index-B3YOj8-_.css → index-D2iiZaNM.css} +1 -1
  13. package/.output/public/assets/{index-BNCySZM-.js → index-DENY-gse.js} +1 -1
  14. package/.output/public/assets/{json-viewer-DT6QQY81.js → json-viewer-Bjmt-Mdw.js} +1 -1
  15. package/.output/server/{_sessionId-DbRqqzqz.mjs → _sessionId-DiAGJ75k.mjs} +2 -2
  16. package/.output/server/_ssr/{CompareDrawer-CVhUSZu1.mjs → CompareDrawer-DF4wc8NT.mjs} +2 -2
  17. package/.output/server/_ssr/{ProxyViewerContainer-BNnDYtc5.mjs → ProxyViewerContainer-BupCsVk6.mjs} +10 -19
  18. package/.output/server/_ssr/{ReplayDialog-DVkGajZU.mjs → ReplayDialog-BIzO8gkO.mjs} +3 -3
  19. package/.output/server/_ssr/{RequestAnatomy-_FIfVjDR.mjs → RequestAnatomy-DR7XdTUQ.mjs} +2 -2
  20. package/.output/server/_ssr/{ResponseView-Bnv5ejVA.mjs → ResponseView-DoadSJYH.mjs} +2 -2
  21. package/.output/server/_ssr/{StreamingChunkSequence-vtwzxw7A.mjs → StreamingChunkSequence-KPnZNTpB.mjs} +2 -2
  22. package/.output/server/_ssr/{index-DFJbRoyq.mjs → index-uv5HMw8-.mjs} +2 -2
  23. package/.output/server/_ssr/index.mjs +2 -2
  24. package/.output/server/_ssr/{json-viewer-BkweASh3.mjs → json-viewer-JNF8ttGZ.mjs} +2 -2
  25. package/.output/server/_ssr/{router-gFd3g7WM.mjs → router-07KkEFRt.mjs} +176 -64
  26. package/.output/server/{_tanstack-start-manifest_v-DeLutIlq.mjs → _tanstack-start-manifest_v-CLXgj2ke.mjs} +1 -1
  27. package/.output/server/index.mjs +70 -70
  28. package/README.md +4 -4
  29. package/package.json +1 -1
  30. package/src/cli/onboard.ts +1 -1
  31. package/src/cli.ts +2 -2
  32. package/src/components/providers/ProviderCard.tsx +5 -13
  33. package/src/contracts/json.ts +7 -2
  34. package/src/lib/providerContract.ts +25 -5
  35. package/src/mcp/server.ts +12 -3
  36. package/src/mcp/toolHandlers.ts +6 -1
  37. package/src/proxy/handler.ts +17 -7
  38. package/src/proxy/logFinalizer.ts +76 -8
  39. package/src/proxy/logIndex.ts +16 -32
  40. package/src/proxy/providers.ts +22 -1
  41. package/src/proxy/sessionProcess.ts +15 -1
  42. package/src/proxy/upstream.ts +4 -2
@@ -2,7 +2,7 @@ import { c as createRouter, a as createRootRoute, b as createFileRoute, l as laz
2
2
  import { r as reactExports, j as jsxRuntimeExports } from "../_libs/react.mjs";
3
3
  import { S as SWRConfig } from "../_libs/swr.mjs";
4
4
  import { existsSync, readFileSync, mkdirSync, writeFileSync, renameSync, copyFileSync, unlinkSync, createReadStream, readdirSync, statSync, rmSync, cpSync, createWriteStream } from "node:fs";
5
- import fs, { mkdir, appendFile, readFile, writeFile, readdir, open, stat, unlink, rm, rename } from "node:fs/promises";
5
+ import fs, { mkdir, appendFile, writeFile, readdir, open, readFile, stat, unlink, rm, rename } from "node:fs/promises";
6
6
  import { createInterface } from "node:readline";
7
7
  import { Buffer } from "node:buffer";
8
8
  import path, { basename, join, dirname, isAbsolute, resolve, relative } from "node:path";
@@ -64,7 +64,7 @@ import "../_libs/immediate.mjs";
64
64
  import "../_libs/setimmediate.mjs";
65
65
  import "../_libs/pako.mjs";
66
66
  const faviconSvg = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20role='img'%20aria-label='Agent%20Inspector'%3e%3cg%20fill='none'%20stroke='%23f59e0b'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'%20%3e%3cpath%20d='M5%2013%20C5%209%208%207%2012%207%20C16%207%2019%209%2019%2013%20C19%2016%2016%2018%2012%2018%20C8%2018%205%2016%205%2013%20Z'%20/%3e%3cpath%20d='M5%2011%20C3.5%209.5%201.5%2010%202%2012.5%20C2.5%2014%204%2013.5%205%2012.5'%20/%3e%3cpath%20d='M19%2011%20C20.5%209.5%2022.5%2010%2022%2012.5%20C21.5%2014%2020%2013.5%2019%2012.5'%20/%3e%3cline%20x1='10'%20y1='7'%20x2='9.5'%20y2='5'%20/%3e%3cline%20x1='14'%20y1='7'%20x2='14.5'%20y2='5'%20/%3e%3cline%20x1='6.5'%20y1='16'%20x2='4.5'%20y2='19.5'%20/%3e%3cline%20x1='9'%20y1='17.5'%20x2='8'%20y2='20.5'%20/%3e%3cline%20x1='15'%20y1='17.5'%20x2='16'%20y2='20.5'%20/%3e%3cline%20x1='17.5'%20y1='16'%20x2='19.5'%20y2='19.5'%20/%3e%3c/g%3e%3ccircle%20cx='9.5'%20cy='4.5'%20r='0.9'%20fill='%23f59e0b'%20/%3e%3ccircle%20cx='14.5'%20cy='4.5'%20r='0.9'%20fill='%23f59e0b'%20/%3e%3c/svg%3e";
67
- const appCss = "/assets/index-B3YOj8-_.css";
67
+ const appCss = "/assets/index-D2iiZaNM.css";
68
68
  const CHUNK_LOAD_RELOAD_AT_KEY = "agent-inspector.chunkLoadReloadAt";
69
69
  const CHUNK_LOAD_RELOAD_WINDOW_MS = 15e3;
70
70
  const CHUNK_LOAD_FAILURE_PATTERNS = [
@@ -176,7 +176,7 @@ function RootDocument({ children }) {
176
176
  ] })
177
177
  ] });
178
178
  }
179
- const $$splitComponentImporter$1 = () => import("./index-DFJbRoyq.mjs");
179
+ const $$splitComponentImporter$1 = () => import("./index-uv5HMw8-.mjs");
180
180
  const Route$L = createFileRoute("/")({
181
181
  ssr: false,
182
182
  component: lazyRouteComponent($$splitComponentImporter$1, "component")
@@ -220,7 +220,7 @@ function decodeSessionIdFromPath(encoded) {
220
220
  function getSessionPath(sessionId) {
221
221
  return `/session/${encodeSessionIdForPath(sessionId)}`;
222
222
  }
223
- const $$splitComponentImporter = () => import("../_sessionId-DbRqqzqz.mjs");
223
+ const $$splitComponentImporter = () => import("../_sessionId-DiAGJ75k.mjs");
224
224
  const Route$K = createFileRoute("/session/$sessionId")({
225
225
  ssr: false,
226
226
  component: lazyRouteComponent($$splitComponentImporter, "component"),
@@ -362,16 +362,16 @@ let writeQueue = Promise.resolve();
362
362
  let logWriteLock = Promise.resolve();
363
363
  async function runWithLogWriteLock(fn) {
364
364
  const previousLock = logWriteLock;
365
- let releaseLock2 = () => {
365
+ let releaseLock = () => {
366
366
  };
367
367
  logWriteLock = new Promise((resolve2) => {
368
- releaseLock2 = resolve2;
368
+ releaseLock = resolve2;
369
369
  });
370
370
  await previousLock;
371
371
  try {
372
372
  return await fn();
373
373
  } finally {
374
- releaseLock2();
374
+ releaseLock();
375
375
  }
376
376
  }
377
377
  function drainBuffer() {
@@ -443,6 +443,9 @@ const JsonValueSchema = lazy(
443
443
  ])
444
444
  );
445
445
  function trustAsJsonValue(value) {
446
+ if (value === void 0 || typeof value === "bigint" || typeof value === "function") {
447
+ return null;
448
+ }
446
449
  return value;
447
450
  }
448
451
  const StreamingChunkSchema$1 = object({
@@ -1832,40 +1835,26 @@ async function rebuildIndex() {
1832
1835
  await replaceSqliteLogIndexEntries(Object.values(newIndex.entries));
1833
1836
  return newIndex;
1834
1837
  }
1835
- let idGenerationPromise = null;
1836
- let releaseLock = null;
1837
- async function acquireLock() {
1838
- if (releaseLock === null) {
1839
- idGenerationPromise = new Promise((resolve2) => {
1840
- releaseLock = resolve2;
1841
- });
1842
- } else {
1843
- await idGenerationPromise;
1844
- idGenerationPromise = new Promise((resolve2) => {
1845
- releaseLock = resolve2;
1846
- });
1847
- }
1848
- }
1849
- function releaseLockFn() {
1850
- if (releaseLock) {
1851
- const resolve2 = releaseLock;
1852
- releaseLock = null;
1853
- idGenerationPromise = null;
1854
- resolve2();
1855
- }
1838
+ let idGenerationChain = Promise.resolve();
1839
+ async function withIdLock(fn) {
1840
+ const run = idGenerationChain.then(fn);
1841
+ idGenerationChain = run.then(
1842
+ () => {
1843
+ },
1844
+ () => {
1845
+ }
1846
+ );
1847
+ return run;
1856
1848
  }
1857
1849
  async function getNextLogId() {
1858
- await acquireLock();
1859
- try {
1850
+ return withIdLock(async () => {
1860
1851
  const index = await loadIndex();
1861
1852
  const sqliteMaxId = await getSqliteLogIndexMaxId();
1862
1853
  const nextId = Math.max(index.maxId, sqliteMaxId ?? 0) + 1;
1863
1854
  index.maxId = nextId;
1864
1855
  cachedIndex = index;
1865
1856
  return nextId;
1866
- } finally {
1867
- releaseLockFn();
1868
- }
1857
+ });
1869
1858
  }
1870
1859
  function getCurrentLogFile() {
1871
1860
  const now = /* @__PURE__ */ new Date();
@@ -2486,6 +2475,14 @@ async function clearSessionArchives() {
2486
2475
  return 0;
2487
2476
  }
2488
2477
  }
2478
+ function isPlainRecord(val) {
2479
+ return typeof val === "object" && val !== null && !Array.isArray(val);
2480
+ }
2481
+ function safeGetOwnProperty(obj, key) {
2482
+ if (obj === null || typeof obj !== "object" || Array.isArray(obj)) return void 0;
2483
+ const desc = Object.getOwnPropertyDescriptor(obj, key);
2484
+ return desc?.value;
2485
+ }
2489
2486
  const IDLE_TIMEOUT_MS = Number(process.env["SESSION_PROCESS_IDLE_MS"]) || 5 * 60 * 1e3;
2490
2487
  const MAX_RESTARTS = 3;
2491
2488
  const _processes = /* @__PURE__ */ new Map();
@@ -2521,7 +2518,18 @@ class SessionProcess {
2521
2518
  windowsHide: true
2522
2519
  });
2523
2520
  this.restartCount += 1;
2524
- this.child.on("message", (msg) => {
2521
+ this.child.on("message", (raw) => {
2522
+ if (!isPlainRecord(raw)) {
2523
+ logger.error("[sessionProcess] Received malformed IPC message from worker, discarding");
2524
+ return;
2525
+ }
2526
+ const id = safeGetOwnProperty(raw, "id");
2527
+ const result = safeGetOwnProperty(raw, "result");
2528
+ if (typeof id !== "string" || !isPlainRecord(result)) {
2529
+ logger.error("[sessionProcess] Received malformed IPC message from worker, discarding");
2530
+ return;
2531
+ }
2532
+ const msg = { id, result };
2525
2533
  const pending = this.pending.get(msg.id);
2526
2534
  if (pending !== void 0) {
2527
2535
  this.pending.delete(msg.id);
@@ -4820,6 +4828,17 @@ function maskApiKey(apiKey) {
4820
4828
  if (apiKey.length <= 8) return "••••••••";
4821
4829
  return apiKey.slice(0, 4) + "••••••••" + apiKey.slice(-4);
4822
4830
  }
4831
+ function httpUrl() {
4832
+ return string().refine((val) => {
4833
+ if (val.length === 0) return true;
4834
+ try {
4835
+ const parsed = new URL(val);
4836
+ return parsed.protocol === "http:" || parsed.protocol === "https:";
4837
+ } catch {
4838
+ return false;
4839
+ }
4840
+ }, "Must be a valid http(s) URL");
4841
+ }
4823
4842
  const ProviderModelMetadataSchema = object({
4824
4843
  model: string().min(1),
4825
4844
  contextWindow: number().int().positive().optional(),
@@ -4833,12 +4852,12 @@ const ProviderConfigSchema = object({
4833
4852
  name: string(),
4834
4853
  apiKey: string(),
4835
4854
  model: string().optional(),
4836
- models: array(string()).min(1),
4855
+ models: array(string()).optional().default([]),
4837
4856
  format: _enum(["anthropic", "openai"]).optional(),
4838
- baseUrl: string().optional(),
4839
- anthropicBaseUrl: string().optional(),
4840
- openaiBaseUrl: string().optional(),
4841
- openaiResponsesBaseUrl: string().optional(),
4857
+ baseUrl: httpUrl().optional(),
4858
+ anthropicBaseUrl: httpUrl().optional(),
4859
+ openaiBaseUrl: httpUrl().optional(),
4860
+ openaiResponsesBaseUrl: httpUrl().optional(),
4842
4861
  authHeader: _enum(["bearer", "x-api-key"]).optional().default("bearer"),
4843
4862
  apiDocsUrl: string().optional(),
4844
4863
  modelMetadataUrl: string().optional(),
@@ -5451,7 +5470,24 @@ if (providersJson !== void 0) {
5451
5470
  }
5452
5471
  }
5453
5472
  function getProviders() {
5454
- return store.get("providers", []);
5473
+ const raw = store.get("providers", []);
5474
+ const valid = [];
5475
+ for (const candidate of raw) {
5476
+ const entry = ProviderConfigSchema.safeParse(candidate);
5477
+ if (entry.success) {
5478
+ valid.push(entry.data);
5479
+ continue;
5480
+ }
5481
+ let candidateName = "<unknown>";
5482
+ if (typeof candidate === "object" && candidate !== null) {
5483
+ const nameResult = object({ name: string() }).safeParse(candidate);
5484
+ if (nameResult.success) candidateName = nameResult.data.name;
5485
+ }
5486
+ logger.warn(
5487
+ `[providers] Skipping invalid on-disk provider "${candidateName}": ${entry.error.message}`
5488
+ );
5489
+ }
5490
+ return valid;
5455
5491
  }
5456
5492
  function getProvider(id) {
5457
5493
  const providers = getProviders();
@@ -6256,14 +6292,6 @@ function toPersistedConfig(value) {
6256
6292
  timeDisplayFormat: value.timeDisplayFormat
6257
6293
  };
6258
6294
  }
6259
- function isPlainRecord(val) {
6260
- return typeof val === "object" && val !== null && !Array.isArray(val);
6261
- }
6262
- function safeGetOwnProperty(obj, key) {
6263
- if (obj === null || typeof obj !== "object" || Array.isArray(obj)) return void 0;
6264
- const desc = Object.getOwnPropertyDescriptor(obj, key);
6265
- return desc?.value;
6266
- }
6267
6295
  const BILLING_HEADER_PREFIX = "x-anthropic-billing-header:";
6268
6296
  function isClaudeCodeBillingHeaderBlock(text) {
6269
6297
  const trimmed = text.trimStart();
@@ -6888,6 +6916,11 @@ function applyOptionalStreamingTiming(log, job) {
6888
6916
  totalStreamMs: job.totalStreamMs
6889
6917
  });
6890
6918
  return;
6919
+ default: {
6920
+ const _exhaustive = job;
6921
+ logger.error(`[logFinalizer] Unhandled job type: ${JSON.stringify(_exhaustive)}`);
6922
+ return;
6923
+ }
6891
6924
  }
6892
6925
  }
6893
6926
  let toolSchemaWarningQueue = Promise.resolve();
@@ -6951,6 +6984,11 @@ function cleanupPathForRawStream(rawStream) {
6951
6984
  return null;
6952
6985
  case "file":
6953
6986
  return rawStream.path;
6987
+ default: {
6988
+ const _exhaustive = rawStream;
6989
+ logger.error(`[logFinalizer] Unhandled raw stream type: ${JSON.stringify(_exhaustive)}`);
6990
+ return null;
6991
+ }
6954
6992
  }
6955
6993
  }
6956
6994
  function rawStreamByteLength(rawStream) {
@@ -6966,6 +7004,11 @@ function rawStreamByteLength(rawStream) {
6966
7004
  } catch {
6967
7005
  return null;
6968
7006
  }
7007
+ default: {
7008
+ const _exhaustive = rawStream;
7009
+ logger.error(`[logFinalizer] Unhandled raw stream type: ${JSON.stringify(_exhaustive)}`);
7010
+ return null;
7011
+ }
6969
7012
  }
6970
7013
  }
6971
7014
  function getOversizedRawStream(rawStream) {
@@ -6996,6 +7039,11 @@ function readRawStream(rawStream) {
6996
7039
  rawStreamText: readFileSync(rawStream.path, "utf-8"),
6997
7040
  cleanupRawStreamPath: rawStream.path
6998
7041
  };
7042
+ default: {
7043
+ const _exhaustive = rawStream;
7044
+ logger.error(`[logFinalizer] Unhandled raw stream type: ${JSON.stringify(_exhaustive)}`);
7045
+ return { rawStreamText: "", cleanupRawStreamPath: null };
7046
+ }
6999
7047
  }
7000
7048
  }
7001
7049
  function finalizeStreaming(job, log) {
@@ -7107,6 +7155,7 @@ function finalizeStreamAbort(job, log) {
7107
7155
  }
7108
7156
  function buildFinalizeLogResult(job) {
7109
7157
  const log = cloneLog(job.log);
7158
+ const upstreamUrl = job.upstreamUrl;
7110
7159
  switch (job.type) {
7111
7160
  case "non-streaming":
7112
7161
  return finalizeNonStreaming(job, log);
@@ -7114,6 +7163,16 @@ function buildFinalizeLogResult(job) {
7114
7163
  return finalizeStreaming(job, log);
7115
7164
  case "stream-abort":
7116
7165
  return finalizeStreamAbort(job, log);
7166
+ default: {
7167
+ const _exhaustive = job;
7168
+ logger.error(`[logFinalizer] Unhandled job type: ${JSON.stringify(_exhaustive)}`);
7169
+ return {
7170
+ log,
7171
+ upstreamUrl,
7172
+ error: "Unhandled job type",
7173
+ cleanupRawStreamPath: null
7174
+ };
7175
+ }
7117
7176
  }
7118
7177
  }
7119
7178
  function commitFinalizeLogResult(result) {
@@ -7162,6 +7221,16 @@ function resolveBuildPromise(job) {
7162
7221
  return executeBuildInWorker(job);
7163
7222
  case "inline":
7164
7223
  return Promise.resolve(buildFinalizeLogResult(job));
7224
+ default: {
7225
+ const _exhaustive = RUNTIME;
7226
+ logger.error(`[logFinalizer] Unhandled runtime: ${JSON.stringify(_exhaustive)}`);
7227
+ return Promise.resolve({
7228
+ log: job.log,
7229
+ upstreamUrl: job.upstreamUrl,
7230
+ error: "Unhandled runtime",
7231
+ cleanupRawStreamPath: null
7232
+ });
7233
+ }
7165
7234
  }
7166
7235
  }
7167
7236
  const WORKER_COUNT = Math.max(1, Number(process.env["FINALIZER_WORKER_COUNT"]) || 4);
@@ -7174,11 +7243,22 @@ function getWorkers() {
7174
7243
  _workers = [];
7175
7244
  for (let i = 0; i < WORKER_COUNT; i++) {
7176
7245
  const w = new Worker(new URL("./logFinalizer.worker.ts", import.meta.url));
7177
- w.on("message", (msg) => {
7178
- const resolve2 = _pending.get(msg.id);
7179
- if (resolve2 !== void 0) {
7246
+ w.on("message", (raw) => {
7247
+ if (!isPlainRecord(raw)) {
7248
+ logger.error("[logFinalizer] Received malformed IPC message from worker, discarding");
7249
+ return;
7250
+ }
7251
+ const id = safeGetOwnProperty(raw, "id");
7252
+ const result = safeGetOwnProperty(raw, "result");
7253
+ if (typeof id !== "string" || !isPlainRecord(result)) {
7254
+ logger.error("[logFinalizer] Received malformed IPC message from worker, discarding");
7255
+ return;
7256
+ }
7257
+ const msg = { id, result };
7258
+ const entry = _pending.get(msg.id);
7259
+ if (entry !== void 0) {
7180
7260
  _pending.delete(msg.id);
7181
- resolve2(msg.result);
7261
+ entry.resolve(msg.result);
7182
7262
  }
7183
7263
  });
7184
7264
  w.on("error", (err) => {
@@ -7186,20 +7266,29 @@ function getWorkers() {
7186
7266
  "[logFinalizer] Worker error:",
7187
7267
  err instanceof Error ? err.message : String(err)
7188
7268
  );
7269
+ for (const [id, entry] of _pending) {
7270
+ _pending.delete(id);
7271
+ entry.reject(
7272
+ new Error(`Worker crashed: ${err instanceof Error ? err.message : String(err)}`)
7273
+ );
7274
+ }
7189
7275
  });
7190
7276
  _workers.push(w);
7191
7277
  }
7192
7278
  return _workers;
7193
7279
  }
7194
7280
  function executeBuildInWorker(job) {
7195
- return new Promise((resolve2) => {
7281
+ return new Promise((resolve2, reject) => {
7196
7282
  const list = getWorkers();
7197
7283
  const idx = _nextWorker % list.length;
7198
7284
  _nextWorker++;
7199
7285
  const w = list[idx];
7200
- if (w === void 0) return;
7286
+ if (w === void 0) {
7287
+ reject(new Error("No workers available"));
7288
+ return;
7289
+ }
7201
7290
  const id = String(++_jobSeq);
7202
- _pending.set(id, resolve2);
7291
+ _pending.set(id, { resolve: resolve2, reject });
7203
7292
  w.postMessage({ id, job });
7204
7293
  });
7205
7294
  }
@@ -7452,6 +7541,9 @@ function setUpstreamHost(headers, upstreamBase) {
7452
7541
  try {
7453
7542
  headers.set(HEADER_HOST, new URL(upstreamBase).host);
7454
7543
  } catch {
7544
+ logger.warn(
7545
+ `[upstream] Invalid provider URL "${upstreamBase}" — falling back to api.anthropic.com for Host header`
7546
+ );
7455
7547
  headers.set(HEADER_HOST, "api.anthropic.com");
7456
7548
  }
7457
7549
  }
@@ -7580,13 +7672,20 @@ function handleStreamingResponse(upstreamRes, req, startTime, upstreamUrl, log,
7580
7672
  if (upstreamRes.body === null) {
7581
7673
  return new Response("No response body", { status: STATUS_BAD_GATEWAY });
7582
7674
  }
7583
- const loggedStream = upstreamRes.body.pipeThrough(transform);
7584
- req.signal?.addEventListener("abort", () => {
7585
- if (log.responseText === null) {
7586
- logger.info(`[handler] Streaming client aborted: ${log.method} ${log.path}`);
7587
- scheduleStreamingFinalization("stream-abort");
7588
- }
7675
+ void upstreamRes.body.pipeTo(transform.writable).catch(() => {
7676
+ scheduleStreamingFinalization("streaming");
7589
7677
  });
7678
+ const loggedStream = transform.readable;
7679
+ if (req.signal === void 0) {
7680
+ logger.warn("[handler] req.signal is undefined; abort detection disabled for this request");
7681
+ } else {
7682
+ req.signal.addEventListener("abort", () => {
7683
+ if (log.responseText === null) {
7684
+ logger.info(`[handler] Streaming client aborted: ${log.method} ${log.path}`);
7685
+ scheduleStreamingFinalization("stream-abort");
7686
+ }
7687
+ });
7688
+ }
7590
7689
  const responseHeaders = new Headers(upstreamRes.headers);
7591
7690
  responseHeaders.delete(HEADER_CONTENT_ENCODING);
7592
7691
  responseHeaders.delete(HEADER_CONTENT_LENGTH);
@@ -9687,7 +9786,7 @@ const Route$E = createFileRoute("/api/models")({
9687
9786
  }
9688
9787
  });
9689
9788
  const name = "@tonyclaw/agent-inspector";
9690
- const version = "3.0.19";
9789
+ const version = "3.0.21";
9691
9790
  const packageJson = {
9692
9791
  name,
9693
9792
  version
@@ -10840,7 +10939,11 @@ async function diagnoseCaptureImpl(callApi2, args = {}) {
10840
10939
  const runtime = await getRuntimeConfigImpl(callApi2);
10841
10940
  if (runtime.isError === true) return runtime;
10842
10941
  const runtimeText = runtime.content[0]?.text ?? "{}";
10843
- const runtimePayload = JSON.parse(runtimeText);
10942
+ let runtimePayload = {};
10943
+ try {
10944
+ runtimePayload = JSON.parse(runtimeText);
10945
+ } catch {
10946
+ }
10844
10947
  const runtimeRecord = isRecord(runtimePayload) ? runtimePayload : {};
10845
10948
  const configRecord = isRecord(runtimeRecord["config"]) ? runtimeRecord["config"] : {};
10846
10949
  const captureMode = stringField(configRecord, "captureMode");
@@ -11304,7 +11407,16 @@ function buildServer() {
11304
11407
  sessionIdGenerator: void 0
11305
11408
  // stateless — see module docstring
11306
11409
  });
11307
- void server.connect(transport);
11410
+ void server.connect(transport).then(
11411
+ () => {
11412
+ },
11413
+ (err) => {
11414
+ logger.error(
11415
+ "[mcp] server.connect failed:",
11416
+ err instanceof Error ? err.message : String(err)
11417
+ );
11418
+ }
11419
+ );
11308
11420
  return { server, transport };
11309
11421
  }
11310
11422
  async function getServer() {
@@ -1,4 +1,4 @@
1
- const tsrStartManifest = () => ({ routes: { __root__: { filePath: "C:/Users/claw/workspace/agent-inspector/src/routes/__root.tsx", children: ["/", "/api/alerts", "/api/config", "/api/groups", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/pi-agent", "/api/providers", "/api/runs", "/api/sessions", "/proxy/$", "/session/$sessionId", "/api/ecosystem/packages", "/api/ecosystem/tasks", "/api/knowledge/candidates", "/api/knowledge/project-context", "/api/knowledge/search", "/api/ecosystem/recipes/$recipeId/run", "/api/knowledge/sessions/$sessionId/candidates"], preloads: ["/assets/index-B-rVc2xu.js"], scripts: [{ attrs: { type: "module", async: true, src: "/assets/index-B-rVc2xu.js" } }] }, "/": { filePath: "C:/Users/claw/workspace/agent-inspector/src/routes/index.tsx", children: void 0, preloads: ["/assets/index-BtCnkWve.js", "/assets/ProxyViewerContainer-B7PZaz5j.js"] }, "/session/$sessionId": { filePath: "C:/Users/claw/workspace/agent-inspector/src/routes/session/$sessionId.tsx", children: void 0, preloads: ["/assets/_sessionId-CtoSDXDC.js", "/assets/ProxyViewerContainer-B7PZaz5j.js"] } } });
1
+ const tsrStartManifest = () => ({ routes: { __root__: { filePath: "C:/Users/claw/workspace/agent-inspector/src/routes/__root.tsx", children: ["/", "/api/alerts", "/api/config", "/api/groups", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/pi-agent", "/api/providers", "/api/runs", "/api/sessions", "/proxy/$", "/session/$sessionId", "/api/ecosystem/packages", "/api/ecosystem/tasks", "/api/knowledge/candidates", "/api/knowledge/project-context", "/api/knowledge/search", "/api/ecosystem/recipes/$recipeId/run", "/api/knowledge/sessions/$sessionId/candidates"], preloads: ["/assets/index-BMVjOrho.js"], scripts: [{ attrs: { type: "module", async: true, src: "/assets/index-BMVjOrho.js" } }] }, "/": { filePath: "C:/Users/claw/workspace/agent-inspector/src/routes/index.tsx", children: void 0, preloads: ["/assets/index-Cu0STzXy.js", "/assets/ProxyViewerContainer-GpMPUmJQ.js"] }, "/session/$sessionId": { filePath: "C:/Users/claw/workspace/agent-inspector/src/routes/session/$sessionId.tsx", children: void 0, preloads: ["/assets/_sessionId-BeinzuQZ.js", "/assets/ProxyViewerContainer-GpMPUmJQ.js"] } } });
2
2
  export {
3
3
  tsrStartManifest
4
4
  };
@@ -17,124 +17,124 @@ const headers = ((m) => function headersRouteRule(event) {
17
17
  }
18
18
  });
19
19
  const assets = {
20
- "/assets/CompareDrawer-DR3WgrId.js": {
20
+ "/assets/CompareDrawer-BhQ8UZBt.js": {
21
21
  "type": "text/javascript; charset=utf-8",
22
- "etag": '"4bc4-g9wGCVQQ0+DTCWBtzf5/WQzC1ms"',
23
- "mtime": "2026-07-09T03:01:37.217Z",
22
+ "etag": '"4bc4-q7/WZBBoHI4QCp2aBIrQbpS+ZwA"',
23
+ "mtime": "2026-07-09T07:33:08.150Z",
24
24
  "size": 19396,
25
- "path": "../public/assets/CompareDrawer-DR3WgrId.js"
25
+ "path": "../public/assets/CompareDrawer-BhQ8UZBt.js"
26
26
  },
27
27
  "/assets/alibaba-TTwafVwX.svg": {
28
28
  "type": "image/svg+xml",
29
29
  "etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
30
- "mtime": "2026-07-09T03:01:37.217Z",
30
+ "mtime": "2026-07-09T07:33:08.149Z",
31
31
  "size": 5915,
32
32
  "path": "../public/assets/alibaba-TTwafVwX.svg"
33
33
  },
34
- "/assets/index-BNCySZM-.js": {
34
+ "/assets/index-Cu0STzXy.js": {
35
35
  "type": "text/javascript; charset=utf-8",
36
- "etag": '"1cd2d-ANSOo1HmeEqtriGBeldBUquTNnk"',
37
- "mtime": "2026-07-09T03:01:37.219Z",
38
- "size": 118061,
39
- "path": "../public/assets/index-BNCySZM-.js"
40
- },
41
- "/assets/index-BtCnkWve.js": {
42
- "type": "text/javascript; charset=utf-8",
43
- "etag": '"265-sEh/TwYI3EgJbVaR+VUN3hntyS8"',
44
- "mtime": "2026-07-09T03:01:37.217Z",
36
+ "etag": '"265-Y2kn4+kLz0UCilDKDhsxBE8vpnc"',
37
+ "mtime": "2026-07-09T07:33:08.150Z",
45
38
  "size": 613,
46
- "path": "../public/assets/index-BtCnkWve.js"
39
+ "path": "../public/assets/index-Cu0STzXy.js"
47
40
  },
48
- "/assets/minimax-BPMzvuL-.jpeg": {
49
- "type": "image/jpeg",
50
- "etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
51
- "mtime": "2026-07-09T03:01:37.217Z",
52
- "size": 6918,
53
- "path": "../public/assets/minimax-BPMzvuL-.jpeg"
54
- },
55
- "/assets/json-viewer-DT6QQY81.js": {
41
+ "/assets/json-viewer-Bjmt-Mdw.js": {
56
42
  "type": "text/javascript; charset=utf-8",
57
- "etag": '"1ae7-RiK2CqjzqBcc3r3qhTcOUeHnVT0"',
58
- "mtime": "2026-07-09T03:01:37.219Z",
43
+ "etag": '"1ae7-tt6uImcLjdS2gr8kUpKvBHv82YY"',
44
+ "mtime": "2026-07-09T07:33:08.150Z",
59
45
  "size": 6887,
60
- "path": "../public/assets/json-viewer-DT6QQY81.js"
46
+ "path": "../public/assets/json-viewer-Bjmt-Mdw.js"
61
47
  },
62
48
  "/assets/agent-inspector-58K1_MsC.ico": {
63
49
  "type": "image/vnd.microsoft.icon",
64
50
  "etag": '"38fa-ZD8kPABHYjPIkcH82FMY6iZM7fI"',
65
- "mtime": "2026-07-09T03:01:37.217Z",
51
+ "mtime": "2026-07-09T07:33:08.149Z",
66
52
  "size": 14586,
67
53
  "path": "../public/assets/agent-inspector-58K1_MsC.ico"
68
54
  },
69
- "/assets/ReplayDialog-Bt9jgdvJ.js": {
70
- "type": "text/javascript; charset=utf-8",
71
- "etag": '"3348-WtWDGmK5jybK+cuTpwIgPOGFwd4"',
72
- "mtime": "2026-07-09T03:01:37.217Z",
73
- "size": 13128,
74
- "path": "../public/assets/ReplayDialog-Bt9jgdvJ.js"
55
+ "/assets/index-D2iiZaNM.css": {
56
+ "type": "text/css; charset=utf-8",
57
+ "etag": '"25cbf-gXyEinEYizYtkUYphvKg/JJAlXM"',
58
+ "mtime": "2026-07-09T07:33:08.149Z",
59
+ "size": 154815,
60
+ "path": "../public/assets/index-D2iiZaNM.css"
75
61
  },
76
- "/assets/RequestAnatomy-C-4630lw.js": {
62
+ "/assets/index-DENY-gse.js": {
77
63
  "type": "text/javascript; charset=utf-8",
78
- "etag": '"43f3-fgvl7dr+n5X7ytjRQEqDqOFrZb4"',
79
- "mtime": "2026-07-09T03:01:37.219Z",
80
- "size": 17395,
81
- "path": "../public/assets/RequestAnatomy-C-4630lw.js"
64
+ "etag": '"1cd2d-azZxx60qWI9z51uvMu8o3Zkmqqg"',
65
+ "mtime": "2026-07-09T07:33:08.150Z",
66
+ "size": 118061,
67
+ "path": "../public/assets/index-DENY-gse.js"
68
+ },
69
+ "/assets/minimax-BPMzvuL-.jpeg": {
70
+ "type": "image/jpeg",
71
+ "etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
72
+ "mtime": "2026-07-09T07:33:08.149Z",
73
+ "size": 6918,
74
+ "path": "../public/assets/minimax-BPMzvuL-.jpeg"
82
75
  },
83
- "/assets/ResponseView-f_JrN1iQ.js": {
76
+ "/assets/RequestAnatomy-DU8c0Ysb.js": {
84
77
  "type": "text/javascript; charset=utf-8",
85
- "etag": '"47fe-Cr70ks/fq7wCCjGwBxxd8BVAcZU"',
86
- "mtime": "2026-07-09T03:01:37.219Z",
87
- "size": 18430,
88
- "path": "../public/assets/ResponseView-f_JrN1iQ.js"
78
+ "etag": '"43f3-tict+3CArhDH0oq7q3mampyiL4o"',
79
+ "mtime": "2026-07-09T07:33:08.150Z",
80
+ "size": 17395,
81
+ "path": "../public/assets/RequestAnatomy-DU8c0Ysb.js"
89
82
  },
90
83
  "/assets/zhipuai-BPNAnxo-.svg": {
91
84
  "type": "image/svg+xml",
92
85
  "etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
93
- "mtime": "2026-07-09T03:01:37.217Z",
86
+ "mtime": "2026-07-09T07:33:08.149Z",
94
87
  "size": 11256,
95
88
  "path": "../public/assets/zhipuai-BPNAnxo-.svg"
96
89
  },
97
- "/assets/StreamingChunkSequence-D8dBm1d8.js": {
90
+ "/assets/_sessionId-BeinzuQZ.js": {
98
91
  "type": "text/javascript; charset=utf-8",
99
- "etag": '"e96-AN1j5BG971yE+OvQe2JDt7ZgrdI"',
100
- "mtime": "2026-07-09T03:01:37.219Z",
92
+ "etag": '"36d-wyDMru6FvHjuW6fdH0fxfDL5csw"',
93
+ "mtime": "2026-07-09T07:33:08.150Z",
94
+ "size": 877,
95
+ "path": "../public/assets/_sessionId-BeinzuQZ.js"
96
+ },
97
+ "/assets/StreamingChunkSequence-DvMcBgID.js": {
98
+ "type": "text/javascript; charset=utf-8",
99
+ "etag": '"e96-6BaPiEMr6EDDv+mO5wBLCpH1qYQ"',
100
+ "mtime": "2026-07-09T07:33:08.150Z",
101
101
  "size": 3734,
102
- "path": "../public/assets/StreamingChunkSequence-D8dBm1d8.js"
102
+ "path": "../public/assets/StreamingChunkSequence-DvMcBgID.js"
103
103
  },
104
- "/assets/_sessionId-CtoSDXDC.js": {
104
+ "/assets/ReplayDialog-CqUvVWFk.js": {
105
105
  "type": "text/javascript; charset=utf-8",
106
- "etag": '"36d-MA+Cf4ijIFGfW0n0A0CkOZUFU/4"',
107
- "mtime": "2026-07-09T03:01:37.217Z",
108
- "size": 877,
109
- "path": "../public/assets/_sessionId-CtoSDXDC.js"
106
+ "etag": '"3348-tWBPWrexRvJS3YQIdPt3HDAs1p0"',
107
+ "mtime": "2026-07-09T07:33:08.150Z",
108
+ "size": 13128,
109
+ "path": "../public/assets/ReplayDialog-CqUvVWFk.js"
110
110
  },
111
- "/assets/index-B3YOj8-_.css": {
112
- "type": "text/css; charset=utf-8",
113
- "etag": '"25d7e-wT0HU4Abt/tuojN/MHx6/a/L3BA"',
114
- "mtime": "2026-07-09T03:01:37.217Z",
115
- "size": 155006,
116
- "path": "../public/assets/index-B3YOj8-_.css"
111
+ "/assets/ResponseView-Ce2JAKBf.js": {
112
+ "type": "text/javascript; charset=utf-8",
113
+ "etag": '"47fe-SBZtSFnLFU3zdUC9GzC5G68XDpI"',
114
+ "mtime": "2026-07-09T07:33:08.150Z",
115
+ "size": 18430,
116
+ "path": "../public/assets/ResponseView-Ce2JAKBf.js"
117
117
  },
118
- "/assets/index-B-rVc2xu.js": {
118
+ "/assets/index-BMVjOrho.js": {
119
119
  "type": "text/javascript; charset=utf-8",
120
- "etag": '"5231f-IxjASzSyrrUSlC4lxQL2r/KbijU"',
121
- "mtime": "2026-07-09T03:01:37.217Z",
120
+ "etag": '"5231f-+JWwi3Ne4jFZpTso0unc0dEWK7M"',
121
+ "mtime": "2026-07-09T07:33:08.150Z",
122
122
  "size": 336671,
123
- "path": "../public/assets/index-B-rVc2xu.js"
123
+ "path": "../public/assets/index-BMVjOrho.js"
124
124
  },
125
125
  "/assets/qwen-CONDcHqt.png": {
126
126
  "type": "image/png",
127
127
  "etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
128
- "mtime": "2026-07-09T03:01:37.217Z",
128
+ "mtime": "2026-07-09T07:33:08.150Z",
129
129
  "size": 357059,
130
130
  "path": "../public/assets/qwen-CONDcHqt.png"
131
131
  },
132
- "/assets/ProxyViewerContainer-B7PZaz5j.js": {
132
+ "/assets/ProxyViewerContainer-GpMPUmJQ.js": {
133
133
  "type": "text/javascript; charset=utf-8",
134
- "etag": '"bd773-O18dWHbUpwNcPJ1CJIocyfAmfPA"',
135
- "mtime": "2026-07-09T03:01:37.219Z",
136
- "size": 776051,
137
- "path": "../public/assets/ProxyViewerContainer-B7PZaz5j.js"
134
+ "etag": '"bd7e1-Uddz5LuKxXdcrqA/GQwaawsmbAI"',
135
+ "mtime": "2026-07-09T07:33:08.150Z",
136
+ "size": 776161,
137
+ "path": "../public/assets/ProxyViewerContainer-GpMPUmJQ.js"
138
138
  }
139
139
  };
140
140
  function readAsset(id) {