@tonyclaw/agent-inspector 2.0.28 → 2.0.30
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-CicCP3Hb.js → CompareDrawer-BDzfRSt1.js} +1 -1
- package/.output/public/assets/ProxyViewerContainer-NtOD8Ex_.js +115 -0
- package/.output/public/assets/{ReplayDialog-Bc8q3ujm.js → ReplayDialog-p-5TKg75.js} +1 -1
- package/.output/public/assets/{RequestAnatomy-Coyy3zcH.js → RequestAnatomy-G0dV8-D_.js} +1 -1
- package/.output/public/assets/{ResponseView-BWJzgh0c.js → ResponseView-D2wE6lD-.js} +1 -1
- package/.output/public/assets/{StreamingChunkSequence-BSC3uuE5.js → StreamingChunkSequence-D8JRK-j_.js} +1 -1
- package/.output/public/assets/_sessionId-zimzVrJE.js +1 -0
- package/.output/public/assets/index-Cv5vPgpr.js +1 -0
- package/.output/public/assets/{index-DsiKfWCp.css → index-CwlHPmgL.css} +1 -1
- package/.output/public/assets/{main-Brj0Gn91.js → main-XHHZsOBK.js} +2 -2
- package/.output/server/_libs/lucide-react.mjs +13 -13
- package/.output/server/{_sessionId-DDdyKVG-.mjs → _sessionId-CK9QEhkB.mjs} +3 -3
- package/.output/server/_ssr/{CompareDrawer-XSExe2ml.mjs → CompareDrawer-BJVPFMIx.mjs} +2 -2
- package/.output/server/_ssr/{ProxyViewerContainer-B5pIiBZN.mjs → ProxyViewerContainer-DhbmJ2zj.mjs} +83 -20
- package/.output/server/_ssr/{ReplayDialog-BOAu0ric.mjs → ReplayDialog-DXRj95Gj.mjs} +4 -4
- package/.output/server/_ssr/{RequestAnatomy-C8Q5lozD.mjs → RequestAnatomy-CrYJTXdJ.mjs} +2 -2
- package/.output/server/_ssr/{ResponseView-a_iJfPUF.mjs → ResponseView-4ESqSITr.mjs} +2 -2
- package/.output/server/_ssr/{StreamingChunkSequence-YMKC0j8U.mjs → StreamingChunkSequence-Czdko5n_.mjs} +2 -2
- package/.output/server/_ssr/{index-CkDwBPzI.mjs → index-bei0I7qL.mjs} +2 -2
- package/.output/server/_ssr/index.mjs +2 -2
- package/.output/server/_ssr/{router-DXOXdFFM.mjs → router-sQh4Gk8J.mjs} +1338 -137
- package/.output/server/_tanstack-start-manifest_v-C0fdSWnA.mjs +4 -0
- package/.output/server/index.mjs +64 -64
- package/README.md +24 -1
- package/package.json +1 -1
- package/src/components/ProxyViewer.tsx +3 -0
- package/src/components/providers/ProviderCard.tsx +32 -0
- package/src/components/proxy-viewer/LogEntryHeader.tsx +38 -1
- package/src/lib/groupContract.ts +139 -0
- package/src/lib/providerTestContract.ts +3 -0
- package/src/lib/sessionInfoContract.ts +3 -0
- package/src/mcp/server.ts +278 -0
- package/src/mcp/toolHandlers.ts +126 -0
- package/src/proxy/evidenceAnalysis.ts +5 -0
- package/src/proxy/evidenceExporter.ts +8 -3
- package/src/proxy/groupEvidenceExporter.ts +341 -0
- package/src/proxy/groupStore.ts +259 -0
- package/src/proxy/handler.ts +8 -1
- package/src/proxy/logFinalizer.ts +36 -0
- package/src/proxy/schemas.ts +3 -0
- package/src/proxy/sessionInfo.ts +3 -0
- package/src/proxy/store.ts +3 -0
- package/src/proxy/streamTiming.ts +31 -0
- package/src/routes/api/groups.$groupId.evidence.ts +62 -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/src/routes/api/logs.$id.replay.ts +25 -2
- package/src/routes/api/providers.$providerId.test.log.ts +34 -2
- package/.output/public/assets/ProxyViewerContainer-BccuA6p5.js +0 -115
- package/.output/public/assets/_sessionId-9rEF0uSE.js +0 -1
- package/.output/public/assets/index-B9_VaAWl.js +0 -1
- package/.output/server/_tanstack-start-manifest_v-DPf3uJys.mjs +0 -4
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/__root.tsx", "children": ["/", "/api/config", "/api/groups", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/providers", "/api/runs", "/api/sessions", "/proxy/$", "/session/$sessionId", "/api/knowledge/candidates", "/api/knowledge/project-context", "/api/knowledge/search", "/api/knowledge/sessions/$sessionId/candidates"], "preloads": ["/assets/main-XHHZsOBK.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-Cv5vPgpr.js", "/assets/ProxyViewerContainer-NtOD8Ex_.js"] }, "/api/config": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/config.ts", "children": ["/api/config/paths"] }, "/api/groups": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/groups.ts", "children": ["/api/groups/$groupId"] }, "/api/health": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/health.ts" }, "/api/logs": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/logs.ts", "children": ["/api/logs/$id", "/api/logs/stream"] }, "/api/mcp": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/mcp.ts" }, "/api/models": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/models.ts" }, "/api/providers": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.ts", "children": ["/api/providers/$providerId", "/api/providers/export", "/api/providers/import", "/api/providers/scan"] }, "/api/runs": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/runs.ts", "children": ["/api/runs/$runId"] }, "/api/sessions": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/sessions.ts" }, "/proxy/$": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/proxy/$.ts" }, "/session/$sessionId": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/session/$sessionId.tsx", "assets": [], "preloads": ["/assets/_sessionId-zimzVrJE.js", "/assets/ProxyViewerContainer-NtOD8Ex_.js"] }, "/api/config/paths": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/config.paths.ts" }, "/api/groups/$groupId": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/groups.$groupId.ts", "children": ["/api/groups/$groupId/evidence", "/api/groups/$groupId/sessions"] }, "/api/knowledge/candidates": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.candidates.ts", "children": ["/api/knowledge/candidates/$candidateId"] }, "/api/knowledge/project-context": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.project-context.ts" }, "/api/knowledge/search": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.search.ts" }, "/api/logs/$id": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/logs.$id.ts", "children": ["/api/logs/$id/chunks", "/api/logs/$id/replay"] }, "/api/logs/stream": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/logs.stream.ts" }, "/api/providers/$providerId": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.$providerId.ts", "children": ["/api/providers/$providerId/model-metadata", "/api/providers/$providerId/test"] }, "/api/providers/export": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.export.ts" }, "/api/providers/import": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.import.ts" }, "/api/providers/scan": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.scan.ts" }, "/api/runs/$runId": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/runs.$runId.ts", "children": ["/api/runs/$runId/evidence"] }, "/api/groups/$groupId/evidence": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/groups.$groupId.evidence.ts" }, "/api/groups/$groupId/sessions": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/groups.$groupId.sessions.ts" }, "/api/knowledge/candidates/$candidateId": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.candidates.$candidateId.ts", "children": ["/api/knowledge/candidates/$candidateId/promote"] }, "/api/logs/$id/chunks": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/logs.$id.chunks.ts" }, "/api/logs/$id/replay": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/logs.$id.replay.ts" }, "/api/providers/$providerId/model-metadata": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.$providerId.model-metadata.ts" }, "/api/providers/$providerId/test": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.$providerId.test.ts", "children": ["/api/providers/$providerId/test/log"] }, "/api/runs/$runId/evidence": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/runs.$runId.evidence.ts" }, "/api/knowledge/candidates/$candidateId/promote": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.candidates.$candidateId.promote.ts" }, "/api/knowledge/sessions/$sessionId/candidates": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/knowledge.sessions.$sessionId.candidates.ts" }, "/api/providers/$providerId/test/log": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.$providerId.test.log.ts" } }, "clientEntry": "/assets/main-XHHZsOBK.js" });
|
|
2
|
+
export {
|
|
3
|
+
tsrStartManifest
|
|
4
|
+
};
|
package/.output/server/index.mjs
CHANGED
|
@@ -35,103 +35,103 @@ const headers = ((m) => function headersRouteRule(event) {
|
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
37
|
const assets = {
|
|
38
|
-
"/assets/index-
|
|
38
|
+
"/assets/index-Cv5vPgpr.js": {
|
|
39
39
|
"type": "text/javascript; charset=utf-8",
|
|
40
|
-
"etag": '"74-
|
|
41
|
-
"mtime": "2026-
|
|
40
|
+
"etag": '"74-qPu6sF/kGmsOicFgVQR8W+cHfLQ"',
|
|
41
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
42
42
|
"size": 116,
|
|
43
|
-
"path": "../public/assets/index-
|
|
43
|
+
"path": "../public/assets/index-Cv5vPgpr.js"
|
|
44
|
+
},
|
|
45
|
+
"/assets/index-CwlHPmgL.css": {
|
|
46
|
+
"type": "text/css; charset=utf-8",
|
|
47
|
+
"etag": '"1a3f0-E2f0kOdSBi1RhjoK38+CSij/apg"',
|
|
48
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
49
|
+
"size": 107504,
|
|
50
|
+
"path": "../public/assets/index-CwlHPmgL.css"
|
|
44
51
|
},
|
|
45
52
|
"/assets/alibaba-TTwafVwX.svg": {
|
|
46
53
|
"type": "image/svg+xml",
|
|
47
54
|
"etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
|
|
48
|
-
"mtime": "2026-
|
|
55
|
+
"mtime": "2026-07-01T01:34:44.485Z",
|
|
49
56
|
"size": 5915,
|
|
50
57
|
"path": "../public/assets/alibaba-TTwafVwX.svg"
|
|
51
58
|
},
|
|
52
|
-
"/assets/CompareDrawer-
|
|
59
|
+
"/assets/CompareDrawer-BDzfRSt1.js": {
|
|
53
60
|
"type": "text/javascript; charset=utf-8",
|
|
54
|
-
"etag": '"49fe-
|
|
55
|
-
"mtime": "2026-
|
|
61
|
+
"etag": '"49fe-SgBlfrYSy5DyWozx9HIYT63pan8"',
|
|
62
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
56
63
|
"size": 18942,
|
|
57
|
-
"path": "../public/assets/CompareDrawer-
|
|
64
|
+
"path": "../public/assets/CompareDrawer-BDzfRSt1.js"
|
|
58
65
|
},
|
|
59
|
-
"/assets/
|
|
60
|
-
"type": "text/
|
|
61
|
-
"etag": '"
|
|
62
|
-
"mtime": "2026-
|
|
63
|
-
"size":
|
|
64
|
-
"path": "../public/assets/
|
|
66
|
+
"/assets/main-XHHZsOBK.js": {
|
|
67
|
+
"type": "text/javascript; charset=utf-8",
|
|
68
|
+
"etag": '"51726-1yTScfInPZoti54sKap6zxOxpvY"',
|
|
69
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
70
|
+
"size": 333606,
|
|
71
|
+
"path": "../public/assets/main-XHHZsOBK.js"
|
|
72
|
+
},
|
|
73
|
+
"/assets/qwen-CONDcHqt.png": {
|
|
74
|
+
"type": "image/png",
|
|
75
|
+
"etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
|
|
76
|
+
"mtime": "2026-07-01T01:34:44.485Z",
|
|
77
|
+
"size": 357059,
|
|
78
|
+
"path": "../public/assets/qwen-CONDcHqt.png"
|
|
65
79
|
},
|
|
66
80
|
"/assets/minimax-BPMzvuL-.jpeg": {
|
|
67
81
|
"type": "image/jpeg",
|
|
68
82
|
"etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
|
|
69
|
-
"mtime": "2026-
|
|
83
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
70
84
|
"size": 6918,
|
|
71
85
|
"path": "../public/assets/minimax-BPMzvuL-.jpeg"
|
|
72
86
|
},
|
|
73
|
-
"/assets/
|
|
74
|
-
"type": "
|
|
75
|
-
"etag": '"
|
|
76
|
-
"mtime": "2026-
|
|
77
|
-
"size":
|
|
78
|
-
"path": "../public/assets/
|
|
87
|
+
"/assets/RequestAnatomy-G0dV8-D_.js": {
|
|
88
|
+
"type": "text/javascript; charset=utf-8",
|
|
89
|
+
"etag": '"4485-dLrPuUurtUkiFHTiud70zTzhUi8"',
|
|
90
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
91
|
+
"size": 17541,
|
|
92
|
+
"path": "../public/assets/RequestAnatomy-G0dV8-D_.js"
|
|
79
93
|
},
|
|
80
|
-
"/assets/ReplayDialog-
|
|
94
|
+
"/assets/ReplayDialog-p-5TKg75.js": {
|
|
81
95
|
"type": "text/javascript; charset=utf-8",
|
|
82
|
-
"etag": '"318c-
|
|
83
|
-
"mtime": "2026-
|
|
96
|
+
"etag": '"318c-2IdqYt4/fxajfqXLAVb8U+TSsfM"',
|
|
97
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
84
98
|
"size": 12684,
|
|
85
|
-
"path": "../public/assets/ReplayDialog-
|
|
99
|
+
"path": "../public/assets/ReplayDialog-p-5TKg75.js"
|
|
100
|
+
},
|
|
101
|
+
"/assets/ResponseView-D2wE6lD-.js": {
|
|
102
|
+
"type": "text/javascript; charset=utf-8",
|
|
103
|
+
"etag": '"30d0-5TfShOzs9M0k3ghgcC/Uc1CZi5U"',
|
|
104
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
105
|
+
"size": 12496,
|
|
106
|
+
"path": "../public/assets/ResponseView-D2wE6lD-.js"
|
|
107
|
+
},
|
|
108
|
+
"/assets/StreamingChunkSequence-D8JRK-j_.js": {
|
|
109
|
+
"type": "text/javascript; charset=utf-8",
|
|
110
|
+
"etag": '"d57-jGvUqgjv7HbrCBsM6bKKdb9Ijro"',
|
|
111
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
112
|
+
"size": 3415,
|
|
113
|
+
"path": "../public/assets/StreamingChunkSequence-D8JRK-j_.js"
|
|
86
114
|
},
|
|
87
115
|
"/assets/zhipuai-BPNAnxo-.svg": {
|
|
88
116
|
"type": "image/svg+xml",
|
|
89
117
|
"etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
|
|
90
|
-
"mtime": "2026-
|
|
118
|
+
"mtime": "2026-07-01T01:34:44.485Z",
|
|
91
119
|
"size": 11256,
|
|
92
120
|
"path": "../public/assets/zhipuai-BPNAnxo-.svg"
|
|
93
121
|
},
|
|
94
|
-
"/assets/
|
|
95
|
-
"type": "text/javascript; charset=utf-8",
|
|
96
|
-
"etag": '"51726-mwq2VuKeQG//deWEjQSFZIL9ZWo"',
|
|
97
|
-
"mtime": "2026-06-30T03:21:19.568Z",
|
|
98
|
-
"size": 333606,
|
|
99
|
-
"path": "../public/assets/main-Brj0Gn91.js"
|
|
100
|
-
},
|
|
101
|
-
"/assets/RequestAnatomy-Coyy3zcH.js": {
|
|
122
|
+
"/assets/_sessionId-zimzVrJE.js": {
|
|
102
123
|
"type": "text/javascript; charset=utf-8",
|
|
103
|
-
"etag": '"
|
|
104
|
-
"mtime": "2026-
|
|
105
|
-
"size": 17541,
|
|
106
|
-
"path": "../public/assets/RequestAnatomy-Coyy3zcH.js"
|
|
107
|
-
},
|
|
108
|
-
"/assets/_sessionId-9rEF0uSE.js": {
|
|
109
|
-
"type": "text/javascript; charset=utf-8",
|
|
110
|
-
"etag": '"d2-+KgPaqhF/ImO1Zb9tZi0sMB8OPI"',
|
|
111
|
-
"mtime": "2026-06-30T03:21:19.568Z",
|
|
124
|
+
"etag": '"d2-XtmPH9ZczbI8wqjiKa5PV3BIn0Y"',
|
|
125
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
112
126
|
"size": 210,
|
|
113
|
-
"path": "../public/assets/_sessionId-
|
|
114
|
-
},
|
|
115
|
-
"/assets/ResponseView-BWJzgh0c.js": {
|
|
116
|
-
"type": "text/javascript; charset=utf-8",
|
|
117
|
-
"etag": '"30d0-XQuX3LcRTXyoZYFeRDp9J2gMpd0"',
|
|
118
|
-
"mtime": "2026-06-30T03:21:19.570Z",
|
|
119
|
-
"size": 12496,
|
|
120
|
-
"path": "../public/assets/ResponseView-BWJzgh0c.js"
|
|
121
|
-
},
|
|
122
|
-
"/assets/StreamingChunkSequence-BSC3uuE5.js": {
|
|
123
|
-
"type": "text/javascript; charset=utf-8",
|
|
124
|
-
"etag": '"d57-1GnBSzcha+n1obLlcv4lwyBhPf4"',
|
|
125
|
-
"mtime": "2026-06-30T03:21:19.570Z",
|
|
126
|
-
"size": 3415,
|
|
127
|
-
"path": "../public/assets/StreamingChunkSequence-BSC3uuE5.js"
|
|
127
|
+
"path": "../public/assets/_sessionId-zimzVrJE.js"
|
|
128
128
|
},
|
|
129
|
-
"/assets/ProxyViewerContainer-
|
|
129
|
+
"/assets/ProxyViewerContainer-NtOD8Ex_.js": {
|
|
130
130
|
"type": "text/javascript; charset=utf-8",
|
|
131
|
-
"etag": '"
|
|
132
|
-
"mtime": "2026-
|
|
133
|
-
"size":
|
|
134
|
-
"path": "../public/assets/ProxyViewerContainer-
|
|
131
|
+
"etag": '"af8bd-AtJl2HP2L1UcDbcZviRHY1WMV8U"',
|
|
132
|
+
"mtime": "2026-07-01T01:34:44.486Z",
|
|
133
|
+
"size": 719037,
|
|
134
|
+
"path": "../public/assets/ProxyViewerContainer-NtOD8Ex_.js"
|
|
135
135
|
}
|
|
136
136
|
};
|
|
137
137
|
function readAsset(id) {
|
package/README.md
CHANGED
|
@@ -154,7 +154,7 @@ http://localhost:25947/api/mcp
|
|
|
154
154
|
Coding agents can use the MCP surface in three ways:
|
|
155
155
|
|
|
156
156
|
- Tools: perform actions such as listing logs, reading bounded log details, testing providers,
|
|
157
|
-
creating evaluation runs, and exporting evidence packs.
|
|
157
|
+
creating evaluation runs/groups, attaching sessions, and exporting evidence packs.
|
|
158
158
|
- Resources: read stable evidence URIs without invoking a tool call.
|
|
159
159
|
- Prompts: start common analysis/reporting tasks from reusable templates.
|
|
160
160
|
|
|
@@ -176,6 +176,24 @@ The evaluation-oriented run flow is:
|
|
|
176
176
|
<dataDir>/evidence/<runId>/evidence.html
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
+
For benchmark or CI systems that spawn multiple coding-agent processes, use a group as the
|
|
180
|
+
outer evaluation artifact:
|
|
181
|
+
|
|
182
|
+
1. Call `inspector_create_group` once for the evaluation batch.
|
|
183
|
+
2. Start each OpenCode/Codex process through the proxy with its own model/provider.
|
|
184
|
+
3. As each process discovers or reports its session id, call `inspector_add_group_session` with
|
|
185
|
+
`groupId`, `sessionId`, and optional `runId`, `provider`, `model`, `agent`, `label`, and
|
|
186
|
+
metadata.
|
|
187
|
+
4. Call `inspector_update_group` to mark the whole batch `running`, `failed`, `completed`, or
|
|
188
|
+
`cancelled`.
|
|
189
|
+
5. Call `inspector_export_group_evidence` to write an aggregate provider/model matrix under:
|
|
190
|
+
|
|
191
|
+
```text
|
|
192
|
+
<dataDir>/evidence/groups/<groupId>/evidence.json
|
|
193
|
+
<dataDir>/evidence/groups/<groupId>/evidence.md
|
|
194
|
+
<dataDir>/evidence/groups/<groupId>/evidence.html
|
|
195
|
+
```
|
|
196
|
+
|
|
179
197
|
Useful MCP resource URIs:
|
|
180
198
|
|
|
181
199
|
| Resource | Purpose |
|
|
@@ -187,12 +205,17 @@ Useful MCP resource URIs:
|
|
|
187
205
|
| `inspector://failures/recent` | Read recent failed/cancelled runs and non-success evidence classifications. |
|
|
188
206
|
| `inspector://runs/{runId}` | Read one declared run and its evidence paths. |
|
|
189
207
|
| `inspector://evidence/{runId}` | Read the exported Markdown evidence pack for a run. |
|
|
208
|
+
| `inspector://groups` | List declared evaluation groups. |
|
|
209
|
+
| `inspector://groups/{groupId}` | Read one group, including attached session/run members and evidence paths. |
|
|
210
|
+
| `inspector://groups/{groupId}/sessions` | Read only the attached group member list. |
|
|
211
|
+
| `inspector://groups/{groupId}/evidence` | Read the exported Markdown evidence pack for a group. |
|
|
190
212
|
|
|
191
213
|
Built-in prompt templates help turn captured evidence into user-facing output:
|
|
192
214
|
|
|
193
215
|
- `inspector_analyze_session_failure`: explain why a session failed and cite log evidence.
|
|
194
216
|
- `inspector_triage_recent_failures`: prioritize recent failed runs and suggest next actions.
|
|
195
217
|
- `inspector_generate_jenkins_report`: produce a Jenkins-ready Markdown report for a run.
|
|
218
|
+
- `inspector_generate_group_report`: produce a provider/model evaluation report for a group.
|
|
196
219
|
- `inspector_extract_repro_steps`: extract concise reproduction steps from a session.
|
|
197
220
|
|
|
198
221
|
## Jenkins And GitCode
|
package/package.json
CHANGED
|
@@ -783,6 +783,9 @@ export function ProxyViewer({
|
|
|
783
783
|
<Plus className="size-4 shrink-0 text-muted-foreground/70" aria-hidden="true" />
|
|
784
784
|
<McpLogo className="size-10 shrink-0" />
|
|
785
785
|
</span>
|
|
786
|
+
<span className="max-w-[calc(100vw-7rem)] text-sm font-semibold text-muted-foreground">
|
|
787
|
+
Local First. Evidence First.
|
|
788
|
+
</span>
|
|
786
789
|
<McpReadyBadge />
|
|
787
790
|
</h1>
|
|
788
791
|
<div className="justify-self-end">
|
|
@@ -87,6 +87,16 @@ function hasHeaderDetails(headers: Record<string, string> | undefined): boolean
|
|
|
87
87
|
return formatHeaders(headers) !== undefined;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
function formatElapsed(ms: number): string {
|
|
91
|
+
if (ms < 1000) return `${ms}ms`;
|
|
92
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function formatTokenRate(tokensPerSecond: number): string {
|
|
96
|
+
if (tokensPerSecond >= 10) return `${tokensPerSecond.toFixed(0)}/s`;
|
|
97
|
+
return `${tokensPerSecond.toFixed(1)}/s`;
|
|
98
|
+
}
|
|
99
|
+
|
|
90
100
|
function hasDiagnosticDetails(result: TestResult): boolean {
|
|
91
101
|
const debug = result.debug;
|
|
92
102
|
return (
|
|
@@ -255,6 +265,7 @@ function TestStatus({ result }: { result: ProviderTestState }): JSX.Element {
|
|
|
255
265
|
}
|
|
256
266
|
if (result.success) {
|
|
257
267
|
const tokenParts: ReactNode[] = [];
|
|
268
|
+
const timingParts: ReactNode[] = [];
|
|
258
269
|
if (result.inputTokens !== undefined) {
|
|
259
270
|
tokenParts.push(<span key="in">{result.inputTokens} in</span>);
|
|
260
271
|
}
|
|
@@ -275,11 +286,29 @@ function TestStatus({ result }: { result: ProviderTestState }): JSX.Element {
|
|
|
275
286
|
</span>,
|
|
276
287
|
);
|
|
277
288
|
}
|
|
289
|
+
if (result.firstChunkMs !== undefined && result.firstChunkMs !== null) {
|
|
290
|
+
timingParts.push(<span key="first">first {formatElapsed(result.firstChunkMs)}</span>);
|
|
291
|
+
}
|
|
292
|
+
if (result.totalStreamMs !== undefined && result.totalStreamMs !== null) {
|
|
293
|
+
timingParts.push(<span key="total">total {formatElapsed(result.totalStreamMs)}</span>);
|
|
294
|
+
}
|
|
295
|
+
if (
|
|
296
|
+
result.tokensPerSecond !== undefined &&
|
|
297
|
+
result.tokensPerSecond !== null &&
|
|
298
|
+
result.tokensPerSecond > 0
|
|
299
|
+
) {
|
|
300
|
+
timingParts.push(<span key="rate">{formatTokenRate(result.tokensPerSecond)} tok/s</span>);
|
|
301
|
+
}
|
|
278
302
|
const displayTokens: ReactNode[] = [];
|
|
279
303
|
for (let i = 0; i < tokenParts.length; i++) {
|
|
280
304
|
if (i > 0) displayTokens.push(", ");
|
|
281
305
|
displayTokens.push(tokenParts[i]);
|
|
282
306
|
}
|
|
307
|
+
const displayTiming: ReactNode[] = [];
|
|
308
|
+
for (let i = 0; i < timingParts.length; i++) {
|
|
309
|
+
if (i > 0) displayTiming.push(", ");
|
|
310
|
+
displayTiming.push(timingParts[i]);
|
|
311
|
+
}
|
|
283
312
|
return (
|
|
284
313
|
<TooltipProvider>
|
|
285
314
|
<Tooltip>
|
|
@@ -290,6 +319,9 @@ function TestStatus({ result }: { result: ProviderTestState }): JSX.Element {
|
|
|
290
319
|
{tokenParts.length > 0 && (
|
|
291
320
|
<span className="text-muted-foreground">({displayTokens})</span>
|
|
292
321
|
)}
|
|
322
|
+
{timingParts.length > 0 && (
|
|
323
|
+
<span className="hidden text-muted-foreground lg:inline">({displayTiming})</span>
|
|
324
|
+
)}
|
|
293
325
|
</div>
|
|
294
326
|
</TooltipTrigger>
|
|
295
327
|
<TooltipContent>Connection test passed</TooltipContent>
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
Copy,
|
|
12
12
|
FileDiff,
|
|
13
13
|
FileTerminal,
|
|
14
|
+
Gauge,
|
|
14
15
|
Globe,
|
|
15
16
|
History,
|
|
16
17
|
Loader2,
|
|
@@ -45,6 +46,11 @@ function formatElapsed(ms: number): string {
|
|
|
45
46
|
return `${(ms / 1000).toFixed(1)}s`;
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
function formatTokenRate(tokensPerSecond: number): string {
|
|
50
|
+
if (tokensPerSecond >= 10) return `${tokensPerSecond.toFixed(0)}/s`;
|
|
51
|
+
return `${tokensPerSecond.toFixed(1)}/s`;
|
|
52
|
+
}
|
|
53
|
+
|
|
48
54
|
/**
|
|
49
55
|
* Inline trend indicator: small arrow (green up / red down) plus the absolute
|
|
50
56
|
* delta in compact form. Returns `null` when there is no trend to display.
|
|
@@ -148,6 +154,11 @@ export const LogEntryHeader = memo(function ({
|
|
|
148
154
|
log.elapsedMs > slowResponseThresholdSeconds * 1000;
|
|
149
155
|
|
|
150
156
|
const hasTokens = log.inputTokens !== null || log.outputTokens !== null;
|
|
157
|
+
const firstChunkMs = log.firstChunkMs ?? null;
|
|
158
|
+
const tokensPerSecond = log.tokensPerSecond ?? null;
|
|
159
|
+
const firstChunkLabel = firstChunkMs === null ? null : formatElapsed(firstChunkMs);
|
|
160
|
+
const tokenRateLabel =
|
|
161
|
+
tokensPerSecond === null || tokensPerSecond <= 0 ? null : formatTokenRate(tokensPerSecond);
|
|
151
162
|
|
|
152
163
|
return (
|
|
153
164
|
<TooltipProvider>
|
|
@@ -238,11 +249,37 @@ export const LogEntryHeader = memo(function ({
|
|
|
238
249
|
? `Slow response: ${formatElapsed(log.elapsedMs)} exceeds ${formatElapsed(
|
|
239
250
|
slowResponseThresholdSeconds * 1000,
|
|
240
251
|
)}`
|
|
241
|
-
:
|
|
252
|
+
: log.streaming
|
|
253
|
+
? "Total streaming response time"
|
|
254
|
+
: "Elapsed response time"}
|
|
242
255
|
</TooltipContent>
|
|
243
256
|
</Tooltip>
|
|
244
257
|
)}
|
|
245
258
|
|
|
259
|
+
{/* Streaming timing */}
|
|
260
|
+
{log.streaming && firstChunkLabel !== null && (
|
|
261
|
+
<Tooltip>
|
|
262
|
+
<TooltipTrigger asChild>
|
|
263
|
+
<span className="flex items-center gap-1 text-xs text-cyan-400 shrink-0">
|
|
264
|
+
<Radio className="size-3" />
|
|
265
|
+
<span className="font-mono tabular-nums">first {firstChunkLabel}</span>
|
|
266
|
+
</span>
|
|
267
|
+
</TooltipTrigger>
|
|
268
|
+
<TooltipContent>Time to first streaming chunk</TooltipContent>
|
|
269
|
+
</Tooltip>
|
|
270
|
+
)}
|
|
271
|
+
{log.streaming && tokenRateLabel !== null && (
|
|
272
|
+
<Tooltip>
|
|
273
|
+
<TooltipTrigger asChild>
|
|
274
|
+
<span className="flex items-center gap-1 text-xs text-emerald-400 shrink-0">
|
|
275
|
+
<Gauge className="size-3" />
|
|
276
|
+
<span className="font-mono tabular-nums">{tokenRateLabel}</span>
|
|
277
|
+
</span>
|
|
278
|
+
</TooltipTrigger>
|
|
279
|
+
<TooltipContent>Output token throughput after first chunk</TooltipContent>
|
|
280
|
+
</Tooltip>
|
|
281
|
+
)}
|
|
282
|
+
|
|
246
283
|
{/* Token counts */}
|
|
247
284
|
{hasTokens && (
|
|
248
285
|
<span className="flex items-center gap-1 text-xs shrink-0">
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { JsonValueSchema } from "../proxy/schemas";
|
|
3
|
+
import { InspectorRunSchema, InspectorRunStatusSchema, JenkinsReportSchema } from "./runContract";
|
|
4
|
+
import { SessionInfoSchema, SessionTokenUsageSchema } from "./sessionInfoContract";
|
|
5
|
+
|
|
6
|
+
export const InspectorGroupStatusSchema = z.enum([
|
|
7
|
+
"created",
|
|
8
|
+
"running",
|
|
9
|
+
"completed",
|
|
10
|
+
"failed",
|
|
11
|
+
"cancelled",
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
export const InspectorGroupKindSchema = z.enum(["evaluation", "batch", "manual"]);
|
|
15
|
+
|
|
16
|
+
export const InspectorGroupEvidenceSchema = z.object({
|
|
17
|
+
jsonPath: z.string(),
|
|
18
|
+
markdownPath: z.string(),
|
|
19
|
+
htmlPath: z.string(),
|
|
20
|
+
exportedAt: z.string(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const InspectorGroupMemberSchema = z.object({
|
|
24
|
+
id: z.string(),
|
|
25
|
+
groupId: z.string(),
|
|
26
|
+
sessionId: z.string(),
|
|
27
|
+
runId: z.string().nullable(),
|
|
28
|
+
label: z.string().nullable(),
|
|
29
|
+
agent: z.string().nullable(),
|
|
30
|
+
provider: z.string().nullable(),
|
|
31
|
+
model: z.string().nullable(),
|
|
32
|
+
status: InspectorRunStatusSchema.nullable(),
|
|
33
|
+
metadata: z.record(z.string(), JsonValueSchema),
|
|
34
|
+
addedAt: z.string(),
|
|
35
|
+
updatedAt: z.string(),
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const InspectorGroupSchema = z.object({
|
|
39
|
+
id: z.string(),
|
|
40
|
+
title: z.string(),
|
|
41
|
+
kind: InspectorGroupKindSchema,
|
|
42
|
+
task: z.string().nullable(),
|
|
43
|
+
project: z.string().nullable(),
|
|
44
|
+
status: InspectorGroupStatusSchema,
|
|
45
|
+
tags: z.array(z.string()),
|
|
46
|
+
metadata: z.record(z.string(), JsonValueSchema),
|
|
47
|
+
evidence: InspectorGroupEvidenceSchema.nullable(),
|
|
48
|
+
members: z.array(InspectorGroupMemberSchema),
|
|
49
|
+
createdAt: z.string(),
|
|
50
|
+
updatedAt: z.string(),
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
export const CreateInspectorGroupInputSchema = z
|
|
54
|
+
.object({
|
|
55
|
+
groupId: z.string().min(1).optional(),
|
|
56
|
+
title: z.string().min(1).optional(),
|
|
57
|
+
kind: InspectorGroupKindSchema.optional(),
|
|
58
|
+
task: z.string().nullable().optional(),
|
|
59
|
+
project: z.string().nullable().optional(),
|
|
60
|
+
status: InspectorGroupStatusSchema.optional(),
|
|
61
|
+
tags: z.array(z.string()).optional(),
|
|
62
|
+
metadata: z.record(z.string(), JsonValueSchema).optional(),
|
|
63
|
+
})
|
|
64
|
+
.optional();
|
|
65
|
+
|
|
66
|
+
export const UpdateInspectorGroupInputSchema = z.object({
|
|
67
|
+
title: z.string().min(1).optional(),
|
|
68
|
+
kind: InspectorGroupKindSchema.optional(),
|
|
69
|
+
task: z.string().nullable().optional(),
|
|
70
|
+
project: z.string().nullable().optional(),
|
|
71
|
+
status: InspectorGroupStatusSchema.optional(),
|
|
72
|
+
tags: z.array(z.string()).optional(),
|
|
73
|
+
metadata: z.record(z.string(), JsonValueSchema).optional(),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export const AddInspectorGroupSessionInputSchema = z.object({
|
|
77
|
+
memberId: z.string().min(1).optional(),
|
|
78
|
+
sessionId: z.string().min(1),
|
|
79
|
+
runId: z.string().min(1).nullable().optional(),
|
|
80
|
+
label: z.string().min(1).nullable().optional(),
|
|
81
|
+
agent: z.string().min(1).nullable().optional(),
|
|
82
|
+
provider: z.string().min(1).nullable().optional(),
|
|
83
|
+
model: z.string().min(1).nullable().optional(),
|
|
84
|
+
status: InspectorRunStatusSchema.nullable().optional(),
|
|
85
|
+
metadata: z.record(z.string(), JsonValueSchema).optional(),
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
export const GroupEvidenceExportOptionsSchema = z
|
|
89
|
+
.object({
|
|
90
|
+
includeHistory: z.boolean().optional(),
|
|
91
|
+
latestLogLimit: z.number().int().positive().max(50).optional(),
|
|
92
|
+
})
|
|
93
|
+
.optional();
|
|
94
|
+
|
|
95
|
+
export const InspectorGroupExportMemberSchema = z.object({
|
|
96
|
+
member: InspectorGroupMemberSchema,
|
|
97
|
+
run: InspectorRunSchema.nullable(),
|
|
98
|
+
session: SessionInfoSchema.nullable(),
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
export const InspectorGroupEvidenceSummarySchema = z.object({
|
|
102
|
+
memberCount: z.number().int().nonnegative(),
|
|
103
|
+
sessionsWithData: z.number().int().nonnegative(),
|
|
104
|
+
missingSessions: z.number().int().nonnegative(),
|
|
105
|
+
requestCount: z.number().int().nonnegative(),
|
|
106
|
+
errorCount: z.number().int().nonnegative(),
|
|
107
|
+
tokenUsage: SessionTokenUsageSchema,
|
|
108
|
+
models: z.array(z.string()),
|
|
109
|
+
providers: z.array(z.string()),
|
|
110
|
+
completedMembers: z.number().int().nonnegative(),
|
|
111
|
+
failedMembers: z.number().int().nonnegative(),
|
|
112
|
+
runningMembers: z.number().int().nonnegative(),
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
export const GroupEvidenceExportResultSchema = z.object({
|
|
116
|
+
group: InspectorGroupSchema,
|
|
117
|
+
evidence: InspectorGroupEvidenceSchema,
|
|
118
|
+
members: z.array(InspectorGroupExportMemberSchema),
|
|
119
|
+
summary: InspectorGroupEvidenceSummarySchema,
|
|
120
|
+
jenkinsReport: JenkinsReportSchema,
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
export const InspectorGroupsListResponseSchema = z.object({
|
|
124
|
+
groups: z.array(InspectorGroupSchema),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
export type InspectorGroupStatus = z.infer<typeof InspectorGroupStatusSchema>;
|
|
128
|
+
export type InspectorGroupKind = z.infer<typeof InspectorGroupKindSchema>;
|
|
129
|
+
export type InspectorGroupEvidence = z.infer<typeof InspectorGroupEvidenceSchema>;
|
|
130
|
+
export type InspectorGroupMember = z.infer<typeof InspectorGroupMemberSchema>;
|
|
131
|
+
export type InspectorGroup = z.infer<typeof InspectorGroupSchema>;
|
|
132
|
+
export type CreateInspectorGroupInput = z.infer<typeof CreateInspectorGroupInputSchema>;
|
|
133
|
+
export type UpdateInspectorGroupInput = z.infer<typeof UpdateInspectorGroupInputSchema>;
|
|
134
|
+
export type AddInspectorGroupSessionInput = z.infer<typeof AddInspectorGroupSessionInputSchema>;
|
|
135
|
+
export type GroupEvidenceExportOptions = z.infer<typeof GroupEvidenceExportOptionsSchema>;
|
|
136
|
+
export type InspectorGroupExportMember = z.infer<typeof InspectorGroupExportMemberSchema>;
|
|
137
|
+
export type InspectorGroupEvidenceSummary = z.infer<typeof InspectorGroupEvidenceSummarySchema>;
|
|
138
|
+
export type GroupEvidenceExportResult = z.infer<typeof GroupEvidenceExportResultSchema>;
|
|
139
|
+
export type InspectorGroupsListResponse = z.infer<typeof InspectorGroupsListResponseSchema>;
|
|
@@ -45,6 +45,9 @@ export const ProviderTestResultSchema = z.object({
|
|
|
45
45
|
cacheCreationInputTokens: z.number().optional(),
|
|
46
46
|
cacheReadInputTokens: z.number().optional(),
|
|
47
47
|
latencyMs: z.number().optional(),
|
|
48
|
+
firstChunkMs: z.number().nullable().optional(),
|
|
49
|
+
totalStreamMs: z.number().nullable().optional(),
|
|
50
|
+
tokensPerSecond: z.number().nullable().optional(),
|
|
48
51
|
content: z.array(ProviderTestContentSchema).optional(),
|
|
49
52
|
rawResponse: z.string().optional(),
|
|
50
53
|
streaming: z.boolean().optional(),
|
|
@@ -21,6 +21,9 @@ export const SessionLogSummarySchema = z.object({
|
|
|
21
21
|
hasError: z.boolean(),
|
|
22
22
|
error: z.string().nullable(),
|
|
23
23
|
latencyMs: z.number().nullable(),
|
|
24
|
+
firstChunkMs: z.number().nullable().optional(),
|
|
25
|
+
totalStreamMs: z.number().nullable().optional(),
|
|
26
|
+
tokensPerSecond: z.number().nullable().optional(),
|
|
24
27
|
tokens: z.object({
|
|
25
28
|
input: z.number().nullable(),
|
|
26
29
|
output: z.number().nullable(),
|