@tonyclaw/agent-inspector 3.0.35 → 3.0.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/{CompareDrawer-R4_8sh1x.js → CompareDrawer-BvF04FAX.js} +1 -1
  3. package/.output/public/assets/{InspectorPet-BXOiEEuy.js → InspectorPet-CSCn4jWU.js} +1 -1
  4. package/.output/public/assets/ProxyViewerContainer-9mjL1YlZ.js +126 -0
  5. package/.output/public/assets/{ReplayDialog-ChEc6SEZ.js → ReplayDialog-DWJkKTDB.js} +1 -1
  6. package/.output/public/assets/{RequestAnatomy-Ur266kvo.js → RequestAnatomy-CDFI55pJ.js} +1 -1
  7. package/.output/public/assets/{ResponseView-JmIcAvf3.js → ResponseView-tlIj9vRr.js} +1 -1
  8. package/.output/public/assets/{StreamingChunkSequence-BxRDf8X0.js → StreamingChunkSequence-C7Ntivbf.js} +1 -1
  9. package/.output/public/assets/{_sessionId-BcTM61oL.js → _sessionId-BbrBvkvn.js} +1 -1
  10. package/.output/public/assets/{_sessionId-T0zMdPhW.js → _sessionId-DUL-l56X.js} +1 -1
  11. package/.output/public/assets/{index-DoGM_H4R.js → index-By0CyDmk.js} +1 -1
  12. package/.output/public/assets/{index-nPB39bG1.js → index-CEdulUJ3.js} +3 -3
  13. package/.output/public/assets/index-DCj1X8Qt.css +1 -0
  14. package/.output/public/assets/{index-DXzxeHNI.js → index-DF6bouqm.js} +1 -1
  15. package/.output/public/assets/{index-BCy0oH7t.js → index-e-fWO2Du.js} +1 -1
  16. package/.output/public/assets/{json-viewer-AR5MqNsi.js → json-viewer-0fOrL_Cz.js} +1 -1
  17. package/.output/public/assets/{jszip.min-Dp1qaNzl.js → jszip.min-2Bsoez0Q.js} +1 -1
  18. package/.output/server/_libs/lucide-react.mjs +69 -69
  19. package/.output/server/_libs/radix-ui__react-id.mjs +1 -1
  20. package/.output/server/{_sessionId-3-efukTe.mjs → _sessionId-D-GcecKN.mjs} +23 -23
  21. package/.output/server/{_sessionId-D0V28kT_.mjs → _sessionId-DzY1bB_L.mjs} +1 -1
  22. package/.output/server/_ssr/{CompareDrawer-CwUnVrgf.mjs → CompareDrawer-BXm8BitS.mjs} +24 -24
  23. package/.output/server/_ssr/{InspectorPet-DEPoGC_D.mjs → InspectorPet-CZUOr9sO.mjs} +1 -1
  24. package/.output/server/_ssr/{ProxyViewerContainer-DT2GnM6k.mjs → ProxyViewerContainer-BAQY5x_x.mjs} +185 -152
  25. package/.output/server/_ssr/{ReplayDialog-DWjyvYZk.mjs → ReplayDialog-BOODYnLb.mjs} +25 -25
  26. package/.output/server/_ssr/{RequestAnatomy-DstKoDNo.mjs → RequestAnatomy-Bd2OBiJP.mjs} +24 -24
  27. package/.output/server/_ssr/{ResponseView-_dBVL1_Y.mjs → ResponseView-ZSjpdHLG.mjs} +24 -24
  28. package/.output/server/_ssr/{StreamingChunkSequence-Dv3MUYgf.mjs → StreamingChunkSequence-BT-yQGLL.mjs} +24 -24
  29. package/.output/server/_ssr/{index-DmUQkdzY.mjs → index-CSJlUfwz.mjs} +1 -1
  30. package/.output/server/_ssr/{index-D9TfBt-A.mjs → index-CXouA5fR.mjs} +23 -23
  31. package/.output/server/_ssr/index.mjs +2 -2
  32. package/.output/server/_ssr/{json-viewer-CWGsCD5R.mjs → json-viewer-DF2oLr4x.mjs} +24 -24
  33. package/.output/server/_ssr/{router-BGaTQE2M.mjs → router-75eycvXZ.mjs} +11 -11
  34. package/.output/server/{_tanstack-start-manifest_v-BjoievXr.mjs → _tanstack-start-manifest_v-DjCobDeN.mjs} +1 -1
  35. package/.output/server/index.mjs +97 -97
  36. package/package.json +7 -1
  37. package/src/components/ProxyViewer.tsx +97 -127
  38. package/src/components/pi-agent/PiAgentPanel.tsx +99 -33
  39. package/src/components/pi-agent/piAgentChatLogic.ts +10 -0
  40. package/src/services/piAgent.ts +7 -5
  41. package/.output/public/assets/ProxyViewerContainer-F4pd4poo.js +0 -126
  42. package/.output/public/assets/index-D17dU-mX.css +0 -1
@@ -20,149 +20,149 @@ const assets = {
20
20
  "/assets/agent-inspector-58K1_MsC.ico": {
21
21
  "type": "image/vnd.microsoft.icon",
22
22
  "etag": '"38fa-ZD8kPABHYjPIkcH82FMY6iZM7fI"',
23
- "mtime": "2026-07-14T01:54:36.183Z",
23
+ "mtime": "2026-07-14T03:37:43.635Z",
24
24
  "size": 14586,
25
25
  "path": "../public/assets/agent-inspector-58K1_MsC.ico"
26
26
  },
27
- "/assets/index-BCy0oH7t.js": {
27
+ "/assets/alibaba-TTwafVwX.svg": {
28
+ "type": "image/svg+xml",
29
+ "etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
30
+ "mtime": "2026-07-14T03:37:43.635Z",
31
+ "size": 5915,
32
+ "path": "../public/assets/alibaba-TTwafVwX.svg"
33
+ },
34
+ "/assets/CompareDrawer-BvF04FAX.js": {
28
35
  "type": "text/javascript; charset=utf-8",
29
- "etag": '"265-hYzUWBDIzVwxHalua5zw5aNmRW0"',
30
- "mtime": "2026-07-14T01:54:36.183Z",
36
+ "etag": '"502d-vMe3KeFpLnAWkOFq8QeKtRah8gs"',
37
+ "mtime": "2026-07-14T03:37:43.636Z",
38
+ "size": 20525,
39
+ "path": "../public/assets/CompareDrawer-BvF04FAX.js"
40
+ },
41
+ "/assets/index-By0CyDmk.js": {
42
+ "type": "text/javascript; charset=utf-8",
43
+ "etag": '"9f-hrCND3nbEmQ8RFp6yZJVVP0Ib0E"',
44
+ "mtime": "2026-07-14T03:37:43.635Z",
45
+ "size": 159,
46
+ "path": "../public/assets/index-By0CyDmk.js"
47
+ },
48
+ "/assets/index-e-fWO2Du.js": {
49
+ "type": "text/javascript; charset=utf-8",
50
+ "etag": '"265-cLb5dkcT7iUo5wAi90rMd2clIV4"',
51
+ "mtime": "2026-07-14T03:37:43.635Z",
31
52
  "size": 613,
32
- "path": "../public/assets/index-BCy0oH7t.js"
53
+ "path": "../public/assets/index-e-fWO2Du.js"
33
54
  },
34
- "/assets/CompareDrawer-R4_8sh1x.js": {
55
+ "/assets/index-DF6bouqm.js": {
35
56
  "type": "text/javascript; charset=utf-8",
36
- "etag": '"502d-sD7mol1o5pFLUefJdDR1VH4YQsw"',
37
- "mtime": "2026-07-14T01:54:36.183Z",
38
- "size": 20525,
39
- "path": "../public/assets/CompareDrawer-R4_8sh1x.js"
57
+ "etag": '"1cd2d-J4Qd2KGSXIQ7hHkU33c2lYg39pI"',
58
+ "mtime": "2026-07-14T03:37:43.636Z",
59
+ "size": 118061,
60
+ "path": "../public/assets/index-DF6bouqm.js"
40
61
  },
41
- "/assets/index-D17dU-mX.css": {
62
+ "/assets/index-DCj1X8Qt.css": {
42
63
  "type": "text/css; charset=utf-8",
43
- "etag": '"2a4f0-2SuF12/r8Z0Yq4rQKaI4iHNWq5k"',
44
- "mtime": "2026-07-14T01:54:36.183Z",
45
- "size": 173296,
46
- "path": "../public/assets/index-D17dU-mX.css"
64
+ "etag": '"2af68-f2xj+LwefmLbVoww7v1Syfl9Ej4"',
65
+ "mtime": "2026-07-14T03:37:43.635Z",
66
+ "size": 175976,
67
+ "path": "../public/assets/index-DCj1X8Qt.css"
47
68
  },
48
- "/assets/json-viewer-AR5MqNsi.js": {
69
+ "/assets/json-viewer-0fOrL_Cz.js": {
49
70
  "type": "text/javascript; charset=utf-8",
50
- "etag": '"1ae2-0rjIpEW4kvTOKtToyGemqoTxN7g"',
51
- "mtime": "2026-07-14T01:54:36.184Z",
71
+ "etag": '"1ae2-zERDSFADkmrVJsfFKTydK3t4NwU"',
72
+ "mtime": "2026-07-14T03:37:43.636Z",
52
73
  "size": 6882,
53
- "path": "../public/assets/json-viewer-AR5MqNsi.js"
54
- },
55
- "/assets/alibaba-TTwafVwX.svg": {
56
- "type": "image/svg+xml",
57
- "etag": '"171b-6dyV5K8QjiaY35sN9qNprh9zDIs"',
58
- "mtime": "2026-07-14T01:54:36.183Z",
59
- "size": 5915,
60
- "path": "../public/assets/alibaba-TTwafVwX.svg"
74
+ "path": "../public/assets/json-viewer-0fOrL_Cz.js"
61
75
  },
62
76
  "/assets/minimax-BPMzvuL-.jpeg": {
63
77
  "type": "image/jpeg",
64
78
  "etag": '"1b06-IwivU89ko5UTMUM1/t7hn4sQK9A"',
65
- "mtime": "2026-07-14T01:54:36.183Z",
79
+ "mtime": "2026-07-14T03:37:43.635Z",
66
80
  "size": 6918,
67
81
  "path": "../public/assets/minimax-BPMzvuL-.jpeg"
68
82
  },
69
- "/assets/index-DXzxeHNI.js": {
70
- "type": "text/javascript; charset=utf-8",
71
- "etag": '"1cd2d-BNaFIwKRfrp9kW9V6U8FgU0GXYQ"',
72
- "mtime": "2026-07-14T01:54:36.184Z",
73
- "size": 118061,
74
- "path": "../public/assets/index-DXzxeHNI.js"
75
- },
76
- "/assets/jszip.min-Dp1qaNzl.js": {
77
- "type": "text/javascript; charset=utf-8",
78
- "etag": '"17b79-Da3nBSVv0Z12p6SLpDLvQqh4PYw"',
79
- "mtime": "2026-07-14T01:54:36.183Z",
80
- "size": 97145,
81
- "path": "../public/assets/jszip.min-Dp1qaNzl.js"
82
- },
83
- "/assets/index-DoGM_H4R.js": {
84
- "type": "text/javascript; charset=utf-8",
85
- "etag": '"9f-uJKoIngGCJvdeGpOcxMHk/DGNVE"',
86
- "mtime": "2026-07-14T01:54:36.183Z",
87
- "size": 159,
88
- "path": "../public/assets/index-DoGM_H4R.js"
89
- },
90
83
  "/assets/qwen-mMn3f5ul.webp": {
91
84
  "type": "image/webp",
92
85
  "etag": '"1b1a-Tw+b2ynhJQl9WztaK3ajSL85yaU"',
93
- "mtime": "2026-07-14T01:54:36.183Z",
86
+ "mtime": "2026-07-14T03:37:43.635Z",
94
87
  "size": 6938,
95
88
  "path": "../public/assets/qwen-mMn3f5ul.webp"
96
89
  },
97
- "/assets/ReplayDialog-ChEc6SEZ.js": {
90
+ "/assets/ReplayDialog-DWJkKTDB.js": {
98
91
  "type": "text/javascript; charset=utf-8",
99
- "etag": '"3294-+0mqaiC0R56ozsgKEsqtPRKAzQU"',
100
- "mtime": "2026-07-14T01:54:36.183Z",
92
+ "etag": '"3294-NzE3/xRIdwdwYT1vR3XfNRdxVyU"',
93
+ "mtime": "2026-07-14T03:37:43.636Z",
101
94
  "size": 12948,
102
- "path": "../public/assets/ReplayDialog-ChEc6SEZ.js"
95
+ "path": "../public/assets/ReplayDialog-DWJkKTDB.js"
103
96
  },
104
- "/assets/ResponseView-JmIcAvf3.js": {
97
+ "/assets/jszip.min-2Bsoez0Q.js": {
105
98
  "type": "text/javascript; charset=utf-8",
106
- "etag": '"44d3-fbDz6PqrBFt89UIYluls5F/HyoM"',
107
- "mtime": "2026-07-14T01:54:36.184Z",
108
- "size": 17619,
109
- "path": "../public/assets/ResponseView-JmIcAvf3.js"
99
+ "etag": '"17b79-eV+GUZhHOuSxBDk1+pKjEBHcPMo"',
100
+ "mtime": "2026-07-14T03:37:43.635Z",
101
+ "size": 97145,
102
+ "path": "../public/assets/jszip.min-2Bsoez0Q.js"
110
103
  },
111
- "/assets/StreamingChunkSequence-BxRDf8X0.js": {
104
+ "/assets/index-CEdulUJ3.js": {
112
105
  "type": "text/javascript; charset=utf-8",
113
- "etag": '"e96-FmItKIcLj/ydGgRWQe+/g2itDrM"',
114
- "mtime": "2026-07-14T01:54:36.184Z",
115
- "size": 3734,
116
- "path": "../public/assets/StreamingChunkSequence-BxRDf8X0.js"
106
+ "etag": '"5c73b-T/oey3Lj3YQ2iBnQAPlrIofqFm4"',
107
+ "mtime": "2026-07-14T03:37:43.635Z",
108
+ "size": 378683,
109
+ "path": "../public/assets/index-CEdulUJ3.js"
117
110
  },
118
- "/assets/zhipuai-BPNAnxo-.svg": {
119
- "type": "image/svg+xml",
120
- "etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
121
- "mtime": "2026-07-14T01:54:36.183Z",
122
- "size": 11256,
123
- "path": "../public/assets/zhipuai-BPNAnxo-.svg"
111
+ "/assets/StreamingChunkSequence-C7Ntivbf.js": {
112
+ "type": "text/javascript; charset=utf-8",
113
+ "etag": '"e96-T2MybOXPmrdvbbhoIeoNoIhF2H4"',
114
+ "mtime": "2026-07-14T03:37:43.636Z",
115
+ "size": 3734,
116
+ "path": "../public/assets/StreamingChunkSequence-C7Ntivbf.js"
124
117
  },
125
- "/assets/RequestAnatomy-Ur266kvo.js": {
118
+ "/assets/RequestAnatomy-CDFI55pJ.js": {
126
119
  "type": "text/javascript; charset=utf-8",
127
- "etag": '"43f3-CpCeeL8r6Xbpsgu/I+qCJ7dQEeo"',
128
- "mtime": "2026-07-14T01:54:36.184Z",
120
+ "etag": '"43f3-DKIGObhj8/cozYL1KLb5ZD86D8E"',
121
+ "mtime": "2026-07-14T03:37:43.635Z",
129
122
  "size": 17395,
130
- "path": "../public/assets/RequestAnatomy-Ur266kvo.js"
123
+ "path": "../public/assets/RequestAnatomy-CDFI55pJ.js"
131
124
  },
132
- "/assets/_sessionId-BcTM61oL.js": {
125
+ "/assets/ResponseView-tlIj9vRr.js": {
133
126
  "type": "text/javascript; charset=utf-8",
134
- "etag": '"a2-DntybH3k9StzHoRNsP3jSVYIjis"',
135
- "mtime": "2026-07-14T01:54:36.183Z",
136
- "size": 162,
137
- "path": "../public/assets/_sessionId-BcTM61oL.js"
127
+ "etag": '"44d3-0CtncbZdVI7Bw7/CJqgJYT8TIvQ"',
128
+ "mtime": "2026-07-14T03:37:43.636Z",
129
+ "size": 17619,
130
+ "path": "../public/assets/ResponseView-tlIj9vRr.js"
138
131
  },
139
- "/assets/index-nPB39bG1.js": {
132
+ "/assets/_sessionId-DUL-l56X.js": {
140
133
  "type": "text/javascript; charset=utf-8",
141
- "etag": '"5c73b-CYHmcgiSs6t1iD9toN3JziYt7eY"',
142
- "mtime": "2026-07-14T01:54:36.183Z",
143
- "size": 378683,
144
- "path": "../public/assets/index-nPB39bG1.js"
134
+ "etag": '"36d-pTsrBY219jOQAmuIO2jD8SvAVQQ"',
135
+ "mtime": "2026-07-14T03:37:43.635Z",
136
+ "size": 877,
137
+ "path": "../public/assets/_sessionId-DUL-l56X.js"
145
138
  },
146
- "/assets/_sessionId-T0zMdPhW.js": {
139
+ "/assets/_sessionId-BbrBvkvn.js": {
147
140
  "type": "text/javascript; charset=utf-8",
148
- "etag": '"36d-qTJiqJflB/jiCHloq9htMAj6LBg"',
149
- "mtime": "2026-07-14T01:54:36.183Z",
150
- "size": 877,
151
- "path": "../public/assets/_sessionId-T0zMdPhW.js"
141
+ "etag": '"a2-eG/rVemopMcQPEdx7c1IqZQ3yCk"',
142
+ "mtime": "2026-07-14T03:37:43.635Z",
143
+ "size": 162,
144
+ "path": "../public/assets/_sessionId-BbrBvkvn.js"
145
+ },
146
+ "/assets/zhipuai-BPNAnxo-.svg": {
147
+ "type": "image/svg+xml",
148
+ "etag": '"2bf8-hNaLCTi89nOFCsIIfWpP/jrfo0s"',
149
+ "mtime": "2026-07-14T03:37:43.635Z",
150
+ "size": 11256,
151
+ "path": "../public/assets/zhipuai-BPNAnxo-.svg"
152
152
  },
153
- "/assets/InspectorPet-BXOiEEuy.js": {
153
+ "/assets/InspectorPet-CSCn4jWU.js": {
154
154
  "type": "text/javascript; charset=utf-8",
155
- "etag": '"818f0-dqfbfV7Hb6vShYtm1ItnpbxGcWE"',
156
- "mtime": "2026-07-14T01:54:36.184Z",
155
+ "etag": '"818f0-jZf+TlVlZrzmIuMRP/t79/ufYyo"',
156
+ "mtime": "2026-07-14T03:37:43.636Z",
157
157
  "size": 530672,
158
- "path": "../public/assets/InspectorPet-BXOiEEuy.js"
158
+ "path": "../public/assets/InspectorPet-CSCn4jWU.js"
159
159
  },
160
- "/assets/ProxyViewerContainer-F4pd4poo.js": {
160
+ "/assets/ProxyViewerContainer-9mjL1YlZ.js": {
161
161
  "type": "text/javascript; charset=utf-8",
162
- "etag": '"a4a42-5QJrtYkQ9nAFuT0PZWLDgsUWFvI"',
163
- "mtime": "2026-07-14T01:54:36.184Z",
164
- "size": 674370,
165
- "path": "../public/assets/ProxyViewerContainer-F4pd4poo.js"
162
+ "etag": '"a503e-ujp5hMMMq2krY7gIT10C2N47tf8"',
163
+ "mtime": "2026-07-14T03:37:43.636Z",
164
+ "size": 675902,
165
+ "path": "../public/assets/ProxyViewerContainer-9mjL1YlZ.js"
166
166
  }
167
167
  };
168
168
  function readAsset(id) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonyclaw/agent-inspector",
3
- "version": "3.0.35",
3
+ "version": "3.0.37",
4
4
  "type": "module",
5
5
  "description": "Agent observability and knowledge capture layer for AI coding tools.",
6
6
  "license": "MIT",
@@ -53,6 +53,12 @@
53
53
  ],
54
54
  "scripts": {
55
55
  "dev": "vite dev",
56
+ "test:smoke": "bun scripts/run-test-suite.mjs smoke",
57
+ "test:fast": "bun scripts/run-test-suite.mjs smoke",
58
+ "test:unit": "bun scripts/run-test-suite.mjs unit",
59
+ "test:integration": "bun scripts/run-test-suite.mjs integration",
60
+ "test:changed": "bun scripts/run-test-suite.mjs changed",
61
+ "test:all": "bun scripts/run-test-suite.mjs all",
56
62
  "start": "node .output/cli.js",
57
63
  "build": "vite build && bun build:workers && bun build:cli && bun build:mcp && bun check:bundle",
58
64
  "build:workers": "npx esbuild src/proxy/logFinalizer.worker.ts src/proxy/sessionWorkerEntry.ts --bundle --platform=node --target=node22 --format=esm --outdir=.output/workers --external:better-sqlite3",
@@ -31,7 +31,6 @@ import {
31
31
  PanelRightClose,
32
32
  PanelRightOpen,
33
33
  RefreshCw,
34
- Search,
35
34
  Siren,
36
35
  Moon,
37
36
  Sun,
@@ -78,7 +77,7 @@ import { AlertsDialog } from "./alerts/AlertsDialog";
78
77
  import { GroupsDialog } from "./groups/GroupsDialog";
79
78
  import { SettingsDialog } from "./providers/SettingsDialog";
80
79
  import { AgentLabDialog } from "./ecosystem/AgentLabDialog";
81
- import { PiAgentPanel } from "./pi-agent/PiAgentPanel";
80
+ import { PiAgentPanel, type PiAgentSearchResult } from "./pi-agent/PiAgentPanel";
82
81
  import { LazyFeatureBoundary } from "./errors/SafeErrorBoundary";
83
82
  import { computeCacheTrends } from "./proxy-viewer/cacheTrend";
84
83
  import { LazyCompareDrawer, LazyInspectorPet } from "./proxy-viewer/lazy";
@@ -1291,11 +1290,9 @@ export type ProxyViewerProps = {
1291
1290
  export function ProxyViewer({
1292
1291
  logs,
1293
1292
  sessions,
1294
- models,
1295
1293
  selectedSession,
1296
1294
  selectedModel,
1297
1295
  onSessionChange,
1298
- onModelChange,
1299
1296
  onClearAll,
1300
1297
  onDeleteCurrentView,
1301
1298
  onReloadSession,
@@ -1333,6 +1330,9 @@ export function ProxyViewer({
1333
1330
  const [detailsPanelStorageLoaded, setDetailsPanelStorageLoaded] = useState(false);
1334
1331
  const [petVisible, setPetVisible] = useState(true);
1335
1332
  const [petVisibilityStorageLoaded, setPetVisibilityStorageLoaded] = useState(false);
1333
+ const [assistantSearchResult, setAssistantSearchResult] = useState<PiAgentSearchResult | null>(
1334
+ null,
1335
+ );
1336
1336
  const [comparePair, setComparePair] = useState<[CapturedLog, CapturedLog] | null>(null);
1337
1337
  const logListRef = useRef<HTMLDivElement>(null);
1338
1338
  const logListWrapperRef = useRef<HTMLDivElement>(null);
@@ -1483,6 +1483,7 @@ export function ProxyViewer({
1483
1483
  useEffect(() => {
1484
1484
  cancelTransientTasks();
1485
1485
  setComparePair(null);
1486
+ setAssistantSearchResult(null);
1486
1487
  }, [cancelTransientTasks, selectedSession, selectedModel]);
1487
1488
 
1488
1489
  const handleClearCurrentView = useCallback(() => {
@@ -1543,7 +1544,18 @@ export function ProxyViewer({
1543
1544
  setPetVisible((value) => !value);
1544
1545
  }, []);
1545
1546
 
1546
- const groups = useMemo(() => groupLogsByConversation(logs), [logs]);
1547
+ const assistantResultLogIds = useMemo(
1548
+ () => (assistantSearchResult === null ? null : new Set<number>(assistantSearchResult.logIds)),
1549
+ [assistantSearchResult],
1550
+ );
1551
+ const displayedLogs = useMemo(
1552
+ () =>
1553
+ assistantResultLogIds === null
1554
+ ? logs
1555
+ : logs.filter((log) => assistantResultLogIds.has(log.id)),
1556
+ [assistantResultLogIds, logs],
1557
+ );
1558
+ const groups = useMemo(() => groupLogsByConversation(displayedLogs), [displayedLogs]);
1547
1559
  const displayNumberByLogId = useMemo(() => buildDisplayNumberByLogId(groups), [groups]);
1548
1560
  const sessionContextScope = useMemo(
1549
1561
  () => resolveSessionContextScope({ pinnedSessionId, selectedSession, sessions, logs }),
@@ -1572,11 +1584,6 @@ export function ProxyViewer({
1572
1584
  ? "Deletes every stored log, streaming chunk, and session archive entry across all sessions."
1573
1585
  : "Deletes every stored log, streaming chunk, and session archive entry for this session, including history that is not currently loaded.";
1574
1586
  const reloadSessionLabel = logs.length === 0 ? "Load" : "Reload";
1575
- const sessionInputValue = selectedSession === "__all__" ? "" : selectedSession;
1576
- const sessionSelectValue =
1577
- selectedSession === "__all__" || sessions.includes(selectedSession)
1578
- ? selectedSession
1579
- : "__typed__";
1580
1587
  const activeScopeLabel =
1581
1588
  hasSessionContext && sessionContextScope !== null
1582
1589
  ? truncateSessionId(sessionContextScope.label)
@@ -1588,13 +1595,13 @@ export function ProxyViewer({
1588
1595
  const slateStats = useMemo(
1589
1596
  () =>
1590
1597
  buildSessionSlateStats({
1591
- logs,
1598
+ logs: displayedLogs,
1592
1599
  conversationGroups: groups,
1593
1600
  isLoading,
1594
1601
  timeDisplayFormat,
1595
1602
  slowResponseThresholdSeconds,
1596
1603
  }),
1597
- [groups, isLoading, logs, slowResponseThresholdSeconds, timeDisplayFormat],
1604
+ [displayedLogs, groups, isLoading, slowResponseThresholdSeconds, timeDisplayFormat],
1598
1605
  );
1599
1606
  const handleCompareWithPrevious = useCallback(
1600
1607
  (log: CapturedLog) => {
@@ -1603,20 +1610,6 @@ export function ProxyViewer({
1603
1610
  },
1604
1611
  [comparisonPredecessors],
1605
1612
  );
1606
- const handleSessionInputChange = useCallback(
1607
- (event: ChangeEvent<HTMLInputElement>) => {
1608
- const value = event.currentTarget.value.trim();
1609
- onSessionChange(value === "" ? "__all__" : value);
1610
- },
1611
- [onSessionChange],
1612
- );
1613
- const handleSessionSelectChange = useCallback(
1614
- (value: string) => {
1615
- if (value === "__typed__") return;
1616
- onSessionChange(value);
1617
- },
1618
- [onSessionChange],
1619
- );
1620
1613
  const labSessionId =
1621
1614
  pinnedSessionId !== undefined
1622
1615
  ? pinnedSessionId
@@ -1668,22 +1661,29 @@ export function ProxyViewer({
1668
1661
  {!detailsPanelCollapsed && (
1669
1662
  <aside className="bg-background/95 order-1 border-b border-white/[0.045] lg:order-2 lg:h-full lg:overflow-y-auto lg:border-b-0 lg:border-l lg:border-white/[0.055] inspector-scrollbar">
1670
1663
  <div className="space-y-4 p-4">
1671
- <SidebarPanel label="Tools">
1672
- <div className="flex flex-wrap items-center gap-1.5">
1673
- <ThemeModeToggle />
1674
- <UiScaleControl
1675
- preference={uiScalePreference}
1676
- resolvedScale={resolvedUiScale}
1677
- onChange={setUiScalePreference}
1678
- />
1679
- <GroupsDialog />
1680
- <AgentLabDialog currentSessionId={labSessionId} logCount={logs.length} />
1664
+ <PiAgentPanel
1665
+ currentSessionId={labSessionId}
1666
+ logCount={logs.length}
1667
+ onResultChange={setAssistantSearchResult}
1668
+ />
1669
+
1670
+ <SidebarPanel label="Current scope">
1671
+ <div className="mb-2 rounded-md bg-black/20 px-3 py-2 shadow-[inset_0_1px_0_rgba(255,255,255,0.035)]">
1672
+ <div
1673
+ className="truncate font-mono text-xs font-semibold text-cyan-100"
1674
+ title={activeScopeLabel}
1675
+ >
1676
+ {activeScopeLabel}
1677
+ </div>
1678
+ <div className="mt-1 text-[11px] text-muted-foreground">
1679
+ {isPinnedSessionPage ? "Pinned session" : "Live Inspector data"}
1680
+ </div>
1681
1681
  </div>
1682
- </SidebarPanel>
1683
-
1684
- <SidebarPanel label="Session">
1685
1682
  <div className="grid grid-cols-2 gap-2">
1686
- <SidebarMetric label="Requests" value={logs.length} />
1683
+ <SidebarMetric
1684
+ label={assistantSearchResult === null ? "Requests" : "Results"}
1685
+ value={displayedLogs.length}
1686
+ />
1687
1687
  <SidebarMetric label="Sessions" value={sessions.length} />
1688
1688
  <SidebarMetric
1689
1689
  label="Input"
@@ -1701,22 +1701,19 @@ export function ProxyViewer({
1701
1701
  )}
1702
1702
  </SidebarPanel>
1703
1703
 
1704
- <SidebarPanel label="Workspace">
1705
- <div className="bg-black/20 rounded-md px-3 py-2 shadow-[inset_0_1px_0_rgba(255,255,255,0.035)]">
1706
- <div
1707
- className="truncate font-mono text-xs font-semibold text-cyan-100"
1708
- title={activeScopeLabel}
1709
- >
1710
- {activeScopeLabel}
1711
- </div>
1712
- <div className="mt-1 text-[11px] text-muted-foreground">
1713
- {isPinnedSessionPage ? "Session workspace" : "Live workspace"}
1714
- </div>
1704
+ <SidebarPanel label="Tools">
1705
+ <div className="flex flex-wrap items-center gap-1.5">
1706
+ <ThemeModeToggle />
1707
+ <UiScaleControl
1708
+ preference={uiScalePreference}
1709
+ resolvedScale={resolvedUiScale}
1710
+ onChange={setUiScalePreference}
1711
+ />
1712
+ <GroupsDialog />
1713
+ <AgentLabDialog currentSessionId={labSessionId} logCount={logs.length} />
1715
1714
  </div>
1716
1715
  </SidebarPanel>
1717
1716
 
1718
- <PiAgentPanel currentSessionId={labSessionId} logCount={logs.length} />
1719
-
1720
1717
  {hasSessionContext && sessionContextScope !== null && (
1721
1718
  <SessionContextBar
1722
1719
  label={sessionContextScope.label}
@@ -1734,75 +1731,6 @@ export function ProxyViewer({
1734
1731
  sessionMemberships.length > 0 && (
1735
1732
  <SessionMembershipPanel memberships={sessionMemberships} />
1736
1733
  )}
1737
-
1738
- <SidebarPanel label="Filters">
1739
- <div className="space-y-2">
1740
- {!hideSessionFilter && (
1741
- <>
1742
- <div className="relative">
1743
- <Search className="pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground" />
1744
- <input
1745
- type="search"
1746
- value={sessionInputValue}
1747
- onChange={handleSessionInputChange}
1748
- placeholder="Paste session ID"
1749
- className="bg-black/25 hover:bg-white/[0.045] focus-visible:ring-ring h-9 w-full rounded-md px-8 font-mono text-xs text-foreground outline-none shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)] transition-colors placeholder:font-sans placeholder:text-muted-foreground focus-visible:ring-1"
1750
- aria-label="Filter by session ID"
1751
- title="Filter by exact session ID"
1752
- />
1753
- {sessionInputValue !== "" && (
1754
- <button
1755
- type="button"
1756
- onClick={() => onSessionChange("__all__")}
1757
- className="absolute right-1.5 top-1/2 inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-white/[0.06] hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none"
1758
- aria-label="Clear session filter"
1759
- title="Clear session filter"
1760
- >
1761
- <X className="size-3.5" />
1762
- </button>
1763
- )}
1764
- </div>
1765
- <Select value={sessionSelectValue} onValueChange={handleSessionSelectChange}>
1766
- <SelectTrigger
1767
- aria-label="Select a session"
1768
- className="bg-black/25 hover:bg-white/[0.045] h-9 w-full border-0 text-xs text-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)]"
1769
- >
1770
- <SelectValue placeholder="All sessions" />
1771
- </SelectTrigger>
1772
- <SelectContent>
1773
- <SelectItem value="__all__">All sessions</SelectItem>
1774
- {sessionSelectValue === "__typed__" && (
1775
- <SelectItem value="__typed__">
1776
- Typed: {truncateSessionId(selectedSession)}
1777
- </SelectItem>
1778
- )}
1779
- {sessions.map((s) => (
1780
- <SelectItem key={s} value={s}>
1781
- {truncateSessionId(s)}
1782
- </SelectItem>
1783
- ))}
1784
- </SelectContent>
1785
- </Select>
1786
- </>
1787
- )}
1788
- <Select value={selectedModel} onValueChange={onModelChange}>
1789
- <SelectTrigger
1790
- aria-label="Select a model"
1791
- className="bg-black/25 hover:bg-white/[0.045] h-9 w-full border-0 text-xs text-foreground shadow-[inset_0_0_0_1px_rgba(255,255,255,0.06)]"
1792
- >
1793
- <SelectValue placeholder="All models" />
1794
- </SelectTrigger>
1795
- <SelectContent>
1796
- <SelectItem value="__all__">All models</SelectItem>
1797
- {models.map((m) => (
1798
- <SelectItem key={m} value={m}>
1799
- {m}
1800
- </SelectItem>
1801
- ))}
1802
- </SelectContent>
1803
- </Select>
1804
- </div>
1805
- </SidebarPanel>
1806
1734
  </div>
1807
1735
  </aside>
1808
1736
  )}
@@ -1949,7 +1877,30 @@ export function ProxyViewer({
1949
1877
  )}
1950
1878
  </div>
1951
1879
  )}
1952
- <LogPaginationBar logs={logs} pagination={pagination} embedded={true} />
1880
+ {assistantSearchResult !== null && (
1881
+ <div className="mt-2 flex items-center gap-3 rounded-md bg-cyan-400/[0.07] px-3 py-2 shadow-[inset_2px_0_0_rgba(103,232,249,0.35),inset_0_0_0_1px_rgba(103,232,249,0.08)]">
1882
+ <div className="min-w-0 flex-1">
1883
+ <div className="truncate text-xs font-medium text-cyan-50">
1884
+ {assistantSearchResult.question}
1885
+ </div>
1886
+ <div className="mt-0.5 text-[10px] text-muted-foreground">
1887
+ Showing {String(displayedLogs.length)} loaded logs from{" "}
1888
+ {String(assistantSearchResult.logIds.length)} linked results
1889
+ </div>
1890
+ </div>
1891
+ <button
1892
+ type="button"
1893
+ onClick={() => setAssistantSearchResult(null)}
1894
+ className="inline-flex h-7 shrink-0 items-center gap-1 rounded-md bg-black/20 px-2 text-[11px] text-muted-foreground transition-colors hover:bg-black/30 hover:text-foreground focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none"
1895
+ >
1896
+ <X className="size-3" />
1897
+ All logs
1898
+ </button>
1899
+ </div>
1900
+ )}
1901
+ {assistantSearchResult === null && (
1902
+ <LogPaginationBar logs={logs} pagination={pagination} embedded={true} />
1903
+ )}
1953
1904
  {onNotify === undefined && exportError !== null && (
1954
1905
  <div className="mt-2 rounded-md border border-destructive/30 bg-destructive/10 px-3 py-2 text-xs text-destructive">
1955
1906
  {exportError}
@@ -1980,7 +1931,24 @@ export function ProxyViewer({
1980
1931
 
1981
1932
  <div className="px-4 py-4 lg:px-5">
1982
1933
  <SessionOpeningSlate stats={slateStats} />
1983
- {logs.length === 0 ? (
1934
+ {assistantSearchResult !== null && displayedLogs.length === 0 ? (
1935
+ <div className="py-16 text-center text-muted-foreground">
1936
+ <div className="mx-auto max-w-xl rounded-[8px] bg-white/[0.035] px-5 py-8 shadow-[inset_0_1px_0_rgba(255,255,255,0.045),0_18px_52px_rgba(0,0,0,0.18)]">
1937
+ <p className="text-sm font-medium text-foreground">No linked logs are loaded</p>
1938
+ <p className="mt-2 text-xs leading-5 text-muted-foreground">
1939
+ Assistant found evidence, but none of its linked log IDs are in the current
1940
+ loaded window. Open an evidence card in Assistant or restore the full log view.
1941
+ </p>
1942
+ <button
1943
+ type="button"
1944
+ onClick={() => setAssistantSearchResult(null)}
1945
+ className="mt-4 inline-flex h-8 items-center rounded-md bg-cyan-400/10 px-3 text-xs text-cyan-100 transition-colors hover:bg-cyan-400/16"
1946
+ >
1947
+ Show all logs
1948
+ </button>
1949
+ </div>
1950
+ </div>
1951
+ ) : logs.length === 0 ? (
1984
1952
  selectedSession !== "__all__" ? (
1985
1953
  <div className="py-16 text-center text-muted-foreground">
1986
1954
  <div className="bg-white/[0.035] shadow-[inset_0_1px_0_rgba(255,255,255,0.045),0_18px_52px_rgba(0,0,0,0.18)] mx-auto max-w-xl space-y-4 rounded-[8px] px-4 py-8">
@@ -2088,9 +2056,11 @@ export function ProxyViewer({
2088
2056
  timeDisplayFormat={timeDisplayFormat}
2089
2057
  />
2090
2058
  </div>
2091
- <div className="mt-3">
2092
- <LogPaginationBar logs={logs} pagination={pagination} />
2093
- </div>
2059
+ {assistantSearchResult === null && (
2060
+ <div className="mt-3">
2061
+ <LogPaginationBar logs={logs} pagination={pagination} />
2062
+ </div>
2063
+ )}
2094
2064
  </div>
2095
2065
  )}
2096
2066
  </div>