@tonyclaw/agent-inspector 2.0.29 → 2.0.31
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/nitro.json +1 -1
- package/.output/public/assets/{CompareDrawer-DcqxlgSQ.js → CompareDrawer-tIUf2EJm.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-BxRaXhKR.js +115 -0
- package/.output/public/assets/{ReplayDialog-CBcnPgx1.js → ReplayDialog-D6v1xcuC.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-DSgSqCYt.js → RequestAnatomy-D6PniTlx.js} +1 -1
- package/.output/public/assets/{ResponseView-CjqzBSoF.js → ResponseView-Sx8PjuvU.js} +1 -1
- package/.output/public/assets/{StreamingChunkSequence-DdBBKolI.js → StreamingChunkSequence-D-Rbfnxh.js} +1 -1
- package/.output/public/assets/_sessionId-BhNTuZ31.js +1 -0
- package/.output/public/assets/index-Byk60-jA.css +1 -0
- package/.output/public/assets/index-Kxptlkpg.js +1 -0
- package/.output/public/assets/{main-B6OLZCp9.js → main-B1kdhY98.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +159 -134
- package/.output/server/{_sessionId-CCfKJJ19.mjs → _sessionId-BceHFKf4.mjs} +3 -3
- package/.output/server/_ssr/{CompareDrawer-uaPI5R6e.mjs → CompareDrawer-uSxK5Ei5.mjs} +3 -3
- package/.output/server/_ssr/{ProxyViewerContainer-BV2nIxXy.mjs → ProxyViewerContainer-_npQ_f2i.mjs} +566 -17
- package/.output/server/_ssr/{ReplayDialog-eE2Hy2Nl.mjs → ReplayDialog-BHAzSLCT.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-B7vwWo57.mjs → RequestAnatomy-DjlZLXBd.mjs} +3 -3
- package/.output/server/_ssr/{ResponseView-Bm6Qp8mo.mjs → ResponseView-BuDEJ3fl.mjs} +3 -3
- package/.output/server/_ssr/{StreamingChunkSequence-CbAJKJQx.mjs → StreamingChunkSequence-DFcu0bD8.mjs} +3 -3
- package/.output/server/_ssr/{index-u14_Aj60.mjs → index-Bw6Fw33c.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-qgeGUp1k.mjs → router-D90tMCb3.mjs} +1236 -143
- package/.output/server/_tanstack-start-manifest_v-BVM4AUlx.mjs +4 -0
- package/.output/server/index.mjs +60 -60
- package/README.md +24 -1
- package/package.json +1 -1
- package/src/components/ProxyViewer.tsx +9 -2
- package/src/components/groups/GroupsDialog.tsx +732 -0
- package/src/lib/groupContract.ts +148 -0
- package/src/lib/runContract.ts +2 -0
- package/src/lib/useGroupEvidence.ts +33 -0
- package/src/lib/useGroups.ts +28 -0
- package/src/mcp/server.ts +282 -1
- package/src/mcp/toolHandlers.ts +123 -0
- package/src/proxy/groupEvidenceExporter.ts +354 -0
- package/src/proxy/groupStore.ts +259 -0
- package/src/routes/api/groups.$groupId.evidence.ts +74 -0
- package/src/routes/api/groups.$groupId.sessions.ts +50 -0
- package/src/routes/api/groups.$groupId.ts +50 -0
- package/src/routes/api/groups.ts +39 -0
- package/.output/public/assets/ProxyViewerContainer-D650kQlv.js +0 -115
- package/.output/public/assets/_sessionId-wctOoGh_.js +0 -1
- package/.output/public/assets/index-BhQGSdhG.js +0 -1
- package/.output/public/assets/index-CwlHPmgL.css +0 -1
- package/.output/server/_tanstack-start-manifest_v-BrfUXnre.mjs +0 -4
|
@@ -50,8 +50,8 @@ import "../_libs/mimic-function.mjs";
|
|
|
50
50
|
import "../_libs/semver.mjs";
|
|
51
51
|
import "../_libs/uint8array-extras.mjs";
|
|
52
52
|
const faviconSvg = "data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2064%2064'%20role='img'%20aria-label='Agent%20Inspector'%3e%3crect%20width='64'%20height='64'%20rx='14'%20fill='%23111827'%20/%3e%3cg%20fill='none'%20stroke='%23f59e0b'%20stroke-width='4.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3e%3cpath%20fill='%23f59e0b'%20d='M15%2036c0-11%207-18%2017-18s17%207%2017%2018c0%208-7%2013-17%2013s-17-5-17-13z'%20/%3e%3cpath%20d='M16%2031c-6-5-12-3-12%204%200%205%206%206%2011%202'%20/%3e%3cpath%20d='M48%2031c6-5%2012-3%2012%204%200%205-6%206-11%202'%20/%3e%3cpath%20d='M27%2019l-3-7'%20/%3e%3cpath%20d='M37%2019l3-7'%20/%3e%3cpath%20d='M19%2045l-6%209'%20/%3e%3cpath%20d='M27%2048l-3%209'%20/%3e%3cpath%20d='M37%2048l3%209'%20/%3e%3cpath%20d='M45%2045l6%209'%20/%3e%3c/g%3e%3cpath%20d='M14%2047l9-8%208%209c-5%203.5-12%203-17-1z'%20fill='%232f6b3f'%20opacity='.95'%20/%3e%3cpath%20d='M18%2046l5-5%205%206c-3%201.6-7%201.4-10-1z'%20fill='%236fb36f'%20opacity='.95'%20/%3e%3cpath%20d='M23%2041v10'%20fill='none'%20stroke='%23d6b45f'%20stroke-width='1.6'%20stroke-linecap='round'%20/%3e%3ccircle%20cx='31'%20cy='48'%20r='1.8'%20fill='%23c2412d'%20/%3e%3cpath%20d='M24%2044l13-11%2014%2013c-8%205.8-18%205.3-27-2z'%20fill='%232f6b3f'%20opacity='.97'%20/%3e%3cpath%20d='M30%2043l7-7%209%209c-5%202.7-11%202.5-16-2z'%20fill='%236fb36f'%20opacity='.95'%20/%3e%3cpath%20d='M37%2036v14'%20fill='none'%20stroke='%23d6b45f'%20stroke-width='2'%20stroke-linecap='round'%20/%3e%3cpath%20d='M30%2043c5-2%2011-1.5%2016%202'%20fill='none'%20stroke='%239fca78'%20stroke-width='1.8'%20stroke-linecap='round'%20/%3e%3ccircle%20cx='51'%20cy='46'%20r='2'%20fill='%23c2412d'%20/%3e%3cpath%20d='M40%2050l8-8%207%208c-4.2%203.2-10%203-15%200z'%20fill='%232f6b3f'%20opacity='.95'%20/%3e%3cpath%20d='M43%2049l5-5%204.5%205.5c-3%201.5-6%201.2-9.5-.5z'%20fill='%236fb36f'%20opacity='.95'%20/%3e%3cpath%20d='M48%2044v9'%20fill='none'%20stroke='%23d6b45f'%20stroke-width='1.5'%20stroke-linecap='round'%20/%3e%3ccircle%20cx='55'%20cy='50'%20r='1.7'%20fill='%23c2412d'%20/%3e%3ccircle%20cx='24'%20cy='11'%20r='3.2'%20fill='%23f59e0b'%20/%3e%3ccircle%20cx='40'%20cy='11'%20r='3.2'%20fill='%23f59e0b'%20/%3e%3ccircle%20cx='25'%20cy='34'%20r='2.1'%20fill='%23111827'%20/%3e%3ccircle%20cx='39'%20cy='34'%20r='2.1'%20fill='%23111827'%20/%3e%3c/svg%3e";
|
|
53
|
-
const appCss = "/assets/index-
|
|
54
|
-
const Route$
|
|
53
|
+
const appCss = "/assets/index-Byk60-jA.css";
|
|
54
|
+
const Route$z = createRootRoute({
|
|
55
55
|
head: () => ({
|
|
56
56
|
meta: [
|
|
57
57
|
{ charSet: "utf-8" },
|
|
@@ -93,8 +93,8 @@ function RootDocument({ children }) {
|
|
|
93
93
|
] })
|
|
94
94
|
] });
|
|
95
95
|
}
|
|
96
|
-
const $$splitComponentImporter$1 = () => import("./index-
|
|
97
|
-
const Route$
|
|
96
|
+
const $$splitComponentImporter$1 = () => import("./index-Bw6Fw33c.mjs");
|
|
97
|
+
const Route$y = createFileRoute("/")({
|
|
98
98
|
component: lazyRouteComponent($$splitComponentImporter$1, "component")
|
|
99
99
|
});
|
|
100
100
|
const B64URL_RE = /^[A-Za-z0-9_-]+$/;
|
|
@@ -136,8 +136,8 @@ function decodeSessionIdFromPath(encoded) {
|
|
|
136
136
|
function getSessionPath(sessionId) {
|
|
137
137
|
return `/session/${encodeSessionIdForPath(sessionId)}`;
|
|
138
138
|
}
|
|
139
|
-
const $$splitComponentImporter = () => import("../_sessionId-
|
|
140
|
-
const Route$
|
|
139
|
+
const $$splitComponentImporter = () => import("../_sessionId-BceHFKf4.mjs");
|
|
140
|
+
const Route$x = createFileRoute("/session/$sessionId")({
|
|
141
141
|
component: lazyRouteComponent($$splitComponentImporter, "component"),
|
|
142
142
|
parseParams: (params) => ({
|
|
143
143
|
sessionId: decodeSessionIdFromPath(params.sessionId)
|
|
@@ -1085,7 +1085,7 @@ function nonNegativeInteger(value) {
|
|
|
1085
1085
|
if (value === null || !Number.isFinite(value) || value < 0) return 0;
|
|
1086
1086
|
return Math.floor(value);
|
|
1087
1087
|
}
|
|
1088
|
-
function addTokenUsage(total, summary) {
|
|
1088
|
+
function addTokenUsage$1(total, summary) {
|
|
1089
1089
|
const input = nonNegativeInteger(summary.tokens.input);
|
|
1090
1090
|
const output = nonNegativeInteger(summary.tokens.output);
|
|
1091
1091
|
const cacheCreate = nonNegativeInteger(summary.tokens.cacheCreate);
|
|
@@ -1115,7 +1115,7 @@ function buildApiPath(sessionId) {
|
|
|
1115
1115
|
function buildCompactLogsPath(sessionId) {
|
|
1116
1116
|
return buildRelativePath("/api/logs", new URLSearchParams({ compact: "1", sessionId }));
|
|
1117
1117
|
}
|
|
1118
|
-
function collectSortedValues(values) {
|
|
1118
|
+
function collectSortedValues$1(values) {
|
|
1119
1119
|
const set = /* @__PURE__ */ new Set();
|
|
1120
1120
|
for (const value of values) {
|
|
1121
1121
|
if (value !== null && value.length > 0) {
|
|
@@ -1159,7 +1159,7 @@ function buildSessionInfo(input) {
|
|
|
1159
1159
|
const errorCount = Math.max(countErrorLogs(summaries), input.snapshot?.failedRequests ?? 0);
|
|
1160
1160
|
const completedLogCount = countCompletedLogs(summaries);
|
|
1161
1161
|
const tokenUsage = summaries.reduce(
|
|
1162
|
-
(total, summary) => addTokenUsage(total, summary),
|
|
1162
|
+
(total, summary) => addTokenUsage$1(total, summary),
|
|
1163
1163
|
{ input: 0, output: 0, cacheCreate: 0, cacheRead: 0, total: 0 }
|
|
1164
1164
|
);
|
|
1165
1165
|
const requestCount = Math.max(input.snapshot?.requestCount ?? 0, logCount);
|
|
@@ -1197,8 +1197,8 @@ function buildSessionInfo(input) {
|
|
|
1197
1197
|
lastTaskError,
|
|
1198
1198
|
logCount,
|
|
1199
1199
|
errorCount,
|
|
1200
|
-
models: collectSortedValues(summaries.map((summary) => summary.model)),
|
|
1201
|
-
providers: collectSortedValues(summaries.map((summary) => summary.provider)),
|
|
1200
|
+
models: collectSortedValues$1(summaries.map((summary) => summary.model)),
|
|
1201
|
+
providers: collectSortedValues$1(summaries.map((summary) => summary.provider)),
|
|
1202
1202
|
tokenUsage,
|
|
1203
1203
|
lastLogId: input.snapshot?.lastLogId ?? latestLog?.id ?? null,
|
|
1204
1204
|
lastModel: normalizeString(input.snapshot?.lastModel) ?? latestLog?.model ?? null,
|
|
@@ -4935,7 +4935,7 @@ async function handleProxy(req) {
|
|
|
4935
4935
|
}
|
|
4936
4936
|
return handleStreamingResponse(upstreamRes, req, startTime, upstreamUrl, log, captureFullDetails);
|
|
4937
4937
|
}
|
|
4938
|
-
const Route$
|
|
4938
|
+
const Route$w = createFileRoute("/proxy/$")({
|
|
4939
4939
|
server: {
|
|
4940
4940
|
handlers: {
|
|
4941
4941
|
GET: ({ request }) => handleProxy(request),
|
|
@@ -4956,7 +4956,7 @@ function parsePositiveInt$2(value) {
|
|
|
4956
4956
|
function parseBooleanFlag(value) {
|
|
4957
4957
|
return value === "1" || value === "true";
|
|
4958
4958
|
}
|
|
4959
|
-
const Route$
|
|
4959
|
+
const Route$v = createFileRoute("/api/sessions")({
|
|
4960
4960
|
server: {
|
|
4961
4961
|
handlers: {
|
|
4962
4962
|
GET: async ({ request }) => {
|
|
@@ -5111,6 +5111,7 @@ const JenkinsReportSchema = object({
|
|
|
5111
5111
|
summary: string(),
|
|
5112
5112
|
markdown: string()
|
|
5113
5113
|
});
|
|
5114
|
+
const EvidenceReportSchema = JenkinsReportSchema;
|
|
5114
5115
|
const InspectorRunSchema = object({
|
|
5115
5116
|
id: string(),
|
|
5116
5117
|
sessionId: string(),
|
|
@@ -5179,10 +5180,10 @@ const RunsFileSchema = object({
|
|
|
5179
5180
|
function runsFilePath() {
|
|
5180
5181
|
return join(getDataDir(), "runs.json");
|
|
5181
5182
|
}
|
|
5182
|
-
function nowIso() {
|
|
5183
|
+
function nowIso$1() {
|
|
5183
5184
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
5184
5185
|
}
|
|
5185
|
-
function stableId(input) {
|
|
5186
|
+
function stableId$1(input) {
|
|
5186
5187
|
return input.trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
5187
5188
|
}
|
|
5188
5189
|
function createRunId() {
|
|
@@ -5190,7 +5191,7 @@ function createRunId() {
|
|
|
5190
5191
|
}
|
|
5191
5192
|
function normalizeRunId(input) {
|
|
5192
5193
|
if (input === void 0) return createRunId();
|
|
5193
|
-
const normalized = stableId(input);
|
|
5194
|
+
const normalized = stableId$1(input);
|
|
5194
5195
|
return normalized.length > 0 ? normalized : createRunId();
|
|
5195
5196
|
}
|
|
5196
5197
|
function normalizeSessionId(input, runId) {
|
|
@@ -5225,7 +5226,7 @@ function createRun(input) {
|
|
|
5225
5226
|
const runId = normalizeRunId(parsed?.runId);
|
|
5226
5227
|
const existing = getRun(runId);
|
|
5227
5228
|
if (existing !== null) return existing;
|
|
5228
|
-
const timestamp = nowIso();
|
|
5229
|
+
const timestamp = nowIso$1();
|
|
5229
5230
|
const sessionId = normalizeSessionId(parsed?.sessionId, runId);
|
|
5230
5231
|
const run = {
|
|
5231
5232
|
id: runId,
|
|
@@ -5264,7 +5265,7 @@ function updateRun(runId, input) {
|
|
|
5264
5265
|
const parsed = UpdateInspectorRunInputSchema.parse(input);
|
|
5265
5266
|
const runs = readRuns();
|
|
5266
5267
|
let updatedRun = null;
|
|
5267
|
-
const updatedAt = nowIso();
|
|
5268
|
+
const updatedAt = nowIso$1();
|
|
5268
5269
|
const updatedRuns = runs.map((run) => {
|
|
5269
5270
|
if (run.id !== runId) return run;
|
|
5270
5271
|
updatedRun = {
|
|
@@ -5351,7 +5352,7 @@ function listRecentFailures(limit) {
|
|
|
5351
5352
|
limit: clampedLimit
|
|
5352
5353
|
};
|
|
5353
5354
|
}
|
|
5354
|
-
async function readJsonBody$
|
|
5355
|
+
async function readJsonBody$6(request) {
|
|
5355
5356
|
try {
|
|
5356
5357
|
const raw = await request.text();
|
|
5357
5358
|
if (raw.trim().length === 0) return { ok: true, value: void 0 };
|
|
@@ -5366,7 +5367,7 @@ function parsePositiveInt$1(value, fallback) {
|
|
|
5366
5367
|
if (!Number.isInteger(parsed) || parsed < 1) return fallback;
|
|
5367
5368
|
return parsed;
|
|
5368
5369
|
}
|
|
5369
|
-
const Route$
|
|
5370
|
+
const Route$u = createFileRoute("/api/runs")({
|
|
5370
5371
|
server: {
|
|
5371
5372
|
handlers: {
|
|
5372
5373
|
GET: ({ request }) => {
|
|
@@ -5381,7 +5382,7 @@ const Route$q = createFileRoute("/api/runs")({
|
|
|
5381
5382
|
return Response.json({ runs: listRuns() });
|
|
5382
5383
|
},
|
|
5383
5384
|
POST: async ({ request }) => {
|
|
5384
|
-
const body = await readJsonBody$
|
|
5385
|
+
const body = await readJsonBody$6(request);
|
|
5385
5386
|
if (!body.ok) {
|
|
5386
5387
|
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
5387
5388
|
}
|
|
@@ -5411,7 +5412,7 @@ const ProviderInputSchema = object({
|
|
|
5411
5412
|
modelMetadata: array(ProviderModelMetadataSchema).optional(),
|
|
5412
5413
|
source: _enum(["company", "personal"]).optional()
|
|
5413
5414
|
});
|
|
5414
|
-
const Route$
|
|
5415
|
+
const Route$t = createFileRoute("/api/providers")({
|
|
5415
5416
|
server: {
|
|
5416
5417
|
handlers: {
|
|
5417
5418
|
GET: ({ request }) => {
|
|
@@ -5445,13 +5446,128 @@ const Route$p = createFileRoute("/api/providers")({
|
|
|
5445
5446
|
}
|
|
5446
5447
|
}
|
|
5447
5448
|
});
|
|
5448
|
-
const Route$
|
|
5449
|
+
const Route$s = createFileRoute("/api/models")({
|
|
5449
5450
|
server: {
|
|
5450
5451
|
handlers: {
|
|
5451
5452
|
GET: () => Response.json(getModels())
|
|
5452
5453
|
}
|
|
5453
5454
|
}
|
|
5454
5455
|
});
|
|
5456
|
+
const version = "2.0.31";
|
|
5457
|
+
const packageJson = {
|
|
5458
|
+
version
|
|
5459
|
+
};
|
|
5460
|
+
const InspectorGroupStatusSchema = _enum([
|
|
5461
|
+
"created",
|
|
5462
|
+
"running",
|
|
5463
|
+
"completed",
|
|
5464
|
+
"failed",
|
|
5465
|
+
"cancelled"
|
|
5466
|
+
]);
|
|
5467
|
+
const InspectorGroupKindSchema = _enum(["evaluation", "batch", "manual"]);
|
|
5468
|
+
const InspectorGroupEvidenceSchema = object({
|
|
5469
|
+
jsonPath: string(),
|
|
5470
|
+
markdownPath: string(),
|
|
5471
|
+
htmlPath: string(),
|
|
5472
|
+
exportedAt: string()
|
|
5473
|
+
});
|
|
5474
|
+
const InspectorGroupMemberSchema = object({
|
|
5475
|
+
id: string(),
|
|
5476
|
+
groupId: string(),
|
|
5477
|
+
sessionId: string(),
|
|
5478
|
+
runId: string().nullable(),
|
|
5479
|
+
label: string().nullable(),
|
|
5480
|
+
agent: string().nullable(),
|
|
5481
|
+
provider: string().nullable(),
|
|
5482
|
+
model: string().nullable(),
|
|
5483
|
+
status: InspectorRunStatusSchema.nullable(),
|
|
5484
|
+
metadata: record(string(), JsonValueSchema),
|
|
5485
|
+
addedAt: string(),
|
|
5486
|
+
updatedAt: string()
|
|
5487
|
+
});
|
|
5488
|
+
const InspectorGroupSchema = object({
|
|
5489
|
+
id: string(),
|
|
5490
|
+
title: string(),
|
|
5491
|
+
kind: InspectorGroupKindSchema,
|
|
5492
|
+
task: string().nullable(),
|
|
5493
|
+
project: string().nullable(),
|
|
5494
|
+
status: InspectorGroupStatusSchema,
|
|
5495
|
+
tags: array(string()),
|
|
5496
|
+
metadata: record(string(), JsonValueSchema),
|
|
5497
|
+
evidence: InspectorGroupEvidenceSchema.nullable(),
|
|
5498
|
+
members: array(InspectorGroupMemberSchema),
|
|
5499
|
+
createdAt: string(),
|
|
5500
|
+
updatedAt: string()
|
|
5501
|
+
});
|
|
5502
|
+
const CreateInspectorGroupInputSchema = object({
|
|
5503
|
+
groupId: string().min(1).optional(),
|
|
5504
|
+
title: string().min(1).optional(),
|
|
5505
|
+
kind: InspectorGroupKindSchema.optional(),
|
|
5506
|
+
task: string().nullable().optional(),
|
|
5507
|
+
project: string().nullable().optional(),
|
|
5508
|
+
status: InspectorGroupStatusSchema.optional(),
|
|
5509
|
+
tags: array(string()).optional(),
|
|
5510
|
+
metadata: record(string(), JsonValueSchema).optional()
|
|
5511
|
+
}).optional();
|
|
5512
|
+
const UpdateInspectorGroupInputSchema = object({
|
|
5513
|
+
title: string().min(1).optional(),
|
|
5514
|
+
kind: InspectorGroupKindSchema.optional(),
|
|
5515
|
+
task: string().nullable().optional(),
|
|
5516
|
+
project: string().nullable().optional(),
|
|
5517
|
+
status: InspectorGroupStatusSchema.optional(),
|
|
5518
|
+
tags: array(string()).optional(),
|
|
5519
|
+
metadata: record(string(), JsonValueSchema).optional()
|
|
5520
|
+
});
|
|
5521
|
+
const AddInspectorGroupSessionInputSchema = object({
|
|
5522
|
+
memberId: string().min(1).optional(),
|
|
5523
|
+
sessionId: string().min(1),
|
|
5524
|
+
runId: string().min(1).nullable().optional(),
|
|
5525
|
+
label: string().min(1).nullable().optional(),
|
|
5526
|
+
agent: string().min(1).nullable().optional(),
|
|
5527
|
+
provider: string().min(1).nullable().optional(),
|
|
5528
|
+
model: string().min(1).nullable().optional(),
|
|
5529
|
+
status: InspectorRunStatusSchema.nullable().optional(),
|
|
5530
|
+
metadata: record(string(), JsonValueSchema).optional()
|
|
5531
|
+
});
|
|
5532
|
+
const GroupEvidenceExportOptionsSchema = object({
|
|
5533
|
+
includeHistory: boolean().optional(),
|
|
5534
|
+
latestLogLimit: number().int().positive().max(50).optional()
|
|
5535
|
+
}).optional();
|
|
5536
|
+
const InspectorGroupExportMemberSchema = object({
|
|
5537
|
+
member: InspectorGroupMemberSchema,
|
|
5538
|
+
run: InspectorRunSchema.nullable(),
|
|
5539
|
+
session: SessionInfoSchema.nullable()
|
|
5540
|
+
});
|
|
5541
|
+
const InspectorGroupEvidenceSummarySchema = object({
|
|
5542
|
+
memberCount: number().int().nonnegative(),
|
|
5543
|
+
sessionsWithData: number().int().nonnegative(),
|
|
5544
|
+
missingSessions: number().int().nonnegative(),
|
|
5545
|
+
requestCount: number().int().nonnegative(),
|
|
5546
|
+
errorCount: number().int().nonnegative(),
|
|
5547
|
+
tokenUsage: SessionTokenUsageSchema,
|
|
5548
|
+
models: array(string()),
|
|
5549
|
+
providers: array(string()),
|
|
5550
|
+
completedMembers: number().int().nonnegative(),
|
|
5551
|
+
failedMembers: number().int().nonnegative(),
|
|
5552
|
+
runningMembers: number().int().nonnegative()
|
|
5553
|
+
});
|
|
5554
|
+
const GroupEvidenceReadResponseSchema$1 = object({
|
|
5555
|
+
group: InspectorGroupSchema,
|
|
5556
|
+
evidence: InspectorGroupEvidenceSchema,
|
|
5557
|
+
markdown: string(),
|
|
5558
|
+
summary: InspectorGroupEvidenceSummarySchema.nullable(),
|
|
5559
|
+
report: EvidenceReportSchema.nullable()
|
|
5560
|
+
});
|
|
5561
|
+
const GroupEvidenceExportResultSchema = object({
|
|
5562
|
+
group: InspectorGroupSchema,
|
|
5563
|
+
evidence: InspectorGroupEvidenceSchema,
|
|
5564
|
+
members: array(InspectorGroupExportMemberSchema),
|
|
5565
|
+
summary: InspectorGroupEvidenceSummarySchema,
|
|
5566
|
+
jenkinsReport: EvidenceReportSchema
|
|
5567
|
+
});
|
|
5568
|
+
const InspectorGroupsListResponseSchema = object({
|
|
5569
|
+
groups: array(InspectorGroupSchema)
|
|
5570
|
+
});
|
|
5455
5571
|
let overridePort = null;
|
|
5456
5572
|
function setCurrentPort(port) {
|
|
5457
5573
|
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
|
|
@@ -5851,6 +5967,85 @@ async function exportEvidenceImpl(callApi2, args) {
|
|
|
5851
5967
|
}
|
|
5852
5968
|
return textJson(parsed.data);
|
|
5853
5969
|
}
|
|
5970
|
+
async function listGroupsImpl(callApi2) {
|
|
5971
|
+
const res = await callApi2("/api/groups");
|
|
5972
|
+
if (!res.ok) return toolError(`GET /api/groups returned ${res.status}`);
|
|
5973
|
+
const rawBody = await res.json();
|
|
5974
|
+
const parsed = InspectorGroupsListResponseSchema.safeParse(rawBody);
|
|
5975
|
+
if (!parsed.success) return toolError("GET /api/groups returned an unparseable group list");
|
|
5976
|
+
return textJson(parsed.data);
|
|
5977
|
+
}
|
|
5978
|
+
async function createGroupImpl(callApi2, args) {
|
|
5979
|
+
const res = await callApi2("/api/groups", {
|
|
5980
|
+
method: "POST",
|
|
5981
|
+
headers: { "content-type": "application/json" },
|
|
5982
|
+
body: JSON.stringify(args ?? {})
|
|
5983
|
+
});
|
|
5984
|
+
if (!res.ok) return toolError(`POST /api/groups returned ${res.status}`);
|
|
5985
|
+
const rawBody = await res.json();
|
|
5986
|
+
const parsed = InspectorGroupSchema.safeParse(rawBody);
|
|
5987
|
+
if (!parsed.success) return toolError("POST /api/groups returned an unparseable group");
|
|
5988
|
+
return textJson(parsed.data);
|
|
5989
|
+
}
|
|
5990
|
+
async function getGroupImpl(callApi2, args) {
|
|
5991
|
+
const path2 = `/api/groups/${encodeURIComponent(args.groupId)}`;
|
|
5992
|
+
const res = await callApi2(path2);
|
|
5993
|
+
if (!res.ok) return toolError(`GET ${path2} returned ${res.status}`);
|
|
5994
|
+
const rawBody = await res.json();
|
|
5995
|
+
const parsed = InspectorGroupSchema.safeParse(rawBody);
|
|
5996
|
+
if (!parsed.success) return toolError("GET /api/groups/{groupId} returned an unparseable group");
|
|
5997
|
+
return textJson(parsed.data);
|
|
5998
|
+
}
|
|
5999
|
+
async function updateGroupImpl(callApi2, args) {
|
|
6000
|
+
const { groupId, ...patch } = args;
|
|
6001
|
+
const path2 = `/api/groups/${encodeURIComponent(groupId)}`;
|
|
6002
|
+
const res = await callApi2(path2, {
|
|
6003
|
+
method: "PATCH",
|
|
6004
|
+
headers: { "content-type": "application/json" },
|
|
6005
|
+
body: JSON.stringify(patch)
|
|
6006
|
+
});
|
|
6007
|
+
if (!res.ok) return toolError(`PATCH ${path2} returned ${res.status}`);
|
|
6008
|
+
const rawBody = await res.json();
|
|
6009
|
+
const parsed = InspectorGroupSchema.safeParse(rawBody);
|
|
6010
|
+
if (!parsed.success) {
|
|
6011
|
+
return toolError("PATCH /api/groups/{groupId} returned an unparseable group");
|
|
6012
|
+
}
|
|
6013
|
+
return textJson(parsed.data);
|
|
6014
|
+
}
|
|
6015
|
+
async function addGroupSessionImpl(callApi2, args) {
|
|
6016
|
+
const { groupId, ...session } = args;
|
|
6017
|
+
const path2 = `/api/groups/${encodeURIComponent(groupId)}/sessions`;
|
|
6018
|
+
const res = await callApi2(path2, {
|
|
6019
|
+
method: "POST",
|
|
6020
|
+
headers: { "content-type": "application/json" },
|
|
6021
|
+
body: JSON.stringify(session)
|
|
6022
|
+
});
|
|
6023
|
+
if (!res.ok) return toolError(`POST ${path2} returned ${res.status}`);
|
|
6024
|
+
const rawBody = await res.json();
|
|
6025
|
+
const parsed = InspectorGroupSchema.safeParse(rawBody);
|
|
6026
|
+
if (!parsed.success) {
|
|
6027
|
+
return toolError("POST /api/groups/{groupId}/sessions returned an unparseable group");
|
|
6028
|
+
}
|
|
6029
|
+
return textJson(parsed.data);
|
|
6030
|
+
}
|
|
6031
|
+
async function exportGroupEvidenceImpl(callApi2, args) {
|
|
6032
|
+
const path2 = `/api/groups/${encodeURIComponent(args.groupId)}/evidence`;
|
|
6033
|
+
const res = await callApi2(path2, {
|
|
6034
|
+
method: "POST",
|
|
6035
|
+
headers: { "content-type": "application/json" },
|
|
6036
|
+
body: JSON.stringify({
|
|
6037
|
+
includeHistory: args.includeHistory,
|
|
6038
|
+
latestLogLimit: args.latestLogLimit
|
|
6039
|
+
})
|
|
6040
|
+
});
|
|
6041
|
+
if (!res.ok) return toolError(`POST ${path2} returned ${res.status}`);
|
|
6042
|
+
const rawBody = await res.json();
|
|
6043
|
+
const parsed = GroupEvidenceExportResultSchema.safeParse(rawBody);
|
|
6044
|
+
if (!parsed.success) {
|
|
6045
|
+
return toolError("POST /api/groups/{groupId}/evidence returned an unparseable evidence result");
|
|
6046
|
+
}
|
|
6047
|
+
return textJson(parsed.data);
|
|
6048
|
+
}
|
|
5854
6049
|
async function listModelsImpl(callApi2) {
|
|
5855
6050
|
const res = await callApi2("/api/models");
|
|
5856
6051
|
if (!res.ok) return toolError(`GET /api/models returned ${res.status}`);
|
|
@@ -5976,11 +6171,12 @@ async function safeCall(fn) {
|
|
|
5976
6171
|
return toolError(`Tool execution failed: ${message}`);
|
|
5977
6172
|
}
|
|
5978
6173
|
}
|
|
6174
|
+
const MCP_SERVER_VERSION = packageJson.version;
|
|
5979
6175
|
let initialized = null;
|
|
5980
6176
|
let initPromise = null;
|
|
5981
6177
|
function buildServer() {
|
|
5982
6178
|
const server = new McpServer(
|
|
5983
|
-
{ name: "agent-inspector", version:
|
|
6179
|
+
{ name: "agent-inspector", version: MCP_SERVER_VERSION },
|
|
5984
6180
|
{ capabilities: { tools: {}, resources: {}, prompts: {} } }
|
|
5985
6181
|
);
|
|
5986
6182
|
registerTools(server);
|
|
@@ -6042,6 +6238,9 @@ const LogResourceListResponseSchema = object({
|
|
|
6042
6238
|
const EvidenceReadResponseSchema = object({
|
|
6043
6239
|
markdown: string()
|
|
6044
6240
|
});
|
|
6241
|
+
const GroupEvidenceReadResponseSchema = object({
|
|
6242
|
+
markdown: string()
|
|
6243
|
+
});
|
|
6045
6244
|
function textResource(uri, mimeType, text) {
|
|
6046
6245
|
return {
|
|
6047
6246
|
contents: [{ uri: uri.href, mimeType, text }]
|
|
@@ -6124,6 +6323,61 @@ async function listRunResources() {
|
|
|
6124
6323
|
return listResult([]);
|
|
6125
6324
|
}
|
|
6126
6325
|
}
|
|
6326
|
+
async function listGroupResources() {
|
|
6327
|
+
try {
|
|
6328
|
+
const response = await callApi("/api/groups");
|
|
6329
|
+
if (!response.ok) return listResult([]);
|
|
6330
|
+
const parsed = InspectorGroupsListResponseSchema.safeParse(await response.json());
|
|
6331
|
+
if (!parsed.success) return listResult([]);
|
|
6332
|
+
return listResult(
|
|
6333
|
+
parsed.data.groups.map((group) => ({
|
|
6334
|
+
uri: `inspector://groups/${encodeURIComponent(group.id)}`,
|
|
6335
|
+
name: `group:${group.id}`,
|
|
6336
|
+
title: group.title,
|
|
6337
|
+
mimeType: "application/json"
|
|
6338
|
+
}))
|
|
6339
|
+
);
|
|
6340
|
+
} catch {
|
|
6341
|
+
return listResult([]);
|
|
6342
|
+
}
|
|
6343
|
+
}
|
|
6344
|
+
async function listGroupSessionResources() {
|
|
6345
|
+
try {
|
|
6346
|
+
const response = await callApi("/api/groups");
|
|
6347
|
+
if (!response.ok) return listResult([]);
|
|
6348
|
+
const parsed = InspectorGroupsListResponseSchema.safeParse(await response.json());
|
|
6349
|
+
if (!parsed.success) return listResult([]);
|
|
6350
|
+
return listResult(
|
|
6351
|
+
parsed.data.groups.map((group) => ({
|
|
6352
|
+
uri: `inspector://groups/${encodeURIComponent(group.id)}/sessions`,
|
|
6353
|
+
name: `group-sessions:${group.id}`,
|
|
6354
|
+
title: `${group.title} sessions`,
|
|
6355
|
+
mimeType: "application/json"
|
|
6356
|
+
}))
|
|
6357
|
+
);
|
|
6358
|
+
} catch {
|
|
6359
|
+
return listResult([]);
|
|
6360
|
+
}
|
|
6361
|
+
}
|
|
6362
|
+
async function listGroupEvidenceResources() {
|
|
6363
|
+
try {
|
|
6364
|
+
const response = await callApi("/api/groups");
|
|
6365
|
+
if (!response.ok) return listResult([]);
|
|
6366
|
+
const parsed = InspectorGroupsListResponseSchema.safeParse(await response.json());
|
|
6367
|
+
if (!parsed.success) return listResult([]);
|
|
6368
|
+
return listResult(
|
|
6369
|
+
parsed.data.groups.filter((group) => group.evidence !== null).map((group) => ({
|
|
6370
|
+
uri: `inspector://groups/${encodeURIComponent(group.id)}/evidence`,
|
|
6371
|
+
name: `group-evidence:${group.id}`,
|
|
6372
|
+
title: `${group.title} evidence pack`,
|
|
6373
|
+
mimeType: "text/markdown",
|
|
6374
|
+
description: group.evidence?.markdownPath
|
|
6375
|
+
}))
|
|
6376
|
+
);
|
|
6377
|
+
} catch {
|
|
6378
|
+
return listResult([]);
|
|
6379
|
+
}
|
|
6380
|
+
}
|
|
6127
6381
|
async function listEvidenceResources() {
|
|
6128
6382
|
try {
|
|
6129
6383
|
const response = await callApi("/api/runs");
|
|
@@ -6296,6 +6550,77 @@ function registerTools(server) {
|
|
|
6296
6550
|
},
|
|
6297
6551
|
(args) => safeCall(() => getRecentFailuresImpl(callApi, args))
|
|
6298
6552
|
);
|
|
6553
|
+
server.registerTool(
|
|
6554
|
+
"inspector_list_groups",
|
|
6555
|
+
{
|
|
6556
|
+
title: "List Inspector groups",
|
|
6557
|
+
description: "Lists declared Inspector groups. Groups aggregate multiple sessions/runs, commonly one evaluation matrix spanning several providers or models.",
|
|
6558
|
+
inputSchema: object({})
|
|
6559
|
+
},
|
|
6560
|
+
() => safeCall(() => listGroupsImpl(callApi))
|
|
6561
|
+
);
|
|
6562
|
+
server.registerTool(
|
|
6563
|
+
"inspector_create_group",
|
|
6564
|
+
{
|
|
6565
|
+
title: "Create or declare an Inspector group",
|
|
6566
|
+
description: "Creates an evaluation/batch group that external systems can use to aggregate multiple OpenCode/Codex sessions across models such as MiniMax, DeepSeek, or GLM.",
|
|
6567
|
+
inputSchema: object({
|
|
6568
|
+
groupId: string().min(1).optional().describe("Stable group id. Generated when omitted."),
|
|
6569
|
+
title: string().min(1).optional().describe("Human-readable group title."),
|
|
6570
|
+
kind: _enum(["evaluation", "batch", "manual"]).optional().describe("Group kind. Defaults to evaluation."),
|
|
6571
|
+
task: string().nullable().optional().describe("Task, benchmark, or evaluation goal."),
|
|
6572
|
+
project: string().nullable().optional().describe("Project or repository under test."),
|
|
6573
|
+
status: InspectorGroupStatusSchema.optional().describe("Initial group status."),
|
|
6574
|
+
tags: array(string()).optional().describe("Free-form group labels."),
|
|
6575
|
+
metadata: record(string(), JsonValueSchema).optional().describe("JSON metadata.")
|
|
6576
|
+
})
|
|
6577
|
+
},
|
|
6578
|
+
(args) => safeCall(() => createGroupImpl(callApi, args))
|
|
6579
|
+
);
|
|
6580
|
+
server.registerTool(
|
|
6581
|
+
"inspector_get_group",
|
|
6582
|
+
{
|
|
6583
|
+
title: "Get an Inspector group",
|
|
6584
|
+
description: "Returns one declared Inspector group with its attached session/run members and exported evidence paths when available.",
|
|
6585
|
+
inputSchema: object({
|
|
6586
|
+
groupId: string().min(1).describe("The Inspector group id.")
|
|
6587
|
+
})
|
|
6588
|
+
},
|
|
6589
|
+
(args) => safeCall(() => getGroupImpl(callApi, args))
|
|
6590
|
+
);
|
|
6591
|
+
server.registerTool(
|
|
6592
|
+
"inspector_update_group",
|
|
6593
|
+
{
|
|
6594
|
+
title: "Update an Inspector group",
|
|
6595
|
+
description: "PATCH-style update for a declared group. Use this to mark a whole evaluation running, failed, completed, or to merge CI metadata.",
|
|
6596
|
+
inputSchema: UpdateInspectorGroupInputSchema.extend({
|
|
6597
|
+
groupId: string().min(1).describe("The Inspector group id.")
|
|
6598
|
+
})
|
|
6599
|
+
},
|
|
6600
|
+
(args) => safeCall(() => updateGroupImpl(callApi, args))
|
|
6601
|
+
);
|
|
6602
|
+
server.registerTool(
|
|
6603
|
+
"inspector_add_group_session",
|
|
6604
|
+
{
|
|
6605
|
+
title: "Attach a session to an Inspector group",
|
|
6606
|
+
description: "Adds or updates one group member. Use it after each OpenCode process discovers its session id, or while an evaluation matrix is running to attach model/provider labels.",
|
|
6607
|
+
inputSchema: AddInspectorGroupSessionInputSchema.extend({
|
|
6608
|
+
groupId: string().min(1).describe("The Inspector group id.")
|
|
6609
|
+
})
|
|
6610
|
+
},
|
|
6611
|
+
(args) => safeCall(() => addGroupSessionImpl(callApi, args))
|
|
6612
|
+
);
|
|
6613
|
+
server.registerTool(
|
|
6614
|
+
"inspector_export_group_evidence",
|
|
6615
|
+
{
|
|
6616
|
+
title: "Export an Inspector group evidence pack",
|
|
6617
|
+
description: "Exports a whole group's evidence pack to local JSON, Markdown, and HTML files under <dataDir>/evidence/groups/<groupId>. The export contains a provider/model matrix and compact session summaries.",
|
|
6618
|
+
inputSchema: GroupEvidenceExportOptionsSchema.unwrap().extend({
|
|
6619
|
+
groupId: string().min(1).describe("The Inspector group id.")
|
|
6620
|
+
})
|
|
6621
|
+
},
|
|
6622
|
+
(args) => safeCall(() => exportGroupEvidenceImpl(callApi, args))
|
|
6623
|
+
);
|
|
6299
6624
|
server.registerTool(
|
|
6300
6625
|
"inspector_list_models",
|
|
6301
6626
|
{
|
|
@@ -6503,6 +6828,46 @@ function registerResources(server) {
|
|
|
6503
6828
|
},
|
|
6504
6829
|
(uri) => readApiJsonResource(uri, "/api/runs")
|
|
6505
6830
|
);
|
|
6831
|
+
server.registerResource(
|
|
6832
|
+
"inspector_groups",
|
|
6833
|
+
"inspector://groups",
|
|
6834
|
+
{
|
|
6835
|
+
title: "Inspector groups",
|
|
6836
|
+
description: "Declared Inspector groups aggregating multiple sessions or runs.",
|
|
6837
|
+
mimeType: "application/json"
|
|
6838
|
+
},
|
|
6839
|
+
(uri) => readApiJsonResource(uri, "/api/groups")
|
|
6840
|
+
);
|
|
6841
|
+
server.registerResource(
|
|
6842
|
+
"inspector_group",
|
|
6843
|
+
new ResourceTemplate("inspector://groups/{groupId}", { list: listGroupResources }),
|
|
6844
|
+
{
|
|
6845
|
+
title: "Inspector group",
|
|
6846
|
+
description: "One declared Inspector group with attached session/run members.",
|
|
6847
|
+
mimeType: "application/json"
|
|
6848
|
+
},
|
|
6849
|
+
(uri, variables) => {
|
|
6850
|
+
const groupId = variableString(variables, "groupId");
|
|
6851
|
+
if (groupId === null) return textResource(uri, "text/plain", "Missing groupId");
|
|
6852
|
+
return readApiJsonResource(uri, `/api/groups/${encodeURIComponent(groupId)}`);
|
|
6853
|
+
}
|
|
6854
|
+
);
|
|
6855
|
+
server.registerResource(
|
|
6856
|
+
"inspector_group_sessions",
|
|
6857
|
+
new ResourceTemplate("inspector://groups/{groupId}/sessions", {
|
|
6858
|
+
list: listGroupSessionResources
|
|
6859
|
+
}),
|
|
6860
|
+
{
|
|
6861
|
+
title: "Inspector group sessions",
|
|
6862
|
+
description: "Attached session/run members for one Inspector group.",
|
|
6863
|
+
mimeType: "application/json"
|
|
6864
|
+
},
|
|
6865
|
+
(uri, variables) => {
|
|
6866
|
+
const groupId = variableString(variables, "groupId");
|
|
6867
|
+
if (groupId === null) return textResource(uri, "text/plain", "Missing groupId");
|
|
6868
|
+
return readApiJsonResource(uri, `/api/groups/${encodeURIComponent(groupId)}/sessions`);
|
|
6869
|
+
}
|
|
6870
|
+
);
|
|
6506
6871
|
server.registerResource(
|
|
6507
6872
|
"inspector_recent_failures",
|
|
6508
6873
|
"inspector://failures/recent",
|
|
@@ -6555,6 +6920,36 @@ function registerResources(server) {
|
|
|
6555
6920
|
}
|
|
6556
6921
|
}
|
|
6557
6922
|
);
|
|
6923
|
+
server.registerResource(
|
|
6924
|
+
"inspector_group_evidence",
|
|
6925
|
+
new ResourceTemplate("inspector://groups/{groupId}/evidence", {
|
|
6926
|
+
list: listGroupEvidenceResources
|
|
6927
|
+
}),
|
|
6928
|
+
{
|
|
6929
|
+
title: "Inspector group evidence pack",
|
|
6930
|
+
description: "Markdown evidence pack for an Inspector group. Generate it first with inspector_export_group_evidence.",
|
|
6931
|
+
mimeType: "text/markdown"
|
|
6932
|
+
},
|
|
6933
|
+
async (uri, variables) => {
|
|
6934
|
+
const groupId = variableString(variables, "groupId");
|
|
6935
|
+
if (groupId === null) return textResource(uri, "text/plain", "Missing groupId");
|
|
6936
|
+
const path2 = `/api/groups/${encodeURIComponent(groupId)}/evidence`;
|
|
6937
|
+
try {
|
|
6938
|
+
const response = await callApi(path2);
|
|
6939
|
+
if (!response.ok) {
|
|
6940
|
+
return textResource(uri, "text/plain", `GET ${path2} returned ${response.status}`);
|
|
6941
|
+
}
|
|
6942
|
+
const parsed = GroupEvidenceReadResponseSchema.safeParse(await response.json());
|
|
6943
|
+
if (!parsed.success) {
|
|
6944
|
+
return textResource(uri, "text/plain", "Evidence endpoint returned an unparseable body");
|
|
6945
|
+
}
|
|
6946
|
+
return textResource(uri, "text/markdown", parsed.data.markdown);
|
|
6947
|
+
} catch (err) {
|
|
6948
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6949
|
+
return textResource(uri, "text/plain", `Resource read failed: ${message}`);
|
|
6950
|
+
}
|
|
6951
|
+
}
|
|
6952
|
+
);
|
|
6558
6953
|
}
|
|
6559
6954
|
function registerPrompts(server) {
|
|
6560
6955
|
server.registerPrompt(
|
|
@@ -6627,6 +7022,31 @@ The report should include:
|
|
|
6627
7022
|
3. Models/providers used, token totals, request counts, and error counts
|
|
6628
7023
|
4. Failure analysis or success evidence
|
|
6629
7024
|
5. Reproducible next action for a developer`)
|
|
7025
|
+
);
|
|
7026
|
+
server.registerPrompt(
|
|
7027
|
+
"inspector_generate_group_report",
|
|
7028
|
+
{
|
|
7029
|
+
title: "Generate group report",
|
|
7030
|
+
description: "Generate a model/provider evaluation report from an Inspector group and group evidence pack.",
|
|
7031
|
+
argsSchema: object({
|
|
7032
|
+
groupId: string().min(1).describe("The Inspector group id.")
|
|
7033
|
+
})
|
|
7034
|
+
},
|
|
7035
|
+
({ groupId }) => userPrompt(`Generate a model/provider evaluation report for this Inspector group.
|
|
7036
|
+
|
|
7037
|
+
Evidence to read:
|
|
7038
|
+
- Group resource: inspector://groups/${encodeURIComponent(groupId)}
|
|
7039
|
+
- Group session members: inspector://groups/${encodeURIComponent(groupId)}/sessions
|
|
7040
|
+
- Group evidence pack: inspector://groups/${encodeURIComponent(groupId)}/evidence
|
|
7041
|
+
|
|
7042
|
+
If the evidence pack resource says it has not been exported, call inspector_export_group_evidence for this group first.
|
|
7043
|
+
|
|
7044
|
+
The report should include:
|
|
7045
|
+
1. Evaluation status summary
|
|
7046
|
+
2. Provider/model matrix with session links
|
|
7047
|
+
3. Request counts, token totals, streaming timing, and error counts
|
|
7048
|
+
4. Winner/loser observations when the evidence supports them
|
|
7049
|
+
5. Concrete next actions for failed or missing sessions`)
|
|
6630
7050
|
);
|
|
6631
7051
|
server.registerPrompt(
|
|
6632
7052
|
"inspector_extract_repro_steps",
|
|
@@ -6651,7 +7071,7 @@ Return:
|
|
|
6651
7071
|
5. Minimal verification command or UI check`)
|
|
6652
7072
|
);
|
|
6653
7073
|
}
|
|
6654
|
-
const Route$
|
|
7074
|
+
const Route$r = createFileRoute("/api/mcp")({
|
|
6655
7075
|
server: {
|
|
6656
7076
|
handlers: {
|
|
6657
7077
|
// The SDK may issue either POST, GET, or DELETE. TanStack Start only
|
|
@@ -6761,7 +7181,7 @@ function parsePositiveInt(value, fallback) {
|
|
|
6761
7181
|
if (!Number.isInteger(parsed) || parsed < 1) return fallback;
|
|
6762
7182
|
return parsed;
|
|
6763
7183
|
}
|
|
6764
|
-
const Route$
|
|
7184
|
+
const Route$q = createFileRoute("/api/logs")({
|
|
6765
7185
|
server: {
|
|
6766
7186
|
handlers: {
|
|
6767
7187
|
GET: async ({ request }) => {
|
|
@@ -6837,7 +7257,7 @@ const Route$m = createFileRoute("/api/logs")({
|
|
|
6837
7257
|
}
|
|
6838
7258
|
});
|
|
6839
7259
|
logger.debug("Health endpoint loaded");
|
|
6840
|
-
const Route$
|
|
7260
|
+
const Route$p = createFileRoute("/api/health")({
|
|
6841
7261
|
server: {
|
|
6842
7262
|
handlers: {
|
|
6843
7263
|
GET: () => {
|
|
@@ -6846,33 +7266,246 @@ const Route$l = createFileRoute("/api/health")({
|
|
|
6846
7266
|
}
|
|
6847
7267
|
}
|
|
6848
7268
|
});
|
|
6849
|
-
const
|
|
6850
|
-
|
|
6851
|
-
hasSeenOnboarding: boolean().optional(),
|
|
6852
|
-
slowResponseThresholdSeconds: number().int().min(0).max(MAX_SLOW_RESPONSE_THRESHOLD_SECONDS).optional(),
|
|
6853
|
-
providerTestTimeoutSeconds: number().int().min(1).max(MAX_PROVIDER_TEST_TIMEOUT_SECONDS).optional(),
|
|
6854
|
-
timeDisplayFormat: TimeDisplayFormatSchema.optional()
|
|
6855
|
-
}).strict().refine((v) => Object.keys(v).length > 0, {
|
|
6856
|
-
message: "At least one field must be provided"
|
|
7269
|
+
const GroupsFileSchema = object({
|
|
7270
|
+
groups: array(InspectorGroupSchema)
|
|
6857
7271
|
});
|
|
6858
|
-
|
|
6859
|
-
|
|
6860
|
-
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
7272
|
+
function groupsFilePath() {
|
|
7273
|
+
return join(getDataDir(), "groups.json");
|
|
7274
|
+
}
|
|
7275
|
+
function nowIso() {
|
|
7276
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
7277
|
+
}
|
|
7278
|
+
function stableId(input) {
|
|
7279
|
+
return input.trim().replace(/[^A-Za-z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
7280
|
+
}
|
|
7281
|
+
function createGroupId() {
|
|
7282
|
+
return `grp_${Date.now().toString(36)}_${randomUUID$1().slice(0, 8)}`;
|
|
7283
|
+
}
|
|
7284
|
+
function createMemberId() {
|
|
7285
|
+
return `mem_${Date.now().toString(36)}_${randomUUID$1().slice(0, 8)}`;
|
|
7286
|
+
}
|
|
7287
|
+
function normalizeGroupId(input) {
|
|
7288
|
+
if (input === void 0) return createGroupId();
|
|
7289
|
+
const normalized = stableId(input);
|
|
7290
|
+
return normalized.length > 0 ? normalized : createGroupId();
|
|
7291
|
+
}
|
|
7292
|
+
function normalizeMemberId(input, sessionId) {
|
|
7293
|
+
if (input === void 0) {
|
|
7294
|
+
const normalizedSession = stableId(sessionId);
|
|
7295
|
+
return normalizedSession.length > 0 ? `mem_${normalizedSession}` : createMemberId();
|
|
7296
|
+
}
|
|
7297
|
+
const normalized = stableId(input);
|
|
7298
|
+
return normalized.length > 0 ? normalized : createMemberId();
|
|
7299
|
+
}
|
|
7300
|
+
function nullableText(value) {
|
|
7301
|
+
if (value === void 0 || value === null) return null;
|
|
7302
|
+
const trimmed = value.trim();
|
|
7303
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
7304
|
+
}
|
|
7305
|
+
function readGroups() {
|
|
7306
|
+
const filePath = groupsFilePath();
|
|
7307
|
+
if (!existsSync(filePath)) return [];
|
|
7308
|
+
try {
|
|
7309
|
+
const parsed = JSON.parse(readFileSync(filePath, "utf8"));
|
|
7310
|
+
const result = GroupsFileSchema.safeParse(parsed);
|
|
7311
|
+
return result.success ? result.data.groups : [];
|
|
7312
|
+
} catch {
|
|
7313
|
+
return [];
|
|
7314
|
+
}
|
|
7315
|
+
}
|
|
7316
|
+
function writeGroups(groups) {
|
|
7317
|
+
const filePath = groupsFilePath();
|
|
7318
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
7319
|
+
writeFileSync(filePath, `${JSON.stringify({ groups }, null, 2)}
|
|
7320
|
+
`, "utf8");
|
|
7321
|
+
}
|
|
7322
|
+
function sortedGroups(groups) {
|
|
7323
|
+
return [...groups].sort((left, right) => right.updatedAt.localeCompare(left.updatedAt));
|
|
7324
|
+
}
|
|
7325
|
+
function listGroups() {
|
|
7326
|
+
return sortedGroups(readGroups());
|
|
7327
|
+
}
|
|
7328
|
+
function getGroup(groupId) {
|
|
7329
|
+
return readGroups().find((group) => group.id === groupId) ?? null;
|
|
7330
|
+
}
|
|
7331
|
+
function createGroup(input) {
|
|
7332
|
+
const parsed = CreateInspectorGroupInputSchema.parse(input);
|
|
7333
|
+
const groupId = normalizeGroupId(parsed?.groupId);
|
|
7334
|
+
const existing = getGroup(groupId);
|
|
7335
|
+
if (existing !== null) return existing;
|
|
7336
|
+
const timestamp = nowIso();
|
|
7337
|
+
const group = {
|
|
7338
|
+
id: groupId,
|
|
7339
|
+
title: parsed?.title ?? `Inspector Group ${groupId}`,
|
|
7340
|
+
kind: parsed?.kind ?? "evaluation",
|
|
7341
|
+
task: parsed?.task ?? null,
|
|
7342
|
+
project: parsed?.project ?? null,
|
|
7343
|
+
status: parsed?.status ?? "created",
|
|
7344
|
+
tags: parsed?.tags ?? [],
|
|
7345
|
+
metadata: parsed?.metadata ?? {},
|
|
7346
|
+
evidence: null,
|
|
7347
|
+
members: [],
|
|
7348
|
+
createdAt: timestamp,
|
|
7349
|
+
updatedAt: timestamp
|
|
7350
|
+
};
|
|
7351
|
+
writeGroups([...readGroups(), group]);
|
|
7352
|
+
return group;
|
|
7353
|
+
}
|
|
7354
|
+
function updateGroup(groupId, input) {
|
|
7355
|
+
const parsed = UpdateInspectorGroupInputSchema.parse(input);
|
|
7356
|
+
const groups = readGroups();
|
|
7357
|
+
let updatedGroup = null;
|
|
7358
|
+
const updatedAt = nowIso();
|
|
7359
|
+
const updatedGroups = groups.map((group) => {
|
|
7360
|
+
if (group.id !== groupId) return group;
|
|
7361
|
+
updatedGroup = {
|
|
7362
|
+
...group,
|
|
7363
|
+
title: parsed.title ?? group.title,
|
|
7364
|
+
kind: parsed.kind ?? group.kind,
|
|
7365
|
+
task: parsed.task === void 0 ? group.task : parsed.task,
|
|
7366
|
+
project: parsed.project === void 0 ? group.project : parsed.project,
|
|
7367
|
+
status: parsed.status ?? group.status,
|
|
7368
|
+
tags: parsed.tags ?? group.tags,
|
|
7369
|
+
metadata: parsed.metadata === void 0 ? group.metadata : { ...group.metadata, ...parsed.metadata },
|
|
7370
|
+
updatedAt
|
|
7371
|
+
};
|
|
7372
|
+
return updatedGroup;
|
|
7373
|
+
});
|
|
7374
|
+
if (updatedGroup === null) return null;
|
|
7375
|
+
writeGroups(updatedGroups);
|
|
7376
|
+
return updatedGroup;
|
|
7377
|
+
}
|
|
7378
|
+
function matchesExistingMember(member, memberId, sessionId, runId) {
|
|
7379
|
+
if (member.id === memberId) return true;
|
|
7380
|
+
if (member.sessionId !== sessionId) return false;
|
|
7381
|
+
return member.runId === runId;
|
|
7382
|
+
}
|
|
7383
|
+
function upsertMember(group, input, updatedAt) {
|
|
7384
|
+
const parsed = AddInspectorGroupSessionInputSchema.parse(input);
|
|
7385
|
+
const sessionId = parsed.sessionId.trim();
|
|
7386
|
+
const runId = nullableText(parsed.runId);
|
|
7387
|
+
const memberId = normalizeMemberId(parsed.memberId, sessionId);
|
|
7388
|
+
let matched = false;
|
|
7389
|
+
const members = group.members.map((member) => {
|
|
7390
|
+
if (!matchesExistingMember(member, memberId, sessionId, runId)) return member;
|
|
7391
|
+
matched = true;
|
|
7392
|
+
return {
|
|
7393
|
+
...member,
|
|
7394
|
+
sessionId,
|
|
7395
|
+
runId,
|
|
7396
|
+
label: parsed.label === void 0 ? member.label : nullableText(parsed.label),
|
|
7397
|
+
agent: parsed.agent === void 0 ? member.agent : nullableText(parsed.agent),
|
|
7398
|
+
provider: parsed.provider === void 0 ? member.provider : nullableText(parsed.provider),
|
|
7399
|
+
model: parsed.model === void 0 ? member.model : nullableText(parsed.model),
|
|
7400
|
+
status: parsed.status === void 0 ? member.status : parsed.status,
|
|
7401
|
+
metadata: parsed.metadata === void 0 ? member.metadata : { ...member.metadata, ...parsed.metadata },
|
|
7402
|
+
updatedAt
|
|
7403
|
+
};
|
|
7404
|
+
});
|
|
7405
|
+
if (!matched) {
|
|
7406
|
+
members.push({
|
|
7407
|
+
id: memberId,
|
|
7408
|
+
groupId: group.id,
|
|
7409
|
+
sessionId,
|
|
7410
|
+
runId,
|
|
7411
|
+
label: nullableText(parsed.label),
|
|
7412
|
+
agent: nullableText(parsed.agent),
|
|
7413
|
+
provider: nullableText(parsed.provider),
|
|
7414
|
+
model: nullableText(parsed.model),
|
|
7415
|
+
status: parsed.status ?? null,
|
|
7416
|
+
metadata: parsed.metadata ?? {},
|
|
7417
|
+
addedAt: updatedAt,
|
|
7418
|
+
updatedAt
|
|
7419
|
+
});
|
|
7420
|
+
}
|
|
7421
|
+
return { ...group, members, updatedAt };
|
|
7422
|
+
}
|
|
7423
|
+
function addGroupSession(groupId, input) {
|
|
7424
|
+
const groups = readGroups();
|
|
7425
|
+
let updatedGroup = null;
|
|
7426
|
+
const updatedAt = nowIso();
|
|
7427
|
+
const updatedGroups = groups.map((group) => {
|
|
7428
|
+
if (group.id !== groupId) return group;
|
|
7429
|
+
updatedGroup = upsertMember(group, input, updatedAt);
|
|
7430
|
+
return updatedGroup;
|
|
7431
|
+
});
|
|
7432
|
+
if (updatedGroup === null) return null;
|
|
7433
|
+
writeGroups(updatedGroups);
|
|
7434
|
+
return updatedGroup;
|
|
7435
|
+
}
|
|
7436
|
+
function updateGroupEvidence(groupId, evidence) {
|
|
7437
|
+
const groups = readGroups();
|
|
7438
|
+
let updatedGroup = null;
|
|
7439
|
+
const updatedGroups = groups.map((group) => {
|
|
7440
|
+
if (group.id !== groupId) return group;
|
|
7441
|
+
updatedGroup = {
|
|
7442
|
+
...group,
|
|
7443
|
+
evidence,
|
|
7444
|
+
updatedAt: evidence.exportedAt
|
|
7445
|
+
};
|
|
7446
|
+
return updatedGroup;
|
|
7447
|
+
});
|
|
7448
|
+
if (updatedGroup === null) return null;
|
|
7449
|
+
writeGroups(updatedGroups);
|
|
7450
|
+
return updatedGroup;
|
|
7451
|
+
}
|
|
7452
|
+
async function readJsonBody$5(request) {
|
|
7453
|
+
try {
|
|
7454
|
+
const raw = await request.text();
|
|
7455
|
+
if (raw.trim().length === 0) return { ok: true, value: void 0 };
|
|
7456
|
+
return { ok: true, value: JSON.parse(raw) };
|
|
7457
|
+
} catch {
|
|
7458
|
+
return { ok: false };
|
|
7459
|
+
}
|
|
7460
|
+
}
|
|
7461
|
+
const Route$o = createFileRoute("/api/groups")({
|
|
7462
|
+
server: {
|
|
7463
|
+
handlers: {
|
|
7464
|
+
GET: () => Response.json({ groups: listGroups() }),
|
|
7465
|
+
POST: async ({ request }) => {
|
|
7466
|
+
const body = await readJsonBody$5(request);
|
|
7467
|
+
if (!body.ok) {
|
|
7468
|
+
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
7469
|
+
}
|
|
7470
|
+
const parsed = CreateInspectorGroupInputSchema.safeParse(body.value);
|
|
7471
|
+
if (!parsed.success) {
|
|
7472
|
+
return Response.json(
|
|
7473
|
+
{ error: "Invalid request body", details: parsed.error.format() },
|
|
7474
|
+
{ status: 400 }
|
|
7475
|
+
);
|
|
7476
|
+
}
|
|
7477
|
+
return Response.json(createGroup(parsed.data), { status: 201 });
|
|
7478
|
+
}
|
|
7479
|
+
}
|
|
7480
|
+
}
|
|
7481
|
+
});
|
|
7482
|
+
const RuntimeConfigPatchSchema = object({
|
|
7483
|
+
stripClaudeCodeBillingHeader: boolean().optional(),
|
|
7484
|
+
hasSeenOnboarding: boolean().optional(),
|
|
7485
|
+
slowResponseThresholdSeconds: number().int().min(0).max(MAX_SLOW_RESPONSE_THRESHOLD_SECONDS).optional(),
|
|
7486
|
+
providerTestTimeoutSeconds: number().int().min(1).max(MAX_PROVIDER_TEST_TIMEOUT_SECONDS).optional(),
|
|
7487
|
+
timeDisplayFormat: TimeDisplayFormatSchema.optional()
|
|
7488
|
+
}).strict().refine((v) => Object.keys(v).length > 0, {
|
|
7489
|
+
message: "At least one field must be provided"
|
|
7490
|
+
});
|
|
7491
|
+
const Route$n = createFileRoute("/api/config")({
|
|
7492
|
+
server: {
|
|
7493
|
+
handlers: {
|
|
7494
|
+
GET: () => {
|
|
7495
|
+
return Response.json(getConfig());
|
|
7496
|
+
},
|
|
7497
|
+
PATCH: async ({ request }) => {
|
|
7498
|
+
let body;
|
|
7499
|
+
try {
|
|
7500
|
+
body = await request.json();
|
|
7501
|
+
} catch {
|
|
7502
|
+
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
7503
|
+
}
|
|
7504
|
+
const result = RuntimeConfigPatchSchema.safeParse(body);
|
|
7505
|
+
if (!result.success) {
|
|
7506
|
+
return Response.json(
|
|
7507
|
+
{
|
|
7508
|
+
error: "Invalid config payload",
|
|
6876
7509
|
issues: result.error.issues
|
|
6877
7510
|
},
|
|
6878
7511
|
{ status: 400 }
|
|
@@ -6884,7 +7517,7 @@ const Route$k = createFileRoute("/api/config")({
|
|
|
6884
7517
|
}
|
|
6885
7518
|
}
|
|
6886
7519
|
});
|
|
6887
|
-
async function readJsonBody$
|
|
7520
|
+
async function readJsonBody$4(request) {
|
|
6888
7521
|
try {
|
|
6889
7522
|
const raw = await request.text();
|
|
6890
7523
|
if (raw.trim().length === 0) return { ok: true, value: {} };
|
|
@@ -6893,7 +7526,7 @@ async function readJsonBody$1(request) {
|
|
|
6893
7526
|
return { ok: false };
|
|
6894
7527
|
}
|
|
6895
7528
|
}
|
|
6896
|
-
const Route$
|
|
7529
|
+
const Route$m = createFileRoute("/api/runs/$runId")({
|
|
6897
7530
|
server: {
|
|
6898
7531
|
handlers: {
|
|
6899
7532
|
GET: ({ params }) => {
|
|
@@ -6904,7 +7537,7 @@ const Route$j = createFileRoute("/api/runs/$runId")({
|
|
|
6904
7537
|
return Response.json(run);
|
|
6905
7538
|
},
|
|
6906
7539
|
PATCH: async ({ params, request }) => {
|
|
6907
|
-
const body = await readJsonBody$
|
|
7540
|
+
const body = await readJsonBody$4(request);
|
|
6908
7541
|
if (!body.ok) {
|
|
6909
7542
|
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
6910
7543
|
}
|
|
@@ -7350,7 +7983,7 @@ function scanExternalProviders() {
|
|
|
7350
7983
|
}
|
|
7351
7984
|
return { providers: filteredProviders, warnings };
|
|
7352
7985
|
}
|
|
7353
|
-
const Route$
|
|
7986
|
+
const Route$l = createFileRoute("/api/providers/scan")({
|
|
7354
7987
|
server: {
|
|
7355
7988
|
handlers: {
|
|
7356
7989
|
GET: () => {
|
|
@@ -7371,7 +8004,7 @@ const Route$i = createFileRoute("/api/providers/scan")({
|
|
|
7371
8004
|
}
|
|
7372
8005
|
});
|
|
7373
8006
|
union([string(), object({ providers: unknown() })]);
|
|
7374
|
-
const Route$
|
|
8007
|
+
const Route$k = createFileRoute("/api/providers/import")({
|
|
7375
8008
|
server: {
|
|
7376
8009
|
handlers: {
|
|
7377
8010
|
POST: async ({ request }) => {
|
|
@@ -7404,7 +8037,7 @@ const Route$h = createFileRoute("/api/providers/import")({
|
|
|
7404
8037
|
}
|
|
7405
8038
|
}
|
|
7406
8039
|
});
|
|
7407
|
-
const Route$
|
|
8040
|
+
const Route$j = createFileRoute("/api/providers/export")({
|
|
7408
8041
|
server: {
|
|
7409
8042
|
handlers: {
|
|
7410
8043
|
GET: ({ request }) => {
|
|
@@ -7437,7 +8070,7 @@ const ProviderUpdateSchema = object({
|
|
|
7437
8070
|
modelMetadata: array(ProviderModelMetadataSchema).optional(),
|
|
7438
8071
|
source: _enum(["company", "personal"]).optional()
|
|
7439
8072
|
});
|
|
7440
|
-
const Route$
|
|
8073
|
+
const Route$i = createFileRoute("/api/providers/$providerId")({
|
|
7441
8074
|
server: {
|
|
7442
8075
|
handlers: {
|
|
7443
8076
|
GET: ({ params, request }) => {
|
|
@@ -7472,7 +8105,7 @@ const Route$f = createFileRoute("/api/providers/$providerId")({
|
|
|
7472
8105
|
}
|
|
7473
8106
|
});
|
|
7474
8107
|
const INITIAL_STREAM_LOG_LIMIT = 100;
|
|
7475
|
-
const Route$
|
|
8108
|
+
const Route$h = createFileRoute("/api/logs/stream")({
|
|
7476
8109
|
server: {
|
|
7477
8110
|
handlers: {
|
|
7478
8111
|
GET: ({ request }) => {
|
|
@@ -7545,7 +8178,7 @@ const Route$e = createFileRoute("/api/logs/stream")({
|
|
|
7545
8178
|
}
|
|
7546
8179
|
}
|
|
7547
8180
|
});
|
|
7548
|
-
const Route$
|
|
8181
|
+
const Route$g = createFileRoute("/api/logs/$id")({
|
|
7549
8182
|
server: {
|
|
7550
8183
|
handlers: {
|
|
7551
8184
|
GET: async ({ params }) => {
|
|
@@ -8082,7 +8715,7 @@ const SearchBodySchema = object({
|
|
|
8082
8715
|
query: string().min(1),
|
|
8083
8716
|
project: string().optional()
|
|
8084
8717
|
});
|
|
8085
|
-
const Route$
|
|
8718
|
+
const Route$f = createFileRoute("/api/knowledge/search")({
|
|
8086
8719
|
server: {
|
|
8087
8720
|
handlers: {
|
|
8088
8721
|
GET: async ({ request }) => {
|
|
@@ -8104,7 +8737,7 @@ const Route$c = createFileRoute("/api/knowledge/search")({
|
|
|
8104
8737
|
}
|
|
8105
8738
|
}
|
|
8106
8739
|
});
|
|
8107
|
-
const Route$
|
|
8740
|
+
const Route$e = createFileRoute("/api/knowledge/project-context")({
|
|
8108
8741
|
server: {
|
|
8109
8742
|
handlers: {
|
|
8110
8743
|
GET: async ({ request }) => {
|
|
@@ -8186,14 +8819,54 @@ function updateCandidateDraft(id, updates) {
|
|
|
8186
8819
|
candidates.set(id, updated);
|
|
8187
8820
|
return updated;
|
|
8188
8821
|
}
|
|
8189
|
-
const Route$
|
|
8822
|
+
const Route$d = createFileRoute("/api/knowledge/candidates")({
|
|
8190
8823
|
server: {
|
|
8191
8824
|
handlers: {
|
|
8192
8825
|
GET: () => Response.json({ candidates: listCandidates() })
|
|
8193
8826
|
}
|
|
8194
8827
|
}
|
|
8195
8828
|
});
|
|
8196
|
-
|
|
8829
|
+
async function readJsonBody$3(request) {
|
|
8830
|
+
try {
|
|
8831
|
+
const raw = await request.text();
|
|
8832
|
+
if (raw.trim().length === 0) return { ok: true, value: {} };
|
|
8833
|
+
return { ok: true, value: JSON.parse(raw) };
|
|
8834
|
+
} catch {
|
|
8835
|
+
return { ok: false };
|
|
8836
|
+
}
|
|
8837
|
+
}
|
|
8838
|
+
const Route$c = createFileRoute("/api/groups/$groupId")({
|
|
8839
|
+
server: {
|
|
8840
|
+
handlers: {
|
|
8841
|
+
GET: ({ params }) => {
|
|
8842
|
+
const group = getGroup(params.groupId);
|
|
8843
|
+
if (group === null) {
|
|
8844
|
+
return Response.json({ error: "Group not found" }, { status: 404 });
|
|
8845
|
+
}
|
|
8846
|
+
return Response.json(group);
|
|
8847
|
+
},
|
|
8848
|
+
PATCH: async ({ params, request }) => {
|
|
8849
|
+
const body = await readJsonBody$3(request);
|
|
8850
|
+
if (!body.ok) {
|
|
8851
|
+
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
8852
|
+
}
|
|
8853
|
+
const parsed = UpdateInspectorGroupInputSchema.safeParse(body.value);
|
|
8854
|
+
if (!parsed.success) {
|
|
8855
|
+
return Response.json(
|
|
8856
|
+
{ error: "Invalid request body", details: parsed.error.format() },
|
|
8857
|
+
{ status: 400 }
|
|
8858
|
+
);
|
|
8859
|
+
}
|
|
8860
|
+
const updated = updateGroup(params.groupId, parsed.data);
|
|
8861
|
+
if (updated === null) {
|
|
8862
|
+
return Response.json({ error: "Group not found" }, { status: 404 });
|
|
8863
|
+
}
|
|
8864
|
+
return Response.json(updated);
|
|
8865
|
+
}
|
|
8866
|
+
}
|
|
8867
|
+
}
|
|
8868
|
+
});
|
|
8869
|
+
const Route$b = createFileRoute("/api/config/paths")({
|
|
8197
8870
|
server: {
|
|
8198
8871
|
handlers: {
|
|
8199
8872
|
GET: () => {
|
|
@@ -8576,7 +9249,7 @@ function timelineMarkdown(timeline) {
|
|
|
8576
9249
|
})
|
|
8577
9250
|
];
|
|
8578
9251
|
}
|
|
8579
|
-
function buildJenkinsReport(input) {
|
|
9252
|
+
function buildJenkinsReport$1(input) {
|
|
8580
9253
|
const status = reportStatus(input.classification);
|
|
8581
9254
|
const session = input.session;
|
|
8582
9255
|
const summary = `[${status}] ${input.classification.summary}`;
|
|
@@ -8624,7 +9297,7 @@ function buildJenkinsReport(input) {
|
|
|
8624
9297
|
function analyzeEvidence(input) {
|
|
8625
9298
|
const classification = classifyRunFailure(input.run, input.session);
|
|
8626
9299
|
const timeline = buildRunTimeline(input.run, input.session, input.exportedAt);
|
|
8627
|
-
const jenkinsReport = buildJenkinsReport({
|
|
9300
|
+
const jenkinsReport = buildJenkinsReport$1({
|
|
8628
9301
|
run: input.run,
|
|
8629
9302
|
session: input.session,
|
|
8630
9303
|
timeline,
|
|
@@ -8636,22 +9309,22 @@ function analyzeEvidence(input) {
|
|
|
8636
9309
|
function evidenceDir(runId) {
|
|
8637
9310
|
return join(getDataDir(), "evidence", runId);
|
|
8638
9311
|
}
|
|
8639
|
-
function jsonPath(runId) {
|
|
9312
|
+
function jsonPath$1(runId) {
|
|
8640
9313
|
return join(evidenceDir(runId), "evidence.json");
|
|
8641
9314
|
}
|
|
8642
|
-
function markdownPath(runId) {
|
|
9315
|
+
function markdownPath$1(runId) {
|
|
8643
9316
|
return join(evidenceDir(runId), "evidence.md");
|
|
8644
9317
|
}
|
|
8645
|
-
function htmlPath(runId) {
|
|
9318
|
+
function htmlPath$1(runId) {
|
|
8646
9319
|
return join(evidenceDir(runId), "evidence.html");
|
|
8647
9320
|
}
|
|
8648
9321
|
function formatList(values) {
|
|
8649
9322
|
return values.length > 0 ? values.join(", ") : "n/a";
|
|
8650
9323
|
}
|
|
8651
|
-
function escapeHtml(value) {
|
|
9324
|
+
function escapeHtml$1(value) {
|
|
8652
9325
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
8653
9326
|
}
|
|
8654
|
-
function buildMarkdown(document) {
|
|
9327
|
+
function buildMarkdown$1(document) {
|
|
8655
9328
|
const session = document.session;
|
|
8656
9329
|
const lines = [
|
|
8657
9330
|
`# ${document.run.title}`,
|
|
@@ -8733,19 +9406,19 @@ function buildMarkdown(document) {
|
|
|
8733
9406
|
return `${lines.join("\n")}
|
|
8734
9407
|
`;
|
|
8735
9408
|
}
|
|
8736
|
-
function buildHtml(markdown, title) {
|
|
9409
|
+
function buildHtml$1(markdown, title) {
|
|
8737
9410
|
return `<!doctype html>
|
|
8738
9411
|
<html lang="en">
|
|
8739
9412
|
<head>
|
|
8740
9413
|
<meta charset="utf-8">
|
|
8741
|
-
<title>${escapeHtml(title)}</title>
|
|
9414
|
+
<title>${escapeHtml$1(title)}</title>
|
|
8742
9415
|
<style>
|
|
8743
9416
|
body { font-family: system-ui, sans-serif; max-width: 960px; margin: 40px auto; line-height: 1.5; }
|
|
8744
9417
|
pre { white-space: pre-wrap; background: #f6f8fa; padding: 16px; border-radius: 8px; }
|
|
8745
9418
|
</style>
|
|
8746
9419
|
</head>
|
|
8747
9420
|
<body>
|
|
8748
|
-
<pre>${escapeHtml(markdown)}</pre>
|
|
9421
|
+
<pre>${escapeHtml$1(markdown)}</pre>
|
|
8749
9422
|
</body>
|
|
8750
9423
|
</html>
|
|
8751
9424
|
`;
|
|
@@ -8758,9 +9431,9 @@ async function exportRunEvidence(run, options, baseUrl) {
|
|
|
8758
9431
|
});
|
|
8759
9432
|
const exportedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
8760
9433
|
const evidence = {
|
|
8761
|
-
jsonPath: jsonPath(run.id),
|
|
8762
|
-
markdownPath: markdownPath(run.id),
|
|
8763
|
-
htmlPath: htmlPath(run.id),
|
|
9434
|
+
jsonPath: jsonPath$1(run.id),
|
|
9435
|
+
markdownPath: markdownPath$1(run.id),
|
|
9436
|
+
htmlPath: htmlPath$1(run.id),
|
|
8764
9437
|
exportedAt
|
|
8765
9438
|
};
|
|
8766
9439
|
const documentRun = {
|
|
@@ -8786,7 +9459,7 @@ async function exportRunEvidence(run, options, baseUrl) {
|
|
|
8786
9459
|
classification: analysis.classification,
|
|
8787
9460
|
jenkinsReport: analysis.jenkinsReport
|
|
8788
9461
|
};
|
|
8789
|
-
const markdown = buildMarkdown(document);
|
|
9462
|
+
const markdown = buildMarkdown$1(document);
|
|
8790
9463
|
mkdirSync(evidenceDir(run.id), { recursive: true });
|
|
8791
9464
|
writeFileSync(
|
|
8792
9465
|
evidence.jsonPath,
|
|
@@ -8795,7 +9468,7 @@ async function exportRunEvidence(run, options, baseUrl) {
|
|
|
8795
9468
|
"utf8"
|
|
8796
9469
|
);
|
|
8797
9470
|
writeFileSync(evidence.markdownPath, markdown, "utf8");
|
|
8798
|
-
writeFileSync(evidence.htmlPath, buildHtml(markdown, run.title), "utf8");
|
|
9471
|
+
writeFileSync(evidence.htmlPath, buildHtml$1(markdown, run.title), "utf8");
|
|
8799
9472
|
const updatedRun = updateRunEvidence(run.id, evidence) ?? documentRun;
|
|
8800
9473
|
return { ...document, run: updatedRun };
|
|
8801
9474
|
}
|
|
@@ -8808,7 +9481,7 @@ function readEvidenceMarkdown(run) {
|
|
|
8808
9481
|
return null;
|
|
8809
9482
|
}
|
|
8810
9483
|
}
|
|
8811
|
-
async function readJsonBody(request) {
|
|
9484
|
+
async function readJsonBody$2(request) {
|
|
8812
9485
|
try {
|
|
8813
9486
|
const raw = await request.text();
|
|
8814
9487
|
if (raw.trim().length === 0) return { ok: true, value: void 0 };
|
|
@@ -8817,7 +9490,7 @@ async function readJsonBody(request) {
|
|
|
8817
9490
|
return { ok: false };
|
|
8818
9491
|
}
|
|
8819
9492
|
}
|
|
8820
|
-
const Route$
|
|
9493
|
+
const Route$a = createFileRoute("/api/runs/$runId/evidence")({
|
|
8821
9494
|
server: {
|
|
8822
9495
|
handlers: {
|
|
8823
9496
|
GET: ({ params }) => {
|
|
@@ -8839,7 +9512,7 @@ const Route$8 = createFileRoute("/api/runs/$runId/evidence")({
|
|
|
8839
9512
|
if (run === null) {
|
|
8840
9513
|
return Response.json({ error: "Run not found" }, { status: 404 });
|
|
8841
9514
|
}
|
|
8842
|
-
const body = await readJsonBody(request);
|
|
9515
|
+
const body = await readJsonBody$2(request);
|
|
8843
9516
|
if (!body.ok) {
|
|
8844
9517
|
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
8845
9518
|
}
|
|
@@ -9473,7 +10146,7 @@ async function testStreamingEndpoint(baseUrl, provider, path2, model, isOpenAI)
|
|
|
9473
10146
|
clearTimeout(timeoutId);
|
|
9474
10147
|
}
|
|
9475
10148
|
}
|
|
9476
|
-
const Route$
|
|
10149
|
+
const Route$9 = createFileRoute("/api/providers/$providerId/test")({
|
|
9477
10150
|
server: {
|
|
9478
10151
|
handlers: {
|
|
9479
10152
|
POST: async ({ params }) => {
|
|
@@ -9567,7 +10240,7 @@ async function readRegistryJson(response) {
|
|
|
9567
10240
|
return null;
|
|
9568
10241
|
}
|
|
9569
10242
|
}
|
|
9570
|
-
const Route$
|
|
10243
|
+
const Route$8 = createFileRoute("/api/providers/$providerId/model-metadata")({
|
|
9571
10244
|
server: {
|
|
9572
10245
|
handlers: {
|
|
9573
10246
|
POST: async ({ params, request }) => {
|
|
@@ -9657,7 +10330,7 @@ const Route$6 = createFileRoute("/api/providers/$providerId/model-metadata")({
|
|
|
9657
10330
|
const ReplayRequestSchema = object({
|
|
9658
10331
|
modifiedBody: string()
|
|
9659
10332
|
});
|
|
9660
|
-
const Route$
|
|
10333
|
+
const Route$7 = createFileRoute("/api/logs/$id/replay")({
|
|
9661
10334
|
server: {
|
|
9662
10335
|
handlers: {
|
|
9663
10336
|
POST: async ({ params, request }) => {
|
|
@@ -9858,7 +10531,7 @@ const Route$5 = createFileRoute("/api/logs/$id/replay")({
|
|
|
9858
10531
|
}
|
|
9859
10532
|
}
|
|
9860
10533
|
});
|
|
9861
|
-
const Route$
|
|
10534
|
+
const Route$6 = createFileRoute("/api/logs/$id/chunks")({
|
|
9862
10535
|
server: {
|
|
9863
10536
|
handlers: {
|
|
9864
10537
|
GET: async ({ params }) => {
|
|
@@ -9893,7 +10566,7 @@ const CandidateUpdateSchema = object({
|
|
|
9893
10566
|
object({
|
|
9894
10567
|
candidate: KnowledgeCandidateSchema
|
|
9895
10568
|
});
|
|
9896
|
-
const Route$
|
|
10569
|
+
const Route$5 = createFileRoute("/api/knowledge/candidates/$candidateId")({
|
|
9897
10570
|
server: {
|
|
9898
10571
|
handlers: {
|
|
9899
10572
|
PATCH: async ({ params, request }) => {
|
|
@@ -9921,6 +10594,390 @@ const Route$3 = createFileRoute("/api/knowledge/candidates/$candidateId")({
|
|
|
9921
10594
|
}
|
|
9922
10595
|
}
|
|
9923
10596
|
});
|
|
10597
|
+
async function readJsonBody$1(request) {
|
|
10598
|
+
try {
|
|
10599
|
+
const raw = await request.text();
|
|
10600
|
+
if (raw.trim().length === 0) return { ok: true, value: {} };
|
|
10601
|
+
return { ok: true, value: JSON.parse(raw) };
|
|
10602
|
+
} catch {
|
|
10603
|
+
return { ok: false };
|
|
10604
|
+
}
|
|
10605
|
+
}
|
|
10606
|
+
const Route$4 = createFileRoute("/api/groups/$groupId/sessions")({
|
|
10607
|
+
server: {
|
|
10608
|
+
handlers: {
|
|
10609
|
+
GET: ({ params }) => {
|
|
10610
|
+
const group = getGroup(params.groupId);
|
|
10611
|
+
if (group === null) {
|
|
10612
|
+
return Response.json({ error: "Group not found" }, { status: 404 });
|
|
10613
|
+
}
|
|
10614
|
+
return Response.json({ groupId: group.id, members: group.members });
|
|
10615
|
+
},
|
|
10616
|
+
POST: async ({ params, request }) => {
|
|
10617
|
+
const body = await readJsonBody$1(request);
|
|
10618
|
+
if (!body.ok) {
|
|
10619
|
+
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
10620
|
+
}
|
|
10621
|
+
const parsed = AddInspectorGroupSessionInputSchema.safeParse(body.value);
|
|
10622
|
+
if (!parsed.success) {
|
|
10623
|
+
return Response.json(
|
|
10624
|
+
{ error: "Invalid request body", details: parsed.error.format() },
|
|
10625
|
+
{ status: 400 }
|
|
10626
|
+
);
|
|
10627
|
+
}
|
|
10628
|
+
const updated = addGroupSession(params.groupId, parsed.data);
|
|
10629
|
+
if (updated === null) {
|
|
10630
|
+
return Response.json({ error: "Group not found" }, { status: 404 });
|
|
10631
|
+
}
|
|
10632
|
+
return Response.json(updated);
|
|
10633
|
+
}
|
|
10634
|
+
}
|
|
10635
|
+
}
|
|
10636
|
+
});
|
|
10637
|
+
function groupEvidenceDir(groupId) {
|
|
10638
|
+
return join(getDataDir(), "evidence", "groups", groupId);
|
|
10639
|
+
}
|
|
10640
|
+
function jsonPath(groupId) {
|
|
10641
|
+
return join(groupEvidenceDir(groupId), "evidence.json");
|
|
10642
|
+
}
|
|
10643
|
+
function markdownPath(groupId) {
|
|
10644
|
+
return join(groupEvidenceDir(groupId), "evidence.md");
|
|
10645
|
+
}
|
|
10646
|
+
function htmlPath(groupId) {
|
|
10647
|
+
return join(groupEvidenceDir(groupId), "evidence.html");
|
|
10648
|
+
}
|
|
10649
|
+
function escapeMarkdownCell(value) {
|
|
10650
|
+
return value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
10651
|
+
}
|
|
10652
|
+
function escapeHtml(value) {
|
|
10653
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
10654
|
+
}
|
|
10655
|
+
function formatText(value) {
|
|
10656
|
+
if (value === null || value === void 0 || value.length === 0) return "n/a";
|
|
10657
|
+
return value;
|
|
10658
|
+
}
|
|
10659
|
+
function formatNumber(value) {
|
|
10660
|
+
if (value === null || value === void 0) return "n/a";
|
|
10661
|
+
return String(value);
|
|
10662
|
+
}
|
|
10663
|
+
function collectSortedValues(values) {
|
|
10664
|
+
const set = /* @__PURE__ */ new Set();
|
|
10665
|
+
for (const value of values) {
|
|
10666
|
+
if (value !== null && value !== void 0 && value.length > 0) {
|
|
10667
|
+
set.add(value);
|
|
10668
|
+
}
|
|
10669
|
+
}
|
|
10670
|
+
return [...set].sort();
|
|
10671
|
+
}
|
|
10672
|
+
function addTokenUsage(total, session) {
|
|
10673
|
+
if (session === null) return total;
|
|
10674
|
+
return {
|
|
10675
|
+
input: total.input + session.tokenUsage.input,
|
|
10676
|
+
output: total.output + session.tokenUsage.output,
|
|
10677
|
+
cacheCreate: total.cacheCreate + session.tokenUsage.cacheCreate,
|
|
10678
|
+
cacheRead: total.cacheRead + session.tokenUsage.cacheRead,
|
|
10679
|
+
total: total.total + session.tokenUsage.total
|
|
10680
|
+
};
|
|
10681
|
+
}
|
|
10682
|
+
function memberEffectiveStatus(member) {
|
|
10683
|
+
if (member.member.status !== null) return member.member.status;
|
|
10684
|
+
if (member.run !== null) return member.run.status;
|
|
10685
|
+
return member.session?.status ?? "unknown";
|
|
10686
|
+
}
|
|
10687
|
+
function isCompletedMember(member) {
|
|
10688
|
+
const status = memberEffectiveStatus(member);
|
|
10689
|
+
return status === "completed";
|
|
10690
|
+
}
|
|
10691
|
+
function isFailedMember(member) {
|
|
10692
|
+
const status = memberEffectiveStatus(member);
|
|
10693
|
+
return status === "failed" || status === "cancelled";
|
|
10694
|
+
}
|
|
10695
|
+
function isRunningMember(member) {
|
|
10696
|
+
const status = memberEffectiveStatus(member);
|
|
10697
|
+
return status === "running" || status === "active";
|
|
10698
|
+
}
|
|
10699
|
+
function latestLogMetric(session, field) {
|
|
10700
|
+
if (session === null) return null;
|
|
10701
|
+
for (const log of session.latestLogs) {
|
|
10702
|
+
const value = log[field];
|
|
10703
|
+
if (value !== void 0 && value !== null) return value;
|
|
10704
|
+
}
|
|
10705
|
+
return null;
|
|
10706
|
+
}
|
|
10707
|
+
function buildSummary(members) {
|
|
10708
|
+
const tokenUsage = members.reduce(
|
|
10709
|
+
(total, member) => addTokenUsage(total, member.session),
|
|
10710
|
+
{ input: 0, output: 0, cacheCreate: 0, cacheRead: 0, total: 0 }
|
|
10711
|
+
);
|
|
10712
|
+
const sessionsWithData = members.filter((member) => member.session !== null).length;
|
|
10713
|
+
const requestCount = members.reduce(
|
|
10714
|
+
(total, member) => total + (member.session?.requestCount ?? 0),
|
|
10715
|
+
0
|
|
10716
|
+
);
|
|
10717
|
+
const errorCount = members.reduce(
|
|
10718
|
+
(total, member) => total + (member.session?.errorCount ?? 0),
|
|
10719
|
+
0
|
|
10720
|
+
);
|
|
10721
|
+
return {
|
|
10722
|
+
memberCount: members.length,
|
|
10723
|
+
sessionsWithData,
|
|
10724
|
+
missingSessions: members.length - sessionsWithData,
|
|
10725
|
+
requestCount,
|
|
10726
|
+
errorCount,
|
|
10727
|
+
tokenUsage,
|
|
10728
|
+
models: collectSortedValues(
|
|
10729
|
+
members.flatMap((member) => [member.member.model, ...member.session?.models ?? []])
|
|
10730
|
+
),
|
|
10731
|
+
providers: collectSortedValues(
|
|
10732
|
+
members.flatMap((member) => [member.member.provider, ...member.session?.providers ?? []])
|
|
10733
|
+
),
|
|
10734
|
+
completedMembers: members.filter(isCompletedMember).length,
|
|
10735
|
+
failedMembers: members.filter(isFailedMember).length,
|
|
10736
|
+
runningMembers: members.filter(isRunningMember).length
|
|
10737
|
+
};
|
|
10738
|
+
}
|
|
10739
|
+
function buildJenkinsReport(group, summary) {
|
|
10740
|
+
if (summary.failedMembers > 0 || summary.errorCount > 0 || group.status === "failed") {
|
|
10741
|
+
return {
|
|
10742
|
+
status: "FAIL",
|
|
10743
|
+
summary: `[FAIL] ${summary.failedMembers} failed members, ${summary.errorCount} captured errors.`,
|
|
10744
|
+
markdown: `# Jenkins Report: ${group.title}
|
|
10745
|
+
|
|
10746
|
+
Status: FAIL
|
|
10747
|
+
|
|
10748
|
+
${summary.failedMembers} failed members and ${summary.errorCount} captured errors need triage.`
|
|
10749
|
+
};
|
|
10750
|
+
}
|
|
10751
|
+
if (summary.runningMembers > 0 || group.status === "running") {
|
|
10752
|
+
return {
|
|
10753
|
+
status: "RUNNING",
|
|
10754
|
+
summary: `[RUNNING] ${summary.runningMembers} group members are still active.`,
|
|
10755
|
+
markdown: `# Jenkins Report: ${group.title}
|
|
10756
|
+
|
|
10757
|
+
Status: RUNNING
|
|
10758
|
+
|
|
10759
|
+
${summary.runningMembers} group members are still active.`
|
|
10760
|
+
};
|
|
10761
|
+
}
|
|
10762
|
+
if (summary.memberCount > 0 && summary.sessionsWithData > 0 && summary.errorCount === 0 && group.status === "completed") {
|
|
10763
|
+
return {
|
|
10764
|
+
status: "PASS",
|
|
10765
|
+
summary: `[PASS] ${summary.memberCount} group members completed with no captured errors.`,
|
|
10766
|
+
markdown: `# Jenkins Report: ${group.title}
|
|
10767
|
+
|
|
10768
|
+
Status: PASS
|
|
10769
|
+
|
|
10770
|
+
${summary.memberCount} group members completed with no captured errors.`
|
|
10771
|
+
};
|
|
10772
|
+
}
|
|
10773
|
+
return {
|
|
10774
|
+
status: "UNKNOWN",
|
|
10775
|
+
summary: `[UNKNOWN] Group has ${summary.memberCount} members and ${summary.missingSessions} missing sessions.`,
|
|
10776
|
+
markdown: `# Jenkins Report: ${group.title}
|
|
10777
|
+
|
|
10778
|
+
Status: UNKNOWN
|
|
10779
|
+
|
|
10780
|
+
Exported group evidence, but the outcome is not conclusive yet.`
|
|
10781
|
+
};
|
|
10782
|
+
}
|
|
10783
|
+
function buildMemberRows(members) {
|
|
10784
|
+
if (members.length === 0) return ["No sessions have been attached to this group.", ""];
|
|
10785
|
+
const rows = [
|
|
10786
|
+
"| Label | Provider | Model | Session | Run | Status | Requests | Errors | Tokens | First Chunk | Stream Total | TPS | Inspector |",
|
|
10787
|
+
"| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |"
|
|
10788
|
+
];
|
|
10789
|
+
for (const member of members) {
|
|
10790
|
+
const session = member.session;
|
|
10791
|
+
rows.push(
|
|
10792
|
+
[
|
|
10793
|
+
formatText(member.member.label),
|
|
10794
|
+
formatText(member.member.provider ?? session?.providers[0]),
|
|
10795
|
+
formatText(member.member.model ?? session?.lastModel),
|
|
10796
|
+
member.member.sessionId,
|
|
10797
|
+
formatText(member.member.runId),
|
|
10798
|
+
memberEffectiveStatus(member),
|
|
10799
|
+
formatNumber(session?.requestCount),
|
|
10800
|
+
formatNumber(session?.errorCount),
|
|
10801
|
+
formatNumber(session?.tokenUsage.total),
|
|
10802
|
+
formatNumber(latestLogMetric(session, "firstChunkMs")),
|
|
10803
|
+
formatNumber(latestLogMetric(session, "totalStreamMs")),
|
|
10804
|
+
formatNumber(latestLogMetric(session, "tokensPerSecond")),
|
|
10805
|
+
formatText(session?.inspectorUrl)
|
|
10806
|
+
].map(escapeMarkdownCell).join(" | ").replace(/^/, "| ").replace(/$/, " |")
|
|
10807
|
+
);
|
|
10808
|
+
}
|
|
10809
|
+
rows.push("");
|
|
10810
|
+
return rows;
|
|
10811
|
+
}
|
|
10812
|
+
function buildMarkdown(document) {
|
|
10813
|
+
const group = document.group;
|
|
10814
|
+
const summary = document.summary;
|
|
10815
|
+
const lines = [
|
|
10816
|
+
`# ${group.title}`,
|
|
10817
|
+
"",
|
|
10818
|
+
`- Group ID: ${group.id}`,
|
|
10819
|
+
`- Kind: ${group.kind}`,
|
|
10820
|
+
`- Status: ${group.status}`,
|
|
10821
|
+
`- Project: ${group.project ?? "n/a"}`,
|
|
10822
|
+
`- Created: ${group.createdAt}`,
|
|
10823
|
+
`- Members: ${summary.memberCount}`,
|
|
10824
|
+
`- Sessions With Data: ${summary.sessionsWithData}`,
|
|
10825
|
+
`- Missing Sessions: ${summary.missingSessions}`,
|
|
10826
|
+
`- Requests: ${summary.requestCount}`,
|
|
10827
|
+
`- Errors: ${summary.errorCount}`,
|
|
10828
|
+
`- Tokens: ${summary.tokenUsage.total}`,
|
|
10829
|
+
`- Models: ${summary.models.length > 0 ? summary.models.join(", ") : "n/a"}`,
|
|
10830
|
+
`- Providers: ${summary.providers.length > 0 ? summary.providers.join(", ") : "n/a"}`,
|
|
10831
|
+
`- Evidence JSON: ${document.evidence.jsonPath}`,
|
|
10832
|
+
`- Evidence HTML: ${document.evidence.htmlPath}`,
|
|
10833
|
+
""
|
|
10834
|
+
];
|
|
10835
|
+
if (group.task !== null) {
|
|
10836
|
+
lines.push("## Task", "", group.task, "");
|
|
10837
|
+
}
|
|
10838
|
+
lines.push("## Evaluation Matrix", "", ...buildMemberRows(document.members));
|
|
10839
|
+
lines.push("## Jenkins Report", "", document.jenkinsReport.markdown, "");
|
|
10840
|
+
return `${lines.join("\n")}
|
|
10841
|
+
`;
|
|
10842
|
+
}
|
|
10843
|
+
function buildHtml(markdown, title) {
|
|
10844
|
+
return `<!doctype html>
|
|
10845
|
+
<html lang="en">
|
|
10846
|
+
<head>
|
|
10847
|
+
<meta charset="utf-8">
|
|
10848
|
+
<title>${escapeHtml(title)}</title>
|
|
10849
|
+
<style>
|
|
10850
|
+
body { font-family: system-ui, sans-serif; max-width: 1120px; margin: 40px auto; line-height: 1.5; }
|
|
10851
|
+
pre { white-space: pre-wrap; background: #f6f8fa; padding: 16px; border-radius: 8px; }
|
|
10852
|
+
</style>
|
|
10853
|
+
</head>
|
|
10854
|
+
<body>
|
|
10855
|
+
<pre>${escapeHtml(markdown)}</pre>
|
|
10856
|
+
</body>
|
|
10857
|
+
</html>
|
|
10858
|
+
`;
|
|
10859
|
+
}
|
|
10860
|
+
async function buildExportMembers(group, options, baseUrl) {
|
|
10861
|
+
const members = [];
|
|
10862
|
+
for (const member of group.members) {
|
|
10863
|
+
const run = member.runId === null ? null : getRun(member.runId);
|
|
10864
|
+
const session = await getSessionInfo(member.sessionId, {
|
|
10865
|
+
baseUrl,
|
|
10866
|
+
includeHistory: options?.includeHistory,
|
|
10867
|
+
latestLogLimit: options?.latestLogLimit
|
|
10868
|
+
});
|
|
10869
|
+
members.push({ member, run, session });
|
|
10870
|
+
}
|
|
10871
|
+
return members;
|
|
10872
|
+
}
|
|
10873
|
+
async function exportGroupEvidence(group, options, baseUrl) {
|
|
10874
|
+
const members = await buildExportMembers(group, options, baseUrl);
|
|
10875
|
+
const exportedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
10876
|
+
const evidence = {
|
|
10877
|
+
jsonPath: jsonPath(group.id),
|
|
10878
|
+
markdownPath: markdownPath(group.id),
|
|
10879
|
+
htmlPath: htmlPath(group.id),
|
|
10880
|
+
exportedAt
|
|
10881
|
+
};
|
|
10882
|
+
const documentGroup = {
|
|
10883
|
+
...group,
|
|
10884
|
+
evidence,
|
|
10885
|
+
updatedAt: exportedAt
|
|
10886
|
+
};
|
|
10887
|
+
const summary = buildSummary(members);
|
|
10888
|
+
const jenkinsReport = buildJenkinsReport(documentGroup, summary);
|
|
10889
|
+
const document = {
|
|
10890
|
+
group: documentGroup,
|
|
10891
|
+
evidence,
|
|
10892
|
+
members,
|
|
10893
|
+
summary,
|
|
10894
|
+
jenkinsReport
|
|
10895
|
+
};
|
|
10896
|
+
const markdown = buildMarkdown(document);
|
|
10897
|
+
mkdirSync(groupEvidenceDir(group.id), { recursive: true });
|
|
10898
|
+
writeFileSync(evidence.jsonPath, `${JSON.stringify(document, null, 2)}
|
|
10899
|
+
`, "utf8");
|
|
10900
|
+
writeFileSync(evidence.markdownPath, markdown, "utf8");
|
|
10901
|
+
writeFileSync(evidence.htmlPath, buildHtml(markdown, group.title), "utf8");
|
|
10902
|
+
const updatedGroup = updateGroupEvidence(group.id, evidence) ?? documentGroup;
|
|
10903
|
+
return { ...document, group: updatedGroup };
|
|
10904
|
+
}
|
|
10905
|
+
function readGroupEvidenceMarkdown(group) {
|
|
10906
|
+
const path2 = group.evidence?.markdownPath;
|
|
10907
|
+
if (path2 === void 0 || !existsSync(path2)) return null;
|
|
10908
|
+
try {
|
|
10909
|
+
return readFileSync(path2, "utf8");
|
|
10910
|
+
} catch {
|
|
10911
|
+
return null;
|
|
10912
|
+
}
|
|
10913
|
+
}
|
|
10914
|
+
function readGroupEvidenceDocument(group) {
|
|
10915
|
+
const path2 = group.evidence?.jsonPath;
|
|
10916
|
+
if (path2 === void 0 || !existsSync(path2)) return null;
|
|
10917
|
+
try {
|
|
10918
|
+
const raw = JSON.parse(readFileSync(path2, "utf8"));
|
|
10919
|
+
const parsed = GroupEvidenceExportResultSchema.safeParse(raw);
|
|
10920
|
+
return parsed.success ? parsed.data : null;
|
|
10921
|
+
} catch {
|
|
10922
|
+
return null;
|
|
10923
|
+
}
|
|
10924
|
+
}
|
|
10925
|
+
async function readJsonBody(request) {
|
|
10926
|
+
try {
|
|
10927
|
+
const raw = await request.text();
|
|
10928
|
+
if (raw.trim().length === 0) return { ok: true, value: void 0 };
|
|
10929
|
+
return { ok: true, value: JSON.parse(raw) };
|
|
10930
|
+
} catch {
|
|
10931
|
+
return { ok: false };
|
|
10932
|
+
}
|
|
10933
|
+
}
|
|
10934
|
+
const Route$3 = createFileRoute("/api/groups/$groupId/evidence")({
|
|
10935
|
+
server: {
|
|
10936
|
+
handlers: {
|
|
10937
|
+
GET: ({ params }) => {
|
|
10938
|
+
const group = getGroup(params.groupId);
|
|
10939
|
+
if (group === null) {
|
|
10940
|
+
return Response.json({ error: "Group not found" }, { status: 404 });
|
|
10941
|
+
}
|
|
10942
|
+
const markdown = readGroupEvidenceMarkdown(group);
|
|
10943
|
+
if (group.evidence === null || markdown === null) {
|
|
10944
|
+
return Response.json(
|
|
10945
|
+
{ error: "Evidence has not been exported for this group" },
|
|
10946
|
+
{ status: 404 }
|
|
10947
|
+
);
|
|
10948
|
+
}
|
|
10949
|
+
const document = readGroupEvidenceDocument(group);
|
|
10950
|
+
return Response.json({
|
|
10951
|
+
group,
|
|
10952
|
+
evidence: group.evidence,
|
|
10953
|
+
markdown,
|
|
10954
|
+
summary: document?.summary ?? null,
|
|
10955
|
+
report: document?.jenkinsReport ?? null
|
|
10956
|
+
});
|
|
10957
|
+
},
|
|
10958
|
+
POST: async ({ params, request }) => {
|
|
10959
|
+
const group = getGroup(params.groupId);
|
|
10960
|
+
if (group === null) {
|
|
10961
|
+
return Response.json({ error: "Group not found" }, { status: 404 });
|
|
10962
|
+
}
|
|
10963
|
+
const body = await readJsonBody(request);
|
|
10964
|
+
if (!body.ok) {
|
|
10965
|
+
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
10966
|
+
}
|
|
10967
|
+
const parsed = GroupEvidenceExportOptionsSchema.safeParse(body.value);
|
|
10968
|
+
if (!parsed.success) {
|
|
10969
|
+
return Response.json(
|
|
10970
|
+
{ error: "Invalid request body", details: parsed.error.format() },
|
|
10971
|
+
{ status: 400 }
|
|
10972
|
+
);
|
|
10973
|
+
}
|
|
10974
|
+
return Response.json(
|
|
10975
|
+
await exportGroupEvidence(group, parsed.data, new URL(request.url).origin)
|
|
10976
|
+
);
|
|
10977
|
+
}
|
|
10978
|
+
}
|
|
10979
|
+
}
|
|
10980
|
+
});
|
|
9924
10981
|
const ProviderTestErrorTypeSchema = _enum([
|
|
9925
10982
|
"timeout",
|
|
9926
10983
|
"network_unreachable",
|
|
@@ -10344,146 +11401,166 @@ const Route = createFileRoute("/api/knowledge/candidates/$candidateId/promote")(
|
|
|
10344
11401
|
}
|
|
10345
11402
|
}
|
|
10346
11403
|
});
|
|
10347
|
-
const IndexRoute = Route$
|
|
11404
|
+
const IndexRoute = Route$y.update({
|
|
10348
11405
|
id: "/",
|
|
10349
11406
|
path: "/",
|
|
10350
|
-
getParentRoute: () => Route$
|
|
11407
|
+
getParentRoute: () => Route$z
|
|
10351
11408
|
});
|
|
10352
|
-
const SessionSessionIdRoute = Route$
|
|
11409
|
+
const SessionSessionIdRoute = Route$x.update({
|
|
10353
11410
|
id: "/session/$sessionId",
|
|
10354
11411
|
path: "/session/$sessionId",
|
|
10355
|
-
getParentRoute: () => Route$
|
|
11412
|
+
getParentRoute: () => Route$z
|
|
10356
11413
|
});
|
|
10357
|
-
const ProxySplatRoute = Route$
|
|
11414
|
+
const ProxySplatRoute = Route$w.update({
|
|
10358
11415
|
id: "/proxy/$",
|
|
10359
11416
|
path: "/proxy/$",
|
|
10360
|
-
getParentRoute: () => Route$
|
|
11417
|
+
getParentRoute: () => Route$z
|
|
10361
11418
|
});
|
|
10362
|
-
const ApiSessionsRoute = Route$
|
|
11419
|
+
const ApiSessionsRoute = Route$v.update({
|
|
10363
11420
|
id: "/api/sessions",
|
|
10364
11421
|
path: "/api/sessions",
|
|
10365
|
-
getParentRoute: () => Route$
|
|
11422
|
+
getParentRoute: () => Route$z
|
|
10366
11423
|
});
|
|
10367
|
-
const ApiRunsRoute = Route$
|
|
11424
|
+
const ApiRunsRoute = Route$u.update({
|
|
10368
11425
|
id: "/api/runs",
|
|
10369
11426
|
path: "/api/runs",
|
|
10370
|
-
getParentRoute: () => Route$
|
|
11427
|
+
getParentRoute: () => Route$z
|
|
10371
11428
|
});
|
|
10372
|
-
const ApiProvidersRoute = Route$
|
|
11429
|
+
const ApiProvidersRoute = Route$t.update({
|
|
10373
11430
|
id: "/api/providers",
|
|
10374
11431
|
path: "/api/providers",
|
|
10375
|
-
getParentRoute: () => Route$
|
|
11432
|
+
getParentRoute: () => Route$z
|
|
10376
11433
|
});
|
|
10377
|
-
const ApiModelsRoute = Route$
|
|
11434
|
+
const ApiModelsRoute = Route$s.update({
|
|
10378
11435
|
id: "/api/models",
|
|
10379
11436
|
path: "/api/models",
|
|
10380
|
-
getParentRoute: () => Route$
|
|
11437
|
+
getParentRoute: () => Route$z
|
|
10381
11438
|
});
|
|
10382
|
-
const ApiMcpRoute = Route$
|
|
11439
|
+
const ApiMcpRoute = Route$r.update({
|
|
10383
11440
|
id: "/api/mcp",
|
|
10384
11441
|
path: "/api/mcp",
|
|
10385
|
-
getParentRoute: () => Route$
|
|
11442
|
+
getParentRoute: () => Route$z
|
|
10386
11443
|
});
|
|
10387
|
-
const ApiLogsRoute = Route$
|
|
11444
|
+
const ApiLogsRoute = Route$q.update({
|
|
10388
11445
|
id: "/api/logs",
|
|
10389
11446
|
path: "/api/logs",
|
|
10390
|
-
getParentRoute: () => Route$
|
|
11447
|
+
getParentRoute: () => Route$z
|
|
10391
11448
|
});
|
|
10392
|
-
const ApiHealthRoute = Route$
|
|
11449
|
+
const ApiHealthRoute = Route$p.update({
|
|
10393
11450
|
id: "/api/health",
|
|
10394
11451
|
path: "/api/health",
|
|
10395
|
-
getParentRoute: () => Route$
|
|
11452
|
+
getParentRoute: () => Route$z
|
|
11453
|
+
});
|
|
11454
|
+
const ApiGroupsRoute = Route$o.update({
|
|
11455
|
+
id: "/api/groups",
|
|
11456
|
+
path: "/api/groups",
|
|
11457
|
+
getParentRoute: () => Route$z
|
|
10396
11458
|
});
|
|
10397
|
-
const ApiConfigRoute = Route$
|
|
11459
|
+
const ApiConfigRoute = Route$n.update({
|
|
10398
11460
|
id: "/api/config",
|
|
10399
11461
|
path: "/api/config",
|
|
10400
|
-
getParentRoute: () => Route$
|
|
11462
|
+
getParentRoute: () => Route$z
|
|
10401
11463
|
});
|
|
10402
|
-
const ApiRunsRunIdRoute = Route$
|
|
11464
|
+
const ApiRunsRunIdRoute = Route$m.update({
|
|
10403
11465
|
id: "/$runId",
|
|
10404
11466
|
path: "/$runId",
|
|
10405
11467
|
getParentRoute: () => ApiRunsRoute
|
|
10406
11468
|
});
|
|
10407
|
-
const ApiProvidersScanRoute = Route$
|
|
11469
|
+
const ApiProvidersScanRoute = Route$l.update({
|
|
10408
11470
|
id: "/scan",
|
|
10409
11471
|
path: "/scan",
|
|
10410
11472
|
getParentRoute: () => ApiProvidersRoute
|
|
10411
11473
|
});
|
|
10412
|
-
const ApiProvidersImportRoute = Route$
|
|
11474
|
+
const ApiProvidersImportRoute = Route$k.update({
|
|
10413
11475
|
id: "/import",
|
|
10414
11476
|
path: "/import",
|
|
10415
11477
|
getParentRoute: () => ApiProvidersRoute
|
|
10416
11478
|
});
|
|
10417
|
-
const ApiProvidersExportRoute = Route$
|
|
11479
|
+
const ApiProvidersExportRoute = Route$j.update({
|
|
10418
11480
|
id: "/export",
|
|
10419
11481
|
path: "/export",
|
|
10420
11482
|
getParentRoute: () => ApiProvidersRoute
|
|
10421
11483
|
});
|
|
10422
|
-
const ApiProvidersProviderIdRoute = Route$
|
|
11484
|
+
const ApiProvidersProviderIdRoute = Route$i.update({
|
|
10423
11485
|
id: "/$providerId",
|
|
10424
11486
|
path: "/$providerId",
|
|
10425
11487
|
getParentRoute: () => ApiProvidersRoute
|
|
10426
11488
|
});
|
|
10427
|
-
const ApiLogsStreamRoute = Route$
|
|
11489
|
+
const ApiLogsStreamRoute = Route$h.update({
|
|
10428
11490
|
id: "/stream",
|
|
10429
11491
|
path: "/stream",
|
|
10430
11492
|
getParentRoute: () => ApiLogsRoute
|
|
10431
11493
|
});
|
|
10432
|
-
const ApiLogsIdRoute = Route$
|
|
11494
|
+
const ApiLogsIdRoute = Route$g.update({
|
|
10433
11495
|
id: "/$id",
|
|
10434
11496
|
path: "/$id",
|
|
10435
11497
|
getParentRoute: () => ApiLogsRoute
|
|
10436
11498
|
});
|
|
10437
|
-
const ApiKnowledgeSearchRoute = Route$
|
|
11499
|
+
const ApiKnowledgeSearchRoute = Route$f.update({
|
|
10438
11500
|
id: "/api/knowledge/search",
|
|
10439
11501
|
path: "/api/knowledge/search",
|
|
10440
|
-
getParentRoute: () => Route$
|
|
11502
|
+
getParentRoute: () => Route$z
|
|
10441
11503
|
});
|
|
10442
|
-
const ApiKnowledgeProjectContextRoute = Route$
|
|
11504
|
+
const ApiKnowledgeProjectContextRoute = Route$e.update({
|
|
10443
11505
|
id: "/api/knowledge/project-context",
|
|
10444
11506
|
path: "/api/knowledge/project-context",
|
|
10445
|
-
getParentRoute: () => Route$
|
|
11507
|
+
getParentRoute: () => Route$z
|
|
10446
11508
|
});
|
|
10447
|
-
const ApiKnowledgeCandidatesRoute = Route$
|
|
11509
|
+
const ApiKnowledgeCandidatesRoute = Route$d.update({
|
|
10448
11510
|
id: "/api/knowledge/candidates",
|
|
10449
11511
|
path: "/api/knowledge/candidates",
|
|
10450
|
-
getParentRoute: () => Route$
|
|
11512
|
+
getParentRoute: () => Route$z
|
|
10451
11513
|
});
|
|
10452
|
-
const
|
|
11514
|
+
const ApiGroupsGroupIdRoute = Route$c.update({
|
|
11515
|
+
id: "/$groupId",
|
|
11516
|
+
path: "/$groupId",
|
|
11517
|
+
getParentRoute: () => ApiGroupsRoute
|
|
11518
|
+
});
|
|
11519
|
+
const ApiConfigPathsRoute = Route$b.update({
|
|
10453
11520
|
id: "/paths",
|
|
10454
11521
|
path: "/paths",
|
|
10455
11522
|
getParentRoute: () => ApiConfigRoute
|
|
10456
11523
|
});
|
|
10457
|
-
const ApiRunsRunIdEvidenceRoute = Route$
|
|
11524
|
+
const ApiRunsRunIdEvidenceRoute = Route$a.update({
|
|
10458
11525
|
id: "/evidence",
|
|
10459
11526
|
path: "/evidence",
|
|
10460
11527
|
getParentRoute: () => ApiRunsRunIdRoute
|
|
10461
11528
|
});
|
|
10462
|
-
const ApiProvidersProviderIdTestRoute = Route$
|
|
11529
|
+
const ApiProvidersProviderIdTestRoute = Route$9.update({
|
|
10463
11530
|
id: "/test",
|
|
10464
11531
|
path: "/test",
|
|
10465
11532
|
getParentRoute: () => ApiProvidersProviderIdRoute
|
|
10466
11533
|
});
|
|
10467
|
-
const ApiProvidersProviderIdModelMetadataRoute = Route$
|
|
11534
|
+
const ApiProvidersProviderIdModelMetadataRoute = Route$8.update({
|
|
10468
11535
|
id: "/model-metadata",
|
|
10469
11536
|
path: "/model-metadata",
|
|
10470
11537
|
getParentRoute: () => ApiProvidersProviderIdRoute
|
|
10471
11538
|
});
|
|
10472
|
-
const ApiLogsIdReplayRoute = Route$
|
|
11539
|
+
const ApiLogsIdReplayRoute = Route$7.update({
|
|
10473
11540
|
id: "/replay",
|
|
10474
11541
|
path: "/replay",
|
|
10475
11542
|
getParentRoute: () => ApiLogsIdRoute
|
|
10476
11543
|
});
|
|
10477
|
-
const ApiLogsIdChunksRoute = Route$
|
|
11544
|
+
const ApiLogsIdChunksRoute = Route$6.update({
|
|
10478
11545
|
id: "/chunks",
|
|
10479
11546
|
path: "/chunks",
|
|
10480
11547
|
getParentRoute: () => ApiLogsIdRoute
|
|
10481
11548
|
});
|
|
10482
|
-
const ApiKnowledgeCandidatesCandidateIdRoute = Route$
|
|
11549
|
+
const ApiKnowledgeCandidatesCandidateIdRoute = Route$5.update({
|
|
10483
11550
|
id: "/$candidateId",
|
|
10484
11551
|
path: "/$candidateId",
|
|
10485
11552
|
getParentRoute: () => ApiKnowledgeCandidatesRoute
|
|
10486
11553
|
});
|
|
11554
|
+
const ApiGroupsGroupIdSessionsRoute = Route$4.update({
|
|
11555
|
+
id: "/sessions",
|
|
11556
|
+
path: "/sessions",
|
|
11557
|
+
getParentRoute: () => ApiGroupsGroupIdRoute
|
|
11558
|
+
});
|
|
11559
|
+
const ApiGroupsGroupIdEvidenceRoute = Route$3.update({
|
|
11560
|
+
id: "/evidence",
|
|
11561
|
+
path: "/evidence",
|
|
11562
|
+
getParentRoute: () => ApiGroupsGroupIdRoute
|
|
11563
|
+
});
|
|
10487
11564
|
const ApiProvidersProviderIdTestLogRoute = Route$2.update({
|
|
10488
11565
|
id: "/log",
|
|
10489
11566
|
path: "/log",
|
|
@@ -10492,7 +11569,7 @@ const ApiProvidersProviderIdTestLogRoute = Route$2.update({
|
|
|
10492
11569
|
const ApiKnowledgeSessionsSessionIdCandidatesRoute = Route$1.update({
|
|
10493
11570
|
id: "/api/knowledge/sessions/$sessionId/candidates",
|
|
10494
11571
|
path: "/api/knowledge/sessions/$sessionId/candidates",
|
|
10495
|
-
getParentRoute: () => Route$
|
|
11572
|
+
getParentRoute: () => Route$z
|
|
10496
11573
|
});
|
|
10497
11574
|
const ApiKnowledgeCandidatesCandidateIdPromoteRoute = Route.update({
|
|
10498
11575
|
id: "/promote",
|
|
@@ -10505,6 +11582,17 @@ const ApiConfigRouteChildren = {
|
|
|
10505
11582
|
const ApiConfigRouteWithChildren = ApiConfigRoute._addFileChildren(
|
|
10506
11583
|
ApiConfigRouteChildren
|
|
10507
11584
|
);
|
|
11585
|
+
const ApiGroupsGroupIdRouteChildren = {
|
|
11586
|
+
ApiGroupsGroupIdEvidenceRoute,
|
|
11587
|
+
ApiGroupsGroupIdSessionsRoute
|
|
11588
|
+
};
|
|
11589
|
+
const ApiGroupsGroupIdRouteWithChildren = ApiGroupsGroupIdRoute._addFileChildren(ApiGroupsGroupIdRouteChildren);
|
|
11590
|
+
const ApiGroupsRouteChildren = {
|
|
11591
|
+
ApiGroupsGroupIdRoute: ApiGroupsGroupIdRouteWithChildren
|
|
11592
|
+
};
|
|
11593
|
+
const ApiGroupsRouteWithChildren = ApiGroupsRoute._addFileChildren(
|
|
11594
|
+
ApiGroupsRouteChildren
|
|
11595
|
+
);
|
|
10508
11596
|
const ApiLogsIdRouteChildren = {
|
|
10509
11597
|
ApiLogsIdChunksRoute,
|
|
10510
11598
|
ApiLogsIdReplayRoute
|
|
@@ -10564,6 +11652,7 @@ const ApiKnowledgeCandidatesRouteWithChildren = ApiKnowledgeCandidatesRoute._add
|
|
|
10564
11652
|
const rootRouteChildren = {
|
|
10565
11653
|
IndexRoute,
|
|
10566
11654
|
ApiConfigRoute: ApiConfigRouteWithChildren,
|
|
11655
|
+
ApiGroupsRoute: ApiGroupsRouteWithChildren,
|
|
10567
11656
|
ApiHealthRoute,
|
|
10568
11657
|
ApiLogsRoute: ApiLogsRouteWithChildren,
|
|
10569
11658
|
ApiMcpRoute,
|
|
@@ -10578,7 +11667,7 @@ const rootRouteChildren = {
|
|
|
10578
11667
|
ApiKnowledgeSearchRoute,
|
|
10579
11668
|
ApiKnowledgeSessionsSessionIdCandidatesRoute
|
|
10580
11669
|
};
|
|
10581
|
-
const routeTree = Route$
|
|
11670
|
+
const routeTree = Route$z._addFileChildren(rootRouteChildren)._addFileTypes();
|
|
10582
11671
|
function getRouter() {
|
|
10583
11672
|
const router2 = createRouter({
|
|
10584
11673
|
routeTree,
|
|
@@ -10594,11 +11683,13 @@ export {
|
|
|
10594
11683
|
AnthropicResponseSchema$1 as A,
|
|
10595
11684
|
CapturedLogSchema as C,
|
|
10596
11685
|
DEFAULT_CAPTURE_MODE as D,
|
|
11686
|
+
GroupEvidenceReadResponseSchema$1 as G,
|
|
11687
|
+
InspectorGroupsListResponseSchema as I,
|
|
10597
11688
|
KnowledgeCandidateSchema as K,
|
|
10598
11689
|
MAX_SLOW_RESPONSE_THRESHOLD_SECONDS as M,
|
|
10599
11690
|
OpenAIRequestSchema as O,
|
|
10600
11691
|
ProviderConfigSchema as P,
|
|
10601
|
-
Route$
|
|
11692
|
+
Route$x as R,
|
|
10602
11693
|
TimeDisplayFormatSchema as T,
|
|
10603
11694
|
DEFAULT_SLOW_RESPONSE_THRESHOLD_SECONDS as a,
|
|
10604
11695
|
DEFAULT_PROVIDER_TEST_TIMEOUT_SECONDS as b,
|
|
@@ -10607,17 +11698,19 @@ export {
|
|
|
10607
11698
|
AnthropicRequestSchema as e,
|
|
10608
11699
|
stripClaudeCodeBillingHeader as f,
|
|
10609
11700
|
getSessionPath as g,
|
|
10610
|
-
|
|
10611
|
-
|
|
10612
|
-
|
|
10613
|
-
|
|
10614
|
-
|
|
11701
|
+
GroupEvidenceExportResultSchema as h,
|
|
11702
|
+
providerHasContextMetadata as i,
|
|
11703
|
+
findProviderModelMetadata as j,
|
|
11704
|
+
createPendingProviderTestResults as k,
|
|
11705
|
+
ProviderTestResultsSchema as l,
|
|
10615
11706
|
maskApiKey as m,
|
|
10616
|
-
|
|
10617
|
-
|
|
11707
|
+
createFailedProviderTestResults as n,
|
|
11708
|
+
MAX_PROVIDER_TEST_TIMEOUT_SECONDS as o,
|
|
10618
11709
|
parseOpenAIResponse as p,
|
|
10619
|
-
|
|
11710
|
+
resolveProviderContextWindow as q,
|
|
10620
11711
|
requestFormatForPath as r,
|
|
10621
11712
|
safeGetOwnProperty as s,
|
|
10622
|
-
|
|
11713
|
+
isPlainRecord as t,
|
|
11714
|
+
packageJson as u,
|
|
11715
|
+
router as v
|
|
10623
11716
|
};
|