@tonyclaw/agent-inspector 2.0.8 → 2.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-Djb4XFZS.js → CompareDrawer-BWMipEjS.js} +1 -1
  3. package/.output/public/assets/ProxyViewerContainer-DIAgurux.js +114 -0
  4. package/.output/public/assets/{ReplayDialog-DBPMIs2I.js → ReplayDialog-DaSzZsvM.js} +1 -1
  5. package/.output/public/assets/RequestAnatomy-BfQmPHCd.js +1 -0
  6. package/.output/public/assets/ResponseView-CblEWDMx.js +1 -0
  7. package/.output/public/assets/StreamingChunkSequence-B4atnL99.js +1 -0
  8. package/.output/public/assets/_sessionId-DUzYnZXV.js +1 -0
  9. package/.output/public/assets/index-CxhRsekH.css +1 -0
  10. package/.output/public/assets/index-jagRsQaV.js +1 -0
  11. package/.output/public/assets/{main-CwhqfJqM.js → main-DE6Y4-wV.js} +2 -2
  12. package/.output/server/{_sessionId-DzBy9gLa.mjs → _sessionId-61HO9rUI.mjs} +3 -3
  13. package/.output/server/_ssr/{CompareDrawer-C5NBvE2e.mjs → CompareDrawer-CSPqneYm.mjs} +2 -2
  14. package/.output/server/_ssr/{ProxyViewerContainer-DiZjOTQT.mjs → ProxyViewerContainer-DrSMa5O7.mjs} +159 -14
  15. package/.output/server/_ssr/{ReplayDialog-EpvTwFvp.mjs → ReplayDialog-Dn3naENv.mjs} +3 -3
  16. package/.output/server/_ssr/{RequestAnatomy-DaQjhixp.mjs → RequestAnatomy-D1X3f3AX.mjs} +336 -42
  17. package/.output/server/_ssr/{ResponseView-D8tGHCGY.mjs → ResponseView-CwXAWOoE.mjs} +2 -2
  18. package/.output/server/_ssr/{StreamingChunkSequence-DGQnb1QE.mjs → StreamingChunkSequence-DRSR2FfN.mjs} +2 -2
  19. package/.output/server/_ssr/{index-N25hqa7t.mjs → index-D4zn5CAg.mjs} +2 -2
  20. package/.output/server/_ssr/index.mjs +2 -2
  21. package/.output/server/_ssr/{router-Bf0m6F0G.mjs → router-CSRaa_tu.mjs} +531 -111
  22. package/.output/server/{_tanstack-start-manifest_v-DlAyJ5DB.mjs → _tanstack-start-manifest_v-CfvVUYYj.mjs} +1 -1
  23. package/.output/server/index.mjs +60 -60
  24. package/bin/agent-inspector.js +2 -0
  25. package/package.json +3 -2
  26. package/src/components/providers/ProviderCard.tsx +59 -5
  27. package/src/components/providers/ProviderForm.tsx +42 -0
  28. package/src/components/providers/ProvidersPanel.tsx +68 -0
  29. package/src/components/proxy-viewer/LogEntry.tsx +6 -1
  30. package/src/components/proxy-viewer/anatomy/RequestAnatomy.tsx +134 -3
  31. package/src/components/proxy-viewer/anatomy/contextIntelligence.ts +298 -40
  32. package/src/lib/providerContract.ts +12 -0
  33. package/src/lib/providerModelMetadata.ts +327 -0
  34. package/src/proxy/providers.ts +112 -52
  35. package/src/routes/api/providers.$providerId.model-metadata.ts +134 -0
  36. package/src/routes/api/providers.$providerId.ts +3 -0
  37. package/src/routes/api/providers.ts +2 -0
  38. package/.output/public/assets/ProxyViewerContainer-CWdkPZsJ.js +0 -114
  39. package/.output/public/assets/RequestAnatomy-FBfRNQN7.js +0 -1
  40. package/.output/public/assets/ResponseView-Db4pJL7U.js +0 -1
  41. package/.output/public/assets/StreamingChunkSequence-BH175O6R.js +0 -1
  42. package/.output/public/assets/_sessionId-3ipVoQtW.js +0 -1
  43. package/.output/public/assets/index-Bo1dGS4R.css +0 -1
  44. package/.output/public/assets/index-CJgaCJo8.js +0 -1
@@ -1,4 +1,4 @@
1
- const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/__root.tsx", "children": ["/", "/api/config", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/session/$sessionId", "/api/knowledge/candidates", "/api/knowledge/project-context", "/api/knowledge/search", "/api/knowledge/sessions/$sessionId/candidates"], "preloads": ["/assets/main-CwhqfJqM.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-CJgaCJo8.js", "/assets/ProxyViewerContainer-CWdkPZsJ.js"] }, "/api/config": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/config.ts", "children": ["/api/config/paths"] }, "/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/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-3ipVoQtW.js", "/assets/ProxyViewerContainer-CWdkPZsJ.js"] }, "/api/config/paths": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/config.paths.ts" }, "/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/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/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/test": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/providers.$providerId.test.ts", "children": ["/api/providers/$providerId/test/log"] }, "/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-CwhqfJqM.js" });
1
+ const tsrStartManifest = () => ({ "routes": { "__root__": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/__root.tsx", "children": ["/", "/api/config", "/api/health", "/api/logs", "/api/mcp", "/api/models", "/api/providers", "/api/sessions", "/proxy/$", "/session/$sessionId", "/api/knowledge/candidates", "/api/knowledge/project-context", "/api/knowledge/search", "/api/knowledge/sessions/$sessionId/candidates"], "preloads": ["/assets/main-DE6Y4-wV.js"], "assets": [] }, "/": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/index.tsx", "assets": [], "preloads": ["/assets/index-jagRsQaV.js", "/assets/ProxyViewerContainer-DIAgurux.js"] }, "/api/config": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/config.ts", "children": ["/api/config/paths"] }, "/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/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-DUzYnZXV.js", "/assets/ProxyViewerContainer-DIAgurux.js"] }, "/api/config/paths": { "filePath": "C:/Users/claw/workspace/agent-inspector/src/routes/api/config.paths.ts" }, "/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/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/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-DE6Y4-wV.js" });
2
2
  export {
3
3
  tsrStartManifest
4
4
  };
@@ -38,100 +38,100 @@ const assets = {
38
38
  "/assets/alibaba-TTwafVwX.svg": {
39
39
  "type": "image/svg+xml",
40
40
  "etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
41
- "mtime": "2026-06-23T00:48:08.639Z",
41
+ "mtime": "2026-06-23T07:22:07.083Z",
42
42
  "size": 5915,
43
43
  "path": "../public/assets/alibaba-TTwafVwX.svg"
44
44
  },
45
- "/assets/index-CJgaCJo8.js": {
45
+ "/assets/index-jagRsQaV.js": {
46
46
  "type": "text/javascript; charset=utf-8",
47
- "etag": '"74-6qvnmISkog5p5/pvGrwRvVnlQD4"',
48
- "mtime": "2026-06-23T00:48:08.639Z",
47
+ "etag": '"74-o8aH3a+LQxw8VtSMo1zFH2AFd9s"',
48
+ "mtime": "2026-06-23T07:22:07.084Z",
49
49
  "size": 116,
50
- "path": "../public/assets/index-CJgaCJo8.js"
50
+ "path": "../public/assets/index-jagRsQaV.js"
51
51
  },
52
- "/assets/minimax-BPMzvuL-.jpeg": {
53
- "type": "image/jpeg",
54
- "etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
55
- "mtime": "2026-06-23T00:48:08.639Z",
56
- "size": 6918,
57
- "path": "../public/assets/minimax-BPMzvuL-.jpeg"
58
- },
59
- "/assets/index-Bo1dGS4R.css": {
60
- "type": "text/css; charset=utf-8",
61
- "etag": '"193d5-fkJLOBIU3M1KTA3n4iL7ijIR5tQ"',
62
- "mtime": "2026-06-23T00:48:08.639Z",
63
- "size": 103381,
64
- "path": "../public/assets/index-Bo1dGS4R.css"
65
- },
66
- "/assets/CompareDrawer-Djb4XFZS.js": {
52
+ "/assets/CompareDrawer-BWMipEjS.js": {
67
53
  "type": "text/javascript; charset=utf-8",
68
- "etag": '"49fe-pznTOv+MMFRbS/BX9TfHAnGiok0"',
69
- "mtime": "2026-06-23T00:48:08.639Z",
54
+ "etag": '"49fe-hR3J/+C0VuiWANK0XlZhyVfJ210"',
55
+ "mtime": "2026-06-23T07:22:07.084Z",
70
56
  "size": 18942,
71
- "path": "../public/assets/CompareDrawer-Djb4XFZS.js"
57
+ "path": "../public/assets/CompareDrawer-BWMipEjS.js"
72
58
  },
73
- "/assets/main-CwhqfJqM.js": {
59
+ "/assets/index-CxhRsekH.css": {
60
+ "type": "text/css; charset=utf-8",
61
+ "etag": '"19708-ZIH0Qzt7qzQMaJIOvVbGyTC2iIs"',
62
+ "mtime": "2026-06-23T07:22:07.083Z",
63
+ "size": 104200,
64
+ "path": "../public/assets/index-CxhRsekH.css"
65
+ },
66
+ "/assets/main-DE6Y4-wV.js": {
74
67
  "type": "text/javascript; charset=utf-8",
75
- "etag": '"51726-qVbs2qbA513grk8p9/KMn4PGqgk"',
76
- "mtime": "2026-06-23T00:48:08.639Z",
68
+ "etag": '"51726-SwgH2GJTY+mB1BN9OIt6pnzmAMo"',
69
+ "mtime": "2026-06-23T07:22:07.084Z",
77
70
  "size": 333606,
78
- "path": "../public/assets/main-CwhqfJqM.js"
71
+ "path": "../public/assets/main-DE6Y4-wV.js"
79
72
  },
80
- "/assets/ReplayDialog-DBPMIs2I.js": {
73
+ "/assets/ReplayDialog-DaSzZsvM.js": {
81
74
  "type": "text/javascript; charset=utf-8",
82
- "etag": '"2361-5jth9isxe9qJDoue9YT48Duur+w"',
83
- "mtime": "2026-06-23T00:48:08.639Z",
75
+ "etag": '"2361-WG4KrKbud/9h19JiHAo9XqZb8TQ"',
76
+ "mtime": "2026-06-23T07:22:07.084Z",
84
77
  "size": 9057,
85
- "path": "../public/assets/ReplayDialog-DBPMIs2I.js"
78
+ "path": "../public/assets/ReplayDialog-DaSzZsvM.js"
79
+ },
80
+ "/assets/ResponseView-CblEWDMx.js": {
81
+ "type": "text/javascript; charset=utf-8",
82
+ "etag": '"30cc-iF/VrWGkLieZnVp8dAicYWbqwl8"',
83
+ "mtime": "2026-06-23T07:22:07.084Z",
84
+ "size": 12492,
85
+ "path": "../public/assets/ResponseView-CblEWDMx.js"
86
86
  },
87
- "/assets/RequestAnatomy-FBfRNQN7.js": {
87
+ "/assets/RequestAnatomy-BfQmPHCd.js": {
88
88
  "type": "text/javascript; charset=utf-8",
89
- "etag": '"438f-d1hToPfSWy/yglcTSVZmqhw6sPs"',
90
- "mtime": "2026-06-23T00:48:08.639Z",
91
- "size": 17295,
92
- "path": "../public/assets/RequestAnatomy-FBfRNQN7.js"
89
+ "etag": '"58ed-vl6OIMLA96fu3bgaH8iHwJjiMIQ"',
90
+ "mtime": "2026-06-23T07:22:07.084Z",
91
+ "size": 22765,
92
+ "path": "../public/assets/RequestAnatomy-BfQmPHCd.js"
93
93
  },
94
- "/assets/ResponseView-Db4pJL7U.js": {
94
+ "/assets/minimax-BPMzvuL-.jpeg": {
95
+ "type": "image/jpeg",
96
+ "etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
97
+ "mtime": "2026-06-23T07:22:07.083Z",
98
+ "size": 6918,
99
+ "path": "../public/assets/minimax-BPMzvuL-.jpeg"
100
+ },
101
+ "/assets/StreamingChunkSequence-B4atnL99.js": {
95
102
  "type": "text/javascript; charset=utf-8",
96
- "etag": '"30c5-qy6J0XN6/3GV385DLW8wrRN5vmM"',
97
- "mtime": "2026-06-23T00:48:08.639Z",
98
- "size": 12485,
99
- "path": "../public/assets/ResponseView-Db4pJL7U.js"
103
+ "etag": '"d5b-ehf7PCZmWUQkbTT5jKTPzOOKdG0"',
104
+ "mtime": "2026-06-23T07:22:07.084Z",
105
+ "size": 3419,
106
+ "path": "../public/assets/StreamingChunkSequence-B4atnL99.js"
100
107
  },
101
108
  "/assets/zhipuai-BPNAnxo-.svg": {
102
109
  "type": "image/svg+xml",
103
110
  "etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
104
- "mtime": "2026-06-23T00:48:08.639Z",
111
+ "mtime": "2026-06-23T07:22:07.083Z",
105
112
  "size": 11256,
106
113
  "path": "../public/assets/zhipuai-BPNAnxo-.svg"
107
114
  },
108
- "/assets/StreamingChunkSequence-BH175O6R.js": {
115
+ "/assets/_sessionId-DUzYnZXV.js": {
109
116
  "type": "text/javascript; charset=utf-8",
110
- "etag": '"d5a-xXaxHLvuFWxj4Xuo8eT8wfx8vC4"',
111
- "mtime": "2026-06-23T00:48:08.639Z",
112
- "size": 3418,
113
- "path": "../public/assets/StreamingChunkSequence-BH175O6R.js"
117
+ "etag": '"d2-BsjKgnQ2mI1zp5E6AjD39KpTe/g"',
118
+ "mtime": "2026-06-23T07:22:07.084Z",
119
+ "size": 210,
120
+ "path": "../public/assets/_sessionId-DUzYnZXV.js"
114
121
  },
115
122
  "/assets/qwen-CONDcHqt.png": {
116
123
  "type": "image/png",
117
124
  "etag": '"572c3-cdJAPaHdOvFCGzuaQjagdgOu6XE"',
118
- "mtime": "2026-06-23T00:48:08.639Z",
125
+ "mtime": "2026-06-23T07:22:07.083Z",
119
126
  "size": 357059,
120
127
  "path": "../public/assets/qwen-CONDcHqt.png"
121
128
  },
122
- "/assets/_sessionId-3ipVoQtW.js": {
123
- "type": "text/javascript; charset=utf-8",
124
- "etag": '"d2-nFYnu19OBrYGuMoYXu2+NgVBGhw"',
125
- "mtime": "2026-06-23T00:48:08.639Z",
126
- "size": 210,
127
- "path": "../public/assets/_sessionId-3ipVoQtW.js"
128
- },
129
- "/assets/ProxyViewerContainer-CWdkPZsJ.js": {
129
+ "/assets/ProxyViewerContainer-DIAgurux.js": {
130
130
  "type": "text/javascript; charset=utf-8",
131
- "etag": '"a2370-RA5+avpa6Zk/W44RGYNOrpe1PtI"',
132
- "mtime": "2026-06-23T00:48:08.639Z",
133
- "size": 664432,
134
- "path": "../public/assets/ProxyViewerContainer-CWdkPZsJ.js"
131
+ "etag": '"a3740-w05aF6UPaJiCj3M72I/hJ/rSNQU"',
132
+ "mtime": "2026-06-23T07:22:07.084Z",
133
+ "size": 669504,
134
+ "path": "../public/assets/ProxyViewerContainer-DIAgurux.js"
135
135
  }
136
136
  };
137
137
  function readAsset(id) {
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "../.output/cli.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonyclaw/agent-inspector",
3
- "version": "2.0.8",
3
+ "version": "2.0.10",
4
4
  "type": "module",
5
5
  "description": "Agent observability and knowledge capture layer for AI coding tools.",
6
6
  "license": "MIT",
@@ -29,9 +29,10 @@
29
29
  "ai-coding-tools"
30
30
  ],
31
31
  "bin": {
32
- "agent-inspector": ".output/cli.js"
32
+ "agent-inspector": "bin/agent-inspector.js"
33
33
  },
34
34
  "files": [
35
+ "bin",
35
36
  "src",
36
37
  "!src/**/*.test.ts",
37
38
  "!src/**/*.stories.tsx",
@@ -23,6 +23,11 @@ import {
23
23
  } from "lucide-react";
24
24
  import type { ProviderConfig } from "../../proxy/providers";
25
25
  import { maskApiKey } from "../../lib/mask";
26
+ import {
27
+ findProviderModelMetadata,
28
+ providerHasContextMetadata,
29
+ } from "../../lib/providerModelMetadata";
30
+ import { formatTokens } from "../../lib/utils";
26
31
  import type {
27
32
  ProviderTestErrorType as ErrorType,
28
33
  ProviderTestResult as TestResult,
@@ -44,6 +49,8 @@ type ProviderCardProps = {
44
49
  onEdit: (provider: ProviderConfig) => void;
45
50
  onDelete: (providerId: string) => void;
46
51
  onTest?: (providerId: string) => void;
52
+ onRefreshMetadata?: (providerId: string) => void;
53
+ isRefreshingMetadata?: boolean;
47
54
  };
48
55
 
49
56
  function hasSuccessField(result: ProviderTestState): result is TestResult {
@@ -217,6 +224,8 @@ export function ProviderCard({
217
224
  onEdit,
218
225
  onDelete,
219
226
  onTest,
227
+ onRefreshMetadata,
228
+ isRefreshingMetadata = false,
220
229
  }: ProviderCardProps): JSX.Element {
221
230
  const [showApiKey, setShowApiKey] = useState(false);
222
231
  const [copied, setCopied] = useState(false);
@@ -234,6 +243,10 @@ export function ProviderCard({
234
243
  Object.entries(KNOWN_PROVIDER_DOCS).find(([keyword]) =>
235
244
  provider.name.toLowerCase().includes(keyword),
236
245
  )?.[1];
246
+ const hasContextMetadata = providerHasContextMetadata(provider);
247
+ const canRefreshMetadata =
248
+ provider.modelMetadataUrl !== undefined && provider.modelMetadataUrl.trim() !== "";
249
+ const metadataImportLabel = canRefreshMetadata ? "Refresh" : "Import defaults";
237
250
 
238
251
  return (
239
252
  <div
@@ -283,11 +296,52 @@ export function ProviderCard({
283
296
 
284
297
  {provider.models !== undefined && provider.models.length > 0 && (
285
298
  <div className="flex flex-wrap gap-1">
286
- {provider.models.map((m) => (
287
- <span key={m} className="text-xs px-1.5 py-0.5 rounded bg-muted text-muted-foreground">
288
- {m}
289
- </span>
290
- ))}
299
+ {provider.models.map((m) => {
300
+ const metadata = findProviderModelMetadata(provider, m);
301
+ return (
302
+ <span
303
+ key={m}
304
+ className="inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded bg-muted text-muted-foreground"
305
+ >
306
+ <span>{m}</span>
307
+ {metadata !== null && metadata.contextWindow !== undefined && (
308
+ <span className="font-mono text-foreground/80">
309
+ {formatTokens(metadata.contextWindow)}
310
+ </span>
311
+ )}
312
+ </span>
313
+ );
314
+ })}
315
+ </div>
316
+ )}
317
+
318
+ {!hasContextMetadata && (
319
+ <div className="flex items-center justify-between gap-2 rounded-md border border-amber-500/25 bg-amber-500/6 px-2 py-1.5 text-xs text-muted-foreground">
320
+ <span>Context window metadata missing</span>
321
+ <div className="flex shrink-0 items-center gap-1">
322
+ <Button
323
+ type="button"
324
+ variant="outline"
325
+ size="sm"
326
+ onClick={() => onRefreshMetadata?.(provider.id)}
327
+ className="h-6 gap-1 px-2 text-xs"
328
+ disabled={isRefreshingMetadata}
329
+ >
330
+ <RotateCw className={`size-3 ${isRefreshingMetadata ? "animate-spin" : ""}`} />
331
+ {metadataImportLabel}
332
+ </Button>
333
+ {!canRefreshMetadata && (
334
+ <Button
335
+ type="button"
336
+ variant="ghost"
337
+ size="sm"
338
+ onClick={() => onEdit(provider)}
339
+ className="h-6 px-2 text-xs"
340
+ >
341
+ Set URL
342
+ </Button>
343
+ )}
344
+ </div>
291
345
  </div>
292
346
  )}
293
347
 
@@ -49,6 +49,7 @@ type ProviderFormProps = {
49
49
  anthropicBaseUrl?: string;
50
50
  openaiBaseUrl?: string;
51
51
  apiDocsUrl?: string;
52
+ modelMetadataUrl?: string;
52
53
  source?: "company" | "personal";
53
54
  }) => void;
54
55
  onCancel: () => void;
@@ -67,6 +68,7 @@ export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps
67
68
  const [anthropicBaseUrl, setAnthropicBaseUrl] = useState(provider?.anthropicBaseUrl ?? "");
68
69
  const [openaiBaseUrl, setOpenaiBaseUrl] = useState(provider?.openaiBaseUrl ?? "");
69
70
  const [apiDocsUrl, setApiDocsUrl] = useState(provider?.apiDocsUrl ?? "");
71
+ const [modelMetadataUrl, setModelMetadataUrl] = useState(provider?.modelMetadataUrl ?? "");
70
72
  const [source, setSource] = useState<"company" | "personal" | undefined>(provider?.source);
71
73
  const [errors, setErrors] = useState<Record<string, string>>({});
72
74
  const [isSubmitting, setIsSubmitting] = useState(false);
@@ -96,6 +98,8 @@ export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps
96
98
  const isMiniMax = name.toLowerCase().includes("minimax");
97
99
  // Check if Alibaba is detected
98
100
  const isAlibaba = name.toLowerCase().includes("alibaba");
101
+ const hasContextMetadata =
102
+ provider?.modelMetadata?.some((metadata) => metadata.contextWindow !== undefined) ?? false;
99
103
 
100
104
  function handleCopy() {
101
105
  navigator.clipboard.writeText(apiKey).catch(() => {});
@@ -111,6 +115,7 @@ export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps
111
115
  setAnthropicBaseUrl(provider.anthropicBaseUrl ?? "");
112
116
  setOpenaiBaseUrl(provider.openaiBaseUrl ?? "");
113
117
  setApiDocsUrl(provider.apiDocsUrl ?? "");
118
+ setModelMetadataUrl(provider.modelMetadataUrl ?? "");
114
119
  setSource(provider.source);
115
120
  setManualAnthropicUrlOverride(false);
116
121
  setManualOpenaiUrlOverride(false);
@@ -160,6 +165,9 @@ export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps
160
165
  if (openaiBaseUrl.trim() && !isValidUrl(openaiBaseUrl.trim())) {
161
166
  newErrors.openaiBaseUrl = "Invalid URL format";
162
167
  }
168
+ if (modelMetadataUrl.trim() && !isValidUrl(modelMetadataUrl.trim())) {
169
+ newErrors.modelMetadataUrl = "Invalid URL format";
170
+ }
163
171
  if (!anthropicBaseUrl.trim() && !openaiBaseUrl.trim()) {
164
172
  newErrors.format = "At least one format URL (Anthropic or OpenAI) is required";
165
173
  }
@@ -188,6 +196,7 @@ export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps
188
196
  anthropicBaseUrl: anthropicBaseUrl.trim() || undefined,
189
197
  openaiBaseUrl: openaiBaseUrl.trim() || undefined,
190
198
  apiDocsUrl: apiDocsUrl.trim() || undefined,
199
+ modelMetadataUrl: modelMetadataUrl.trim() || undefined,
191
200
  source,
192
201
  });
193
202
  } finally {
@@ -237,6 +246,39 @@ export function ProviderForm({ provider, onSubmit, onCancel }: ProviderFormProps
237
246
  </p>
238
247
  </div>
239
248
 
249
+ <div className="space-y-2">
250
+ <label htmlFor="provider-model-metadata-url" className="text-sm font-medium">
251
+ Model Metadata URL
252
+ </label>
253
+ <input
254
+ id="provider-model-metadata-url"
255
+ type="text"
256
+ value={modelMetadataUrl}
257
+ onChange={(e) => setModelMetadataUrl(e.target.value)}
258
+ placeholder="https://example.com/agent-inspector-models.json"
259
+ className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:border-ring focus-visible:outline-ring focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50"
260
+ />
261
+ {errors.modelMetadataUrl !== undefined && (
262
+ <p className="text-xs text-destructive">{errors.modelMetadataUrl}</p>
263
+ )}
264
+ {modelMetadataUrl.trim() === "" && (
265
+ <div className="rounded-md border border-border bg-muted/20 px-3 py-2 text-xs text-muted-foreground">
266
+ Built-in limits cover DeepSeek v4 pro/flash and MiniMax M3/M2.7/M2.5/M2.1. Use a
267
+ registry URL for private or custom model limits.
268
+ </div>
269
+ )}
270
+ {provider !== undefined && !hasContextMetadata && modelMetadataUrl.trim() === "" && (
271
+ <p className="text-xs text-amber-400">
272
+ This provider has no matching context metadata yet.
273
+ </p>
274
+ )}
275
+ {modelMetadataUrl.trim() !== "" && (
276
+ <p className="text-xs text-muted-foreground">
277
+ Agent Inspector will refresh model limits from this JSON registry after save.
278
+ </p>
279
+ )}
280
+ </div>
281
+
240
282
  <div className="space-y-2">
241
283
  <label htmlFor="provider-apikey" className="text-sm font-medium">
242
284
  API Key <span className="text-destructive">*</span>
@@ -29,6 +29,14 @@ const ImportResponseSchema = z.object({
29
29
  errors: z.array(z.string()).optional(),
30
30
  });
31
31
 
32
+ const ModelMetadataRefreshResponseSchema = z.object({
33
+ provider: ProviderConfigSchema,
34
+ imported: z.number(),
35
+ matchedModels: z.array(z.string()),
36
+ missingModels: z.array(z.string()),
37
+ sourceUrl: z.string(),
38
+ });
39
+
32
40
  const TEST_TIMEOUT_SECONDS = 30;
33
41
  const NETWORK_ERROR_MESSAGE = "Network error: could not reach the server. Is the proxy running?";
34
42
 
@@ -39,6 +47,7 @@ type ProviderFormData = {
39
47
  anthropicBaseUrl?: string;
40
48
  openaiBaseUrl?: string;
41
49
  apiDocsUrl?: string;
50
+ modelMetadataUrl?: string;
42
51
  source?: "company" | "personal";
43
52
  };
44
53
 
@@ -50,6 +59,7 @@ function createProviderPayload(data: ProviderFormData) {
50
59
  anthropicBaseUrl: (data.anthropicBaseUrl?.length ?? 0) > 0 ? data.anthropicBaseUrl : undefined,
51
60
  openaiBaseUrl: (data.openaiBaseUrl?.length ?? 0) > 0 ? data.openaiBaseUrl : undefined,
52
61
  apiDocsUrl: (data.apiDocsUrl?.length ?? 0) > 0 ? data.apiDocsUrl : undefined,
62
+ modelMetadataUrl: (data.modelMetadataUrl?.length ?? 0) > 0 ? data.modelMetadataUrl : undefined,
53
63
  source: data.source,
54
64
  };
55
65
  }
@@ -107,6 +117,9 @@ export function ProvidersPanel({
107
117
  const [confirmOpen, setConfirmOpen] = useState(false);
108
118
  const [deletingProviderId, setDeletingProviderId] = useState<string | null>(null);
109
119
  const [sourceFilter, setSourceFilter] = useState<"all" | "personal" | "company">("all");
120
+ const [refreshingMetadataProviders, setRefreshingMetadataProviders] = useState<Set<string>>(
121
+ new Set(),
122
+ );
110
123
  const listScrollRef = useRef<HTMLDivElement>(null);
111
124
  const highlightTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
112
125
 
@@ -273,6 +286,51 @@ export function ProvidersPanel({
273
286
  [setTestingTimeLeft, updateTestResults, updateTestingState],
274
287
  );
275
288
 
289
+ const refreshProviderMetadata = useCallback(
290
+ async (providerId: string, url?: string, showError = true): Promise<boolean> => {
291
+ setRefreshingMetadataProviders((prev) => {
292
+ const next = new Set(prev);
293
+ next.add(providerId);
294
+ return next;
295
+ });
296
+ try {
297
+ const payload = url !== undefined && url.trim() !== "" ? { url } : {};
298
+ const res = await fetch(`/api/providers/${providerId}/model-metadata`, {
299
+ method: "POST",
300
+ headers: { "Content-Type": "application/json" },
301
+ body: JSON.stringify(payload),
302
+ });
303
+ if (!res.ok) {
304
+ if (showError) {
305
+ setError(await readApiError(res, "Failed to refresh model metadata"));
306
+ }
307
+ return false;
308
+ }
309
+ const data = await parseJsonResponse(res, ModelMetadataRefreshResponseSchema);
310
+ if (data.imported === 0 && showError) {
311
+ setError("No matching model metadata found for this provider.");
312
+ } else {
313
+ setError(null);
314
+ }
315
+ triggerHighlight(data.provider.id);
316
+ refreshProviders();
317
+ return data.imported > 0;
318
+ } catch {
319
+ if (showError) {
320
+ setError(NETWORK_ERROR_MESSAGE);
321
+ }
322
+ return false;
323
+ } finally {
324
+ setRefreshingMetadataProviders((prev) => {
325
+ const next = new Set(prev);
326
+ next.delete(providerId);
327
+ return next;
328
+ });
329
+ }
330
+ },
331
+ [refreshProviders, triggerHighlight],
332
+ );
333
+
276
334
  function handleAddProvider(data: ProviderFormData): void {
277
335
  void (async () => {
278
336
  try {
@@ -288,6 +346,9 @@ export function ProvidersPanel({
288
346
  const newProvider = await parseJsonResponse(res, ProviderConfigSchema);
289
347
  setShowForm(false);
290
348
  triggerHighlight(newProvider.id);
349
+ if (data.modelMetadataUrl !== undefined && data.modelMetadataUrl.trim() !== "") {
350
+ await refreshProviderMetadata(newProvider.id, data.modelMetadataUrl, false);
351
+ }
291
352
  refreshProviders();
292
353
  await runTest(newProvider.id);
293
354
  } catch {
@@ -312,6 +373,9 @@ export function ProvidersPanel({
312
373
  const updated = await parseJsonResponse(res, ProviderConfigSchema);
313
374
  setEditingProvider(undefined);
314
375
  triggerHighlight(updated.id);
376
+ if (data.modelMetadataUrl !== undefined && data.modelMetadataUrl.trim() !== "") {
377
+ await refreshProviderMetadata(updated.id, data.modelMetadataUrl, false);
378
+ }
315
379
  refreshProviders();
316
380
  // Only run connection test when critical fields (apiKey, model, base URLs) changed
317
381
  const criticalFieldsChanged =
@@ -602,6 +666,10 @@ export function ProvidersPanel({
602
666
  isHighlighted={provider.id === highlightedProviderId}
603
667
  onEdit={(p) => setEditingProvider(p)}
604
668
  onDelete={handleDeleteProvider}
669
+ onRefreshMetadata={(id) => {
670
+ void refreshProviderMetadata(id);
671
+ }}
672
+ isRefreshingMetadata={refreshingMetadataProviders.has(provider.id)}
605
673
  onTest={(id: string) => {
606
674
  void runTest(id);
607
675
  }}
@@ -1,6 +1,6 @@
1
1
  import { GitCompareArrows } from "lucide-react";
2
2
  import { Suspense, type JSX } from "react";
3
- import { useMemo, useRef, useState, memo } from "react";
3
+ import { useEffect, useMemo, useRef, useState, memo } from "react";
4
4
  import type { CapturedLog } from "../../proxy/schemas";
5
5
  import type { TimeDisplayFormat } from "../../lib/runtimeConfig";
6
6
  import { stripClaudeCodeBillingHeader } from "../../proxy/claudeCodeStrip";
@@ -297,6 +297,11 @@ export const LogEntry = memo(function ({
297
297
  },
298
298
  });
299
299
 
300
+ useEffect(() => {
301
+ if (!expanded) return;
302
+ setActiveTab(anatomySegments !== null ? "anatomy" : "request");
303
+ }, [anatomySegments, expanded]);
304
+
300
305
  return (
301
306
  <TooltipProvider>
302
307
  <div className="border border-border rounded-lg mb-1 overflow-hidden">