@tonyclaw/agent-inspector 3.1.19 → 3.1.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.
- package/.output/backend/nitro.json +1 -1
- package/.output/cli.js +140 -20
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-0qlvqhVh.mjs → router-Be6BLuut.mjs} +2454 -1135
- package/.output/server/_tanstack-start-manifest_v-ClTaMkEj.mjs +4 -0
- package/.output/server/index.mjs +1 -1
- package/.output/ui/assets/{CompareDrawer-BOk9hd-Z.js → CompareDrawer-CGk2HFI1.js} +1 -1
- package/.output/ui/assets/{InspectorPet-DhHDBpk7.js → InspectorPet-CDM7SdOT.js} +1 -1
- package/.output/ui/assets/ProxyViewerContainer-CaWD78tw.js +60 -0
- package/.output/ui/assets/{ReplayDialog-DJhKtuNB.js → ReplayDialog-DqaeV1He.js} +1 -1
- package/.output/ui/assets/{RequestAnatomy-hP0tsqDC.js → RequestAnatomy-BtHl9P0k.js} +1 -1
- package/.output/ui/assets/{ResponseView-BSiUkwCb.js → ResponseView-C6t1vpxs.js} +1 -1
- package/.output/ui/assets/{StreamingChunkSequence-CzQqwv4X.js → StreamingChunkSequence-R4mgd3GQ.js} +1 -1
- package/.output/ui/assets/{_sessionId-BU-i6h0V.js → _sessionId-CL3hdLlQ.js} +1 -1
- package/.output/ui/assets/{_sessionId-C2Pq4Jb0.js → _sessionId-HS666S72.js} +1 -1
- package/.output/ui/assets/index-B-Qod-aA.css +1 -0
- package/.output/ui/assets/{index-D8C-t-2U.js → index-Bd9jPL4n.js} +1 -1
- package/.output/ui/assets/{index-zHpVF0jk.js → index-C4NHrclw.js} +1 -1
- package/.output/ui/assets/{index-UUnRwbOJ.js → index-UF1PJEcq.js} +1 -1
- package/.output/ui/assets/{index-B7NeIBDf.js → index-tX38BNV2.js} +2 -2
- package/.output/ui/assets/{json-viewer-DOzS5rUT.js → json-viewer-KSgzN_Ov.js} +1 -1
- package/.output/ui/assets/{jszip.min-CCCY7qNk.js → jszip.min-BiMDxghN.js} +1 -1
- package/.output/ui/index.html +2 -2
- package/.output/workers/logFinalizer.worker.js +261 -0
- package/.output/workers/sessionWorkerEntry.js +261 -0
- package/package.json +13 -6
- package/src/backend/routes/api/logs.$id.replay.ts +6 -1
- package/src/backend/routes/api/logs.stream.ts +7 -0
- package/src/backend/routes/api/providers.$providerId.model-metadata.ts +15 -4
- package/src/backend/routes/api/storage.ts +56 -0
- package/src/backend/routes/metrics.ts +14 -0
- package/src/cli/doctor.ts +135 -2
- package/src/cli.ts +7 -4
- package/src/components/ProxyViewerContainer.tsx +41 -24
- package/src/components/providers/SettingsDialog.tsx +261 -70
- package/src/components/proxy-viewer/LogEntry.tsx +19 -5
- package/src/components/proxy-viewer/bodyHydration.ts +67 -0
- package/src/components/proxy-viewer/proxyViewerContainerLogic.ts +78 -0
- package/src/contracts/index.ts +2 -0
- package/src/contracts/log.ts +5 -0
- package/src/knowledge/openclawClient.ts +11 -2
- package/src/knowledge/openclawGatewayClient.ts +6 -1
- package/src/lib/resourceLimits.ts +191 -0
- package/src/lib/safeFetch.ts +428 -20
- package/src/lib/stopReason.ts +66 -39
- package/src/proxy/ecosystemTasks.ts +20 -0
- package/src/proxy/handler.ts +17 -4
- package/src/proxy/identityProxy.ts +36 -16
- package/src/proxy/logIndex.ts +57 -6
- package/src/proxy/logger.ts +4 -0
- package/src/proxy/rawStreamCapture.ts +16 -1
- package/src/proxy/runtimeHealth.ts +4 -2
- package/src/proxy/runtimeMetrics.ts +149 -0
- package/src/proxy/schemas.ts +2 -0
- package/src/proxy/sessionRuntime.ts +38 -0
- package/src/proxy/sqliteLogIndex.ts +78 -2
- package/src/proxy/storageLifecycle.ts +432 -0
- package/src/proxy/store.ts +69 -13
- package/.output/server/_tanstack-start-manifest_v-DnbdNeun.mjs +0 -4
- package/.output/ui/assets/ProxyViewerContainer-BRYf987G.js +0 -59
- package/.output/ui/assets/index-IBEDJoV_.css +0 -1
|
@@ -14948,6 +14948,8 @@ var ToolTraceEventSchema = external_exports.object({
|
|
|
14948
14948
|
argumentsText: external_exports.string().nullable(),
|
|
14949
14949
|
argumentsPreview: external_exports.string().nullable()
|
|
14950
14950
|
});
|
|
14951
|
+
var StopReasonValueSchema = external_exports.enum(["end_turn", "tool_use", "stop", "length"]);
|
|
14952
|
+
var StopReasonSchema = StopReasonValueSchema.nullable();
|
|
14951
14953
|
var StreamingChunksArraySchema = external_exports.object({
|
|
14952
14954
|
chunks: external_exports.array(StreamingChunkSchema),
|
|
14953
14955
|
truncated: external_exports.boolean().optional().default(false)
|
|
@@ -15008,6 +15010,7 @@ var CapturedLogSchema = external_exports.object({
|
|
|
15008
15010
|
captureIncompleteReason: CaptureIncompleteReasonSchema.nullable().optional(),
|
|
15009
15011
|
warnings: external_exports.array(external_exports.string()).optional(),
|
|
15010
15012
|
toolTraceEvents: external_exports.array(ToolTraceEventSchema).optional(),
|
|
15013
|
+
stopReason: StopReasonSchema.optional(),
|
|
15011
15014
|
/** Error message from streaming response (e.g., SSE error event) */
|
|
15012
15015
|
error: external_exports.string().nullable().optional()
|
|
15013
15016
|
});
|
|
@@ -17164,6 +17167,264 @@ var idGenerationChain = Promise.resolve();
|
|
|
17164
17167
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
17165
17168
|
var publicRequestStorage = new AsyncLocalStorage();
|
|
17166
17169
|
|
|
17170
|
+
// src/lib/resourceLimits.ts
|
|
17171
|
+
var MAX_REST_LOG_PAGE_SIZE = 200;
|
|
17172
|
+
var MAX_SEARCH_QUERY_CHARS = 512;
|
|
17173
|
+
var MAX_SEARCH_PROJECT_CHARS = 256;
|
|
17174
|
+
var MAX_PROVIDER_MODELS = 64;
|
|
17175
|
+
var MAX_PROVIDER_MODEL_METADATA = 64;
|
|
17176
|
+
var MAX_SSE_CLIENTS = 32;
|
|
17177
|
+
var MAX_ACTIVE_PROVIDER_TESTS = 2;
|
|
17178
|
+
var MAX_PROVIDER_TEST_CONCURRENCY = 4;
|
|
17179
|
+
var MAX_ACTIVE_PROXY_REQUESTS = 16;
|
|
17180
|
+
var positiveInteger = external_exports.number().int().positive();
|
|
17181
|
+
var RuntimeBudgetPolicySchema = external_exports.object({
|
|
17182
|
+
proxy: external_exports.object({
|
|
17183
|
+
requestBytes: positiveInteger,
|
|
17184
|
+
responseBytes: positiveInteger,
|
|
17185
|
+
headerBytes: positiveInteger,
|
|
17186
|
+
deadlineMs: positiveInteger,
|
|
17187
|
+
idleTimeoutMs: positiveInteger,
|
|
17188
|
+
activeRequests: positiveInteger
|
|
17189
|
+
}),
|
|
17190
|
+
control: external_exports.object({
|
|
17191
|
+
requestBytes: positiveInteger,
|
|
17192
|
+
responseBytes: positiveInteger,
|
|
17193
|
+
headerBytes: positiveInteger,
|
|
17194
|
+
deadlineMs: positiveInteger,
|
|
17195
|
+
idleTimeoutMs: positiveInteger,
|
|
17196
|
+
activeRequests: positiveInteger
|
|
17197
|
+
}),
|
|
17198
|
+
upstream: external_exports.object({
|
|
17199
|
+
fetchResponseBytes: positiveInteger,
|
|
17200
|
+
fetchDeadlineMs: positiveInteger,
|
|
17201
|
+
replayResponseBytes: positiveInteger,
|
|
17202
|
+
replayDeadlineMs: positiveInteger,
|
|
17203
|
+
metadataResponseBytes: positiveInteger,
|
|
17204
|
+
metadataDeadlineMs: positiveInteger,
|
|
17205
|
+
connectTimeoutMs: positiveInteger,
|
|
17206
|
+
idleTimeoutMs: positiveInteger
|
|
17207
|
+
}),
|
|
17208
|
+
pagination: external_exports.object({
|
|
17209
|
+
restPageSize: positiveInteger,
|
|
17210
|
+
searchQueryChars: positiveInteger,
|
|
17211
|
+
searchProjectChars: positiveInteger
|
|
17212
|
+
}),
|
|
17213
|
+
sse: external_exports.object({
|
|
17214
|
+
clients: positiveInteger,
|
|
17215
|
+
initLogs: positiveInteger,
|
|
17216
|
+
heartbeatMs: positiveInteger
|
|
17217
|
+
}),
|
|
17218
|
+
imports: external_exports.object({
|
|
17219
|
+
archiveBytes: positiveInteger,
|
|
17220
|
+
entries: positiveInteger,
|
|
17221
|
+
entryBytes: positiveInteger,
|
|
17222
|
+
uncompressedBytes: positiveInteger,
|
|
17223
|
+
expansionRatio: positiveInteger
|
|
17224
|
+
}),
|
|
17225
|
+
fanOut: external_exports.object({
|
|
17226
|
+
providerModels: positiveInteger,
|
|
17227
|
+
providerModelMetadata: positiveInteger,
|
|
17228
|
+
providerTestConcurrency: positiveInteger,
|
|
17229
|
+
activeProviderTests: positiveInteger
|
|
17230
|
+
}),
|
|
17231
|
+
queues: external_exports.object({
|
|
17232
|
+
proxyRequests: positiveInteger,
|
|
17233
|
+
finalizerJobs: positiveInteger,
|
|
17234
|
+
rawStreamMessages: positiveInteger,
|
|
17235
|
+
rawStreamBytes: positiveInteger,
|
|
17236
|
+
backgroundWorkers: positiveInteger
|
|
17237
|
+
})
|
|
17238
|
+
}).superRefine((policy, context) => {
|
|
17239
|
+
if (policy.control.requestBytes > policy.proxy.requestBytes) {
|
|
17240
|
+
context.addIssue({
|
|
17241
|
+
code: "custom",
|
|
17242
|
+
path: ["control", "requestBytes"],
|
|
17243
|
+
message: "control request budget must not exceed proxy request budget"
|
|
17244
|
+
});
|
|
17245
|
+
}
|
|
17246
|
+
if (policy.control.responseBytes > policy.proxy.responseBytes) {
|
|
17247
|
+
context.addIssue({
|
|
17248
|
+
code: "custom",
|
|
17249
|
+
path: ["control", "responseBytes"],
|
|
17250
|
+
message: "control response budget must not exceed proxy response budget"
|
|
17251
|
+
});
|
|
17252
|
+
}
|
|
17253
|
+
if (policy.control.activeRequests > policy.proxy.activeRequests) {
|
|
17254
|
+
context.addIssue({
|
|
17255
|
+
code: "custom",
|
|
17256
|
+
path: ["control", "activeRequests"],
|
|
17257
|
+
message: "control active request budget must not exceed proxy active request budget"
|
|
17258
|
+
});
|
|
17259
|
+
}
|
|
17260
|
+
if (policy.upstream.fetchResponseBytes > policy.proxy.responseBytes) {
|
|
17261
|
+
context.addIssue({
|
|
17262
|
+
code: "custom",
|
|
17263
|
+
path: ["upstream", "fetchResponseBytes"],
|
|
17264
|
+
message: "upstream fetch response budget must not exceed proxy response budget"
|
|
17265
|
+
});
|
|
17266
|
+
}
|
|
17267
|
+
if (policy.upstream.replayResponseBytes > policy.proxy.responseBytes) {
|
|
17268
|
+
context.addIssue({
|
|
17269
|
+
code: "custom",
|
|
17270
|
+
path: ["upstream", "replayResponseBytes"],
|
|
17271
|
+
message: "upstream replay response budget must not exceed proxy response budget"
|
|
17272
|
+
});
|
|
17273
|
+
}
|
|
17274
|
+
if (policy.upstream.metadataResponseBytes > policy.control.responseBytes) {
|
|
17275
|
+
context.addIssue({
|
|
17276
|
+
code: "custom",
|
|
17277
|
+
path: ["upstream", "metadataResponseBytes"],
|
|
17278
|
+
message: "upstream metadata response budget must not exceed control response budget"
|
|
17279
|
+
});
|
|
17280
|
+
}
|
|
17281
|
+
if (policy.upstream.metadataDeadlineMs > policy.control.deadlineMs) {
|
|
17282
|
+
context.addIssue({
|
|
17283
|
+
code: "custom",
|
|
17284
|
+
path: ["upstream", "metadataDeadlineMs"],
|
|
17285
|
+
message: "upstream metadata deadline must not exceed control deadline"
|
|
17286
|
+
});
|
|
17287
|
+
}
|
|
17288
|
+
if (policy.queues.proxyRequests < policy.proxy.activeRequests) {
|
|
17289
|
+
context.addIssue({
|
|
17290
|
+
code: "custom",
|
|
17291
|
+
path: ["queues", "proxyRequests"],
|
|
17292
|
+
message: "proxy request queue budget must cover active proxy requests"
|
|
17293
|
+
});
|
|
17294
|
+
}
|
|
17295
|
+
});
|
|
17296
|
+
var DEFAULT_RUNTIME_BUDGET_POLICY = RuntimeBudgetPolicySchema.parse({
|
|
17297
|
+
proxy: {
|
|
17298
|
+
requestBytes: 64 * 1024 * 1024,
|
|
17299
|
+
responseBytes: 256 * 1024 * 1024,
|
|
17300
|
+
headerBytes: 64 * 1024,
|
|
17301
|
+
deadlineMs: 12e4,
|
|
17302
|
+
idleTimeoutMs: 3e4,
|
|
17303
|
+
activeRequests: MAX_ACTIVE_PROXY_REQUESTS
|
|
17304
|
+
},
|
|
17305
|
+
control: {
|
|
17306
|
+
requestBytes: 8 * 1024 * 1024,
|
|
17307
|
+
responseBytes: 64 * 1024 * 1024,
|
|
17308
|
+
headerBytes: 32 * 1024,
|
|
17309
|
+
deadlineMs: 3e4,
|
|
17310
|
+
idleTimeoutMs: 1e4,
|
|
17311
|
+
activeRequests: 8
|
|
17312
|
+
},
|
|
17313
|
+
upstream: {
|
|
17314
|
+
fetchResponseBytes: 256 * 1024 * 1024,
|
|
17315
|
+
fetchDeadlineMs: 12e4,
|
|
17316
|
+
replayResponseBytes: 256 * 1024 * 1024,
|
|
17317
|
+
replayDeadlineMs: 12e4,
|
|
17318
|
+
metadataResponseBytes: 10 * 1024 * 1024,
|
|
17319
|
+
metadataDeadlineMs: 3e4,
|
|
17320
|
+
connectTimeoutMs: 1e4,
|
|
17321
|
+
idleTimeoutMs: 3e4
|
|
17322
|
+
},
|
|
17323
|
+
pagination: {
|
|
17324
|
+
restPageSize: MAX_REST_LOG_PAGE_SIZE,
|
|
17325
|
+
searchQueryChars: MAX_SEARCH_QUERY_CHARS,
|
|
17326
|
+
searchProjectChars: MAX_SEARCH_PROJECT_CHARS
|
|
17327
|
+
},
|
|
17328
|
+
sse: {
|
|
17329
|
+
clients: MAX_SSE_CLIENTS,
|
|
17330
|
+
initLogs: 500,
|
|
17331
|
+
heartbeatMs: 15e3
|
|
17332
|
+
},
|
|
17333
|
+
imports: {
|
|
17334
|
+
archiveBytes: 64 * 1024 * 1024,
|
|
17335
|
+
entries: 5e3,
|
|
17336
|
+
entryBytes: 32 * 1024 * 1024,
|
|
17337
|
+
uncompressedBytes: 256 * 1024 * 1024,
|
|
17338
|
+
expansionRatio: 20
|
|
17339
|
+
},
|
|
17340
|
+
fanOut: {
|
|
17341
|
+
providerModels: MAX_PROVIDER_MODELS,
|
|
17342
|
+
providerModelMetadata: MAX_PROVIDER_MODEL_METADATA,
|
|
17343
|
+
providerTestConcurrency: MAX_PROVIDER_TEST_CONCURRENCY,
|
|
17344
|
+
activeProviderTests: MAX_ACTIVE_PROVIDER_TESTS
|
|
17345
|
+
},
|
|
17346
|
+
queues: {
|
|
17347
|
+
proxyRequests: MAX_ACTIVE_PROXY_REQUESTS,
|
|
17348
|
+
finalizerJobs: 1e3,
|
|
17349
|
+
rawStreamMessages: 16384,
|
|
17350
|
+
rawStreamBytes: 64 * 1024 * 1024,
|
|
17351
|
+
backgroundWorkers: 4
|
|
17352
|
+
}
|
|
17353
|
+
});
|
|
17354
|
+
var ResourceLimitErrorCodeSchema = external_exports.enum([
|
|
17355
|
+
"invalid-page-request",
|
|
17356
|
+
"search-limit-exceeded",
|
|
17357
|
+
"provider-model-limit-exceeded",
|
|
17358
|
+
"sse-capacity-exceeded",
|
|
17359
|
+
"provider-test-capacity-exceeded",
|
|
17360
|
+
"proxy-capacity-exceeded"
|
|
17361
|
+
]);
|
|
17362
|
+
var ResourceLimitStatusSchema = external_exports.union([
|
|
17363
|
+
external_exports.literal(400),
|
|
17364
|
+
external_exports.literal(413),
|
|
17365
|
+
external_exports.literal(429),
|
|
17366
|
+
external_exports.literal(503)
|
|
17367
|
+
]);
|
|
17368
|
+
var ResourceLimitErrorSchema = external_exports.object({
|
|
17369
|
+
error: external_exports.string().min(1).max(300),
|
|
17370
|
+
code: ResourceLimitErrorCodeSchema,
|
|
17371
|
+
status: ResourceLimitStatusSchema,
|
|
17372
|
+
resource: external_exports.string().min(1).max(80),
|
|
17373
|
+
limit: external_exports.number().int().positive(),
|
|
17374
|
+
retryable: external_exports.boolean()
|
|
17375
|
+
});
|
|
17376
|
+
|
|
17377
|
+
// src/proxy/rawStreamCapture.ts
|
|
17378
|
+
var DEFAULT_MEMORY_LIMIT_BYTES = 1024 * 1024;
|
|
17379
|
+
var FILE_WRITE_BATCH_BYTES = 64 * 1024;
|
|
17380
|
+
var DEFAULT_QUEUE_MAX_BYTES = 8 * 1024 * 1024;
|
|
17381
|
+
var DEFAULT_GLOBAL_QUEUE_MAX_MESSAGES = 4096;
|
|
17382
|
+
var DEFAULT_GLOBAL_QUEUE_MAX_BYTES = 64 * 1024 * 1024;
|
|
17383
|
+
function resolvePositiveIntegerEnv(name, fallback) {
|
|
17384
|
+
const raw = process.env[name];
|
|
17385
|
+
if (raw === void 0 || raw === "") return fallback;
|
|
17386
|
+
const parsed = Number(raw);
|
|
17387
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1) return fallback;
|
|
17388
|
+
return parsed;
|
|
17389
|
+
}
|
|
17390
|
+
var RawStreamObservationBudget = class {
|
|
17391
|
+
constructor(maxMessages, maxBytes) {
|
|
17392
|
+
this.maxMessages = maxMessages;
|
|
17393
|
+
this.maxBytes = maxBytes;
|
|
17394
|
+
}
|
|
17395
|
+
maxMessages;
|
|
17396
|
+
maxBytes;
|
|
17397
|
+
messages = 0;
|
|
17398
|
+
bytes = 0;
|
|
17399
|
+
tryAcquire(bytes) {
|
|
17400
|
+
if (this.messages + 1 > this.maxMessages || this.bytes + bytes > this.maxBytes) return null;
|
|
17401
|
+
this.messages += 1;
|
|
17402
|
+
this.bytes += bytes;
|
|
17403
|
+
let released = false;
|
|
17404
|
+
return () => {
|
|
17405
|
+
if (released) return;
|
|
17406
|
+
released = true;
|
|
17407
|
+
this.messages -= 1;
|
|
17408
|
+
this.bytes -= bytes;
|
|
17409
|
+
};
|
|
17410
|
+
}
|
|
17411
|
+
};
|
|
17412
|
+
var globalObservationBudget = new RawStreamObservationBudget(
|
|
17413
|
+
resolvePositiveIntegerEnv(
|
|
17414
|
+
"AGENT_INSPECTOR_OBSERVATION_GLOBAL_QUEUE_MESSAGES",
|
|
17415
|
+
DEFAULT_GLOBAL_QUEUE_MAX_MESSAGES
|
|
17416
|
+
),
|
|
17417
|
+
resolvePositiveIntegerEnv(
|
|
17418
|
+
"AGENT_INSPECTOR_OBSERVATION_GLOBAL_QUEUE_BYTES",
|
|
17419
|
+
DEFAULT_GLOBAL_QUEUE_MAX_BYTES
|
|
17420
|
+
)
|
|
17421
|
+
);
|
|
17422
|
+
|
|
17423
|
+
// src/proxy/storageLifecycle.ts
|
|
17424
|
+
var DAY_MS2 = 24 * 60 * 60 * 1e3;
|
|
17425
|
+
var DEFAULT_MAX_TOTAL_BYTES = 2 * 1024 * 1024 * 1024;
|
|
17426
|
+
var DEFAULT_MAINTENANCE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
17427
|
+
|
|
17167
17428
|
// src/proxy/store.ts
|
|
17168
17429
|
var sessionArchiveQueue = Promise.resolve();
|
|
17169
17430
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tonyclaw/agent-inspector",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent observability and knowledge capture layer for AI coding tools.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"test:integration": "node scripts/run-local-bun.mjs scripts/run-test-suite.mjs integration",
|
|
65
65
|
"test:changed": "node scripts/run-local-bun.mjs scripts/run-test-suite.mjs changed",
|
|
66
66
|
"test:all": "node scripts/run-local-bun.mjs scripts/run-test-suite.mjs all",
|
|
67
|
+
"test:hostile-inputs": "bun test src/proxy/identityProxy.test.ts src/proxy/handler.cancellationCompatibility.test.ts src/proxy/logImporter.test.ts src/backend/routes/api/-logs.stream.test.ts src/proxy/handler.admission.test.ts src/proxy/runtimeHealth.test.ts src/proxy/storageLifecycle.test.ts",
|
|
67
68
|
"test:compatibility-tooling": "node scripts/run-compatibility-tests.mjs ultra",
|
|
68
69
|
"test:compatibility-tooling:extended": "node scripts/run-compatibility-tests.mjs extended",
|
|
69
70
|
"test:compatibility-conformance": "node scripts/run-compatibility-tests.mjs conformance",
|
|
@@ -82,6 +83,9 @@
|
|
|
82
83
|
"smoke:ui-preview": "node scripts/smoke-decoupled-ui-preview.mjs",
|
|
83
84
|
"check:bundle": "node scripts/check-client-bundle.mjs",
|
|
84
85
|
"check:boundaries": "node scripts/check-runtime-boundaries.mjs",
|
|
86
|
+
"check:commercial-performance": "node scripts/check-commercial-performance-budgets.mjs",
|
|
87
|
+
"check:hostile-inputs": "node scripts/check-hostile-input-coverage.mjs",
|
|
88
|
+
"check:supply-chain": "node scripts/check-commercial-supply-chain.mjs",
|
|
85
89
|
"compatibility:bdd": "node scripts/lint-bdd-catalog.mjs",
|
|
86
90
|
"compatibility:compare": "node scripts/compatibility/cli.mjs compare",
|
|
87
91
|
"compatibility:drift": "node scripts/check-backend-compatibility.mjs",
|
|
@@ -98,7 +102,10 @@
|
|
|
98
102
|
"rust:pack-package": "node scripts/rust/pack-platform.mjs",
|
|
99
103
|
"rust:native-artifact": "node scripts/rust/create-native-artifact.mjs",
|
|
100
104
|
"rust:native:aggregate": "node scripts/rust/aggregate-native-artifacts.mjs",
|
|
101
|
-
"
|
|
105
|
+
"rust:release-gate:preflight": "node scripts/rust/release-gate-preflight.mjs",
|
|
106
|
+
"commercial:release-gate:preflight": "node scripts/commercial-release-preflight.mjs",
|
|
107
|
+
"test:commercial-release-gate": "bun test scripts/commercialReleasePreflight.test.ts",
|
|
108
|
+
"test:rust-packaging": "bun test scripts/rust/npmPackaging.test.ts scripts/rust/nativeReleaseContract.test.ts scripts/rust/nativeStartupSmoke.test.ts scripts/rust/releaseGatePreflight.test.ts scripts/releaseCore.test.ts",
|
|
102
109
|
"rust:packages:check": "node scripts/rust/sync-package-versions.mjs",
|
|
103
110
|
"rust:packages:sync": "node scripts/rust/sync-package-versions.mjs --write",
|
|
104
111
|
"themes:generate": "node scripts/generate-theme-scales.mjs",
|
|
@@ -116,7 +123,7 @@
|
|
|
116
123
|
"extension:release": "node scripts/release-chrome-extension.mjs",
|
|
117
124
|
"release": "node scripts/release.mjs",
|
|
118
125
|
"knip": "knip",
|
|
119
|
-
"check": "bun scripts/run-static-checks.mjs --format && bun check:boundaries && bun compatibility:bdd && bun rust:packages:check",
|
|
126
|
+
"check": "bun scripts/run-static-checks.mjs --format && bun check:boundaries && bun check:commercial-performance && bun check:hostile-inputs && bun compatibility:bdd && bun rust:packages:check",
|
|
120
127
|
"prepare": "husky",
|
|
121
128
|
"ladle": "ladle serve",
|
|
122
129
|
"ladle:build": "ladle build"
|
|
@@ -146,9 +153,9 @@
|
|
|
146
153
|
"zod": "^4.4.3"
|
|
147
154
|
},
|
|
148
155
|
"optionalDependencies": {
|
|
149
|
-
"@tonyclaw/agent-inspector-backend-darwin-arm64": "3.1.
|
|
150
|
-
"@tonyclaw/agent-inspector-backend-linux-x64-gnu": "3.1.
|
|
151
|
-
"@tonyclaw/agent-inspector-backend-win32-x64-msvc": "3.1.
|
|
156
|
+
"@tonyclaw/agent-inspector-backend-darwin-arm64": "3.1.21",
|
|
157
|
+
"@tonyclaw/agent-inspector-backend-linux-x64-gnu": "3.1.21",
|
|
158
|
+
"@tonyclaw/agent-inspector-backend-win32-x64-msvc": "3.1.21",
|
|
152
159
|
"better-sqlite3": "^12.11.1",
|
|
153
160
|
"rcedit": "4.0.1"
|
|
154
161
|
},
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
} from "../../../proxy/upstream";
|
|
25
25
|
import { computeTokensPerSecond } from "../../../proxy/streamTiming";
|
|
26
26
|
import { safeFetch } from "../../../lib/safeFetch";
|
|
27
|
+
import { DEFAULT_RUNTIME_BUDGET_POLICY } from "../../../lib/resourceLimits";
|
|
27
28
|
|
|
28
29
|
type ReplayRequest = {
|
|
29
30
|
modifiedBody: string;
|
|
@@ -136,7 +137,11 @@ export const Route = createFileRoute("/api/logs/$id/replay")({
|
|
|
136
137
|
headers,
|
|
137
138
|
body: modifiedBody,
|
|
138
139
|
},
|
|
139
|
-
{
|
|
140
|
+
{
|
|
141
|
+
allowLoopback: process.env["AGENT_INSPECTOR_ALLOW_LOOPBACK"] === "1",
|
|
142
|
+
deadlineMs: DEFAULT_RUNTIME_BUDGET_POLICY.upstream.replayDeadlineMs,
|
|
143
|
+
responseBytes: DEFAULT_RUNTIME_BUDGET_POLICY.upstream.replayResponseBytes,
|
|
144
|
+
},
|
|
140
145
|
);
|
|
141
146
|
if (!fetchResult.ok) {
|
|
142
147
|
return Response.json({
|
|
@@ -18,6 +18,13 @@ const UPDATE_COALESCE_MS = 50;
|
|
|
18
18
|
const MAX_BUFFERED_UPDATE_EVENTS = 16;
|
|
19
19
|
const sseClientLimiter = createCapacityLimiter(MAX_SSE_CLIENTS);
|
|
20
20
|
|
|
21
|
+
export function getLogsStreamMetrics(): { activeClients: number; capacity: number } {
|
|
22
|
+
return {
|
|
23
|
+
activeClients: sseClientLimiter.activeCount(),
|
|
24
|
+
capacity: sseClientLimiter.capacity,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
21
28
|
export function streamIncludesBodies(url: URL): boolean {
|
|
22
29
|
return url.searchParams.get("compact") === "0";
|
|
23
30
|
}
|
|
@@ -9,7 +9,11 @@ import {
|
|
|
9
9
|
ProviderModelRegistrySchema,
|
|
10
10
|
} from "../../../lib/providerModelMetadata";
|
|
11
11
|
import { safeFetch } from "../../../lib/safeFetch";
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
DEFAULT_RUNTIME_BUDGET_POLICY,
|
|
14
|
+
MAX_PROVIDER_MODELS,
|
|
15
|
+
resourceLimitResponse,
|
|
16
|
+
} from "../../../lib/resourceLimits";
|
|
13
17
|
|
|
14
18
|
const RefreshModelMetadataInputSchema = z.object({
|
|
15
19
|
url: z.string().optional(),
|
|
@@ -85,9 +89,16 @@ export const Route = createFileRoute("/api/providers/$providerId/model-metadata"
|
|
|
85
89
|
|
|
86
90
|
let response: Response;
|
|
87
91
|
try {
|
|
88
|
-
const fetchResult = await safeFetch(
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
const fetchResult = await safeFetch(
|
|
93
|
+
sourceUrl,
|
|
94
|
+
{
|
|
95
|
+
headers: { Accept: "application/json" },
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
deadlineMs: DEFAULT_RUNTIME_BUDGET_POLICY.upstream.metadataDeadlineMs,
|
|
99
|
+
responseBytes: DEFAULT_RUNTIME_BUDGET_POLICY.upstream.metadataResponseBytes,
|
|
100
|
+
},
|
|
101
|
+
);
|
|
91
102
|
if (!fetchResult.ok) {
|
|
92
103
|
return Response.json(
|
|
93
104
|
{ error: `Model metadata URL blocked: ${fetchResult.reason}` },
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
2
|
+
import { getLogStorageStats } from "../../../proxy/store";
|
|
3
|
+
import {
|
|
4
|
+
getLastStorageLifecycleGcResult,
|
|
5
|
+
getStorageLifecycleInventory,
|
|
6
|
+
resolveStorageLifecycleQuotaPolicy,
|
|
7
|
+
runStorageLifecycleGc,
|
|
8
|
+
type StorageLifecycleGcResult,
|
|
9
|
+
} from "../../../proxy/storageLifecycle";
|
|
10
|
+
|
|
11
|
+
function summarizeGcResult(result: StorageLifecycleGcResult | null) {
|
|
12
|
+
if (result === null) return null;
|
|
13
|
+
return {
|
|
14
|
+
checkedAt: result.checkedAt,
|
|
15
|
+
filesDeleted: result.filesDeleted,
|
|
16
|
+
bytesDeleted: result.bytesDeleted,
|
|
17
|
+
errors: result.errors.length,
|
|
18
|
+
beforeTotalBytes: result.before.totalBytes,
|
|
19
|
+
afterTotalBytes: result.after.totalBytes,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function getStorageResponse() {
|
|
24
|
+
const logStats = getLogStorageStats();
|
|
25
|
+
const inventory = getStorageLifecycleInventory();
|
|
26
|
+
const policy = resolveStorageLifecycleQuotaPolicy();
|
|
27
|
+
const reclaimableBytes = inventory.artifacts
|
|
28
|
+
.filter(
|
|
29
|
+
(artifact) =>
|
|
30
|
+
artifact.cleanupBehavior === "retention-gc" ||
|
|
31
|
+
artifact.cleanupBehavior === "orphan-reclaim",
|
|
32
|
+
)
|
|
33
|
+
.reduce((sum, artifact) => sum + artifact.bytes, 0);
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
memoryCount: logStats.memoryCount,
|
|
37
|
+
inventory,
|
|
38
|
+
policy,
|
|
39
|
+
reclaimableBytes,
|
|
40
|
+
lastGc: summarizeGcResult(getLastStorageLifecycleGcResult()),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const Route = createFileRoute("/api/storage")({
|
|
45
|
+
server: {
|
|
46
|
+
handlers: {
|
|
47
|
+
GET: () => {
|
|
48
|
+
return Response.json(getStorageResponse(), { headers: { "cache-control": "no-store" } });
|
|
49
|
+
},
|
|
50
|
+
POST: () => {
|
|
51
|
+
runStorageLifecycleGc();
|
|
52
|
+
return Response.json(getStorageResponse(), { headers: { "cache-control": "no-store" } });
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
2
|
+
import { getLogsStreamMetrics } from "./api/logs.stream";
|
|
3
|
+
import { getSafeOperationalMetrics } from "../../proxy/runtimeMetrics";
|
|
4
|
+
|
|
5
|
+
export const Route = createFileRoute("/metrics")({
|
|
6
|
+
server: {
|
|
7
|
+
handlers: {
|
|
8
|
+
GET: async () => {
|
|
9
|
+
const metrics = await getSafeOperationalMetrics(getLogsStreamMetrics());
|
|
10
|
+
return Response.json(metrics, { headers: { "cache-control": "no-store" } });
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|