pi-mega-compact 0.11.4 → 0.11.6

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 (381) hide show
  1. package/dist/extensions/dashboard-server/api-contracts/cache-stripes.js +8 -0
  2. package/dist/extensions/dashboard-server/api-contracts/endpoints.js +32 -0
  3. package/dist/extensions/dashboard-server/api-contracts/memory-map.js +1 -0
  4. package/dist/extensions/dashboard-server/api-contracts/memory.js +8 -0
  5. package/dist/extensions/dashboard-server/api-contracts/provider-cache.js +1 -0
  6. package/dist/extensions/dashboard-server/api-contracts/setup.js +10 -0
  7. package/dist/extensions/dashboard-server/index-reader.js +6 -2
  8. package/dist/extensions/dashboard-server/routes-cache.js +135 -47
  9. package/dist/extensions/dashboard-server/routes-game.js +3 -0
  10. package/dist/extensions/dashboard-server/routes-memory-map.js +50 -0
  11. package/dist/extensions/dashboard-server/routes-memory.js +51 -0
  12. package/dist/extensions/dashboard-server/routes-repo.js +2 -2
  13. package/dist/extensions/dashboard-server/routes-setup.js +267 -0
  14. package/dist/extensions/dashboard-server/routes.js +4 -0
  15. package/dist/extensions/dashboard-server/server.js +13 -1
  16. package/dist/extensions/mega-commands.js +189 -1
  17. package/dist/extensions/mega-compact.js +5 -0
  18. package/dist/extensions/mega-config.js +7 -0
  19. package/dist/extensions/mega-events/agent-handlers.js +19 -4
  20. package/dist/extensions/mega-events/compact-handlers.js +1 -0
  21. package/dist/extensions/mega-events/context-handler.js +45 -92
  22. package/dist/extensions/mega-events/context-hwm.js +51 -0
  23. package/dist/extensions/mega-events/error-classifier.js +16 -5
  24. package/dist/extensions/mega-events/mirror-append.js +107 -0
  25. package/dist/extensions/mega-events/outage-advisor.js +7 -1
  26. package/dist/extensions/mega-events/perf-handler.js +134 -2
  27. package/dist/extensions/mega-events/recall-tail.js +59 -0
  28. package/dist/extensions/mega-events/separated-prompt.js +248 -0
  29. package/dist/extensions/mega-events/session-handlers.js +15 -8
  30. package/dist/extensions/mega-runtime/env-loader.js +56 -0
  31. package/dist/extensions/mega-runtime/reset-runtime.js +6 -0
  32. package/dist/extensions/mega-runtime/runtime-snapshot.js +1 -0
  33. package/dist/extensions/mega-runtime/runtime.js +7 -0
  34. package/dist/extensions/mega-runtime/snapshot.js +1 -0
  35. package/dist/extensions/mega-runtime/widget.js +5 -0
  36. package/dist/src/cache-stripe-impl.js +288 -0
  37. package/dist/src/cache-stripe.js +11 -0
  38. package/dist/src/config/stopwords.js +24 -0
  39. package/dist/src/config.js +17 -0
  40. package/dist/src/embedder.js +41 -2
  41. package/dist/src/memoryGraph.js +299 -0
  42. package/dist/src/memoryStats.js +75 -0
  43. package/dist/src/monitoring.js +13 -0
  44. package/dist/src/prefix-break.js +43 -0
  45. package/dist/src/pricing.js +1 -1
  46. package/dist/src/queryExpansion.js +163 -0
  47. package/dist/src/queryReformulation/cache.js +123 -0
  48. package/dist/src/queryReformulation/rrf.js +29 -0
  49. package/dist/src/queryReformulation/tfidf.js +61 -0
  50. package/dist/src/queryReformulation/vagueness.js +33 -0
  51. package/dist/src/queryReformulation.js +225 -0
  52. package/dist/src/recallMetrics.js +258 -0
  53. package/dist/src/store/sqlite/cache-stripes.js +133 -0
  54. package/dist/src/store/sqlite/fts5-search.js +68 -0
  55. package/dist/src/store/sqlite/perf-samples.js +145 -16
  56. package/dist/src/store/sqlite/schema.js +60 -1
  57. package/dist/src/store/sqlite.js +1 -0
  58. package/dist/src/store/turns/memory-store.js +8 -0
  59. package/dist/src/store/turns/sqlite-store.js +14 -3
  60. package/dist/src/store/turns/types.js +18 -1
  61. package/dist/src/store/vectorIndex.js +55 -10
  62. package/dist/src/tiered-router/types.js +18 -0
  63. package/dist/src/tieredRouter.js +421 -0
  64. package/dist/src/vectorStore.js +8 -6
  65. package/extensions/dashboard-client/dist/assets/{AchievementTiles-vEo2MtE2.js → AchievementTiles-DR9cLGDL.js} +2 -2
  66. package/extensions/dashboard-client/dist/assets/{AchievementTiles-vEo2MtE2.js.map → AchievementTiles-DR9cLGDL.js.map} +1 -1
  67. package/extensions/dashboard-client/dist/assets/AchievementsTab-svNUgJ1e.js +2 -0
  68. package/extensions/dashboard-client/dist/assets/{AchievementsTab-DjxfYrDc.js.map → AchievementsTab-svNUgJ1e.js.map} +1 -1
  69. package/extensions/dashboard-client/dist/assets/CacheTab-ASwhOMjR.js +2 -0
  70. package/extensions/dashboard-client/dist/assets/CacheTab-ASwhOMjR.js.map +1 -0
  71. package/extensions/dashboard-client/dist/assets/{ConfigTab-Cm6ymbmx.js → ConfigTab-CmmWheuW.js} +2 -2
  72. package/extensions/dashboard-client/dist/assets/{ConfigTab-Cm6ymbmx.js.map → ConfigTab-CmmWheuW.js.map} +1 -1
  73. package/extensions/dashboard-client/dist/assets/{EventsTab-DXWl_YzI.js → EventsTab-CFE7jLsa.js} +2 -2
  74. package/extensions/dashboard-client/dist/assets/{EventsTab-DXWl_YzI.js.map → EventsTab-CFE7jLsa.js.map} +1 -1
  75. package/extensions/dashboard-client/dist/assets/GameTab-CJAX_th_.js +2 -0
  76. package/extensions/dashboard-client/dist/assets/{GameTab-BLDudcO5.js.map → GameTab-CJAX_th_.js.map} +1 -1
  77. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DLkKCztn.js → MaintenanceTab-P4SUsvMf.js} +2 -2
  78. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DLkKCztn.js.map → MaintenanceTab-P4SUsvMf.js.map} +1 -1
  79. package/extensions/dashboard-client/dist/assets/MemoryMapTab-BBiH76eF.js +2 -0
  80. package/extensions/dashboard-client/dist/assets/MemoryMapTab-BBiH76eF.js.map +1 -0
  81. package/extensions/dashboard-client/dist/assets/{MetricsTab-Cq4u-rZF.js → MetricsTab-CHQscixy.js} +2 -2
  82. package/extensions/dashboard-client/dist/assets/{MetricsTab-Cq4u-rZF.js.map → MetricsTab-CHQscixy.js.map} +1 -1
  83. package/extensions/dashboard-client/dist/assets/OverviewTab-DBs4DJdd.js +2 -0
  84. package/extensions/dashboard-client/dist/assets/{OverviewTab-D4kGvsiQ.js.map → OverviewTab-DBs4DJdd.js.map} +1 -1
  85. package/extensions/dashboard-client/dist/assets/ReposTab-DeFz76L5.js +2 -0
  86. package/extensions/dashboard-client/dist/assets/ReposTab-DeFz76L5.js.map +1 -0
  87. package/extensions/dashboard-client/dist/assets/{SessionsTab-DZC2-GCn.js → SessionsTab-BWNsj1OB.js} +2 -2
  88. package/extensions/dashboard-client/dist/assets/{SessionsTab-DZC2-GCn.js.map → SessionsTab-BWNsj1OB.js.map} +1 -1
  89. package/extensions/dashboard-client/dist/assets/SetupTab-uS6A0xmw.js +2 -0
  90. package/extensions/dashboard-client/dist/assets/SetupTab-uS6A0xmw.js.map +1 -0
  91. package/extensions/dashboard-client/dist/assets/TimeSavedCard-CiqCOQuL.js +2 -0
  92. package/extensions/dashboard-client/dist/assets/TimeSavedCard-CiqCOQuL.js.map +1 -0
  93. package/extensions/dashboard-client/dist/assets/{TopicsTab-01G71hv1.js → TopicsTab-BWWQxltv.js} +2 -2
  94. package/extensions/dashboard-client/dist/assets/{TopicsTab-01G71hv1.js.map → TopicsTab-BWWQxltv.js.map} +1 -1
  95. package/extensions/dashboard-client/dist/assets/{TurnsTab-DLRg0LZT.js → TurnsTab-CVz4f4-o.js} +2 -2
  96. package/extensions/dashboard-client/dist/assets/{TurnsTab-DLRg0LZT.js.map → TurnsTab-CVz4f4-o.js.map} +1 -1
  97. package/extensions/dashboard-client/dist/assets/format-COjDIVGj.js +2 -0
  98. package/extensions/dashboard-client/dist/assets/format-COjDIVGj.js.map +1 -0
  99. package/extensions/dashboard-client/dist/assets/index-CUNn22iV.css +1 -0
  100. package/extensions/dashboard-client/dist/assets/index-DrktNOoT.js +42 -0
  101. package/extensions/dashboard-client/dist/assets/index-DrktNOoT.js.map +1 -0
  102. package/extensions/dashboard-client/dist/assets/pricing-CvE4NllQ.js +2 -0
  103. package/extensions/dashboard-client/dist/assets/pricing-CvE4NllQ.js.map +1 -0
  104. package/extensions/dashboard-client/dist/assets/{useSSE-BBYt5UPB.js → useSSE-Bf5LOLSi.js} +2 -2
  105. package/extensions/dashboard-client/dist/assets/{useSSE-BBYt5UPB.js.map → useSSE-Bf5LOLSi.js.map} +1 -1
  106. package/extensions/dashboard-client/dist/index.html +2 -2
  107. package/extensions/dashboard-client/src/App.tsx +28 -8
  108. package/extensions/dashboard-client/src/api/client.ts +29 -0
  109. package/extensions/dashboard-client/src/components/ActiveReposTable.tsx +21 -12
  110. package/extensions/dashboard-client/src/components/CacheHitRateTrendCard.tsx +100 -0
  111. package/extensions/dashboard-client/src/components/ProviderCacheCard.tsx +56 -0
  112. package/extensions/dashboard-client/src/components/SavingsByModelTable.tsx +38 -57
  113. package/extensions/dashboard-client/src/components/StripeDistributionCard.tsx +110 -0
  114. package/extensions/dashboard-client/src/components/TabBar.tsx +49 -4
  115. package/extensions/dashboard-client/src/main.tsx +1 -0
  116. package/extensions/dashboard-client/src/styles/base.css +30 -0
  117. package/extensions/dashboard-client/src/styles/cache.css +167 -0
  118. package/extensions/dashboard-client/src/tabs/CacheTab.tsx +75 -12
  119. package/extensions/dashboard-client/src/tabs/MemoryMapTab.tsx +440 -0
  120. package/extensions/dashboard-client/src/tabs/SetupTab.tsx +418 -0
  121. package/extensions/dashboard-client/tsconfig.json +3 -2
  122. package/extensions/dashboard-client/vite.config.ts +2 -0
  123. package/extensions/dashboard-server/api-contracts/cache-stripes.ts +49 -0
  124. package/extensions/dashboard-server/api-contracts/endpoints.ts +66 -3
  125. package/extensions/dashboard-server/api-contracts/index.ts +22 -0
  126. package/extensions/dashboard-server/api-contracts/memory-map.ts +50 -0
  127. package/extensions/dashboard-server/api-contracts/memory.ts +27 -0
  128. package/extensions/dashboard-server/api-contracts/multi-repo.ts +231 -231
  129. package/extensions/dashboard-server/api-contracts/provider-cache.ts +37 -0
  130. package/extensions/dashboard-server/api-contracts/setup.ts +80 -0
  131. package/extensions/dashboard-server/index-reader.ts +138 -121
  132. package/extensions/dashboard-server/routes-cache.ts +186 -75
  133. package/extensions/dashboard-server/routes-game.ts +3 -0
  134. package/extensions/dashboard-server/routes-memory-map.ts +105 -0
  135. package/extensions/dashboard-server/routes-memory.ts +63 -0
  136. package/extensions/dashboard-server/routes-repo.ts +36 -36
  137. package/extensions/dashboard-server/routes-setup.ts +293 -0
  138. package/extensions/dashboard-server/routes.ts +4 -0
  139. package/extensions/dashboard-server/server.ts +12 -0
  140. package/extensions/mega-commands.ts +211 -1
  141. package/extensions/mega-compact.ts +5 -0
  142. package/extensions/mega-config.ts +27 -0
  143. package/extensions/mega-events/agent-handlers.ts +20 -4
  144. package/extensions/mega-events/compact-handlers.ts +1 -0
  145. package/extensions/mega-events/context-handler.ts +53 -110
  146. package/extensions/mega-events/context-hwm.ts +85 -0
  147. package/extensions/mega-events/error-classifier.ts +15 -4
  148. package/extensions/mega-events/mirror-append.ts +155 -0
  149. package/extensions/mega-events/outage-advisor.ts +11 -5
  150. package/extensions/mega-events/perf-handler.ts +190 -6
  151. package/extensions/mega-events/recall-tail.ts +88 -0
  152. package/extensions/mega-events/separated-prompt.ts +329 -0
  153. package/extensions/mega-events/session-handlers.ts +14 -7
  154. package/extensions/mega-runtime/env-loader.ts +55 -0
  155. package/extensions/mega-runtime/helpers.ts +14 -0
  156. package/extensions/mega-runtime/reset-runtime.ts +6 -0
  157. package/extensions/mega-runtime/runtime-snapshot.ts +1 -0
  158. package/extensions/mega-runtime/runtime.ts +7 -0
  159. package/extensions/mega-runtime/snapshot.ts +6 -0
  160. package/extensions/mega-runtime/widget-types.ts +3 -0
  161. package/extensions/mega-runtime/widget.ts +5 -0
  162. package/package.json +5 -2
  163. package/src/cache-stripe-impl.ts +385 -0
  164. package/src/cache-stripe.ts +18 -0
  165. package/src/config/stopwords.ts +25 -0
  166. package/src/config.ts +26 -0
  167. package/src/embedder.ts +42 -2
  168. package/src/memoryGraph.ts +438 -0
  169. package/src/memoryStats.ts +107 -0
  170. package/src/monitoring.ts +35 -0
  171. package/src/prefix-break.ts +83 -0
  172. package/src/pricing.ts +2 -2
  173. package/src/queryExpansion.ts +206 -0
  174. package/src/queryReformulation/cache.ts +169 -0
  175. package/src/queryReformulation/rrf.ts +51 -0
  176. package/src/queryReformulation/tfidf.ts +79 -0
  177. package/src/queryReformulation/vagueness.ts +38 -0
  178. package/src/queryReformulation.ts +355 -0
  179. package/src/recallMetrics.ts +388 -0
  180. package/src/store/sqlite/cache-stripes.ts +196 -0
  181. package/src/store/sqlite/fts5-search.ts +90 -0
  182. package/src/store/sqlite/perf-samples.ts +218 -23
  183. package/src/store/sqlite/schema.ts +60 -1
  184. package/src/store/sqlite.ts +1 -0
  185. package/src/store/turns/memory-store.ts +10 -1
  186. package/src/store/turns/sqlite-store.ts +27 -15
  187. package/src/store/turns/types.ts +21 -0
  188. package/src/store/vectorIndex.ts +71 -11
  189. package/src/tiered-router/types.ts +64 -0
  190. package/src/tieredRouter.ts +489 -0
  191. package/src/vectorStore.ts +9 -5
  192. package/dist/extensions/conflict-scan.test.js +0 -115
  193. package/dist/extensions/dashboard-server/api-contracts.test.js +0 -884
  194. package/dist/extensions/dashboard-server/html.test.js +0 -52
  195. package/dist/extensions/dashboard-server/perf-server.test.js +0 -80
  196. package/dist/extensions/dashboard-server/routes-cache.test.js +0 -248
  197. package/dist/extensions/dashboard-server/server.test.js +0 -120
  198. package/dist/extensions/dashboard-server-s32.test.js +0 -181
  199. package/dist/extensions/dashboard-server.test.js +0 -339
  200. package/dist/extensions/mega-cache-replay.test.js +0 -400
  201. package/dist/extensions/mega-compact-s38.test.js +0 -1383
  202. package/dist/extensions/mega-compact.test.js +0 -1112
  203. package/dist/extensions/mega-events.test.js +0 -47
  204. package/dist/extensions/mega-game-cmds.test.js +0 -163
  205. package/dist/extensions/mega-runtime/snapshot.test.js +0 -127
  206. package/dist/extensions/mega-runtime/state.test.js +0 -266
  207. package/dist/extensions/mega-runtime/widget.test.js +0 -343
  208. package/dist/extensions/mega-shutdown-widget.test.js +0 -121
  209. package/dist/extensions/mega-teamrun.test.js +0 -156
  210. package/dist/extensions/mega-trim.test.js +0 -58
  211. package/dist/extensions/mega-turn-store.test.js +0 -68
  212. package/dist/src/boundary.test.js +0 -170
  213. package/dist/src/compact.test.js +0 -78
  214. package/dist/src/config/themes.test.js +0 -94
  215. package/dist/src/dedup/dedup.test.js +0 -41
  216. package/dist/src/dedup/l1.test.js +0 -50
  217. package/dist/src/dedup/raptor/buildHistory.test.js +0 -292
  218. package/dist/src/dedup/raptor/multilevel-serve.test.js +0 -229
  219. package/dist/src/dedup/raptor/multilevel.test.js +0 -238
  220. package/dist/src/dedup/raptor/promote.test.js +0 -69
  221. package/dist/src/dedup/raptor/raptor.test.js +0 -248
  222. package/dist/src/dedup/raptor/retrieval.test.js +0 -95
  223. package/dist/src/dedup/raptor/serve-gate.test.js +0 -298
  224. package/dist/src/dedup/sprint12.test.js +0 -219
  225. package/dist/src/dedup-engine.test.js +0 -472
  226. package/dist/src/driftDetection.test.js +0 -87
  227. package/dist/src/e2e.test.js +0 -698
  228. package/dist/src/engine.test.js +0 -111
  229. package/dist/src/extractive.test.js +0 -147
  230. package/dist/src/fork.test.js +0 -81
  231. package/dist/src/game/scoring.test.js +0 -98
  232. package/dist/src/httpEmbedder.test.js +0 -277
  233. package/dist/src/importance.test.js +0 -372
  234. package/dist/src/intent.test.js +0 -78
  235. package/dist/src/log.test.js +0 -42
  236. package/dist/src/mechanical-fix.test.js +0 -65
  237. package/dist/src/memory.test.js +0 -70
  238. package/dist/src/memoryConsolidate.test.js +0 -38
  239. package/dist/src/memoryOps.test.js +0 -129
  240. package/dist/src/memoryRecall.test.js +0 -171
  241. package/dist/src/memoryRoundtrip.test.js +0 -137
  242. package/dist/src/metrics/turns.test.js +0 -152
  243. package/dist/src/mirror/mirror.test.js +0 -185
  244. package/dist/src/raptor-inject-summaries.test.js +0 -162
  245. package/dist/src/ratio.bench.test.js +0 -897
  246. package/dist/src/recall.integration.test.js +0 -77
  247. package/dist/src/recall.test.js +0 -379
  248. package/dist/src/sprint14.test.js +0 -219
  249. package/dist/src/sprint4x-rag-verification.test.js +0 -93
  250. package/dist/src/store/compression.test.js +0 -139
  251. package/dist/src/store/memoryIndex.test.js +0 -51
  252. package/dist/src/store/migrate.test.js +0 -139
  253. package/dist/src/store/pgOpenGuard.test.js +0 -74
  254. package/dist/src/store/phase01.test.js +0 -81
  255. package/dist/src/store/phase04.test.js +0 -54
  256. package/dist/src/store/sprint10.test.js +0 -186
  257. package/dist/src/store/sqlite/game-achievements.test.js +0 -67
  258. package/dist/src/store/sqlite/game-scores.test.js +0 -106
  259. package/dist/src/store/sqlite/game-state.test.js +0 -76
  260. package/dist/src/store/sqlite/global-index.test.js +0 -136
  261. package/dist/src/store/sqlite/mechanical-fix.test.js +0 -146
  262. package/dist/src/store/sqlite/perf-samples.test.js +0 -146
  263. package/dist/src/store/sqlite/raptor.test.js +0 -106
  264. package/dist/src/store/sqlite/turns.test.js +0 -183
  265. package/dist/src/store/sqlite.cachehit.test.js +0 -55
  266. package/dist/src/store/sqlite.dbmaint.test.js +0 -158
  267. package/dist/src/store/sqlite.dbmirror.test.js +0 -184
  268. package/dist/src/store/turns/contract-compliance.test.js +0 -428
  269. package/dist/src/store/turns/memory-store.test.js +0 -9
  270. package/dist/src/store/turns/migrations.test.js +0 -138
  271. package/dist/src/store/turns/sqlite-store.test.js +0 -144
  272. package/dist/src/store/vectorIndex.test.js +0 -123
  273. package/dist/src/store.test.js +0 -161
  274. package/dist/src/supersede.test.js +0 -36
  275. package/dist/src/topics/cluster.test.js +0 -150
  276. package/dist/src/topics/store.test.js +0 -117
  277. package/dist/src/types.test.js +0 -9
  278. package/dist/src/vector-search-cache.test.js +0 -157
  279. package/dist/src/vectorStore.test.js +0 -479
  280. package/dist/src/wiki.test.js +0 -171
  281. package/extensions/conflict-scan.test.ts +0 -129
  282. package/extensions/dashboard-client/dist/assets/AchievementsTab-DjxfYrDc.js +0 -2
  283. package/extensions/dashboard-client/dist/assets/CacheTab-Dnpv94wq.js +0 -2
  284. package/extensions/dashboard-client/dist/assets/CacheTab-Dnpv94wq.js.map +0 -1
  285. package/extensions/dashboard-client/dist/assets/GameTab-BLDudcO5.js +0 -2
  286. package/extensions/dashboard-client/dist/assets/OverviewTab-D4kGvsiQ.js +0 -2
  287. package/extensions/dashboard-client/dist/assets/ReposTab-C0Wnrf2u.js +0 -2
  288. package/extensions/dashboard-client/dist/assets/ReposTab-C0Wnrf2u.js.map +0 -1
  289. package/extensions/dashboard-client/dist/assets/TimeSavedCard-UqljSyP-.js +0 -2
  290. package/extensions/dashboard-client/dist/assets/TimeSavedCard-UqljSyP-.js.map +0 -1
  291. package/extensions/dashboard-client/dist/assets/index-BEdKlpAB.css +0 -1
  292. package/extensions/dashboard-client/dist/assets/index-BX0bcgLu.js +0 -42
  293. package/extensions/dashboard-client/dist/assets/index-BX0bcgLu.js.map +0 -1
  294. package/extensions/dashboard-server/api-contracts.test.ts +0 -1065
  295. package/extensions/dashboard-server/html.test.ts +0 -62
  296. package/extensions/dashboard-server/perf-server.test.ts +0 -101
  297. package/extensions/dashboard-server/routes-cache.test.ts +0 -302
  298. package/extensions/dashboard-server/server.test.ts +0 -131
  299. package/extensions/dashboard-server-s32.test.ts +0 -195
  300. package/extensions/dashboard-server.test.ts +0 -382
  301. package/extensions/mega-cache-replay.test.ts +0 -526
  302. package/extensions/mega-compact-s38.test.ts +0 -1433
  303. package/extensions/mega-compact.test.ts +0 -1509
  304. package/extensions/mega-events.test.ts +0 -55
  305. package/extensions/mega-game-cmds.test.ts +0 -197
  306. package/extensions/mega-runtime/snapshot.test.ts +0 -139
  307. package/extensions/mega-runtime/state.test.ts +0 -262
  308. package/extensions/mega-runtime/widget.test.ts +0 -468
  309. package/extensions/mega-shutdown-widget.test.ts +0 -141
  310. package/extensions/mega-teamrun.test.ts +0 -176
  311. package/extensions/mega-trim.test.ts +0 -64
  312. package/extensions/mega-turn-store.test.ts +0 -108
  313. package/src/boundary.test.ts +0 -187
  314. package/src/compact.test.ts +0 -99
  315. package/src/config/themes.test.ts +0 -116
  316. package/src/dedup/dedup.test.ts +0 -46
  317. package/src/dedup/l1.test.ts +0 -57
  318. package/src/dedup/raptor/buildHistory.test.ts +0 -353
  319. package/src/dedup/raptor/multilevel-serve.test.ts +0 -273
  320. package/src/dedup/raptor/multilevel.test.ts +0 -325
  321. package/src/dedup/raptor/promote.test.ts +0 -82
  322. package/src/dedup/raptor/raptor.test.ts +0 -297
  323. package/src/dedup/raptor/retrieval.test.ts +0 -118
  324. package/src/dedup/raptor/serve-gate.test.ts +0 -348
  325. package/src/dedup/sprint12.test.ts +0 -242
  326. package/src/dedup-engine.test.ts +0 -670
  327. package/src/driftDetection.test.ts +0 -100
  328. package/src/e2e.test.ts +0 -843
  329. package/src/engine.test.ts +0 -123
  330. package/src/extractive.test.ts +0 -174
  331. package/src/fork.test.ts +0 -94
  332. package/src/game/scoring.test.ts +0 -103
  333. package/src/httpEmbedder.test.ts +0 -286
  334. package/src/importance.test.ts +0 -538
  335. package/src/intent.test.ts +0 -87
  336. package/src/log.test.ts +0 -47
  337. package/src/mechanical-fix.test.ts +0 -70
  338. package/src/memory.test.ts +0 -92
  339. package/src/memoryConsolidate.test.ts +0 -47
  340. package/src/memoryOps.test.ts +0 -148
  341. package/src/memoryRecall.test.ts +0 -194
  342. package/src/memoryRoundtrip.test.ts +0 -155
  343. package/src/metrics/turns.test.ts +0 -165
  344. package/src/mirror/mirror.test.ts +0 -240
  345. package/src/raptor-inject-summaries.test.ts +0 -228
  346. package/src/ratio.bench.test.ts +0 -1316
  347. package/src/recall.integration.test.ts +0 -96
  348. package/src/recall.test.ts +0 -467
  349. package/src/sprint14.test.ts +0 -245
  350. package/src/sprint4x-rag-verification.test.ts +0 -119
  351. package/src/store/compression.test.ts +0 -168
  352. package/src/store/memoryIndex.test.ts +0 -61
  353. package/src/store/migrate.test.ts +0 -158
  354. package/src/store/pgOpenGuard.test.ts +0 -89
  355. package/src/store/phase01.test.ts +0 -88
  356. package/src/store/phase04.test.ts +0 -58
  357. package/src/store/sprint10.test.ts +0 -214
  358. package/src/store/sqlite/game-achievements.test.ts +0 -80
  359. package/src/store/sqlite/game-scores.test.ts +0 -132
  360. package/src/store/sqlite/game-state.test.ts +0 -89
  361. package/src/store/sqlite/global-index.test.ts +0 -222
  362. package/src/store/sqlite/mechanical-fix.test.ts +0 -162
  363. package/src/store/sqlite/perf-samples.test.ts +0 -169
  364. package/src/store/sqlite/raptor.test.ts +0 -139
  365. package/src/store/sqlite/turns.test.ts +0 -218
  366. package/src/store/sqlite.cachehit.test.ts +0 -68
  367. package/src/store/sqlite.dbmaint.test.ts +0 -193
  368. package/src/store/sqlite.dbmirror.test.ts +0 -229
  369. package/src/store/turns/contract-compliance.test.ts +0 -562
  370. package/src/store/turns/memory-store.test.ts +0 -15
  371. package/src/store/turns/migrations.test.ts +0 -161
  372. package/src/store/turns/sqlite-store.test.ts +0 -161
  373. package/src/store/vectorIndex.test.ts +0 -140
  374. package/src/store.test.ts +0 -191
  375. package/src/supersede.test.ts +0 -42
  376. package/src/topics/cluster.test.ts +0 -176
  377. package/src/topics/store.test.ts +0 -132
  378. package/src/types.test.ts +0 -10
  379. package/src/vector-search-cache.test.ts +0 -190
  380. package/src/vectorStore.test.ts +0 -533
  381. package/src/wiki.test.ts +0 -217
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemoryMapTab-BBiH76eF.js","sources":["../../src/tabs/MemoryMapTab.tsx"],"sourcesContent":["/**\n * MemoryMapTab.tsx — S46 visual memory map (force-directed graph of checkpoints).\n *\n * Fetches graph data from /api/memory-map and renders an SVG-based\n * force-directed layout. Uses no external graph library (no @xyflow/react).\n * The simulation uses Coulomb repulsion + Hooke attraction + center gravity.\n */\nimport type React from \"react\";\nimport { useEffect, useRef, useState, useCallback, useMemo } from \"react\";\n\n// ---------------------------------------------------------------------------\n// Types (mirror of api-contracts/memory-map.ts — client-side only)\n// ---------------------------------------------------------------------------\n\ninterface GraphNode {\n id: string;\n sessionId: string;\n label: string;\n summaryTruncated: string;\n tokenEstimate: number;\n timestamp: number;\n dedupStatus: string | undefined;\n raptorLevel: number;\n topicSummary: string | undefined;\n decisionCount: number;\n textSnippet: string;\n}\n\ninterface GraphEdge {\n source: string;\n target: string;\n weight: number;\n type: \"temporal\" | \"semantic\" | \"raptor_parent\";\n}\n\ninterface GraphMetadata {\n sessionCount: number;\n totalCheckpoints: number;\n totalEdges: number;\n semanticEdgeCount: number;\n temporalEdgeCount: number;\n raptorEdgeCount: number;\n similarityThresholdUsed: number;\n builtAt: number;\n}\n\ninterface MemoryMapResponse {\n nodes: GraphNode[];\n edges: GraphEdge[];\n metadata: GraphMetadata;\n}\n\n// ---------------------------------------------------------------------------\n// Force-directed layout types\n// ---------------------------------------------------------------------------\n\ninterface Position {\n x: number;\n y: number;\n}\n\ninterface LayoutNode extends GraphNode {\n pos: Position;\n vx: number;\n vy: number;\n pinned: boolean;\n}\n\ninterface LayoutEdge {\n source: number;\n target: number;\n weight: number;\n type: GraphEdge[\"type\"];\n}\n\n// ---------------------------------------------------------------------------\n// Force simulation constants\n// ---------------------------------------------------------------------------\n\nconst REPULSION = 5_000;\nconst ATTRACTION = 0.005;\nconst CENTER_GRAVITY = 0.01;\nconst DAMPING = 0.9;\nconst MIN_VELOCITY = 0.1;\nconst MAX_ITERATIONS = 300;\nconst EDGE_ALPHA = 0.3;\nconst SVG_WIDTH = 900;\nconst SVG_HEIGHT = 600;\nconst PADDING = 40;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction edgeColor(type: GraphEdge[\"type\"]): string {\n switch (type) {\n case \"temporal\":\n return \"#6366f1\"; // indigo\n case \"semantic\":\n return \"#22c55e\"; // green\n case \"raptor_parent\":\n return \"#f59e0b\"; // amber\n }\n}\n\nfunction nodeOpacity(dedupStatus: string | undefined): number {\n if (!dedupStatus || dedupStatus === \"active\") return 1;\n return 0.5;\n}\n\n// ---------------------------------------------------------------------------\n// Force simulation engine\n// ---------------------------------------------------------------------------\n\nfunction buildLayout(data: MemoryMapResponse): { nodes: LayoutNode[]; edges: LayoutEdge[] } {\n const nodes: LayoutNode[] = data.nodes.map((n, i) => {\n const angle = (2 * Math.PI * i) / Math.max(data.nodes.length, 1);\n const radius = 200;\n return {\n ...n,\n pos: { x: Math.cos(angle) * radius + 300, y: Math.sin(angle) * radius + 200 },\n vx: 0,\n vy: 0,\n pinned: false,\n };\n });\n\n const nodeIndex = new Map<string, number>();\n nodes.forEach((n, i) => nodeIndex.set(n.id, i));\n\n const edges: LayoutEdge[] = data.edges\n .map((e) => {\n const si = nodeIndex.get(e.source);\n const ti = nodeIndex.get(e.target);\n if (si === undefined || ti === undefined || si === ti) return null;\n return { source: si, target: ti, weight: e.weight, type: e.type };\n })\n .filter((e): e is LayoutEdge => e !== null);\n\n return { nodes, edges };\n}\n\nfunction applyForces(layout: { nodes: LayoutNode[]; edges: LayoutEdge[] }): void {\n const { nodes, edges } = layout;\n const n = nodes.length;\n if (n === 0) return;\n\n for (let i = 0; i < n; i++) {\n if (nodes[i].pinned) continue;\n let fx = 0;\n let fy = 0;\n\n for (let j = 0; j < n; j++) {\n if (i === j) continue;\n const dx = nodes[i].pos.x - nodes[j].pos.x;\n const dy = nodes[i].pos.y - nodes[j].pos.y;\n const distSq = dx * dx + dy * dy || 1;\n const force = REPULSION / distSq;\n const dist = Math.sqrt(distSq);\n fx += (dx / dist) * force;\n fy += (dy / dist) * force;\n }\n\n for (const e of edges) {\n let other: number;\n if (e.source === i) other = e.target;\n else if (e.target === i) other = e.source;\n else continue;\n const dx = nodes[other].pos.x - nodes[i].pos.x;\n const dy = nodes[other].pos.y - nodes[i].pos.y;\n const dist = Math.sqrt(dx * dx + dy * dy) || 1;\n fx += dx * ATTRACTION * e.weight;\n fy += dy * ATTRACTION * e.weight;\n }\n\n fx -= nodes[i].pos.x * CENTER_GRAVITY;\n fy -= nodes[i].pos.y * CENTER_GRAVITY;\n\n nodes[i].vx = (nodes[i].vx + fx) * DAMPING;\n nodes[i].vy = (nodes[i].vy + fy) * DAMPING;\n\n const speed = Math.sqrt(nodes[i].vx * nodes[i].vx + nodes[i].vy * nodes[i].vy);\n if (speed > 50) {\n nodes[i].vx = (nodes[i].vx / speed) * 50;\n nodes[i].vy = (nodes[i].vy / speed) * 50;\n }\n\n if (speed > MIN_VELOCITY) {\n nodes[i].pos.x += nodes[i].vx;\n nodes[i].pos.y += nodes[i].vy;\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nconst MemoryMapTab: React.FC = () => {\n const [data, setData] = useState<MemoryMapResponse | null>(null);\n const [loading, setLoading] = useState<boolean>(true);\n const [error, setError] = useState<string | null>(null);\n const [selectedNode, setSelectedNode] = useState<GraphNode | null>(null);\n const [searchQuery, setSearchQuery] = useState<string>(\"\");\n const [filterSession, setFilterSession] = useState<string>(\"\");\n const [frame, setFrame] = useState<number>(0);\n\n const layoutRef = useRef<{ nodes: LayoutNode[]; edges: LayoutEdge[] } | null>(null);\n const animRef = useRef<number>(0);\n\n // Fetch graph data when filterSession changes\n useEffect(() => {\n let cancelled = false;\n const params = new URLSearchParams();\n if (filterSession) params.set(\"sessionId\", filterSession);\n params.set(\"threshold\", \"0.7\");\n params.set(\"maxEdgesPerNode\", \"4\");\n\n setLoading(true);\n setError(null);\n\n fetch(`/api/memory-map?${params.toString()}`)\n .then((r) => {\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n return r.json() as Promise<MemoryMapResponse>;\n })\n .then((d) => {\n if (!cancelled) {\n setData(d);\n layoutRef.current = buildLayout(d);\n setFrame(1);\n setLoading(false);\n }\n })\n .catch((e: unknown) => {\n if (!cancelled) {\n setError(e instanceof Error ? e.message : \"Unknown error\");\n setLoading(false);\n }\n });\n\n return () => {\n cancelled = true;\n cancelAnimationFrame(animRef.current);\n };\n }, [filterSession]);\n\n // Run force simulation via requestAnimationFrame\n useEffect(() => {\n if (!layoutRef.current || frame === 0) return;\n\n const layout = layoutRef.current;\n let iter = 0;\n\n const tick = () => {\n if (iter >= MAX_ITERATIONS) return;\n applyForces(layout);\n iter++;\n setFrame(iter);\n animRef.current = requestAnimationFrame(tick);\n };\n\n animRef.current = requestAnimationFrame(tick);\n return () => cancelAnimationFrame(animRef.current);\n }, [frame]);\n\n // Toggle pin / select a node\n const handleNodeClick = useCallback((node: LayoutNode, index: number) => {\n const layout = layoutRef.current;\n if (!layout) return;\n layout.nodes[index].pinned = !layout.nodes[index].pinned;\n if (!layout.nodes[index].pinned) {\n layout.nodes[index].vx = 0;\n layout.nodes[index].vy = 0;\n }\n setSelectedNode((prev) => (prev?.id === node.id ? null : (node as unknown as GraphNode)));\n setFrame((s) => s + 1);\n }, []);\n\n // Filtered node indices for search\n const filteredSet = useMemo<Set<number> | null>(() => {\n const layout = layoutRef.current;\n if (!layout || !searchQuery) return null;\n const q = searchQuery.toLowerCase();\n return new Set(\n layout.nodes\n .map((n, i) =>\n n.summaryTruncated.toLowerCase().includes(q) || n.label.toLowerCase().includes(q) ? i : -1,\n )\n .filter((i) => i >= 0),\n );\n }, [searchQuery]);\n\n // ---------- Loading state ----------\n\n if (loading) {\n return <div className=\"memory-map-loading\">Loading memory graph...</div>;\n }\n\n // ---------- Error state ----------\n\n if (error) {\n return (\n <div className=\"memory-map-error\">\n <p>Failed to load memory map: {error}</p>\n <button\n className=\"memory-map-retry-btn\"\n onClick={() => setFrame((s) => s + 1)}\n >\n Retry\n </button>\n </div>\n );\n }\n\n // ---------- Empty state ----------\n\n if (!data || !layoutRef.current) {\n return <div className=\"memory-map-empty\">No memory data available.</div>;\n }\n\n const layout = layoutRef.current;\n\n // ---------- Render ----------\n\n return (\n <div className=\"memory-map-container\">\n {/* Toolbar */}\n <div className=\"memory-map-toolbar\">\n <input\n type=\"text\"\n placeholder=\"Search memories...\"\n value={searchQuery}\n onInput={(e: React.FormEvent<HTMLInputElement>) =>\n setSearchQuery((e.target as HTMLInputElement).value)\n }\n className=\"memory-map-search\"\n />\n <span className=\"memory-map-stats\">\n {data.nodes.length} memories, {data.edges.length} edges\n <br />\n Sessions: {data.metadata.sessionCount} | Threshold:{\" \"}\n {data.metadata.similarityThresholdUsed.toFixed(2)}\n </span>\n </div>\n\n {/* Legend */}\n <div className=\"memory-map-legend\">\n <span style={{ color: edgeColor(\"semantic\") }}>Semantic</span>\n <span style={{ color: edgeColor(\"temporal\") }}>Temporal</span>\n <span style={{ color: edgeColor(\"raptor_parent\") }}>Raptor</span>\n </div>\n\n {/* SVG graph */}\n <svg\n width={SVG_WIDTH}\n height={SVG_HEIGHT}\n viewBox={`0 0 ${SVG_WIDTH} ${SVG_HEIGHT}`}\n className=\"memory-map-svg\"\n >\n {/* Edges */}\n {layout.edges.map((e, i) => {\n const src = layout.nodes[e.source];\n const tgt = layout.nodes[e.target];\n const color = edgeColor(e.type);\n const strokeW = Math.max(1, e.weight * 2.5);\n return (\n <line\n key={`edge-${i}`}\n x1={PADDING + (src.pos.x / (layout.nodes.length || 1)) * (SVG_WIDTH - 2 * PADDING)}\n y1={PADDING + (src.pos.y / (layout.nodes.length || 1)) * (SVG_HEIGHT - 2 * PADDING)}\n x2={PADDING + (tgt.pos.x / (layout.nodes.length || 1)) * (SVG_WIDTH - 2 * PADDING)}\n y2={PADDING + (tgt.pos.y / (layout.nodes.length || 1)) * (SVG_HEIGHT - 2 * PADDING)}\n stroke={color}\n strokeWidth={strokeW}\n opacity={EDGE_ALPHA}\n />\n );\n })}\n\n {/* Nodes */}\n {layout.nodes.map((n, i) => {\n const cx =\n PADDING + (n.pos.x / (layout.nodes.length || 1)) * (SVG_WIDTH - 2 * PADDING);\n const cy =\n PADDING + (n.pos.y / (layout.nodes.length || 1)) * (SVG_HEIGHT - 2 * PADDING);\n const radius = Math.min(20, 8 + n.tokenEstimate / 500);\n const isFiltered = filteredSet ? filteredSet.has(i) : true;\n const isSelected = selectedNode?.id === n.id;\n const nodeLabel = n.label.length > 20 ? n.label.slice(0, 18) + \"...\" : n.label;\n\n return (\n <g key={`node-${i}`} className=\"memory-map-node-group\">\n <circle\n cx={cx}\n cy={cy}\n r={isSelected ? radius + 3 : radius}\n fill={isFiltered ? (n.raptorLevel > 0 ? \"#f59e0b\" : \"#6366f1\") : \"#d1d5db\"}\n opacity={nodeOpacity(n.dedupStatus)}\n stroke={isSelected ? \"#ef4444\" : \"none\"}\n strokeWidth={isSelected ? 2 : 0}\n className=\"memory-map-node\"\n onClick={() => handleNodeClick(n, i)}\n />\n <text\n x={cx}\n y={cy + radius + 12}\n textAnchor=\"middle\"\n fontSize=\"9px\"\n fill=\"#374151\"\n className=\"memory-map-label\"\n >\n {nodeLabel}\n </text>\n </g>\n );\n })}\n </svg>\n\n {/* Node detail panel */}\n {selectedNode ? (\n <div className=\"memory-map-detail\">\n <h3>{selectedNode.label}</h3>\n <p>{selectedNode.summaryTruncated}</p>\n {selectedNode.topicSummary ? (\n <p className=\"memory-map-topic\">Topic: {selectedNode.topicSummary}</p>\n ) : null}\n <p>\n Tokens: {selectedNode.tokenEstimate} | Decisions: {selectedNode.decisionCount}\n </p>\n <p>Session: {selectedNode.sessionId}</p>\n <p>Raptor Level: {selectedNode.raptorLevel}</p>\n <p className=\"memory-map-snippet\">{selectedNode.textSnippet}</p>\n </div>\n ) : null}\n </div>\n );\n};\n\nexport default MemoryMapTab;\n"],"names":["REPULSION","ATTRACTION","CENTER_GRAVITY","DAMPING","MIN_VELOCITY","MAX_ITERATIONS","EDGE_ALPHA","SVG_WIDTH","SVG_HEIGHT","PADDING","edgeColor","type","nodeOpacity","dedupStatus","buildLayout","data","nodes","n","angle","radius","nodeIndex","edges","si","ti","applyForces","layout","i","fx","fy","j","dx","dy","distSq","force","dist","e","other","speed","MemoryMapTab","setData","useState","loading","setLoading","error","setError","selectedNode","setSelectedNode","searchQuery","setSearchQuery","filterSession","setFilterSession","frame","setFrame","layoutRef","useRef","animRef","useEffect","cancelled","params","r","d","iter","tick","handleNodeClick","useCallback","node","index","prev","s","filteredSet","useMemo","q","jsx","jsxs","src","tgt","color","strokeW","cx","cy","isFiltered","isSelected","nodeLabel"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{j as e,u as o,r as x,e as j,c as N}from"./index-BX0bcgLu.js";function i(s){return s>=1e3?`${(s/1e3).toFixed(1)}s`:`${s.toFixed(0)}ms`}function c({value:s,max:a,colorClass:r}){const p=a>0?Math.max(0,Math.min(100,s/a*100)):0;return e.jsx("div",{className:"perf-bar-track",children:e.jsx("div",{className:`perf-bar-fill ${r}`,style:{width:`${p}%`}})})}function _({perf:s}){const a=Math.max(s.turn_latency_ms.p95,s.provider_latency_ms.p95,1),r=Math.max(s.tps.avg,1);return e.jsxs("div",{className:"perf-chart",children:[e.jsxs("div",{className:"perf-header",children:[e.jsx("h3",{children:"Performance"}),e.jsxs("span",{className:"perf-window",children:[s.windowMinutes,"min window · ",s.sampleCount," samples"]})]}),e.jsxs("div",{className:"perf-grid",children:[e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Turn latency p50 / p95"}),e.jsxs("span",{className:"perf-value",children:[i(s.turn_latency_ms.p50)," /"," ",i(s.turn_latency_ms.p95)]}),e.jsx(c,{value:s.turn_latency_ms.p95,max:a,colorClass:"perf-blue"})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Provider latency p50 / p95"}),e.jsxs("span",{className:"perf-value",children:[i(s.provider_latency_ms.p50)," /"," ",i(s.provider_latency_ms.p95)]}),e.jsx(c,{value:s.provider_latency_ms.p95,max:a,colorClass:"perf-purple"})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Tokens/sec (avg)"}),e.jsx("span",{className:"perf-value",children:s.tps.avg.toFixed(1)}),e.jsx(c,{value:s.tps.avg,max:r,colorClass:"perf-green"})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Cache hit (avg / latest)"}),e.jsxs("span",{className:"perf-value",children:[s.cache_hit_pct.avg.toFixed(1),"% /"," ",s.cache_hit_pct.latest.toFixed(1),"%"]}),e.jsx(c,{value:s.cache_hit_pct.avg,max:100,colorClass:"perf-green"})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"DB recompute p95"}),e.jsx("span",{className:"perf-value",children:i(s.db_recompute_ms.p95)}),e.jsx(c,{value:s.db_recompute_ms.p95,max:a,colorClass:"perf-yellow"})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Disk write p95"}),e.jsx("span",{className:"perf-value",children:i(s.disk_write_ms.p95)}),e.jsx(c,{value:s.disk_write_ms.p95,max:a,colorClass:"perf-yellow"})]})]}),e.jsxs("div",{className:"perf-resources",children:[e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"RSS"}),e.jsxs("span",{className:"perf-value",children:[s.rss_mb.latest.toFixed(0)," MB"]})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Heap"}),e.jsxs("span",{className:"perf-value",children:[s.heap_mb.latest.toFixed(0)," MB"]})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"CPU user"}),e.jsxs("span",{className:"perf-value",children:[(s.cpu_user_ms.latest/1e3).toFixed(1),"s"]})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"CPU sys"}),e.jsxs("span",{className:"perf-value",children:[(s.cpu_sys_ms.latest/1e3).toFixed(1),"s"]})]})]}),s.diag&&e.jsxs("div",{className:"perf-diag",children:[e.jsxs("span",{className:"perf-label",children:["Fast-gate fires: ",s.diag.ctxFastGate]}),e.jsxs("span",{className:"perf-label",children:["Live trim fires: ",s.diag.liveTrimFires]}),e.jsxs("span",{className:"perf-label",children:["Live trim replays: ",s.diag.liveTrimReplays]})]})]})}function t(s){return s==null?"—":s>=100?`${Math.round(s)}ms`:`${s.toFixed(1)}ms`}function n(s,a){return s==null||typeof s!="number"?"—":s.toFixed(a)}function u(s){return s==null?"—":String(s)}function l({label:s,value:a}){return e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:s}),e.jsx("span",{className:"perf-value",children:a})]})}function d({title:s,children:a}){return e.jsxs("div",{className:"perf-card",children:[e.jsx("h3",{className:"perf-card-title",children:s}),e.jsx("div",{className:"perf-card-body",children:a})]})}function f({perf:s}){const a=`${n(s.cpu_user_ms.latest,1)} / ${n(s.cpu_sys_ms.latest,1)} ms`;return e.jsxs("div",{className:"perf-cards-grid",children:[e.jsxs(d,{title:"Model latency",children:[e.jsx(l,{label:"Turn p50",value:t(s.turn_latency_ms.p50)}),e.jsx(l,{label:"Turn p95",value:t(s.turn_latency_ms.p95)}),e.jsx(l,{label:"Provider p50",value:t(s.provider_latency_ms.p50)}),e.jsx(l,{label:"Provider p95",value:t(s.provider_latency_ms.p95)})]}),e.jsxs(d,{title:"Throughput",children:[e.jsx(l,{label:"TPS (avg)",value:n(s.tps.avg,1)}),e.jsx(l,{label:"Cache hit %",value:`${n(s.cache_hit_pct.avg,1)}%`})]}),e.jsxs(d,{title:"Process",children:[e.jsx(l,{label:"RSS",value:`${n(s.rss_mb.latest,1)} MB`}),e.jsx(l,{label:"Heap",value:`${n(s.heap_mb.latest,1)} MB`}),e.jsx(l,{label:"CPU user / sys",value:a})]}),e.jsxs(d,{title:"Snapshot cost",children:[e.jsx(l,{label:"DB recompute p50",value:t(s.db_recompute_ms.p50)}),e.jsx(l,{label:"DB recompute p95",value:t(s.db_recompute_ms.p95)}),e.jsx(l,{label:"Disk write p50",value:t(s.disk_write_ms.p50)})]}),e.jsxs(d,{title:"TUI lag proxy",children:[e.jsx(l,{label:"Live-trim fires",value:u(s.diag?.liveTrimFires)}),e.jsx(l,{label:"Cache replays",value:u(s.diag?.liveTrimReplays)}),e.jsx(l,{label:"Fast-gate skips",value:u(s.diag?.ctxFastGate)}),e.jsx("span",{className:"perf-card-note",children:"skip vs recompute vs replay cadence"})]})]})}function m({label:s,value:a,title:r}){return e.jsxs("div",{className:"model-field",title:r,children:[e.jsx("span",{className:"model-field-label",children:s}),e.jsx("span",{className:"model-field-value",children:a})]})}function b({name:s,providerName:a,provider:r,inputRate:p,outputRate:h}){const v=a||r||"—";return e.jsxs("div",{className:"model-badge",children:[e.jsx(m,{label:"Model",value:s,title:"The model pi is currently using — its pricing drives the cost figure."}),e.jsx(m,{label:"Provider",value:v,title:"The provider serving the model."}),e.jsx(m,{label:"Input Rate",value:`$${p.toFixed(6)}`,title:"USD per input token, from the model's pricing."}),e.jsx(m,{label:"Output Rate",value:`$${h.toFixed(6)}`,title:"USD per output token, from the model's pricing."})]})}function y(){const{data:s,error:a}=o(x.useCallback(()=>j({minutes:30}),[]),{pollInterval:1e4}),{data:r}=o(x.useCallback(()=>N(),[]),{pollInterval:1e4});return a&&!s?e.jsxs("div",{className:"tab-stub",children:["Error loading perf: ",a.message]}):s?e.jsxs("div",{className:"metrics-tab",children:[r?.model&&e.jsx(b,{name:r.model.name,providerName:r.model.providerName,provider:r.model.provider,inputRate:r.model.inputRate,outputRate:r.model.outputRate}),e.jsx(_,{perf:s}),e.jsx(f,{perf:s}),e.jsxs("div",{className:"perf-footer",children:[s.sampleCount," samples · updated ",s.updatedAt]})]}):e.jsx("div",{className:"tab-stub",children:"Loading perf…"})}export{y as default};
2
- //# sourceMappingURL=MetricsTab-Cq4u-rZF.js.map
1
+ import{j as e,u as o,r as x,i as j,c as N}from"./index-DrktNOoT.js";function i(s){return s>=1e3?`${(s/1e3).toFixed(1)}s`:`${s.toFixed(0)}ms`}function c({value:s,max:a,colorClass:r}){const p=a>0?Math.max(0,Math.min(100,s/a*100)):0;return e.jsx("div",{className:"perf-bar-track",children:e.jsx("div",{className:`perf-bar-fill ${r}`,style:{width:`${p}%`}})})}function _({perf:s}){const a=Math.max(s.turn_latency_ms.p95,s.provider_latency_ms.p95,1),r=Math.max(s.tps.avg,1);return e.jsxs("div",{className:"perf-chart",children:[e.jsxs("div",{className:"perf-header",children:[e.jsx("h3",{children:"Performance"}),e.jsxs("span",{className:"perf-window",children:[s.windowMinutes,"min window · ",s.sampleCount," samples"]})]}),e.jsxs("div",{className:"perf-grid",children:[e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Turn latency p50 / p95"}),e.jsxs("span",{className:"perf-value",children:[i(s.turn_latency_ms.p50)," /"," ",i(s.turn_latency_ms.p95)]}),e.jsx(c,{value:s.turn_latency_ms.p95,max:a,colorClass:"perf-blue"})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Provider latency p50 / p95"}),e.jsxs("span",{className:"perf-value",children:[i(s.provider_latency_ms.p50)," /"," ",i(s.provider_latency_ms.p95)]}),e.jsx(c,{value:s.provider_latency_ms.p95,max:a,colorClass:"perf-purple"})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Tokens/sec (avg)"}),e.jsx("span",{className:"perf-value",children:s.tps.avg.toFixed(1)}),e.jsx(c,{value:s.tps.avg,max:r,colorClass:"perf-green"})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Cache hit (avg / latest)"}),e.jsxs("span",{className:"perf-value",children:[s.cache_hit_pct.avg.toFixed(1),"% /"," ",s.cache_hit_pct.latest.toFixed(1),"%"]}),e.jsx(c,{value:s.cache_hit_pct.avg,max:100,colorClass:"perf-green"})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"DB recompute p95"}),e.jsx("span",{className:"perf-value",children:i(s.db_recompute_ms.p95)}),e.jsx(c,{value:s.db_recompute_ms.p95,max:a,colorClass:"perf-yellow"})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Disk write p95"}),e.jsx("span",{className:"perf-value",children:i(s.disk_write_ms.p95)}),e.jsx(c,{value:s.disk_write_ms.p95,max:a,colorClass:"perf-yellow"})]})]}),e.jsxs("div",{className:"perf-resources",children:[e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"RSS"}),e.jsxs("span",{className:"perf-value",children:[s.rss_mb.latest.toFixed(0)," MB"]})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"Heap"}),e.jsxs("span",{className:"perf-value",children:[s.heap_mb.latest.toFixed(0)," MB"]})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"CPU user"}),e.jsxs("span",{className:"perf-value",children:[(s.cpu_user_ms.latest/1e3).toFixed(1),"s"]})]}),e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:"CPU sys"}),e.jsxs("span",{className:"perf-value",children:[(s.cpu_sys_ms.latest/1e3).toFixed(1),"s"]})]})]}),s.diag&&e.jsxs("div",{className:"perf-diag",children:[e.jsxs("span",{className:"perf-label",children:["Fast-gate fires: ",s.diag.ctxFastGate]}),e.jsxs("span",{className:"perf-label",children:["Live trim fires: ",s.diag.liveTrimFires]}),e.jsxs("span",{className:"perf-label",children:["Live trim replays: ",s.diag.liveTrimReplays]})]})]})}function t(s){return s==null?"—":s>=100?`${Math.round(s)}ms`:`${s.toFixed(1)}ms`}function n(s,a){return s==null||typeof s!="number"?"—":s.toFixed(a)}function u(s){return s==null?"—":String(s)}function l({label:s,value:a}){return e.jsxs("div",{className:"perf-metric",children:[e.jsx("span",{className:"perf-label",children:s}),e.jsx("span",{className:"perf-value",children:a})]})}function d({title:s,children:a}){return e.jsxs("div",{className:"perf-card",children:[e.jsx("h3",{className:"perf-card-title",children:s}),e.jsx("div",{className:"perf-card-body",children:a})]})}function f({perf:s}){const a=`${n(s.cpu_user_ms.latest,1)} / ${n(s.cpu_sys_ms.latest,1)} ms`;return e.jsxs("div",{className:"perf-cards-grid",children:[e.jsxs(d,{title:"Model latency",children:[e.jsx(l,{label:"Turn p50",value:t(s.turn_latency_ms.p50)}),e.jsx(l,{label:"Turn p95",value:t(s.turn_latency_ms.p95)}),e.jsx(l,{label:"Provider p50",value:t(s.provider_latency_ms.p50)}),e.jsx(l,{label:"Provider p95",value:t(s.provider_latency_ms.p95)})]}),e.jsxs(d,{title:"Throughput",children:[e.jsx(l,{label:"TPS (avg)",value:n(s.tps.avg,1)}),e.jsx(l,{label:"Cache hit %",value:`${n(s.cache_hit_pct.avg,1)}%`})]}),e.jsxs(d,{title:"Process",children:[e.jsx(l,{label:"RSS",value:`${n(s.rss_mb.latest,1)} MB`}),e.jsx(l,{label:"Heap",value:`${n(s.heap_mb.latest,1)} MB`}),e.jsx(l,{label:"CPU user / sys",value:a})]}),e.jsxs(d,{title:"Snapshot cost",children:[e.jsx(l,{label:"DB recompute p50",value:t(s.db_recompute_ms.p50)}),e.jsx(l,{label:"DB recompute p95",value:t(s.db_recompute_ms.p95)}),e.jsx(l,{label:"Disk write p50",value:t(s.disk_write_ms.p50)})]}),e.jsxs(d,{title:"TUI lag proxy",children:[e.jsx(l,{label:"Live-trim fires",value:u(s.diag?.liveTrimFires)}),e.jsx(l,{label:"Cache replays",value:u(s.diag?.liveTrimReplays)}),e.jsx(l,{label:"Fast-gate skips",value:u(s.diag?.ctxFastGate)}),e.jsx("span",{className:"perf-card-note",children:"skip vs recompute vs replay cadence"})]})]})}function m({label:s,value:a,title:r}){return e.jsxs("div",{className:"model-field",title:r,children:[e.jsx("span",{className:"model-field-label",children:s}),e.jsx("span",{className:"model-field-value",children:a})]})}function b({name:s,providerName:a,provider:r,inputRate:p,outputRate:h}){const v=a||r||"—";return e.jsxs("div",{className:"model-badge",children:[e.jsx(m,{label:"Model",value:s,title:"The model pi is currently using — its pricing drives the cost figure."}),e.jsx(m,{label:"Provider",value:v,title:"The provider serving the model."}),e.jsx(m,{label:"Input Rate",value:`$${p.toFixed(6)}`,title:"USD per input token, from the model's pricing."}),e.jsx(m,{label:"Output Rate",value:`$${h.toFixed(6)}`,title:"USD per output token, from the model's pricing."})]})}function y(){const{data:s,error:a}=o(x.useCallback(()=>j({minutes:30}),[]),{pollInterval:1e4}),{data:r}=o(x.useCallback(()=>N(),[]),{pollInterval:1e4});return a&&!s?e.jsxs("div",{className:"tab-stub",children:["Error loading perf: ",a.message]}):s?e.jsxs("div",{className:"metrics-tab",children:[r?.model&&e.jsx(b,{name:r.model.name,providerName:r.model.providerName,provider:r.model.provider,inputRate:r.model.inputRate,outputRate:r.model.outputRate}),e.jsx(_,{perf:s}),e.jsx(f,{perf:s}),e.jsxs("div",{className:"perf-footer",children:[s.sampleCount," samples · updated ",s.updatedAt]})]}):e.jsx("div",{className:"tab-stub",children:"Loading perf…"})}export{y as default};
2
+ //# sourceMappingURL=MetricsTab-CHQscixy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MetricsTab-Cq4u-rZF.js","sources":["../../src/components/PerfChart.tsx","../../src/components/PerfCards.tsx","../../src/components/ModelBadge.tsx","../../src/tabs/MetricsTab.tsx"],"sourcesContent":["/**\n * dashboard-client/src/components/PerfChart.tsx — perf stat chart.\n *\n * The /api/perf endpoint returns rolling-window aggregates (not time-series),\n * so this renders a stat-card \"chart\": p50/p95 latency bars, TPS, cache hit %,\n * db recompute + disk write. Each metric shows a normalized bar + numeric.\n */\n\nimport type React from \"react\";\nimport type { PerfResponse } from \"@contracts\";\n\nexport interface PerfChartProps {\n\tperf: PerfResponse;\n}\n\nfunction fmtMs(n: number): string {\n\treturn n >= 1000 ? `${(n / 1000).toFixed(1)}s` : `${n.toFixed(0)}ms`;\n}\n\ninterface BarProps {\n\t/** Current value. */\n\tvalue: number;\n\t/** Value that represents 100% bar fill (the \"max\" reference). */\n\tmax: number;\n\t/** Color class. */\n\tcolorClass: string;\n}\n\nfunction Bar({ value, max, colorClass }: BarProps): React.ReactElement {\n\tconst pct = max > 0 ? Math.max(0, Math.min(100, (value / max) * 100)) : 0;\n\treturn (\n\t\t<div className=\"perf-bar-track\">\n\t\t\t<div\n\t\t\t\tclassName={`perf-bar-fill ${colorClass}`}\n\t\t\t\tstyle={{ width: `${pct}%` }}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nexport function PerfChart({ perf }: PerfChartProps): React.ReactElement {\n\t// Reference maxes: p95 is the upper bound for latency bars; rates scale to a\n\t// reasonable reference (tok/s) so bars are visually meaningful even with\n\t// small samples. cache_hit_pct is already 0-100.\n\tconst latencyMax = Math.max(\n\t\tperf.turn_latency_ms.p95,\n\t\tperf.provider_latency_ms.p95,\n\t\t1,\n\t);\n\tconst tpsRef = Math.max(perf.tps.avg, 1);\n\n\treturn (\n\t\t<div className=\"perf-chart\">\n\t\t\t<div className=\"perf-header\">\n\t\t\t\t<h3>Performance</h3>\n\t\t\t\t<span className=\"perf-window\">\n\t\t\t\t\t{perf.windowMinutes}min window · {perf.sampleCount} samples\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<div className=\"perf-grid\">\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Turn latency p50 / p95</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{fmtMs(perf.turn_latency_ms.p50)} /{\" \"}\n\t\t\t\t\t\t{fmtMs(perf.turn_latency_ms.p95)}\n\t\t\t\t\t</span>\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tvalue={perf.turn_latency_ms.p95}\n\t\t\t\t\t\tmax={latencyMax}\n\t\t\t\t\t\tcolorClass=\"perf-blue\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Provider latency p50 / p95</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{fmtMs(perf.provider_latency_ms.p50)} /{\" \"}\n\t\t\t\t\t\t{fmtMs(perf.provider_latency_ms.p95)}\n\t\t\t\t\t</span>\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tvalue={perf.provider_latency_ms.p95}\n\t\t\t\t\t\tmax={latencyMax}\n\t\t\t\t\t\tcolorClass=\"perf-purple\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Tokens/sec (avg)</span>\n\t\t\t\t\t<span className=\"perf-value\">{perf.tps.avg.toFixed(1)}</span>\n\t\t\t\t\t<Bar value={perf.tps.avg} max={tpsRef} colorClass=\"perf-green\" />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Cache hit (avg / latest)</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{perf.cache_hit_pct.avg.toFixed(1)}% /{\" \"}\n\t\t\t\t\t\t{perf.cache_hit_pct.latest.toFixed(1)}%\n\t\t\t\t\t</span>\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tvalue={perf.cache_hit_pct.avg}\n\t\t\t\t\t\tmax={100}\n\t\t\t\t\t\tcolorClass=\"perf-green\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">DB recompute p95</span>\n\t\t\t\t\t<span className=\"perf-value\">{fmtMs(perf.db_recompute_ms.p95)}</span>\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tvalue={perf.db_recompute_ms.p95}\n\t\t\t\t\t\tmax={latencyMax}\n\t\t\t\t\t\tcolorClass=\"perf-yellow\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Disk write p95</span>\n\t\t\t\t\t<span className=\"perf-value\">{fmtMs(perf.disk_write_ms.p95)}</span>\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tvalue={perf.disk_write_ms.p95}\n\t\t\t\t\t\tmax={latencyMax}\n\t\t\t\t\t\tcolorClass=\"perf-yellow\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className=\"perf-resources\">\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">RSS</span>\n\t\t\t\t\t<span className=\"perf-value\">{perf.rss_mb.latest.toFixed(0)} MB</span>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Heap</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{perf.heap_mb.latest.toFixed(0)} MB\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">CPU user</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{(perf.cpu_user_ms.latest / 1000).toFixed(1)}s\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">CPU sys</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{(perf.cpu_sys_ms.latest / 1000).toFixed(1)}s\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{perf.diag && (\n\t\t\t\t<div className=\"perf-diag\">\n\t\t\t\t\t<span className=\"perf-label\">\n\t\t\t\t\t\tFast-gate fires: {perf.diag.ctxFastGate}\n\t\t\t\t\t</span>\n\t\t\t\t\t<span className=\"perf-label\">\n\t\t\t\t\t\tLive trim fires: {perf.diag.liveTrimFires}\n\t\t\t\t\t</span>\n\t\t\t\t\t<span className=\"perf-label\">\n\t\t\t\t\t\tLive trim replays: {perf.diag.liveTrimReplays}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","/**\n * dashboard-client/src/components/PerfCards.tsx — 5 perf metric cards.\n *\n * Mirrors the old html.ts perf grid: model latency, throughput, process,\n * snapshot cost, and TUI lag proxy. Uses the existing perf-metric CSS\n * classes from repos-metrics.css plus metrics-extra.css for card headers.\n */\n\nimport type React from \"react\";\nimport type { PerfResponse } from \"@contracts\";\n\n/** Format milliseconds (em-dash for null/undefined). */\nfunction fmtMs(v: number | null | undefined): string {\n\treturn v == null ? \"\\u2014\" : v >= 100 ? `${Math.round(v)}ms` : `${v.toFixed(1)}ms`;\n}\n\n/** Format a number with fixed decimals (em-dash for null/non-number). */\nfunction fmtNum(v: number | null | undefined, dec: number): string {\n\treturn v == null || typeof v !== \"number\" ? \"\\u2014\" : v.toFixed(dec);\n}\n\n/** Format a diag counter (em-dash for null). */\nfunction fmtDiag(v: number | null | undefined): string {\n\treturn v == null ? \"\\u2014\" : String(v);\n}\n\ninterface PerfCardsProps {\n\tperf: PerfResponse;\n}\n\n/** A single stat row inside a perf card. */\nfunction Stat({ label, value }: { label: string; value: string }): React.ReactElement {\n\treturn (\n\t\t<div className=\"perf-metric\">\n\t\t\t<span className=\"perf-label\">{label}</span>\n\t\t\t<span className=\"perf-value\">{value}</span>\n\t\t</div>\n\t);\n}\n\n/** Card wrapper with a title. */\nfunction Card({ title, children }: { title: string; children: React.ReactNode }): React.ReactElement {\n\treturn (\n\t\t<div className=\"perf-card\">\n\t\t\t<h3 className=\"perf-card-title\">{title}</h3>\n\t\t\t<div className=\"perf-card-body\">{children}</div>\n\t\t</div>\n\t);\n}\n\nexport function PerfCards({ perf }: PerfCardsProps): React.ReactElement {\n\tconst cpuTxt = `${fmtNum(perf.cpu_user_ms.latest, 1)} / ${fmtNum(perf.cpu_sys_ms.latest, 1)} ms`;\n\n\treturn (\n\t\t<div className=\"perf-cards-grid\">\n\t\t\t<Card title=\"Model latency\">\n\t\t\t\t<Stat label=\"Turn p50\" value={fmtMs(perf.turn_latency_ms.p50)} />\n\t\t\t\t<Stat label=\"Turn p95\" value={fmtMs(perf.turn_latency_ms.p95)} />\n\t\t\t\t<Stat label=\"Provider p50\" value={fmtMs(perf.provider_latency_ms.p50)} />\n\t\t\t\t<Stat label=\"Provider p95\" value={fmtMs(perf.provider_latency_ms.p95)} />\n\t\t\t</Card>\n\n\t\t\t<Card title=\"Throughput\">\n\t\t\t\t<Stat label=\"TPS (avg)\" value={fmtNum(perf.tps.avg, 1)} />\n\t\t\t\t<Stat\n\t\t\t\t\tlabel=\"Cache hit %\"\n\t\t\t\t\tvalue={`${fmtNum(perf.cache_hit_pct.avg, 1)}%`}\n\t\t\t\t/>\n\t\t\t</Card>\n\n\t\t\t<Card title=\"Process\">\n\t\t\t\t<Stat label=\"RSS\" value={`${fmtNum(perf.rss_mb.latest, 1)} MB`} />\n\t\t\t\t<Stat label=\"Heap\" value={`${fmtNum(perf.heap_mb.latest, 1)} MB`} />\n\t\t\t\t<Stat label=\"CPU user / sys\" value={cpuTxt} />\n\t\t\t</Card>\n\n\t\t\t<Card title=\"Snapshot cost\">\n\t\t\t\t<Stat label=\"DB recompute p50\" value={fmtMs(perf.db_recompute_ms.p50)} />\n\t\t\t\t<Stat label=\"DB recompute p95\" value={fmtMs(perf.db_recompute_ms.p95)} />\n\t\t\t\t<Stat label=\"Disk write p50\" value={fmtMs(perf.disk_write_ms.p50)} />\n\t\t\t</Card>\n\n\t\t\t<Card title=\"TUI lag proxy\">\n\t\t\t\t<Stat label=\"Live-trim fires\" value={fmtDiag(perf.diag?.liveTrimFires)} />\n\t\t\t\t<Stat label=\"Cache replays\" value={fmtDiag(perf.diag?.liveTrimReplays)} />\n\t\t\t\t<Stat label=\"Fast-gate skips\" value={fmtDiag(perf.diag?.ctxFastGate)} />\n\t\t\t\t<span className=\"perf-card-note\">skip vs recompute vs replay cadence</span>\n\t\t\t</Card>\n\t\t</div>\n\t);\n}\n","/**\n * dashboard-client/src/components/ModelBadge.tsx — model + provider + rates.\n *\n * Shows the active model name, provider, and input/output rates.\n * Tooltips copied verbatim from html.ts. Used in the Metrics tab header.\n */\n\nimport type React from \"react\";\n\nexport interface ModelBadgeProps {\n\t/** Model name/identifier. */\n\tname: string;\n\t/** Human-readable provider name. */\n\tproviderName: string;\n\t/** Machine-readable provider identifier. */\n\tprovider: string;\n\t/** USD per input token (from model pricing). */\n\tinputRate: number;\n\t/** USD per output token (from model pricing). */\n\toutputRate: number;\n}\n\nfunction Field({\n\tlabel,\n\tvalue,\n\ttitle,\n}: {\n\tlabel: string;\n\tvalue: string;\n\ttitle?: string;\n}): React.ReactElement {\n\treturn (\n\t\t<div className=\"model-field\" title={title}>\n\t\t\t<span className=\"model-field-label\">{label}</span>\n\t\t\t<span className=\"model-field-value\">{value}</span>\n\t\t</div>\n\t);\n}\n\nexport function ModelBadge({\n\tname,\n\tproviderName,\n\tprovider,\n\tinputRate,\n\toutputRate,\n}: ModelBadgeProps): React.ReactElement {\n\tconst providerDisplay = providerName || provider || \"—\";\n\treturn (\n\t\t<div className=\"model-badge\">\n\t\t\t<Field\n\t\t\t\tlabel=\"Model\"\n\t\t\t\tvalue={name}\n\t\t\t\ttitle=\"The model pi is currently using — its pricing drives the cost figure.\"\n\t\t\t/>\n\t\t\t<Field\n\t\t\t\tlabel=\"Provider\"\n\t\t\t\tvalue={providerDisplay}\n\t\t\t\ttitle=\"The provider serving the model.\"\n\t\t\t/>\n\t\t\t<Field\n\t\t\t\tlabel=\"Input Rate\"\n\t\t\t\tvalue={`$${inputRate.toFixed(6)}`}\n\t\t\t\ttitle=\"USD per input token, from the model's pricing.\"\n\t\t\t/>\n\t\t\t<Field\n\t\t\t\tlabel=\"Output Rate\"\n\t\t\t\tvalue={`$${outputRate.toFixed(6)}`}\n\t\t\t\ttitle=\"USD per output token, from the model's pricing.\"\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MetricsTab.tsx — Metrics tab (C2).\n *\n * Fetches /api/perf (rolling-window aggregates) + /api/snapshot (for model).\n * Renders ModelBadge + PerfChart + 5 perf cards (latency, throughput, process,\n * snapshot cost, TUI lag proxy). Polls every 10s.\n */\n\nimport type React from \"react\";\nimport { useCallback } from \"react\";\nimport { useApi } from \"../hooks/useApi\";\nimport { fetchPerf, fetchSnapshot } from \"../api/client\";\nimport type { PerfResponse, SnapshotResponse } from \"@contracts\";\nimport { PerfChart } from \"../components/PerfChart\";\nimport { PerfCards } from \"../components/PerfCards\";\nimport { ModelBadge } from \"../components/ModelBadge\";\n\nexport default function MetricsTab(): React.ReactElement {\n\tconst { data: perf, error: perfErr } = useApi<PerfResponse>(\n\t\tuseCallback(() => fetchPerf({ minutes: 30 }), []),\n\t\t{ pollInterval: 10_000 },\n\t);\n\tconst { data: snapshot } = useApi<SnapshotResponse>(\n\t\tuseCallback(() => fetchSnapshot(), []),\n\t\t{ pollInterval: 10_000 },\n\t);\n\n\tif (perfErr && !perf) {\n\t\treturn (\n\t\t\t<div className=\"tab-stub\">Error loading perf: {perfErr.message}</div>\n\t\t);\n\t}\n\tif (!perf) {\n\t\treturn <div className=\"tab-stub\">Loading perf…</div>;\n\t}\n\n\treturn (\n\t\t<div className=\"metrics-tab\">\n\t\t\t{snapshot?.model && (\n\t\t\t\t<ModelBadge\n\t\t\t\t\tname={snapshot.model.name}\n\t\t\t\t\tproviderName={snapshot.model.providerName}\n\t\t\t\t\tprovider={snapshot.model.provider}\n\t\t\t\t\tinputRate={snapshot.model.inputRate}\n\t\t\t\t\toutputRate={snapshot.model.outputRate}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t<PerfChart perf={perf} />\n\t\t\t<PerfCards perf={perf} />\n\t\t\t<div className=\"perf-footer\">\n\t\t\t\t{perf.sampleCount} samples · updated {perf.updatedAt}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"names":["fmtMs","n","Bar","value","max","colorClass","pct","jsx","PerfChart","perf","latencyMax","tpsRef","jsxs","v","fmtNum","dec","fmtDiag","Stat","label","Card","title","children","PerfCards","cpuTxt","Field","ModelBadge","name","providerName","provider","inputRate","outputRate","providerDisplay","MetricsTab","perfErr","useApi","useCallback","fetchPerf","snapshot","fetchSnapshot"],"mappings":"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"}
1
+ {"version":3,"file":"MetricsTab-CHQscixy.js","sources":["../../src/components/PerfChart.tsx","../../src/components/PerfCards.tsx","../../src/components/ModelBadge.tsx","../../src/tabs/MetricsTab.tsx"],"sourcesContent":["/**\n * dashboard-client/src/components/PerfChart.tsx — perf stat chart.\n *\n * The /api/perf endpoint returns rolling-window aggregates (not time-series),\n * so this renders a stat-card \"chart\": p50/p95 latency bars, TPS, cache hit %,\n * db recompute + disk write. Each metric shows a normalized bar + numeric.\n */\n\nimport type React from \"react\";\nimport type { PerfResponse } from \"@contracts\";\n\nexport interface PerfChartProps {\n\tperf: PerfResponse;\n}\n\nfunction fmtMs(n: number): string {\n\treturn n >= 1000 ? `${(n / 1000).toFixed(1)}s` : `${n.toFixed(0)}ms`;\n}\n\ninterface BarProps {\n\t/** Current value. */\n\tvalue: number;\n\t/** Value that represents 100% bar fill (the \"max\" reference). */\n\tmax: number;\n\t/** Color class. */\n\tcolorClass: string;\n}\n\nfunction Bar({ value, max, colorClass }: BarProps): React.ReactElement {\n\tconst pct = max > 0 ? Math.max(0, Math.min(100, (value / max) * 100)) : 0;\n\treturn (\n\t\t<div className=\"perf-bar-track\">\n\t\t\t<div\n\t\t\t\tclassName={`perf-bar-fill ${colorClass}`}\n\t\t\t\tstyle={{ width: `${pct}%` }}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n\nexport function PerfChart({ perf }: PerfChartProps): React.ReactElement {\n\t// Reference maxes: p95 is the upper bound for latency bars; rates scale to a\n\t// reasonable reference (tok/s) so bars are visually meaningful even with\n\t// small samples. cache_hit_pct is already 0-100.\n\tconst latencyMax = Math.max(\n\t\tperf.turn_latency_ms.p95,\n\t\tperf.provider_latency_ms.p95,\n\t\t1,\n\t);\n\tconst tpsRef = Math.max(perf.tps.avg, 1);\n\n\treturn (\n\t\t<div className=\"perf-chart\">\n\t\t\t<div className=\"perf-header\">\n\t\t\t\t<h3>Performance</h3>\n\t\t\t\t<span className=\"perf-window\">\n\t\t\t\t\t{perf.windowMinutes}min window · {perf.sampleCount} samples\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t\t<div className=\"perf-grid\">\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Turn latency p50 / p95</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{fmtMs(perf.turn_latency_ms.p50)} /{\" \"}\n\t\t\t\t\t\t{fmtMs(perf.turn_latency_ms.p95)}\n\t\t\t\t\t</span>\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tvalue={perf.turn_latency_ms.p95}\n\t\t\t\t\t\tmax={latencyMax}\n\t\t\t\t\t\tcolorClass=\"perf-blue\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Provider latency p50 / p95</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{fmtMs(perf.provider_latency_ms.p50)} /{\" \"}\n\t\t\t\t\t\t{fmtMs(perf.provider_latency_ms.p95)}\n\t\t\t\t\t</span>\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tvalue={perf.provider_latency_ms.p95}\n\t\t\t\t\t\tmax={latencyMax}\n\t\t\t\t\t\tcolorClass=\"perf-purple\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Tokens/sec (avg)</span>\n\t\t\t\t\t<span className=\"perf-value\">{perf.tps.avg.toFixed(1)}</span>\n\t\t\t\t\t<Bar value={perf.tps.avg} max={tpsRef} colorClass=\"perf-green\" />\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Cache hit (avg / latest)</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{perf.cache_hit_pct.avg.toFixed(1)}% /{\" \"}\n\t\t\t\t\t\t{perf.cache_hit_pct.latest.toFixed(1)}%\n\t\t\t\t\t</span>\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tvalue={perf.cache_hit_pct.avg}\n\t\t\t\t\t\tmax={100}\n\t\t\t\t\t\tcolorClass=\"perf-green\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">DB recompute p95</span>\n\t\t\t\t\t<span className=\"perf-value\">{fmtMs(perf.db_recompute_ms.p95)}</span>\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tvalue={perf.db_recompute_ms.p95}\n\t\t\t\t\t\tmax={latencyMax}\n\t\t\t\t\t\tcolorClass=\"perf-yellow\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Disk write p95</span>\n\t\t\t\t\t<span className=\"perf-value\">{fmtMs(perf.disk_write_ms.p95)}</span>\n\t\t\t\t\t<Bar\n\t\t\t\t\t\tvalue={perf.disk_write_ms.p95}\n\t\t\t\t\t\tmax={latencyMax}\n\t\t\t\t\t\tcolorClass=\"perf-yellow\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div className=\"perf-resources\">\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">RSS</span>\n\t\t\t\t\t<span className=\"perf-value\">{perf.rss_mb.latest.toFixed(0)} MB</span>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">Heap</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{perf.heap_mb.latest.toFixed(0)} MB\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">CPU user</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{(perf.cpu_user_ms.latest / 1000).toFixed(1)}s\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"perf-metric\">\n\t\t\t\t\t<span className=\"perf-label\">CPU sys</span>\n\t\t\t\t\t<span className=\"perf-value\">\n\t\t\t\t\t\t{(perf.cpu_sys_ms.latest / 1000).toFixed(1)}s\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t{perf.diag && (\n\t\t\t\t<div className=\"perf-diag\">\n\t\t\t\t\t<span className=\"perf-label\">\n\t\t\t\t\t\tFast-gate fires: {perf.diag.ctxFastGate}\n\t\t\t\t\t</span>\n\t\t\t\t\t<span className=\"perf-label\">\n\t\t\t\t\t\tLive trim fires: {perf.diag.liveTrimFires}\n\t\t\t\t\t</span>\n\t\t\t\t\t<span className=\"perf-label\">\n\t\t\t\t\t\tLive trim replays: {perf.diag.liveTrimReplays}\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n","/**\n * dashboard-client/src/components/PerfCards.tsx — 5 perf metric cards.\n *\n * Mirrors the old html.ts perf grid: model latency, throughput, process,\n * snapshot cost, and TUI lag proxy. Uses the existing perf-metric CSS\n * classes from repos-metrics.css plus metrics-extra.css for card headers.\n */\n\nimport type React from \"react\";\nimport type { PerfResponse } from \"@contracts\";\n\n/** Format milliseconds (em-dash for null/undefined). */\nfunction fmtMs(v: number | null | undefined): string {\n\treturn v == null ? \"\\u2014\" : v >= 100 ? `${Math.round(v)}ms` : `${v.toFixed(1)}ms`;\n}\n\n/** Format a number with fixed decimals (em-dash for null/non-number). */\nfunction fmtNum(v: number | null | undefined, dec: number): string {\n\treturn v == null || typeof v !== \"number\" ? \"\\u2014\" : v.toFixed(dec);\n}\n\n/** Format a diag counter (em-dash for null). */\nfunction fmtDiag(v: number | null | undefined): string {\n\treturn v == null ? \"\\u2014\" : String(v);\n}\n\ninterface PerfCardsProps {\n\tperf: PerfResponse;\n}\n\n/** A single stat row inside a perf card. */\nfunction Stat({ label, value }: { label: string; value: string }): React.ReactElement {\n\treturn (\n\t\t<div className=\"perf-metric\">\n\t\t\t<span className=\"perf-label\">{label}</span>\n\t\t\t<span className=\"perf-value\">{value}</span>\n\t\t</div>\n\t);\n}\n\n/** Card wrapper with a title. */\nfunction Card({ title, children }: { title: string; children: React.ReactNode }): React.ReactElement {\n\treturn (\n\t\t<div className=\"perf-card\">\n\t\t\t<h3 className=\"perf-card-title\">{title}</h3>\n\t\t\t<div className=\"perf-card-body\">{children}</div>\n\t\t</div>\n\t);\n}\n\nexport function PerfCards({ perf }: PerfCardsProps): React.ReactElement {\n\tconst cpuTxt = `${fmtNum(perf.cpu_user_ms.latest, 1)} / ${fmtNum(perf.cpu_sys_ms.latest, 1)} ms`;\n\n\treturn (\n\t\t<div className=\"perf-cards-grid\">\n\t\t\t<Card title=\"Model latency\">\n\t\t\t\t<Stat label=\"Turn p50\" value={fmtMs(perf.turn_latency_ms.p50)} />\n\t\t\t\t<Stat label=\"Turn p95\" value={fmtMs(perf.turn_latency_ms.p95)} />\n\t\t\t\t<Stat label=\"Provider p50\" value={fmtMs(perf.provider_latency_ms.p50)} />\n\t\t\t\t<Stat label=\"Provider p95\" value={fmtMs(perf.provider_latency_ms.p95)} />\n\t\t\t</Card>\n\n\t\t\t<Card title=\"Throughput\">\n\t\t\t\t<Stat label=\"TPS (avg)\" value={fmtNum(perf.tps.avg, 1)} />\n\t\t\t\t<Stat\n\t\t\t\t\tlabel=\"Cache hit %\"\n\t\t\t\t\tvalue={`${fmtNum(perf.cache_hit_pct.avg, 1)}%`}\n\t\t\t\t/>\n\t\t\t</Card>\n\n\t\t\t<Card title=\"Process\">\n\t\t\t\t<Stat label=\"RSS\" value={`${fmtNum(perf.rss_mb.latest, 1)} MB`} />\n\t\t\t\t<Stat label=\"Heap\" value={`${fmtNum(perf.heap_mb.latest, 1)} MB`} />\n\t\t\t\t<Stat label=\"CPU user / sys\" value={cpuTxt} />\n\t\t\t</Card>\n\n\t\t\t<Card title=\"Snapshot cost\">\n\t\t\t\t<Stat label=\"DB recompute p50\" value={fmtMs(perf.db_recompute_ms.p50)} />\n\t\t\t\t<Stat label=\"DB recompute p95\" value={fmtMs(perf.db_recompute_ms.p95)} />\n\t\t\t\t<Stat label=\"Disk write p50\" value={fmtMs(perf.disk_write_ms.p50)} />\n\t\t\t</Card>\n\n\t\t\t<Card title=\"TUI lag proxy\">\n\t\t\t\t<Stat label=\"Live-trim fires\" value={fmtDiag(perf.diag?.liveTrimFires)} />\n\t\t\t\t<Stat label=\"Cache replays\" value={fmtDiag(perf.diag?.liveTrimReplays)} />\n\t\t\t\t<Stat label=\"Fast-gate skips\" value={fmtDiag(perf.diag?.ctxFastGate)} />\n\t\t\t\t<span className=\"perf-card-note\">skip vs recompute vs replay cadence</span>\n\t\t\t</Card>\n\t\t</div>\n\t);\n}\n","/**\n * dashboard-client/src/components/ModelBadge.tsx — model + provider + rates.\n *\n * Shows the active model name, provider, and input/output rates.\n * Tooltips copied verbatim from html.ts. Used in the Metrics tab header.\n */\n\nimport type React from \"react\";\n\nexport interface ModelBadgeProps {\n\t/** Model name/identifier. */\n\tname: string;\n\t/** Human-readable provider name. */\n\tproviderName: string;\n\t/** Machine-readable provider identifier. */\n\tprovider: string;\n\t/** USD per input token (from model pricing). */\n\tinputRate: number;\n\t/** USD per output token (from model pricing). */\n\toutputRate: number;\n}\n\nfunction Field({\n\tlabel,\n\tvalue,\n\ttitle,\n}: {\n\tlabel: string;\n\tvalue: string;\n\ttitle?: string;\n}): React.ReactElement {\n\treturn (\n\t\t<div className=\"model-field\" title={title}>\n\t\t\t<span className=\"model-field-label\">{label}</span>\n\t\t\t<span className=\"model-field-value\">{value}</span>\n\t\t</div>\n\t);\n}\n\nexport function ModelBadge({\n\tname,\n\tproviderName,\n\tprovider,\n\tinputRate,\n\toutputRate,\n}: ModelBadgeProps): React.ReactElement {\n\tconst providerDisplay = providerName || provider || \"—\";\n\treturn (\n\t\t<div className=\"model-badge\">\n\t\t\t<Field\n\t\t\t\tlabel=\"Model\"\n\t\t\t\tvalue={name}\n\t\t\t\ttitle=\"The model pi is currently using — its pricing drives the cost figure.\"\n\t\t\t/>\n\t\t\t<Field\n\t\t\t\tlabel=\"Provider\"\n\t\t\t\tvalue={providerDisplay}\n\t\t\t\ttitle=\"The provider serving the model.\"\n\t\t\t/>\n\t\t\t<Field\n\t\t\t\tlabel=\"Input Rate\"\n\t\t\t\tvalue={`$${inputRate.toFixed(6)}`}\n\t\t\t\ttitle=\"USD per input token, from the model's pricing.\"\n\t\t\t/>\n\t\t\t<Field\n\t\t\t\tlabel=\"Output Rate\"\n\t\t\t\tvalue={`$${outputRate.toFixed(6)}`}\n\t\t\t\ttitle=\"USD per output token, from the model's pricing.\"\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","/**\n * dashboard-client/src/tabs/MetricsTab.tsx — Metrics tab (C2).\n *\n * Fetches /api/perf (rolling-window aggregates) + /api/snapshot (for model).\n * Renders ModelBadge + PerfChart + 5 perf cards (latency, throughput, process,\n * snapshot cost, TUI lag proxy). Polls every 10s.\n */\n\nimport type React from \"react\";\nimport { useCallback } from \"react\";\nimport { useApi } from \"../hooks/useApi\";\nimport { fetchPerf, fetchSnapshot } from \"../api/client\";\nimport type { PerfResponse, SnapshotResponse } from \"@contracts\";\nimport { PerfChart } from \"../components/PerfChart\";\nimport { PerfCards } from \"../components/PerfCards\";\nimport { ModelBadge } from \"../components/ModelBadge\";\n\nexport default function MetricsTab(): React.ReactElement {\n\tconst { data: perf, error: perfErr } = useApi<PerfResponse>(\n\t\tuseCallback(() => fetchPerf({ minutes: 30 }), []),\n\t\t{ pollInterval: 10_000 },\n\t);\n\tconst { data: snapshot } = useApi<SnapshotResponse>(\n\t\tuseCallback(() => fetchSnapshot(), []),\n\t\t{ pollInterval: 10_000 },\n\t);\n\n\tif (perfErr && !perf) {\n\t\treturn (\n\t\t\t<div className=\"tab-stub\">Error loading perf: {perfErr.message}</div>\n\t\t);\n\t}\n\tif (!perf) {\n\t\treturn <div className=\"tab-stub\">Loading perf…</div>;\n\t}\n\n\treturn (\n\t\t<div className=\"metrics-tab\">\n\t\t\t{snapshot?.model && (\n\t\t\t\t<ModelBadge\n\t\t\t\t\tname={snapshot.model.name}\n\t\t\t\t\tproviderName={snapshot.model.providerName}\n\t\t\t\t\tprovider={snapshot.model.provider}\n\t\t\t\t\tinputRate={snapshot.model.inputRate}\n\t\t\t\t\toutputRate={snapshot.model.outputRate}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t<PerfChart perf={perf} />\n\t\t\t<PerfCards perf={perf} />\n\t\t\t<div className=\"perf-footer\">\n\t\t\t\t{perf.sampleCount} samples · updated {perf.updatedAt}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"names":["fmtMs","n","Bar","value","max","colorClass","pct","jsx","PerfChart","perf","latencyMax","tpsRef","jsxs","v","fmtNum","dec","fmtDiag","Stat","label","Card","title","children","PerfCards","cpuTxt","Field","ModelBadge","name","providerName","provider","inputRate","outputRate","providerDisplay","MetricsTab","perfErr","useApi","useCallback","fetchPerf","snapshot","fetchSnapshot"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{j as e,u as H,r as C,f as I}from"./index-DrktNOoT.js";import{u as A}from"./useSSE-Bf5LOLSi.js";import{f as g,a as E}from"./format-COjDIVGj.js";import{C as _,T as G}from"./TimeSavedCard-CiqCOQuL.js";const $=["#58a6ff","#3fb950","#d29922","#f85149","#bc8cff","#ff7b72","#79c0ff","#56d4dd","#e3b341","#a5d6ff","#7ee787","#ffa657"];function B(s){let t=5381;for(let a=0;a<s.length;a++)t=(t<<5)+t+s.charCodeAt(a)>>>0;return t}function U(s){return s?$[B(s)%$.length]:$[0]}function K(s){if(!s)return"(unknown)";const t=s.replace(/[\\/]+$/,"");if(!t)return"(unknown)";const a=t.split(/[\\/]/);return a[a.length-1]||t}function z(s){const t=new Map;for(const o of s){const i=o.repoRoot??"__null__",u=o.tokens??0,m=t.get(i);if(m)m.tokens+=u;else{const c=K(o.repoRoot);t.set(i,{repoRoot:o.repoRoot,basename:c,tokens:u,color:U(c)})}}const a=[...t.values()],r=a.reduce((o,i)=>o+i.tokens,0),l=s.reduce((o,i)=>Math.max(o,i.ctxWindow),0);return{repos:a,totalTokens:r,maxWindow:l,sessionCount:s.length}}function R(s){return s>=1e5?`${(s/1e3).toFixed(0)}k`:s.toLocaleString()}function V({sessions:s,loading:t,error:a}){if(a)return e.jsxs("div",{className:"card repo-stack-card",children:[e.jsx("h3",{children:"Context per Repo (live)"}),e.jsxs("div",{className:"sessions-empty",children:["Error loading sessions: ",a.message]})]});if(t&&!s)return e.jsxs("div",{className:"card repo-stack-card",children:[e.jsx("h3",{children:"Context per Repo (live)"}),e.jsx("div",{className:"sessions-empty",children:"Loading sessions…"})]});const r=s?.sessions??[],{repos:l,totalTokens:o,maxWindow:i,sessionCount:u}=z(r);if(l.length===0)return e.jsxs("div",{className:"card repo-stack-card",children:[e.jsx("h3",{children:"Context per Repo (live)"}),e.jsx("div",{className:"sessions-empty",children:"No active sessions."})]});const m=i>0?Math.round(o/i*100):0;return e.jsxs("div",{className:"card repo-stack-card",children:[e.jsx("h3",{children:"Context per Repo (live)"}),e.jsx("div",{className:"repo-stack-bar",role:"group","aria-label":"Per-repo context usage",children:l.map(c=>{const n=o>0?c.tokens/o*100:0,h=o>0?n:0,d=`${c.basename}: ${R(c.tokens)} tokens (${n.toFixed(1)}% of total)`;return e.jsx("div",{className:"repo-stack-segment",style:{width:`${Math.max(h,.5)}%`,backgroundColor:c.color},title:d,"aria-label":d},c.repoRoot??"__null__")})}),e.jsxs("p",{className:"repo-stack-total",children:[R(o)," tokens across ",l.length," ",l.length===1?"repo":"repos"," /"," ",u," ",u===1?"session":"sessions"," ",e.jsxs("span",{className:"pct",children:["— ",m,"% of combined max window"]})]}),e.jsx("div",{className:"repo-stack-legend",children:l.map(c=>{const n=o>0?c.tokens/o*100:0;return e.jsxs("div",{className:"repo-stack-legend-item",children:[e.jsx("span",{className:"repo-stack-legend-swatch",style:{backgroundColor:c.color}}),e.jsx("span",{className:"repo-stack-legend-name",children:c.basename}),e.jsxs("span",{children:[R(c.tokens)," (",n.toFixed(0),"%)"]})]},c.repoRoot??"__null__")})})]})}function q(s){return s>=90?"gauge-red":s>=70?"gauge-yellow":"gauge-green"}function X(s){return s==null?"?":s>=1e5?`${(s/1e3).toFixed(0)}k`:s.toLocaleString()}function J(s){if(!s)return"(unknown)";const t=s.replace(/[\\/]+$/,"");if(!t)return"(unknown)";const a=t.split(/[\\/]/);return a[a.length-1]||t}function Q(s){const t=Math.max(0,Math.round(s/1e3));if(t<60)return`${t}s ago`;const a=Math.floor(t/60);return a<60?`${a}m ago`:`${Math.floor(a/60)}h ${a%60}m ago`}function W({data:s}){const t=s.percent??0,a=Math.max(t,1),r=q(t),l=X(s.tokens),o=s.contextWindow.toLocaleString(),i=`${l} / ${o} tokens`;return e.jsxs("div",{className:`session-gauge ${s.isSelf?"session-gauge-self":""}`,children:[e.jsxs("div",{className:"session-gauge-head",children:[e.jsx("span",{className:"session-gauge-label",children:s.label}),e.jsxs("span",{className:"session-gauge-pct",children:[t,"%"]})]}),e.jsx("div",{className:`gauge-bar ${r}`,role:"meter","aria-valuenow":t,"aria-valuemin":0,"aria-valuemax":100,"aria-label":`${s.label}: ${t}%`,children:e.jsx("div",{className:"gauge-fill",style:{width:`${a}%`}})}),e.jsx("p",{className:"gauge-label session-gauge-sub",children:i}),s.sublabel&&e.jsx("p",{className:"session-gauge-meta",children:s.sublabel})]})}function Y({sessions:s,loading:t,error:a,launcherSessionId:r,launcher:l}){const o=Date.now(),i=[{key:"self",label:"this session",sublabel:"",tokens:l.tokens,percent:l.percent,contextWindow:l.contextWindow,isSelf:!0}],u=(s?.sessions??[]).filter(n=>n.sessionId!==r);u.sort((n,h)=>h.lastSeen-n.lastSeen);for(const n of u)i.push({key:n.sessionId,label:J(n.repoRoot),sublabel:`pid ${n.pid} · ${Q(o-n.lastSeen)}${n.model?` · ${n.model}`:""}`,tokens:n.tokens,percent:n.percent,contextWindow:n.ctxWindow||0,isSelf:!1});const m=a&&!s,c=t&&!s;return e.jsxs("div",{className:"card session-gauges-card",children:[e.jsx("h3",{children:"Context per Session (live)"}),m?e.jsxs("div",{className:"sessions-empty",children:["Error loading sessions: ",a.message]}):c?e.jsx("div",{className:"sessions-empty",children:"Loading sessions…"}):i.length<=1&&u.length===0?e.jsx("div",{className:"session-gauges-grid",children:i.map(n=>e.jsx(W,{data:n},n.key))}):e.jsx("div",{className:"session-gauges-grid",children:i.map(n=>e.jsx(W,{data:n},n.key))})]})}function M({state:s,label:t}){const a=s==="on"?"bullet-on":s==="na"?"bullet-na":"bullet-off";return e.jsxs("div",{className:`bullet ${a}`,children:[e.jsx("span",{className:"bullet-dot","aria-hidden":"true"}),e.jsx("span",{className:"bullet-label",children:t})]})}function Z({armed:s,ready:t}){const a=s?"on":"off",r=t?"on":s?"off":"na",l=t?"THRESHOLD EXCEEDED — compacting next event":s?"past fast gate — monitoring token count":"idle — below fast gate";return e.jsxs("div",{className:"card trigger-status",children:[e.jsx("h3",{children:"Trigger Status"}),e.jsxs("div",{className:"bullet-row",children:[e.jsx(M,{state:a,label:"Armed"}),e.jsx(M,{state:r,label:"Ready"})]}),e.jsx("p",{className:"trigger-state-text",children:l})]})}function ee(s){return s>=.9?"meter-green":s>=.6?"meter-yellow":"meter-red"}function p({label:s,value:t,title:a}){return e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",title:a,children:s}),e.jsx("span",{className:"ov-stat-value",children:t})]})}function se(s){const t=s.compressionPct,a=ee(t),r=Math.max(t*100,.5),l=`${g(t)} tokens saved · dedup: ${g(s.dedupPct)}`;return e.jsxs("div",{className:"card vector-store-card",children:[e.jsx("h3",{children:"Vector Store (session)"}),e.jsx(p,{label:"Checkpoints",value:s.checkpointCount.toLocaleString(),title:"A saved summary of a chunk of your conversation that was compacted to free up space."}),e.jsx(p,{label:"Original (dropped)",value:s.tokensIn.toLocaleString(),title:"Total size of the original conversation text dropped into compaction this session, including redundant regions skipped by dedup. This is the 'in'."}),e.jsx(p,{label:"Kept (summaries)",value:s.tokensOut.toLocaleString(),title:"Compact summaries we are currently holding as 'memory' for this session (the 'out'). Smaller is better."}),e.jsx(p,{label:"Freed",value:s.tokensFreed.toLocaleString(),title:"Conversation space freed = dropped − kept (the 'saved')."}),e.jsx(p,{label:"Injected",value:s.injectedCount,title:"How many times old context was automatically brought back into the conversation because it was relevant to what you were doing."}),e.jsx(p,{label:"Recall Relevance",value:g(s.dedupHitRate),title:"Of the times we recalled old context, how often it was actually on-topic."}),e.jsx(p,{label:"Storage Dedup",value:g(s.storageDedupRate),title:"How often new content matched something we already had, so we skipped storing a duplicate copy. Higher = less wasted space."}),e.jsx(p,{label:"Collapsed",value:s.dedupCollapsed,title:"How many duplicate chunks we collapsed into one instead of storing separately."}),e.jsx(p,{label:"Last ID",value:s.lastCheckpointId??"—",title:"The ID of the most recent saved checkpoint."}),e.jsxs("div",{className:"ov-compression-meter",children:[e.jsx("div",{className:"meter-track",children:e.jsx("div",{className:`meter-fill ${a}`,style:{width:`${r}%`}})}),e.jsx("span",{className:"meter-sub",children:l})]})]})}function te(s){return s>=.9?"meter-green":s>=.6?"meter-yellow":"meter-red"}function x({label:s,value:t}){return e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",children:s}),e.jsx("span",{className:"ov-stat-value",children:t})]})}function ae(s){const t=s.compressionPct,a=te(t),r=Math.max(t*100,.5),l=`${g(t)} tokens saved · dedup: ${g(s.dedupPct)}`;return e.jsxs("div",{className:"card repo-sessions-card",children:[e.jsx("h3",{children:"Repo (all sessions)"}),e.jsx(x,{label:"Checkpoints",value:s.checkpointCount.toLocaleString()}),e.jsx(x,{label:"Original",value:s.tokensIn.toLocaleString()}),e.jsx(x,{label:"Kept",value:s.tokensOut.toLocaleString()}),e.jsx(x,{label:"Freed",value:s.tokensFreed.toLocaleString()}),e.jsx(x,{label:"Sessions",value:s.sessionCount.toLocaleString()}),e.jsx(x,{label:"Collapsed",value:s.dedupCollapsed}),e.jsx(x,{label:"Storage Dedup",value:g(s.storageDedupRate)}),e.jsxs("div",{className:"ov-compression-meter",children:[e.jsx("div",{className:"meter-track",children:e.jsx("div",{className:`meter-fill ${a}`,style:{width:`${r}%`}})}),e.jsx("span",{className:"meter-sub",children:l})]})]})}function ne(s){return e.jsxs("div",{className:"card data-safety-card",children:[e.jsx("h3",{children:"🛡 Data Safety"}),e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",children:"Regions Retained"}),e.jsx("span",{className:"ov-stat-value",children:s.regionsRetained.toLocaleString()})]}),e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",children:"Compressed-Original"}),e.jsx("span",{className:"ov-stat-value",children:E(s.compressedOriginalBytes)})]}),e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",children:"Dedup Duplicates"}),e.jsx("span",{className:"ov-stat-value",children:s.duplicatesCollapsed.toLocaleString()})]}),e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",children:"Permanently Deleted"}),e.jsx("span",{className:"ov-stat-value ov-value-ok",children:E(s.bytesPermanentlyDeleted)})]}),e.jsx("p",{className:"safe-note",children:'Every compacted region is kept verbatim (compressed). "Drop" = removed from the live window only. We never delete your data.'})]})}function v({label:s,value:t,title:a}){return e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",title:a,children:s}),e.jsx("span",{className:"ov-stat-value",children:t})]})}function oe(s){const t=`${Math.round((s.pressure??0)*100)}%`;let a=s.thresholdTokens.toLocaleString();return s.tierPct!=null&&s.contextWindow>0&&(a+=` (${Math.round(s.tierPct*100)}% of ${s.contextWindow.toLocaleString()})`),e.jsxs("div",{className:"card config-summary-card",children:[e.jsx("h3",{children:"Configuration"}),e.jsx(v,{label:"Tier",value:`${s.tier} (live)`,title:"Live pressure band — climbs low→mega as context fills the window."}),e.jsx(v,{label:"Preset",value:s.presetTier,title:"The env-resolved base compaction preset (low/medium/high/ultra/mega) that set the token threshold."}),e.jsx(v,{label:"Pressure",value:t,title:"Live pressure = currentTokens / threshold — % of the model context window (threshold fires at the tier's % of window)."}),e.jsx(v,{label:"Threshold",value:a,title:"Compaction threshold = tierPct × model context window — mega-compact trims BELOW pi's native ~80% auto-compact for any model size."}),e.jsx(v,{label:"Fast Gate",value:`${s.fastGatePct}%`,title:"Fast-gate arming floor — the live trim arms once context passes this % of the window."}),e.jsx(v,{label:"Auto",value:s.auto?"enabled":"disabled"}),e.jsx(v,{label:"Anchor",value:String(s.anchorUserMessages)})]})}function T({label:s,value:t,title:a}){return e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",title:a,children:s}),e.jsx("span",{className:"ov-stat-value",children:t})]})}function le(s){const t=s.repoTokensFreed||0;let a=0,r="0";if(s.inputRate&&t>0){a=t*s.inputRate;const i=s.contextWindow||0;r=i>0?(t/i).toFixed(1):"0"}const l=`≈ $${a.toFixed(4)} saved`,o=`${r} context-windows extended`;return e.jsxs("div",{className:"card model-cost-card",children:[e.jsx("h3",{children:"💰 Model & Cost Savings"}),e.jsx("div",{className:"ov-cost-usd",children:l}),e.jsx("div",{className:"ov-cost-sub",children:o}),e.jsx(T,{label:"Model",value:s.name,title:"The model pi is currently using — its pricing drives the cost figure."}),e.jsx(T,{label:"Provider",value:s.provider,title:"The provider serving the model."}),e.jsx(T,{label:"Input Rate",value:`$${s.inputRate.toFixed(6)}`,title:"USD per input token, from the model's pricing."}),e.jsx(T,{label:"Output Rate",value:`$${s.outputRate.toFixed(6)}`,title:"USD per output token, from the model's pricing."})]})}function re(s){const{activeAgents:t,currentTurn:a}=s,r=t>0?`▶ ${t} running`:"idle";return e.jsxs("div",{className:"card crew-card",children:[e.jsx("h3",{children:"Crew / Agents"}),e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",children:"Active Agents"}),e.jsx("span",{className:"ov-stat-value",children:t})]}),e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",children:"Current Turn"}),e.jsx("span",{className:"ov-stat-value",children:a})]}),e.jsxs("div",{className:"ov-stat-row",children:[e.jsx("span",{className:"ov-stat-label",children:"Status"}),e.jsx("span",{className:"ov-stat-value",children:r})]})]})}const ie=[e.jsxs("li",{children:[e.jsx("b",{children:"Original (dropped)"}),' — everything compacted away (including duplicates caught by dedup). The "in."']},"1"),e.jsxs("li",{children:[e.jsx("b",{children:"Kept (summaries)"}),' — compact summaries still held as "memory" (the "out").']},"2"),e.jsxs("li",{children:[e.jsx("b",{children:"Freed"})," = dropped − kept — tokens saved so far (higher = better)."]},"3"),e.jsxs("li",{children:[e.jsx("b",{children:"Compression %"})," — Freed ÷ Dropped — the headline efficiency number. Higher = more space reclaimed."]},"4"),e.jsxs("li",{children:[e.jsx("b",{children:"Storage dedup %"})," — how often new content matched something already saved, so no duplicate copy was written."]},"5"),e.jsxs("li",{children:[e.jsx("b",{children:"Data safety"})," — every compacted region is kept verbatim (compressed). Nothing is permanently deleted; you can restore any of it."]},"6")];function ce(){return e.jsx("div",{className:"card legend-card",children:e.jsxs("details",{children:[e.jsx("summary",{children:"What these numbers mean"}),e.jsx("ol",{className:"legend-list",children:ie}),e.jsx("p",{className:"legend-note",children:"Hover any label above for a quick explanation."})]})})}function de(s){return s.type==="session_sample"}function ue(s){if(!s)return"never";try{return new Date(s).toLocaleString()}catch{return s}}function ve({snapshot:s,loading:t,error:a}){const{data:r,error:l,loading:o,refetch:i}=H(C.useCallback(()=>I(),[]),{pollInterval:2e3}),{events:u}=A(),m=C.useMemo(()=>u.filter(de),[u]),c=C.useMemo(()=>m.length===0?null:m[m.length-1].ts,[m]);if(C.useEffect(()=>{c!=null&&i()},[c,i]),t&&!s)return e.jsx("div",{className:"tab-stub",children:"Loading snapshot…"});if(a&&!s)return e.jsxs("div",{className:"tab-stub",children:["Error: ",a.message]});if(!s)return e.jsx("div",{className:"tab-stub",children:"No snapshot data."});const n=s,{context:h,compression:d,trigger:f,session:P,store:b,tier:D,updatedAt:O}=n,k=n.config,L=n.crew,w=n.integrity,N=n.cacheHits,F=n.compacts,S=n.timeSaved,y=n.repo,j=n.model;return e.jsxs("div",{className:"overview-tab",children:[e.jsxs("div",{className:"overview-header",children:[e.jsx("span",{className:"tier-pill",children:D}),e.jsxs("span",{className:"updated",children:["updated ",ue(O)]})]}),e.jsxs("div",{className:"card-grid overview-card-grid",children:[e.jsx(Y,{sessions:r,loading:o,error:l,launcherSessionId:P.id,launcher:{tokens:h.tokens,percent:h.percent,contextWindow:h.contextWindow}}),e.jsx(V,{sessions:r,loading:o,error:l}),e.jsx(Z,{armed:f.armed,ready:f.ready,currentTokens:f.currentTokens,thresholdTokens:f.thresholdTokens,fastGatePct:f.fastGatePct}),e.jsx(se,{checkpointCount:b.checkpointCount,tokensIn:d.session.tokensIn,tokensOut:d.session.tokensOut,tokensFreed:d.session.tokensFreed,injectedCount:b.injectedCount,dedupHitRate:b.dedupHitRate,storageDedupRate:b.storageDedupRate,dedupCollapsed:b.dedupCollapsed,lastCheckpointId:P.lastCheckpointId,compressionPct:d.session.compressionPct,dedupPct:d.session.dedupPct}),e.jsx(ae,{checkpointCount:y.checkpointCount,tokensIn:d.repo.tokensIn,tokensOut:d.repo.tokensOut,tokensFreed:d.repo.tokensFreed,sessionCount:y.sessionCount,dedupCollapsed:y.dedupCollapsed,storageDedupRate:y.storageDedupRate,compressionPct:d.repo.compressionPct,dedupPct:d.repo.dedupPct}),e.jsx(ne,{regionsRetained:w.regionsRetained,compressedOriginalBytes:w.compressedOriginalBytes,duplicatesCollapsed:w.duplicatesCollapsed,bytesPermanentlyDeleted:w.bytesPermanentlyDeleted}),e.jsx(oe,{tier:D,presetTier:n.presetTier,pressure:n.pressure,thresholdTokens:k.thresholdTokens,tierPct:k.tierPct,contextWindow:h.contextWindow,fastGatePct:k.fastGatePct,auto:k.auto,anchorUserMessages:k.anchorUserMessages}),j&&e.jsx(le,{name:j.name,provider:j.providerName||j.provider,inputRate:j.inputRate,outputRate:j.outputRate,repoTokensFreed:d.repo.tokensFreed,contextWindow:h.contextWindow}),e.jsx(re,{activeAgents:L.activeAgents,currentTurn:L.currentTurn}),e.jsx(_,{cacheHitsSession:N.session,cacheHitsTotal:N.total,tokensSavedSession:N.sessionTokensSaved,tokensSavedTotal:N.totalTokensSaved,compactionsSession:F.session,compactionsTotal:F.total}),e.jsx(G,{compactSessionSec:S.compact.sessionSec,compactTotalSec:S.compact.totalSec,cacheHitSessionSec:S.cacheHit.sessionSec,cacheHitTotalSec:S.cacheHit.totalSec}),e.jsx(ce,{})]})]})}export{ve as default};
2
+ //# sourceMappingURL=OverviewTab-DBs4DJdd.js.map