pi-mega-compact 0.11.4 → 0.11.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions/dashboard-server/api-contracts/endpoints.js +19 -0
- package/dist/extensions/dashboard-server/api-contracts/memory.js +8 -0
- package/dist/extensions/dashboard-server/api-contracts/provider-cache.js +1 -0
- package/dist/extensions/dashboard-server/api-contracts/setup.js +10 -0
- package/dist/extensions/dashboard-server/index-reader.js +6 -2
- package/dist/extensions/dashboard-server/routes-cache.js +115 -55
- package/dist/extensions/dashboard-server/routes-memory.js +51 -0
- package/dist/extensions/dashboard-server/routes-repo.js +2 -2
- package/dist/extensions/dashboard-server/routes-setup.js +162 -0
- package/dist/extensions/dashboard-server/routes.js +2 -0
- package/dist/extensions/dashboard-server/server.js +7 -1
- package/dist/extensions/mega-commands.js +189 -1
- package/dist/extensions/mega-config.js +2 -0
- package/dist/extensions/mega-events/agent-handlers.js +19 -4
- package/dist/extensions/mega-events/compact-handlers.js +1 -0
- package/dist/extensions/mega-events/context-handler.js +37 -92
- package/dist/extensions/mega-events/context-hwm.js +51 -0
- package/dist/extensions/mega-events/error-classifier.js +16 -5
- package/dist/extensions/mega-events/mirror-append.js +107 -0
- package/dist/extensions/mega-events/outage-advisor.js +7 -1
- package/dist/extensions/mega-events/perf-handler.js +51 -1
- package/dist/extensions/mega-events/recall-tail.js +59 -0
- package/dist/extensions/mega-events/session-handlers.js +15 -8
- package/dist/extensions/mega-runtime/reset-runtime.js +5 -0
- package/dist/extensions/mega-runtime/runtime.js +6 -0
- package/dist/src/embedder.js +41 -2
- package/dist/src/memoryStats.js +75 -0
- package/dist/src/prefix-break.js +43 -0
- package/dist/src/pricing.js +1 -1
- package/dist/src/store/sqlite/perf-samples.js +144 -16
- package/dist/src/store/turns/memory-store.js +8 -0
- package/dist/src/store/turns/sqlite-store.js +14 -3
- package/dist/src/store/turns/types.js +18 -1
- package/dist/src/store/vectorIndex.js +26 -5
- package/extensions/dashboard-client/dist/assets/{AchievementTiles-vEo2MtE2.js → AchievementTiles-BoL7qBOJ.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AchievementTiles-vEo2MtE2.js.map → AchievementTiles-BoL7qBOJ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/AchievementsTab-BFDE3HYc.js +2 -0
- package/extensions/dashboard-client/dist/assets/{AchievementsTab-DjxfYrDc.js.map → AchievementsTab-BFDE3HYc.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/CacheTab-eKVc-NV1.js +2 -0
- package/extensions/dashboard-client/dist/assets/CacheTab-eKVc-NV1.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{ConfigTab-Cm6ymbmx.js → ConfigTab-DDFE-ckA.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ConfigTab-Cm6ymbmx.js.map → ConfigTab-DDFE-ckA.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-DXWl_YzI.js → EventsTab-B6UxZ7PM.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-DXWl_YzI.js.map → EventsTab-B6UxZ7PM.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{GameTab-BLDudcO5.js → GameTab-DehUX-KE.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{GameTab-BLDudcO5.js.map → GameTab-DehUX-KE.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DLkKCztn.js → MaintenanceTab-0GWRt4wn.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DLkKCztn.js.map → MaintenanceTab-0GWRt4wn.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsTab-Cq4u-rZF.js → MetricsTab-C3rwMVsN.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsTab-Cq4u-rZF.js.map → MetricsTab-C3rwMVsN.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/OverviewTab-39O9_x5j.js +2 -0
- package/extensions/dashboard-client/dist/assets/{OverviewTab-D4kGvsiQ.js.map → OverviewTab-39O9_x5j.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/ReposTab-Cfj6Q5sH.js +2 -0
- package/extensions/dashboard-client/dist/assets/ReposTab-Cfj6Q5sH.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{SessionsTab-DZC2-GCn.js → SessionsTab-DXDTCi3r.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-DZC2-GCn.js.map → SessionsTab-DXDTCi3r.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/SetupTab-mMlfunJa.js +2 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-mMlfunJa.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/TimeSavedCard-Cw1dJ4e9.js +2 -0
- package/extensions/dashboard-client/dist/assets/TimeSavedCard-Cw1dJ4e9.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{TopicsTab-01G71hv1.js → TopicsTab-BAw972BV.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TopicsTab-01G71hv1.js.map → TopicsTab-BAw972BV.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnsTab-DLRg0LZT.js → TurnsTab-Cf5mGIdl.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnsTab-DLRg0LZT.js.map → TurnsTab-Cf5mGIdl.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/format-COjDIVGj.js +2 -0
- package/extensions/dashboard-client/dist/assets/format-COjDIVGj.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{index-BX0bcgLu.js → index-4gQ7auad.js} +10 -10
- package/extensions/dashboard-client/dist/assets/index-4gQ7auad.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/pricing-CvE4NllQ.js +2 -0
- package/extensions/dashboard-client/dist/assets/pricing-CvE4NllQ.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{useSSE-BBYt5UPB.js → useSSE-DNgMuyP6.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-BBYt5UPB.js.map → useSSE-DNgMuyP6.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-client/src/App.tsx +4 -0
- package/extensions/dashboard-client/src/api/client.ts +14 -0
- package/extensions/dashboard-client/src/components/ActiveReposTable.tsx +21 -12
- package/extensions/dashboard-client/src/components/ProviderCacheCard.tsx +56 -0
- package/extensions/dashboard-client/src/components/SavingsByModelTable.tsx +38 -57
- package/extensions/dashboard-client/src/tabs/CacheTab.tsx +1 -0
- package/extensions/dashboard-client/src/tabs/SetupTab.tsx +355 -0
- package/extensions/dashboard-client/tsconfig.json +3 -2
- package/extensions/dashboard-client/vite.config.ts +2 -0
- package/extensions/dashboard-server/api-contracts/endpoints.ts +36 -3
- package/extensions/dashboard-server/api-contracts/index.ts +7 -0
- package/extensions/dashboard-server/api-contracts/memory.ts +27 -0
- package/extensions/dashboard-server/api-contracts/multi-repo.ts +231 -231
- package/extensions/dashboard-server/api-contracts/provider-cache.ts +37 -0
- package/extensions/dashboard-server/api-contracts/setup.ts +58 -0
- package/extensions/dashboard-server/index-reader.ts +138 -121
- package/extensions/dashboard-server/routes-cache.ts +161 -85
- package/extensions/dashboard-server/routes-memory.ts +63 -0
- package/extensions/dashboard-server/routes-repo.ts +36 -36
- package/extensions/dashboard-server/routes-setup.ts +181 -0
- package/extensions/dashboard-server/routes.ts +2 -0
- package/extensions/dashboard-server/server.ts +6 -0
- package/extensions/mega-commands.ts +211 -1
- package/extensions/mega-config.ts +10 -0
- package/extensions/mega-events/agent-handlers.ts +20 -4
- package/extensions/mega-events/compact-handlers.ts +1 -0
- package/extensions/mega-events/context-handler.ts +45 -110
- package/extensions/mega-events/context-hwm.ts +85 -0
- package/extensions/mega-events/error-classifier.ts +15 -4
- package/extensions/mega-events/mirror-append.ts +155 -0
- package/extensions/mega-events/outage-advisor.ts +11 -5
- package/extensions/mega-events/perf-handler.ts +79 -5
- package/extensions/mega-events/recall-tail.ts +88 -0
- package/extensions/mega-events/session-handlers.ts +14 -7
- package/extensions/mega-runtime/helpers.ts +12 -0
- package/extensions/mega-runtime/reset-runtime.ts +5 -0
- package/extensions/mega-runtime/runtime.ts +6 -0
- package/package.json +5 -2
- package/src/embedder.ts +42 -2
- package/src/memoryStats.ts +107 -0
- package/src/prefix-break.ts +83 -0
- package/src/pricing.ts +2 -2
- package/src/store/sqlite/perf-samples.ts +215 -22
- package/src/store/turns/memory-store.ts +10 -1
- package/src/store/turns/sqlite-store.ts +27 -15
- package/src/store/turns/types.ts +21 -0
- package/src/store/vectorIndex.ts +33 -4
- package/dist/extensions/conflict-scan.test.js +0 -115
- package/dist/extensions/dashboard-server/api-contracts.test.js +0 -884
- package/dist/extensions/dashboard-server/html.test.js +0 -52
- package/dist/extensions/dashboard-server/perf-server.test.js +0 -80
- package/dist/extensions/dashboard-server/routes-cache.test.js +0 -248
- package/dist/extensions/dashboard-server/server.test.js +0 -120
- package/dist/extensions/dashboard-server-s32.test.js +0 -181
- package/dist/extensions/dashboard-server.test.js +0 -339
- package/dist/extensions/mega-cache-replay.test.js +0 -400
- package/dist/extensions/mega-compact-s38.test.js +0 -1383
- package/dist/extensions/mega-compact.test.js +0 -1112
- package/dist/extensions/mega-events.test.js +0 -47
- package/dist/extensions/mega-game-cmds.test.js +0 -163
- package/dist/extensions/mega-runtime/snapshot.test.js +0 -127
- package/dist/extensions/mega-runtime/state.test.js +0 -266
- package/dist/extensions/mega-runtime/widget.test.js +0 -343
- package/dist/extensions/mega-shutdown-widget.test.js +0 -121
- package/dist/extensions/mega-teamrun.test.js +0 -156
- package/dist/extensions/mega-trim.test.js +0 -58
- package/dist/extensions/mega-turn-store.test.js +0 -68
- package/dist/src/boundary.test.js +0 -170
- package/dist/src/compact.test.js +0 -78
- package/dist/src/config/themes.test.js +0 -94
- package/dist/src/dedup/dedup.test.js +0 -41
- package/dist/src/dedup/l1.test.js +0 -50
- package/dist/src/dedup/raptor/buildHistory.test.js +0 -292
- package/dist/src/dedup/raptor/multilevel-serve.test.js +0 -229
- package/dist/src/dedup/raptor/multilevel.test.js +0 -238
- package/dist/src/dedup/raptor/promote.test.js +0 -69
- package/dist/src/dedup/raptor/raptor.test.js +0 -248
- package/dist/src/dedup/raptor/retrieval.test.js +0 -95
- package/dist/src/dedup/raptor/serve-gate.test.js +0 -298
- package/dist/src/dedup/sprint12.test.js +0 -219
- package/dist/src/dedup-engine.test.js +0 -472
- package/dist/src/driftDetection.test.js +0 -87
- package/dist/src/e2e.test.js +0 -698
- package/dist/src/engine.test.js +0 -111
- package/dist/src/extractive.test.js +0 -147
- package/dist/src/fork.test.js +0 -81
- package/dist/src/game/scoring.test.js +0 -98
- package/dist/src/httpEmbedder.test.js +0 -277
- package/dist/src/importance.test.js +0 -372
- package/dist/src/intent.test.js +0 -78
- package/dist/src/log.test.js +0 -42
- package/dist/src/mechanical-fix.test.js +0 -65
- package/dist/src/memory.test.js +0 -70
- package/dist/src/memoryConsolidate.test.js +0 -38
- package/dist/src/memoryOps.test.js +0 -129
- package/dist/src/memoryRecall.test.js +0 -171
- package/dist/src/memoryRoundtrip.test.js +0 -137
- package/dist/src/metrics/turns.test.js +0 -152
- package/dist/src/mirror/mirror.test.js +0 -185
- package/dist/src/raptor-inject-summaries.test.js +0 -162
- package/dist/src/ratio.bench.test.js +0 -897
- package/dist/src/recall.integration.test.js +0 -77
- package/dist/src/recall.test.js +0 -379
- package/dist/src/sprint14.test.js +0 -219
- package/dist/src/sprint4x-rag-verification.test.js +0 -93
- package/dist/src/store/compression.test.js +0 -139
- package/dist/src/store/memoryIndex.test.js +0 -51
- package/dist/src/store/migrate.test.js +0 -139
- package/dist/src/store/pgOpenGuard.test.js +0 -74
- package/dist/src/store/phase01.test.js +0 -81
- package/dist/src/store/phase04.test.js +0 -54
- package/dist/src/store/sprint10.test.js +0 -186
- package/dist/src/store/sqlite/game-achievements.test.js +0 -67
- package/dist/src/store/sqlite/game-scores.test.js +0 -106
- package/dist/src/store/sqlite/game-state.test.js +0 -76
- package/dist/src/store/sqlite/global-index.test.js +0 -136
- package/dist/src/store/sqlite/mechanical-fix.test.js +0 -146
- package/dist/src/store/sqlite/perf-samples.test.js +0 -146
- package/dist/src/store/sqlite/raptor.test.js +0 -106
- package/dist/src/store/sqlite/turns.test.js +0 -183
- package/dist/src/store/sqlite.cachehit.test.js +0 -55
- package/dist/src/store/sqlite.dbmaint.test.js +0 -158
- package/dist/src/store/sqlite.dbmirror.test.js +0 -184
- package/dist/src/store/turns/contract-compliance.test.js +0 -428
- package/dist/src/store/turns/memory-store.test.js +0 -9
- package/dist/src/store/turns/migrations.test.js +0 -138
- package/dist/src/store/turns/sqlite-store.test.js +0 -144
- package/dist/src/store/vectorIndex.test.js +0 -123
- package/dist/src/store.test.js +0 -161
- package/dist/src/supersede.test.js +0 -36
- package/dist/src/topics/cluster.test.js +0 -150
- package/dist/src/topics/store.test.js +0 -117
- package/dist/src/types.test.js +0 -9
- package/dist/src/vector-search-cache.test.js +0 -157
- package/dist/src/vectorStore.test.js +0 -479
- package/dist/src/wiki.test.js +0 -171
- package/extensions/conflict-scan.test.ts +0 -129
- package/extensions/dashboard-client/dist/assets/AchievementsTab-DjxfYrDc.js +0 -2
- package/extensions/dashboard-client/dist/assets/CacheTab-Dnpv94wq.js +0 -2
- package/extensions/dashboard-client/dist/assets/CacheTab-Dnpv94wq.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/OverviewTab-D4kGvsiQ.js +0 -2
- package/extensions/dashboard-client/dist/assets/ReposTab-C0Wnrf2u.js +0 -2
- package/extensions/dashboard-client/dist/assets/ReposTab-C0Wnrf2u.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/TimeSavedCard-UqljSyP-.js +0 -2
- package/extensions/dashboard-client/dist/assets/TimeSavedCard-UqljSyP-.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/index-BX0bcgLu.js.map +0 -1
- package/extensions/dashboard-server/api-contracts.test.ts +0 -1065
- package/extensions/dashboard-server/html.test.ts +0 -62
- package/extensions/dashboard-server/perf-server.test.ts +0 -101
- package/extensions/dashboard-server/routes-cache.test.ts +0 -302
- package/extensions/dashboard-server/server.test.ts +0 -131
- package/extensions/dashboard-server-s32.test.ts +0 -195
- package/extensions/dashboard-server.test.ts +0 -382
- package/extensions/mega-cache-replay.test.ts +0 -526
- package/extensions/mega-compact-s38.test.ts +0 -1433
- package/extensions/mega-compact.test.ts +0 -1509
- package/extensions/mega-events.test.ts +0 -55
- package/extensions/mega-game-cmds.test.ts +0 -197
- package/extensions/mega-runtime/snapshot.test.ts +0 -139
- package/extensions/mega-runtime/state.test.ts +0 -262
- package/extensions/mega-runtime/widget.test.ts +0 -468
- package/extensions/mega-shutdown-widget.test.ts +0 -141
- package/extensions/mega-teamrun.test.ts +0 -176
- package/extensions/mega-trim.test.ts +0 -64
- package/extensions/mega-turn-store.test.ts +0 -108
- package/src/boundary.test.ts +0 -187
- package/src/compact.test.ts +0 -99
- package/src/config/themes.test.ts +0 -116
- package/src/dedup/dedup.test.ts +0 -46
- package/src/dedup/l1.test.ts +0 -57
- package/src/dedup/raptor/buildHistory.test.ts +0 -353
- package/src/dedup/raptor/multilevel-serve.test.ts +0 -273
- package/src/dedup/raptor/multilevel.test.ts +0 -325
- package/src/dedup/raptor/promote.test.ts +0 -82
- package/src/dedup/raptor/raptor.test.ts +0 -297
- package/src/dedup/raptor/retrieval.test.ts +0 -118
- package/src/dedup/raptor/serve-gate.test.ts +0 -348
- package/src/dedup/sprint12.test.ts +0 -242
- package/src/dedup-engine.test.ts +0 -670
- package/src/driftDetection.test.ts +0 -100
- package/src/e2e.test.ts +0 -843
- package/src/engine.test.ts +0 -123
- package/src/extractive.test.ts +0 -174
- package/src/fork.test.ts +0 -94
- package/src/game/scoring.test.ts +0 -103
- package/src/httpEmbedder.test.ts +0 -286
- package/src/importance.test.ts +0 -538
- package/src/intent.test.ts +0 -87
- package/src/log.test.ts +0 -47
- package/src/mechanical-fix.test.ts +0 -70
- package/src/memory.test.ts +0 -92
- package/src/memoryConsolidate.test.ts +0 -47
- package/src/memoryOps.test.ts +0 -148
- package/src/memoryRecall.test.ts +0 -194
- package/src/memoryRoundtrip.test.ts +0 -155
- package/src/metrics/turns.test.ts +0 -165
- package/src/mirror/mirror.test.ts +0 -240
- package/src/raptor-inject-summaries.test.ts +0 -228
- package/src/ratio.bench.test.ts +0 -1316
- package/src/recall.integration.test.ts +0 -96
- package/src/recall.test.ts +0 -467
- package/src/sprint14.test.ts +0 -245
- package/src/sprint4x-rag-verification.test.ts +0 -119
- package/src/store/compression.test.ts +0 -168
- package/src/store/memoryIndex.test.ts +0 -61
- package/src/store/migrate.test.ts +0 -158
- package/src/store/pgOpenGuard.test.ts +0 -89
- package/src/store/phase01.test.ts +0 -88
- package/src/store/phase04.test.ts +0 -58
- package/src/store/sprint10.test.ts +0 -214
- package/src/store/sqlite/game-achievements.test.ts +0 -80
- package/src/store/sqlite/game-scores.test.ts +0 -132
- package/src/store/sqlite/game-state.test.ts +0 -89
- package/src/store/sqlite/global-index.test.ts +0 -222
- package/src/store/sqlite/mechanical-fix.test.ts +0 -162
- package/src/store/sqlite/perf-samples.test.ts +0 -169
- package/src/store/sqlite/raptor.test.ts +0 -139
- package/src/store/sqlite/turns.test.ts +0 -218
- package/src/store/sqlite.cachehit.test.ts +0 -68
- package/src/store/sqlite.dbmaint.test.ts +0 -193
- package/src/store/sqlite.dbmirror.test.ts +0 -229
- package/src/store/turns/contract-compliance.test.ts +0 -562
- package/src/store/turns/memory-store.test.ts +0 -15
- package/src/store/turns/migrations.test.ts +0 -161
- package/src/store/turns/sqlite-store.test.ts +0 -161
- package/src/store/vectorIndex.test.ts +0 -140
- package/src/store.test.ts +0 -191
- package/src/supersede.test.ts +0 -42
- package/src/topics/cluster.test.ts +0 -176
- package/src/topics/store.test.ts +0 -132
- package/src/types.test.ts +0 -10
- package/src/vector-search-cache.test.ts +0 -190
- package/src/vectorStore.test.ts +0 -533
- package/src/wiki.test.ts +0 -217
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as l,e as S,g as E,j as e}from"./index-4gQ7auad.js";const t={container:{padding:"1rem",maxWidth:"720px",margin:"0 auto",fontFamily:"system-ui, sans-serif",color:"#e0e0e0"},section:{background:"#1a1a2e",borderRadius:"8px",padding:"1rem",marginBottom:"1rem",border:"1px solid #2a2a4e"},sectionTitle:{fontSize:"1.1rem",fontWeight:700,marginTop:0,marginBottom:"0.75rem",color:"#e0e0e0",borderBottom:"1px solid #333",paddingBottom:"0.5rem"},label:{fontWeight:600,color:"#a0a0c0",marginRight:"0.5rem"},value:{color:"#e0e0e0"},row:{marginBottom:"0.4rem",fontSize:"0.9rem"},warning:{background:"#3a2a00",border:"1px solid #665500",borderRadius:"8px",padding:"0.75rem",marginTop:"0.5rem",color:"#ffcc00",fontSize:"0.85rem"},badge:{display:"inline-block",padding:"0.15rem 0.5rem",borderRadius:"4px",fontSize:"0.8rem",fontWeight:600,marginLeft:"0.5rem"},detectRow:{display:"flex",justifyContent:"space-between",alignItems:"center",padding:"0.5rem 0",borderBottom:"1px solid #2a2a4e"},button:{background:"#3a5a9f",color:"#fff",border:"none",borderRadius:"6px",padding:"0.5rem 1rem",cursor:"pointer",fontSize:"0.9rem",fontWeight:600}};function w(){const[s,p]=l.useState(null),[n,u]=l.useState(null),[i,x]=l.useState(null),[c,m]=l.useState(null),[h,o]=l.useState(!1),a=l.useCallback(()=>{S().then(p).catch(r=>x(r instanceof Error?r.message:String(r)))},[]),g=l.useCallback(()=>{o(!0),m(null),E().then(r=>{u(r),o(!1)}).catch(r=>{m(r instanceof Error?r.message:String(r)),o(!1)})},[]);l.useEffect(()=>{a()},[a]),l.useEffect(()=>{const r=setInterval(a,3e4);return()=>clearInterval(r)},[a]);const f=r=>{switch(r){case"trigram":return"TrigramEmbedder (heuristic, default)";case"http":return"HTTP Embedder (BYO localhost)";case"minilm":return"MiniLM (experimental)";default:return"Unknown"}},j=s?.currentEmbedder==="trigram"&&e.jsxs("div",{style:t.warning,children:[e.jsx("strong",{children:"Note:"})," TrigramEmbedder is a heuristic-strength default embedder. It works without any setup but recall quality may be lower than a dedicated embedding backend. If you notice poor recall results, consider installing Ollama and running the"," ",e.jsx("code",{children:"/megasetup"})," command, or set"," ",e.jsx("code",{children:"MEGACOMPACT_EMBEDDING_URL"})," to point at your own localhost embedding server."]}),d=r=>{const b=r?"#1a5a1a":"#3a1a1a",y=r?"#4caf50":"#f44336";return e.jsx("span",{style:{...t.badge,background:b,color:y},children:r?"Detected":"Not found"})};return e.jsxs("div",{style:t.container,children:[e.jsx("h2",{style:{fontSize:"1.3rem",marginTop:0,marginBottom:"1rem"},children:"Embedder Setup"}),e.jsxs("div",{style:t.section,children:[e.jsx("h3",{style:t.sectionTitle,children:"Current Embedder Configuration"}),i&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error: ",i]}),s&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:t.row,children:[e.jsx("span",{style:t.label,children:"Active Embedder:"}),e.jsx("span",{style:t.value,children:f(s.currentEmbedder)})]}),e.jsxs("div",{style:t.row,children:[e.jsx("span",{style:t.label,children:"Embedding URL:"}),e.jsx("span",{style:t.value,children:s.embeddingUrl??e.jsx("span",{style:{color:"#888"},children:"not set"})})]}),e.jsxs("div",{style:t.row,children:[e.jsx("span",{style:t.label,children:"Embed Cache:"}),e.jsx("span",{style:t.value,children:s.embedCache??e.jsx("span",{style:{color:"#888"},children:"not set"})})]}),e.jsxs("div",{style:t.row,children:[e.jsx("span",{style:t.label,children:"MiniLM:"}),e.jsx("span",{style:t.value,children:s.minilm?"enabled":"disabled"})]}),j]}),!s&&!i&&e.jsx("p",{style:{color:"#888",fontSize:"0.85rem"},children:"Loading configuration..."})]}),e.jsxs("div",{style:t.section,children:[e.jsx("h3",{style:t.sectionTitle,children:"Local Embedder Detection"}),e.jsx("p",{style:{fontSize:"0.85rem",color:"#a0a0c0",marginTop:0},children:"Detect which local embedding backends are available on this machine. No software is installed — detection only."}),n&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{style:t.detectRow,children:[e.jsx("span",{children:e.jsx("strong",{children:"Ollama"})}),n.ollama!==null?e.jsxs("span",{children:[d(n.ollama.installed),n.ollama.installed&&e.jsx("span",{style:{fontSize:"0.8rem",color:"#a0a0c0",marginLeft:"0.5rem"},children:n.ollama.running?`server running, ${n.ollama.models.length} model(s)`:"server not running"})]}):e.jsx("span",{style:{color:"#888",fontSize:"0.85rem"},children:"not checked"})]}),e.jsxs("div",{style:t.detectRow,children:[e.jsx("span",{children:e.jsx("strong",{children:"llama.cpp"})}),n.llamaCpp!==null?e.jsxs("span",{children:[d(n.llamaCpp.installed),n.llamaCpp.installed&&n.llamaCpp.detail&&e.jsx("span",{style:{fontSize:"0.8rem",color:"#a0a0c0",marginLeft:"0.5rem"},children:n.llamaCpp.detail})]}):e.jsx("span",{style:{color:"#888",fontSize:"0.85rem"},children:"not checked"})]}),e.jsxs("div",{style:t.detectRow,children:[e.jsx("span",{children:e.jsx("strong",{children:"ONNX Runtime"})}),n.onnx!==null?e.jsxs("span",{children:[d(n.onnx.installed),n.onnx.installed&&n.onnx.detail&&e.jsx("span",{style:{fontSize:"0.8rem",color:"#a0a0c0",marginLeft:"0.5rem"},children:n.onnx.detail})]}):e.jsx("span",{style:{color:"#888",fontSize:"0.85rem"},children:"not checked"})]}),n.error&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.8rem",marginTop:"0.5rem"},children:["Detection error: ",n.error]})]}),c&&e.jsxs("p",{style:{color:"#f44336",fontSize:"0.85rem"},children:["Error: ",c]}),e.jsxs("div",{style:{marginTop:"1rem"},children:[e.jsx("button",{style:t.button,onClick:g,disabled:h,children:h?"Detecting...":"Run Detection"}),e.jsxs("span",{style:{fontSize:"0.8rem",color:"#888",marginLeft:"0.75rem"},children:["Or run ",e.jsx("code",{children:"/megasetup"})," in the chat for an interactive wizard."]})]})]}),e.jsxs("div",{style:t.section,children:[e.jsx("h3",{style:t.sectionTitle,children:"How to Upgrade"}),e.jsxs("ul",{style:{fontSize:"0.85rem",lineHeight:1.6,paddingLeft:"1.25rem"},children:[e.jsxs("li",{children:[e.jsx("strong",{children:"Ollama:"})," Install from"," ",e.jsx("a",{href:"https://ollama.com",style:{color:"#6a9fff"},target:"_blank",rel:"noopener noreferrer",children:"ollama.com"}),", then ",e.jsx("code",{children:"ollama pull nomic-embed-text"})," and restart pi. Set ",e.jsx("code",{children:"MEGACOMPACT_EMBEDDING_URL=http://localhost:11434/api/embeddings"}),"."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"llama.cpp:"})," Build or install llama.cpp, run"," ",e.jsx("code",{children:"llama-server"})," with an embedding model, and set the URL accordingly."]}),e.jsxs("li",{children:[e.jsx("strong",{children:"ONNX Runtime:"})," Install"," ",e.jsx("code",{children:"onnxruntime-node"})," in the project root. Not yet integrated — see docs for manual setup."]})]})]})]})}export{w as default};
|
|
2
|
+
//# sourceMappingURL=SetupTab-mMlfunJa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SetupTab-mMlfunJa.js","sources":["../../src/tabs/SetupTab.tsx"],"sourcesContent":["/**\n * dashboard-client/src/tabs/SetupTab.tsx — Setup wizard tab (P0b).\n *\n * Shows current embedder configuration, warns about trigram recall quality,\n * and mirrors the /megasetup command with detection results.\n *\n * PREVENT-PI-004: all data comes from localhost dashboard API endpoints —\n * no external network calls.\n */\n\nimport type React from \"react\";\nimport { useState, useEffect, useCallback } from \"react\";\nimport type { SetupStatusResponse, SetupDetectResponse } from \"@contracts\";\nimport { fetchSetupStatus, fetchSetupDetect } from \"../api/client\";\n\n// ---------------------------------------------------------------------------\n// Style constants\n// ---------------------------------------------------------------------------\n\nconst styles: Record<string, React.CSSProperties> = {\n\tcontainer: {\n\t\tpadding: \"1rem\",\n\t\tmaxWidth: \"720px\",\n\t\tmargin: \"0 auto\",\n\t\tfontFamily: \"system-ui, sans-serif\",\n\t\tcolor: \"#e0e0e0\",\n\t},\n\tsection: {\n\t\tbackground: \"#1a1a2e\",\n\t\tborderRadius: \"8px\",\n\t\tpadding: \"1rem\",\n\t\tmarginBottom: \"1rem\",\n\t\tborder: \"1px solid #2a2a4e\",\n\t},\n\tsectionTitle: {\n\t\tfontSize: \"1.1rem\",\n\t\tfontWeight: 700,\n\t\tmarginTop: 0,\n\t\tmarginBottom: \"0.75rem\",\n\t\tcolor: \"#e0e0e0\",\n\t\tborderBottom: \"1px solid #333\",\n\t\tpaddingBottom: \"0.5rem\",\n\t},\n\tlabel: { fontWeight: 600, color: \"#a0a0c0\", marginRight: \"0.5rem\" },\n\tvalue: { color: \"#e0e0e0\" },\n\trow: { marginBottom: \"0.4rem\", fontSize: \"0.9rem\" },\n\twarning: {\n\t\tbackground: \"#3a2a00\",\n\t\tborder: \"1px solid #665500\",\n\t\tborderRadius: \"8px\",\n\t\tpadding: \"0.75rem\",\n\t\tmarginTop: \"0.5rem\",\n\t\tcolor: \"#ffcc00\",\n\t\tfontSize: \"0.85rem\",\n\t},\n\tbadge: {\n\t\tdisplay: \"inline-block\",\n\t\tpadding: \"0.15rem 0.5rem\",\n\t\tborderRadius: \"4px\",\n\t\tfontSize: \"0.8rem\",\n\t\tfontWeight: 600,\n\t\tmarginLeft: \"0.5rem\",\n\t},\n\tdetectRow: {\n\t\tdisplay: \"flex\",\n\t\tjustifyContent: \"space-between\",\n\t\talignItems: \"center\",\n\t\tpadding: \"0.5rem 0\",\n\t\tborderBottom: \"1px solid #2a2a4e\",\n\t},\n\tbutton: {\n\t\tbackground: \"#3a5a9f\",\n\t\tcolor: \"#fff\",\n\t\tborder: \"none\",\n\t\tborderRadius: \"6px\",\n\t\tpadding: \"0.5rem 1rem\",\n\t\tcursor: \"pointer\",\n\t\tfontSize: \"0.9rem\",\n\t\tfontWeight: 600,\n\t},\n};\n\n// ---------------------------------------------------------------------------\n// SetupTab component\n// ---------------------------------------------------------------------------\n\nexport default function SetupTab(): React.ReactElement {\n\tconst [status, setStatus] = useState<SetupStatusResponse | null>(null);\n\tconst [detect, setDetect] = useState<SetupDetectResponse | null>(null);\n\tconst [statusError, setStatusError] = useState<string | null>(null);\n\tconst [detectError, setDetectError] = useState<string | null>(null);\n\tconst [runningDetect, setRunningDetect] = useState(false);\n\n\tconst loadStatus = useCallback(() => {\n\t\tfetchSetupStatus()\n\t\t\t.then(setStatus)\n\t\t\t.catch((e: unknown) =>\n\t\t\t\tsetStatusError(e instanceof Error ? e.message : String(e)),\n\t\t\t);\n\t}, []);\n\n\tconst runDetect = useCallback(() => {\n\t\tsetRunningDetect(true);\n\t\tsetDetectError(null);\n\t\tfetchSetupDetect()\n\t\t\t.then((d) => {\n\t\t\t\tsetDetect(d);\n\t\t\t\tsetRunningDetect(false);\n\t\t\t})\n\t\t\t.catch((e: unknown) => {\n\t\t\t\tsetDetectError(e instanceof Error ? e.message : String(e));\n\t\t\t\tsetRunningDetect(false);\n\t\t\t});\n\t}, []);\n\n\tuseEffect(() => {\n\t\tloadStatus();\n\t}, [loadStatus]);\n\n\t// Poll status every 30s\n\tuseEffect(() => {\n\t\tconst id = setInterval(loadStatus, 30000);\n\t\treturn () => clearInterval(id);\n\t}, [loadStatus]);\n\n\t// -----------------------------------------------------------------------\n\t// Render helpers\n\t// -----------------------------------------------------------------------\n\n\tconst embedderLabel = (e: string): string => {\n\t\tswitch (e) {\n\t\t\tcase \"trigram\":\n\t\t\t\treturn \"TrigramEmbedder (heuristic, default)\";\n\t\t\tcase \"http\":\n\t\t\t\treturn \"HTTP Embedder (BYO localhost)\";\n\t\t\tcase \"minilm\":\n\t\t\t\treturn \"MiniLM (experimental)\";\n\t\t\tdefault:\n\t\t\t\treturn \"Unknown\";\n\t\t}\n\t};\n\n\tconst trigramWarning = status?.currentEmbedder === \"trigram\" && (\n\t\t<div style={styles.warning}>\n\t\t\t<strong>Note:</strong> TrigramEmbedder is a heuristic-strength default\n\t\t\tembedder. It works without any setup but recall quality may be lower\n\t\t\tthan a dedicated embedding backend. If you notice poor recall results,\n\t\t\tconsider installing Ollama and running the{\" \"}\n\t\t\t<code>/megasetup</code> command, or set{\" \"}\n\t\t\t<code>MEGACOMPACT_EMBEDDING_URL</code> to point at your own localhost\n\t\t\tembedding server.\n\t\t</div>\n\t);\n\n\tconst detectBadge = (installed: boolean): React.ReactElement => {\n\t\tconst bg = installed ? \"#1a5a1a\" : \"#3a1a1a\";\n\t\tconst color = installed ? \"#4caf50\" : \"#f44336\";\n\t\treturn (\n\t\t\t<span style={{ ...styles.badge, background: bg, color }}>\n\t\t\t\t{installed ? \"Detected\" : \"Not found\"}\n\t\t\t</span>\n\t\t);\n\t};\n\n\t// -----------------------------------------------------------------------\n\t// Main render\n\t// -----------------------------------------------------------------------\n\n\treturn (\n\t\t<div style={styles.container}>\n\t\t\t<h2 style={{ fontSize: \"1.3rem\", marginTop: 0, marginBottom: \"1rem\" }}>\n\t\t\t\tEmbedder Setup\n\t\t\t</h2>\n\n\t\t\t{/* Current Config Section */}\n\t\t\t<div style={styles.section}>\n\t\t\t\t<h3 style={styles.sectionTitle}>Current Embedder Configuration</h3>\n\t\t\t\t{statusError && (\n\t\t\t\t\t<p style={{ color: \"#f44336\", fontSize: \"0.85rem\" }}>\n\t\t\t\t\t\tError: {statusError}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\t\t\t\t{status && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<div style={styles.row}>\n\t\t\t\t\t\t\t<span style={styles.label}>Active Embedder:</span>\n\t\t\t\t\t\t\t<span style={styles.value}>\n\t\t\t\t\t\t\t\t{embedderLabel(status.currentEmbedder)}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div style={styles.row}>\n\t\t\t\t\t\t\t<span style={styles.label}>Embedding URL:</span>\n\t\t\t\t\t\t\t<span style={styles.value}>\n\t\t\t\t\t\t\t\t{status.embeddingUrl ?? (\n\t\t\t\t\t\t\t\t\t<span style={{ color: \"#888\" }}>not set</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div style={styles.row}>\n\t\t\t\t\t\t\t<span style={styles.label}>Embed Cache:</span>\n\t\t\t\t\t\t\t<span style={styles.value}>\n\t\t\t\t\t\t\t\t{status.embedCache ?? (\n\t\t\t\t\t\t\t\t\t<span style={{ color: \"#888\" }}>not set</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div style={styles.row}>\n\t\t\t\t\t\t\t<span style={styles.label}>MiniLM:</span>\n\t\t\t\t\t\t\t<span style={styles.value}>{status.minilm ? \"enabled\" : \"disabled\"}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{trigramWarning}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\t\t\t\t{!status && !statusError && (\n\t\t\t\t\t<p style={{ color: \"#888\", fontSize: \"0.85rem\" }}>\n\t\t\t\t\t\tLoading configuration...\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t{/* Detection Section */}\n\t\t\t<div style={styles.section}>\n\t\t\t\t<h3 style={styles.sectionTitle}>Local Embedder Detection</h3>\n\t\t\t\t<p style={{ fontSize: \"0.85rem\", color: \"#a0a0c0\", marginTop: 0 }}>\n\t\t\t\t\tDetect which local embedding backends are available on this machine.\n\t\t\t\t\tNo software is installed — detection only.\n\t\t\t\t</p>\n\n\t\t\t\t{detect && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t{/* Ollama */}\n\t\t\t\t\t\t<div style={styles.detectRow}>\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<strong>Ollama</strong>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t{detect.ollama !== null ? (\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t{detectBadge(detect.ollama.installed)}\n\t\t\t\t\t\t\t\t\t{detect.ollama.installed && (\n\t\t\t\t\t\t\t\t\t\t<span style={{ fontSize: \"0.8rem\", color: \"#a0a0c0\", marginLeft: \"0.5rem\" }}>\n\t\t\t\t\t\t\t\t\t\t\t{detect.ollama.running\n\t\t\t\t\t\t\t\t\t\t\t\t? `server running, ${detect.ollama.models.length} model(s)`\n\t\t\t\t\t\t\t\t\t\t\t\t: \"server not running\"}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<span style={{ color: \"#888\", fontSize: \"0.85rem\" }}>\n\t\t\t\t\t\t\t\t\tnot checked\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* llama.cpp */}\n\t\t\t\t\t\t<div style={styles.detectRow}>\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<strong>llama.cpp</strong>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t{detect.llamaCpp !== null ? (\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t{detectBadge(detect.llamaCpp.installed)}\n\t\t\t\t\t\t\t\t\t{detect.llamaCpp.installed && detect.llamaCpp.detail && (\n\t\t\t\t\t\t\t\t\t\t<span style={{ fontSize: \"0.8rem\", color: \"#a0a0c0\", marginLeft: \"0.5rem\" }}>\n\t\t\t\t\t\t\t\t\t\t\t{detect.llamaCpp.detail}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<span style={{ color: \"#888\", fontSize: \"0.85rem\" }}>\n\t\t\t\t\t\t\t\t\tnot checked\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{/* ONNX */}\n\t\t\t\t\t\t<div style={styles.detectRow}>\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<strong>ONNX Runtime</strong>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t{detect.onnx !== null ? (\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t{detectBadge(detect.onnx.installed)}\n\t\t\t\t\t\t\t\t\t{detect.onnx.installed && detect.onnx.detail && (\n\t\t\t\t\t\t\t\t\t\t<span style={{ fontSize: \"0.8rem\", color: \"#a0a0c0\", marginLeft: \"0.5rem\" }}>\n\t\t\t\t\t\t\t\t\t\t\t{detect.onnx.detail}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<span style={{ color: \"#888\", fontSize: \"0.85rem\" }}>\n\t\t\t\t\t\t\t\t\tnot checked\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t{detect.error && (\n\t\t\t\t\t\t\t<p style={{ color: \"#f44336\", fontSize: \"0.8rem\", marginTop: \"0.5rem\" }}>\n\t\t\t\t\t\t\t\tDetection error: {detect.error}\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</>\n\t\t\t\t)}\n\n\t\t\t\t{detectError && (\n\t\t\t\t\t<p style={{ color: \"#f44336\", fontSize: \"0.85rem\" }}>\n\t\t\t\t\t\tError: {detectError}\n\t\t\t\t\t</p>\n\t\t\t\t)}\n\n\t\t\t\t<div style={{ marginTop: \"1rem\" }}>\n\t\t\t\t\t<button\n\t\t\t\t\t\tstyle={styles.button}\n\t\t\t\t\t\tonClick={runDetect}\n\t\t\t\t\t\tdisabled={runningDetect}\n\t\t\t\t\t>\n\t\t\t\t\t\t{runningDetect ? \"Detecting...\" : \"Run Detection\"}\n\t\t\t\t\t</button>\n\t\t\t\t\t<span style={{ fontSize: \"0.8rem\", color: \"#888\", marginLeft: \"0.75rem\" }}>\n\t\t\t\t\t\tOr run <code>/megasetup</code> in the chat for an interactive wizard.\n\t\t\t\t\t</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t{/* Help Section */}\n\t\t\t<div style={styles.section}>\n\t\t\t\t<h3 style={styles.sectionTitle}>How to Upgrade</h3>\n\t\t\t\t<ul style={{ fontSize: \"0.85rem\", lineHeight: 1.6, paddingLeft: \"1.25rem\" }}>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<strong>Ollama:</strong> Install from{\" \"}\n\t\t\t\t\t\t<a\n\t\t\t\t\t\t\thref=\"https://ollama.com\"\n\t\t\t\t\t\t\tstyle={{ color: \"#6a9fff\" }}\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tollama.com\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t, then <code>ollama pull nomic-embed-text</code> and restart pi.\n\t\t\t\t\t\tSet <code>MEGACOMPACT_EMBEDDING_URL=http://localhost:11434/api/embeddings</code>.\n\t\t\t\t\t</li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<strong>llama.cpp:</strong> Build or install llama.cpp, run{\" \"}\n\t\t\t\t\t\t<code>llama-server</code> with an embedding model, and set\n\t\t\t\t\t\tthe URL accordingly.\n\t\t\t\t\t</li>\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<strong>ONNX Runtime:</strong> Install{\" \"}\n\t\t\t\t\t\t<code>onnxruntime-node</code> in the project root. Not yet\n\t\t\t\t\t\tintegrated — see docs for manual setup.\n\t\t\t\t\t</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"names":["styles","SetupTab","status","setStatus","useState","detect","setDetect","statusError","setStatusError","detectError","setDetectError","runningDetect","setRunningDetect","loadStatus","useCallback","fetchSetupStatus","e","runDetect","fetchSetupDetect","d","useEffect","id","embedderLabel","trigramWarning","jsx","detectBadge","installed","bg","color","jsxs","Fragment"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{j as a}from"./index-4gQ7auad.js";import{g as t}from"./format-COjDIVGj.js";function s({label:e,value:c}){return a.jsxs("div",{className:"ov-stat-row",children:[a.jsx("span",{className:"ov-stat-label",children:e}),a.jsx("span",{className:"ov-stat-value",children:c})]})}function n(e){return a.jsxs("div",{className:"card cache-hits-card",children:[a.jsx("h3",{children:"💾 Cache Hits & Compactions"}),a.jsx(s,{label:"Cache Hits (session)",value:e.cacheHitsSession.toLocaleString()}),a.jsx(s,{label:"Cache Hits (total)",value:e.cacheHitsTotal.toLocaleString()}),a.jsx(s,{label:"Tokens Saved (session)",value:e.tokensSavedSession.toLocaleString()}),a.jsx(s,{label:"Tokens Saved (total)",value:e.tokensSavedTotal.toLocaleString()}),a.jsx(s,{label:"Compactions (session)",value:e.compactionsSession.toLocaleString()}),a.jsx(s,{label:"Compactions (total)",value:e.compactionsTotal.toLocaleString()})]})}function l({label:e,value:c}){return a.jsxs("div",{className:"ov-stat-row",children:[a.jsx("span",{className:"ov-stat-label",children:e}),a.jsx("span",{className:"ov-stat-value",children:c})]})}function r(e){return a.jsxs("div",{className:"card time-saved-card",children:[a.jsx("h3",{children:"⏱ Time Saved (est.)"}),a.jsx(l,{label:"Compact (session)",value:t(e.compactSessionSec)}),a.jsx(l,{label:"Compact (total)",value:t(e.compactTotalSec)}),a.jsx(l,{label:"Cache Hit (session)",value:t(e.cacheHitSessionSec)}),a.jsx(l,{label:"Cache Hit (total)",value:t(e.cacheHitTotalSec)})]})}export{n as C,r as T};
|
|
2
|
+
//# sourceMappingURL=TimeSavedCard-Cw1dJ4e9.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeSavedCard-Cw1dJ4e9.js","sources":["../../src/components/CacheHitsCard.tsx","../../src/components/TimeSavedCard.tsx"],"sourcesContent":["/**\n * dashboard-client/src/components/CacheHitsCard.tsx — Cache Hits & Compactions card.\n *\n * 6 fields: Cache Hits (session), Cache Hits (total),\n * Tokens Saved (session), Tokens Saved (total),\n * Compactions (session), Compactions (total).\n */\n\nimport type React from \"react\";\n\nexport interface CacheHitsCardProps {\n\t/** Cache hits in the current session. */\n\tcacheHitsSession: number;\n\t/** Total cache hits across all sessions. */\n\tcacheHitsTotal: number;\n\t/** Tokens saved by cache hits this session. */\n\ttokensSavedSession: number;\n\t/** Total tokens saved by cache hits. */\n\ttokensSavedTotal: number;\n\t/** Compactions performed this session. */\n\tcompactionsSession: number;\n\t/** Total compactions performed. */\n\tcompactionsTotal: number;\n}\n\nfunction StatRow({\n\tlabel,\n\tvalue,\n}: {\n\tlabel: string;\n\tvalue: string | number;\n}): React.ReactElement {\n\treturn (\n\t\t<div className=\"ov-stat-row\">\n\t\t\t<span className=\"ov-stat-label\">{label}</span>\n\t\t\t<span className=\"ov-stat-value\">{value}</span>\n\t\t</div>\n\t);\n}\n\nexport function CacheHitsCard(\n\tprops: CacheHitsCardProps,\n): React.ReactElement {\n\treturn (\n\t\t<div className=\"card cache-hits-card\">\n\t\t\t<h3>💾 Cache Hits & Compactions</h3>\n\t\t\t<StatRow\n\t\t\t\tlabel=\"Cache Hits (session)\"\n\t\t\t\tvalue={props.cacheHitsSession.toLocaleString()}\n\t\t\t/>\n\t\t\t<StatRow\n\t\t\t\tlabel=\"Cache Hits (total)\"\n\t\t\t\tvalue={props.cacheHitsTotal.toLocaleString()}\n\t\t\t/>\n\t\t\t<StatRow\n\t\t\t\tlabel=\"Tokens Saved (session)\"\n\t\t\t\tvalue={props.tokensSavedSession.toLocaleString()}\n\t\t\t/>\n\t\t\t<StatRow\n\t\t\t\tlabel=\"Tokens Saved (total)\"\n\t\t\t\tvalue={props.tokensSavedTotal.toLocaleString()}\n\t\t\t/>\n\t\t\t<StatRow\n\t\t\t\tlabel=\"Compactions (session)\"\n\t\t\t\tvalue={props.compactionsSession.toLocaleString()}\n\t\t\t/>\n\t\t\t<StatRow\n\t\t\t\tlabel=\"Compactions (total)\"\n\t\t\t\tvalue={props.compactionsTotal.toLocaleString()}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n","/**\n * dashboard-client/src/components/TimeSavedCard.tsx — Time Saved (est.) card.\n *\n * 4 fields: Compact (session), Compact (total),\n * Cache Hit (session), Cache Hit (total).\n */\n\nimport type React from \"react\";\nimport { fmtSec } from \"../utils/format\";\n\nexport interface TimeSavedCardProps {\n\t/** Seconds saved by compaction this session. */\n\tcompactSessionSec: number;\n\t/** Total seconds saved by compaction. */\n\tcompactTotalSec: number;\n\t/** Seconds saved by cache hits this session. */\n\tcacheHitSessionSec: number;\n\t/** Total seconds saved by cache hits. */\n\tcacheHitTotalSec: number;\n}\n\nfunction StatRow({\n\tlabel,\n\tvalue,\n}: {\n\tlabel: string;\n\tvalue: string;\n}): React.ReactElement {\n\treturn (\n\t\t<div className=\"ov-stat-row\">\n\t\t\t<span className=\"ov-stat-label\">{label}</span>\n\t\t\t<span className=\"ov-stat-value\">{value}</span>\n\t\t</div>\n\t);\n}\n\nexport function TimeSavedCard(\n\tprops: TimeSavedCardProps,\n): React.ReactElement {\n\treturn (\n\t\t<div className=\"card time-saved-card\">\n\t\t\t<h3>⏱ Time Saved (est.)</h3>\n\t\t\t<StatRow\n\t\t\t\tlabel=\"Compact (session)\"\n\t\t\t\tvalue={fmtSec(props.compactSessionSec)}\n\t\t\t/>\n\t\t\t<StatRow\n\t\t\t\tlabel=\"Compact (total)\"\n\t\t\t\tvalue={fmtSec(props.compactTotalSec)}\n\t\t\t/>\n\t\t\t<StatRow\n\t\t\t\tlabel=\"Cache Hit (session)\"\n\t\t\t\tvalue={fmtSec(props.cacheHitSessionSec)}\n\t\t\t/>\n\t\t\t<StatRow\n\t\t\t\tlabel=\"Cache Hit (total)\"\n\t\t\t\tvalue={fmtSec(props.cacheHitTotalSec)}\n\t\t\t/>\n\t\t</div>\n\t);\n}\n"],"names":["StatRow","label","value","jsxs","jsx","CacheHitsCard","props","TimeSavedCard","fmtSec"],"mappings":"iFAyBA,SAASA,EAAQ,CAChB,MAAAC,EACA,MAAAC,CACD,EAGuB,CACtB,OACCC,EAAAA,KAAC,MAAA,CAAI,UAAU,cACd,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,gBAAiB,SAAAH,EAAM,EACvCG,EAAAA,IAAC,OAAA,CAAK,UAAU,gBAAiB,SAAAF,CAAA,CAAM,CAAA,EACxC,CAEF,CAEO,SAASG,EACfC,EACqB,CACrB,OACCH,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACd,SAAA,CAAAC,EAAAA,IAAC,MAAG,SAAA,6BAAA,CAA+B,EACnCA,EAAAA,IAACJ,EAAA,CACA,MAAM,uBACN,MAAOM,EAAM,iBAAiB,eAAA,CAAe,CAAA,EAE9CF,EAAAA,IAACJ,EAAA,CACA,MAAM,qBACN,MAAOM,EAAM,eAAe,eAAA,CAAe,CAAA,EAE5CF,EAAAA,IAACJ,EAAA,CACA,MAAM,yBACN,MAAOM,EAAM,mBAAmB,eAAA,CAAe,CAAA,EAEhDF,EAAAA,IAACJ,EAAA,CACA,MAAM,uBACN,MAAOM,EAAM,iBAAiB,eAAA,CAAe,CAAA,EAE9CF,EAAAA,IAACJ,EAAA,CACA,MAAM,wBACN,MAAOM,EAAM,mBAAmB,eAAA,CAAe,CAAA,EAEhDF,EAAAA,IAACJ,EAAA,CACA,MAAM,sBACN,MAAOM,EAAM,iBAAiB,eAAA,CAAe,CAAA,CAC9C,EACD,CAEF,CCnDA,SAASN,EAAQ,CAChB,MAAAC,EACA,MAAAC,CACD,EAGuB,CACtB,OACCC,EAAAA,KAAC,MAAA,CAAI,UAAU,cACd,SAAA,CAAAC,EAAAA,IAAC,OAAA,CAAK,UAAU,gBAAiB,SAAAH,EAAM,EACvCG,EAAAA,IAAC,OAAA,CAAK,UAAU,gBAAiB,SAAAF,CAAA,CAAM,CAAA,EACxC,CAEF,CAEO,SAASK,EACfD,EACqB,CACrB,OACCH,EAAAA,KAAC,MAAA,CAAI,UAAU,uBACd,SAAA,CAAAC,EAAAA,IAAC,MAAG,SAAA,qBAAA,CAAmB,EACvBA,EAAAA,IAACJ,EAAA,CACA,MAAM,oBACN,MAAOQ,EAAOF,EAAM,iBAAiB,CAAA,CAAA,EAEtCF,EAAAA,IAACJ,EAAA,CACA,MAAM,kBACN,MAAOQ,EAAOF,EAAM,eAAe,CAAA,CAAA,EAEpCF,EAAAA,IAACJ,EAAA,CACA,MAAM,sBACN,MAAOQ,EAAOF,EAAM,kBAAkB,CAAA,CAAA,EAEvCF,EAAAA,IAACJ,EAAA,CACA,MAAM,oBACN,MAAOQ,EAAOF,EAAM,gBAAgB,CAAA,CAAA,CACrC,EACD,CAEF"}
|
package/extensions/dashboard-client/dist/assets/{TopicsTab-01G71hv1.js → TopicsTab-BAw972BV.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as h,r as a,
|
|
2
|
-
//# sourceMappingURL=TopicsTab-
|
|
1
|
+
import{u as h,r as a,q as u,s as p,j as e}from"./index-4gQ7auad.js";function b(s){return s?new Date(s).toLocaleString():"—"}function f(){const{data:s,loading:m,error:n}=h(a.useCallback(()=>u(),[]),{pollInterval:3e4}),[l,x]=a.useState(""),[i,o]=a.useState(null),r=h(a.useCallback(()=>i?p(i):Promise.reject(),[i]),{pollInterval:0}),d=a.useMemo(()=>{if(!s)return[];const t=l.trim().toLowerCase();return t?s.topics.filter(c=>c.label.toLowerCase().includes(t)||c.termScore.some(j=>j.term.toLowerCase().includes(t))):s.topics},[s,l]);return n&&!s?e.jsxs("div",{className:"tab-stub",children:["Error loading topics: ",n.message]}):m&&!s?e.jsx("div",{className:"tab-stub",children:"Loading topics…"}):s?s.totalTopics===0?e.jsxs("div",{className:"tab-stub",children:[e.jsx("h3",{children:"Wiki"}),e.jsx("p",{children:"No topics yet. Topics are auto-generated after every 10th compaction from real memory embeddings (k-means + TF-IDF)."}),e.jsx("p",{children:"Check back after a few more compaction cycles."})]}):e.jsxs("div",{className:"tab-content topics-tab",children:[e.jsx("h3",{children:"Wiki"}),e.jsxs("p",{className:"subtitle",children:[s.totalTopics," topic",s.totalTopics!==1?"s":""," ·"," ",s.totalAssigned," assigned memori",s.totalAssigned!==1?"es":"y",s.lastRebuildAt!=null&&e.jsxs(e.Fragment,{children:[" · last rebuild ",new Date(s.lastRebuildAt).toLocaleString()]})]}),e.jsx("input",{type:"search",className:"topics-search",placeholder:"Filter topics by label or term…",value:l,onChange:t=>x(t.target.value)}),i&&e.jsxs("section",{className:"topic-drilldown",children:[e.jsxs("h4",{children:[e.jsx("button",{type:"button",className:"link-btn",onClick:()=>o(null),children:"← back"})," ","Topic ",e.jsx("code",{children:i}),r.data&&e.jsxs(e.Fragment,{children:[" · ",r.data.label]}),r.data&&e.jsxs(e.Fragment,{children:[" · ",r.data.assignments.length," memories"]})]}),r.error?e.jsxs("div",{className:"tab-stub",children:["Error: ",r.error.message]}):r.loading&&!r.data?e.jsx("div",{className:"tab-stub",children:"Loading memories…"}):r.data?e.jsxs("table",{className:"data-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Memory id"}),e.jsx("th",{children:"Confidence"}),e.jsx("th",{children:"Assigned"})]})}),e.jsx("tbody",{children:r.data.assignments.map(t=>e.jsxs("tr",{children:[e.jsx("td",{children:e.jsx("code",{children:t.memoryId})}),e.jsx("td",{children:t.confidence!=null?t.confidence.toFixed(2):"—"}),e.jsx("td",{children:b(t.assignedAt)})]},t.memoryId))})]}):null]}),!i&&e.jsxs("table",{className:"data-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Label"}),e.jsx("th",{children:"Memories"}),e.jsx("th",{children:"Top Terms"}),e.jsx("th",{})]})}),e.jsxs("tbody",{children:[d.map(t=>e.jsxs("tr",{className:"topic-row",onClick:()=>o(t.id),style:{cursor:"pointer"},children:[e.jsx("td",{className:"topic-label",children:t.label}),e.jsx("td",{className:"topic-count",children:t.memoryCount}),e.jsx("td",{className:"topic-terms",children:t.termScore.slice(0,8).map(c=>c.term).join(", ")}),e.jsx("td",{children:e.jsx("button",{type:"button",className:"mini-btn",children:"drill"})})]},t.id)),d.length===0&&e.jsx("tr",{children:e.jsxs("td",{colSpan:4,className:"muted",children:["No topics match “",l,"”."]})})]})]})]}):e.jsx("div",{className:"tab-stub",children:"No topic data available."})}export{f as default};
|
|
2
|
+
//# sourceMappingURL=TopicsTab-BAw972BV.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TopicsTab-
|
|
1
|
+
{"version":3,"file":"TopicsTab-BAw972BV.js","sources":["../../src/tabs/TopicsTab.tsx"],"sourcesContent":["/**\n * dashboard-client/src/tabs/TopicsTab.tsx — Auto-categorizing wiki (S51 + S52 polish).\n *\n * Fetches /api/topics and renders the k-means + TF-IDF topic clusters. S52 polish\n * adds: (1) a search box filtering topics by label / discriminative term, and\n * (2) a topic drill-down — click a topic to load its member memories\n * (/api/topics/:id/memories). Read-only; no write operations.\n */\n\nimport type React from \"react\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { useApi } from \"../hooks/useApi\";\nimport { fetchTopics, fetchTopicMemories } from \"../api/client\";\nimport type { TopicsResponse, TopicMemoriesResponse } from \"@contracts\";\n\nfunction fmtTs(ms: number | null): string {\n\tif (!ms) return \"—\";\n\treturn new Date(ms).toLocaleString();\n}\n\nexport default function TopicsTab(): React.ReactElement {\n\tconst { data, loading, error } = useApi<TopicsResponse>(\n\t\tuseCallback(() => fetchTopics(), []),\n\t\t{ pollInterval: 30_000 },\n\t);\n\tconst [query, setQuery] = useState(\"\");\n\tconst [drillTopicId, setDrillTopicId] = useState<string | null>(null);\n\n\tconst drill = useApi<TopicMemoriesResponse>(\n\t\tuseCallback(\n\t\t\t() =>\n\t\t\t\tdrillTopicId ? fetchTopicMemories(drillTopicId) : Promise.reject(),\n\t\t\t[drillTopicId],\n\t\t),\n\t\t{ pollInterval: 0 },\n\t);\n\n\tconst filtered = useMemo(() => {\n\t\tif (!data) return [];\n\t\tconst q = query.trim().toLowerCase();\n\t\tif (!q) return data.topics;\n\t\treturn data.topics.filter(\n\t\t\t(t) =>\n\t\t\t\tt.label.toLowerCase().includes(q) ||\n\t\t\t\tt.termScore.some((s) => s.term.toLowerCase().includes(q)),\n\t\t);\n\t}, [data, query]);\n\n\tif (error && !data) {\n\t\treturn (\n\t\t\t<div className=\"tab-stub\">Error loading topics: {error.message}</div>\n\t\t);\n\t}\n\tif (loading && !data) {\n\t\treturn <div className=\"tab-stub\">Loading topics…</div>;\n\t}\n\tif (!data) {\n\t\treturn <div className=\"tab-stub\">No topic data available.</div>;\n\t}\n\n\tif (data.totalTopics === 0) {\n\t\treturn (\n\t\t\t<div className=\"tab-stub\">\n\t\t\t\t<h3>Wiki</h3>\n\t\t\t\t<p>\n\t\t\t\t\tNo topics yet. Topics are auto-generated after every 10th compaction\n\t\t\t\t\tfrom real memory embeddings (k-means + TF-IDF).\n\t\t\t\t</p>\n\t\t\t\t<p>Check back after a few more compaction cycles.</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"tab-content topics-tab\">\n\t\t\t<h3>Wiki</h3>\n\t\t\t<p className=\"subtitle\">\n\t\t\t\t{data.totalTopics} topic{data.totalTopics !== 1 ? \"s\" : \"\"} ·{\" \"}\n\t\t\t\t{data.totalAssigned} assigned memori\n\t\t\t\t{data.totalAssigned !== 1 ? \"es\" : \"y\"}\n\t\t\t\t{data.lastRebuildAt != null && (\n\t\t\t\t\t<> · last rebuild {new Date(data.lastRebuildAt).toLocaleString()}</>\n\t\t\t\t)}\n\t\t\t</p>\n\n\t\t\t<input\n\t\t\t\ttype=\"search\"\n\t\t\t\tclassName=\"topics-search\"\n\t\t\t\tplaceholder=\"Filter topics by label or term…\"\n\t\t\t\tvalue={query}\n\t\t\t\tonChange={(e) => setQuery(e.target.value)}\n\t\t\t/>\n\n\t\t\t{drillTopicId && (\n\t\t\t\t<section className=\"topic-drilldown\">\n\t\t\t\t\t<h4>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclassName=\"link-btn\"\n\t\t\t\t\t\t\tonClick={() => setDrillTopicId(null)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t← back\n\t\t\t\t\t\t</button>{\" \"}\n\t\t\t\t\t\tTopic <code>{drillTopicId}</code>\n\t\t\t\t\t\t{drill.data && <> · {drill.data.label}</>}\n\t\t\t\t\t\t{drill.data && <> · {drill.data.assignments.length} memories</>}\n\t\t\t\t\t</h4>\n\t\t\t\t\t{drill.error ? (\n\t\t\t\t\t\t<div className=\"tab-stub\">\n\t\t\t\t\t\t\tError: {(drill.error as Error).message}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : drill.loading && !drill.data ? (\n\t\t\t\t\t\t<div className=\"tab-stub\">Loading memories…</div>\n\t\t\t\t\t) : drill.data ? (\n\t\t\t\t\t\t<table className=\"data-table\">\n\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t<th>Memory id</th>\n\t\t\t\t\t\t\t\t\t<th>Confidence</th>\n\t\t\t\t\t\t\t\t\t<th>Assigned</th>\n\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t{drill.data.assignments.map((a) => (\n\t\t\t\t\t\t\t\t\t<tr key={a.memoryId}>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t<code>{a.memoryId}</code>\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t{a.confidence != null ? a.confidence.toFixed(2) : \"—\"}\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td>{fmtTs(a.assignedAt)}</td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t</table>\n\t\t\t\t\t) : null}\n\t\t\t\t</section>\n\t\t\t)}\n\n\t\t\t{!drillTopicId && (\n\t\t\t\t<table className=\"data-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th>Label</th>\n\t\t\t\t\t\t\t<th>Memories</th>\n\t\t\t\t\t\t\t<th>Top Terms</th>\n\t\t\t\t\t\t\t<th></th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{filtered.map((t) => (\n\t\t\t\t\t\t\t<tr\n\t\t\t\t\t\t\t\tkey={t.id}\n\t\t\t\t\t\t\t\tclassName=\"topic-row\"\n\t\t\t\t\t\t\t\tonClick={() => setDrillTopicId(t.id)}\n\t\t\t\t\t\t\t\tstyle={{ cursor: \"pointer\" }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<td className=\"topic-label\">{t.label}</td>\n\t\t\t\t\t\t\t\t<td className=\"topic-count\">{t.memoryCount}</td>\n\t\t\t\t\t\t\t\t<td className=\"topic-terms\">\n\t\t\t\t\t\t\t\t\t{t.termScore\n\t\t\t\t\t\t\t\t\t\t.slice(0, 8)\n\t\t\t\t\t\t\t\t\t\t.map((s) => s.term)\n\t\t\t\t\t\t\t\t\t\t.join(\", \")}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t<button type=\"button\" className=\"mini-btn\">\n\t\t\t\t\t\t\t\t\t\tdrill\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t{filtered.length === 0 && (\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td colSpan={4} className=\"muted\">\n\t\t\t\t\t\t\t\t\tNo topics match “{query}”.\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n"],"names":["fmtTs","ms","TopicsTab","data","loading","error","useApi","useCallback","fetchTopics","query","setQuery","useState","drillTopicId","setDrillTopicId","drill","fetchTopicMemories","filtered","useMemo","q","t","s","jsxs","jsx","Fragment","e","a"],"mappings":"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"}
|
package/extensions/dashboard-client/dist/assets/{TurnsTab-DLRg0LZT.js → TurnsTab-Cf5mGIdl.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{u as f,r,
|
|
2
|
-
//# sourceMappingURL=TurnsTab-
|
|
1
|
+
import{u as f,r,t as C,v as w,w as I,x as T,y as $,j as e}from"./index-4gQ7auad.js";function j(n){return n?new Date(n).toLocaleString():"—"}function E(n){return n==="green"?"band band-green":n==="yellow"?"band band-yellow":n==="red"?"band band-red":"band"}function L(n){return n==="checkpoint"?"ckpt":n==="cluster_summary"?"raptor":"mem"}function S(){const{data:n,loading:i,error:d}=f(r.useCallback(()=>C(),[]),{pollInterval:1e4}),{data:c}=f(r.useCallback(()=>w(),[]),{pollInterval:5e3}),[s,l]=r.useState(null),[m,x]=r.useState(null),[v,p]=r.useState(!1),[N,u]=r.useState(null),[b,o]=r.useState(null),g=r.useCallback(async t=>{if(s===t){l(null),x(null);return}l(t),p(!0),x(null);try{const a=await I(t);x(a)}finally{p(!1)}},[s]),y=r.useCallback(async(t,a)=>{u(`fork:${t}:${a}`),o(null);try{const h=await T(t,a);o(`Forked → ${h.childConversationId} (${h.recalledCount} recalled)`)}catch(h){o(`Fork failed: ${h.message}`)}finally{u(null)}},[]),k=r.useCallback(async(t,a)=>{u(`rewind:${t}:${a}`),o(null);try{await $(t,a),o(`Rewind intent queued for turn ${a}`)}catch(h){o(`Rewind failed: ${h.message}`)}finally{u(null)}},[]);return d&&!n?e.jsxs("div",{className:"tab-stub",children:["Error loading turns: ",d.message]}):i&&!n?e.jsx("div",{className:"tab-stub",children:"Loading turns…"}):!n||n.conversations.length===0?e.jsxs("div",{className:"tab-stub",children:[e.jsx("h3",{children:"Turn-by-turn memory"}),e.jsxs("p",{children:["No turns recorded yet. Per-turn tracking starts when"," ",e.jsx("code",{children:"MEGACOMPACT_TURNS_DB=1"})," and the session runs through a compaction. Each turn records its context metrics + the checkpoints recalled into it."]})]}):e.jsxs("div",{className:"turns-tab",children:[e.jsx("h3",{children:"Turn-by-turn memory tracking + recall"}),b&&e.jsx("div",{className:"turns-notice",children:b}),c&&c.intents.length>0&&e.jsxs("section",{className:"turns-intents",children:[e.jsxs("h4",{children:["Pending rewind intents (",c.intents.length,")"]}),e.jsx("ul",{children:c.intents.map(t=>e.jsxs("li",{children:[j(t.createdAt)," — rewind ",e.jsx("code",{children:t.conversationId})," to turn ",t.targetTurnIndex]},t.id))})]}),e.jsxs("section",{className:"turns-conv-list",children:[e.jsxs("h4",{children:["Conversations (",n.conversations.length,")"]}),e.jsxs("table",{className:"turns-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"Conversation"}),e.jsx("th",{children:"Turns"}),e.jsx("th",{children:"Recall"}),e.jsx("th",{children:"Epochs"}),e.jsx("th",{children:"Avg ctx%"}),e.jsx("th",{children:"Last turn"}),e.jsx("th",{})]})}),e.jsx("tbody",{children:n.conversations.map(t=>e.jsx(R,{c:t,active:n.activeConversationId===t.conversationId,expanded:s===t.conversationId,onExpand:()=>g(t.conversationId)},t.conversationId))})]})]}),s&&e.jsxs("section",{className:"turns-detail",children:[e.jsxs("h4",{children:["Turns in ",e.jsx("code",{children:s})]}),v?e.jsx("div",{className:"tab-stub",children:"Loading turns…"}):m?e.jsx(A,{detail:m,busy:N,onFork:y,onRewind:k}):e.jsx("div",{className:"tab-stub",children:"No detail."})]})]})}function R({c:n,active:i,expanded:d,onExpand:c}){return e.jsx(e.Fragment,{children:e.jsxs("tr",{className:i?"turns-row active":"turns-row",onClick:c,style:{cursor:"pointer"},children:[e.jsxs("td",{children:[d?"▾":"▸"," ",e.jsx("code",{children:n.conversationId}),i&&e.jsx("span",{className:"pill",children:"active"})]}),e.jsx("td",{children:n.turnCount}),e.jsx("td",{children:n.totalRecall}),e.jsx("td",{children:n.epochCount}),e.jsxs("td",{children:[(n.avgCtxPercent*100).toFixed(0),"%"]}),e.jsx("td",{children:j(n.lastTurnAt)}),e.jsx("td",{})]})})}function A({detail:n,busy:i,onFork:d,onRewind:c}){return e.jsxs("table",{className:"turns-detail-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:"#"}),e.jsx("th",{children:"Role"}),e.jsx("th",{children:"Ctx"}),e.jsx("th",{children:"Band"}),e.jsx("th",{children:"Epoch"}),e.jsx("th",{children:"Recalled checkpoints (memory recall)"}),e.jsx("th",{children:"Ended"}),e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:n.turns.map(s=>e.jsxs("tr",{children:[e.jsx("td",{children:s.turnIndex}),e.jsx("td",{children:s.role}),e.jsxs("td",{children:[s.ctxTokens??"—",s.ctxPercent!=null&&e.jsxs("span",{className:"muted",children:[" ","· ",(s.ctxPercent*100).toFixed(0),"%"]})]}),e.jsx("td",{children:e.jsx("span",{className:E(s.pressureBand),children:s.pressureBand??"—"})}),e.jsx("td",{children:s.epochId?e.jsx("code",{children:s.epochId.slice(0,8)}):"—"}),e.jsx("td",{className:"recall-cell",children:s.recall.length===0?e.jsx("span",{className:"muted",children:"—"}):e.jsx("ul",{className:"recall-list",children:s.recall.map(l=>e.jsxs("li",{children:[e.jsx("code",{children:l.checkpointId.slice(0,12)})," ",e.jsxs("span",{className:"muted",children:[L(l.source)," · ",l.score.toFixed(2),l.raptorLevel!=null?` · L${l.raptorLevel}`:""]})]},l.checkpointId))})}),e.jsx("td",{children:j(s.endedAt)}),e.jsxs("td",{className:"actions-cell",children:[e.jsx("button",{type:"button",className:"mini-btn",disabled:i!==null,onClick:()=>d(s.conversationId,s.turnIndex),children:"fork"}),e.jsx("button",{type:"button",className:"mini-btn",disabled:i!==null,onClick:()=>c(s.conversationId,s.turnIndex),children:"rewind"})]})]},`${s.conversationId}:${s.turnIndex}`))})]})}export{S as default};
|
|
2
|
+
//# sourceMappingURL=TurnsTab-Cf5mGIdl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TurnsTab-DLRg0LZT.js","sources":["../../src/tabs/TurnsTab.tsx"],"sourcesContent":["/**\n * dashboard-client/src/tabs/TurnsTab.tsx — Turn-by-turn memory tracking + recall (S52).\n *\n * Fetches /api/turns (conversation list), expands the active conversation into\n * per-turn detail (/api/turns/conversation/:id), and renders:\n * - Conversation summary list (turn count, recall total, epochs, last turn).\n * - Per-turn rows: turn index, role, ctx tokens/percent + pressure band,\n * epoch id, and the injected-checkpoint recall set (the memory recalled\n * at each turn, with score + source).\n * - Pending rewind intents (S52A) + Fork action (S50C primitive).\n *\n * Read-mostly via /api/turns; fork/intent/prune via POST. No absolute URLs\n * (PREVENT-PI-004: loopback-only, same-origin static bundle).\n */\n\nimport type React from \"react\";\nimport { useCallback, useState } from \"react\";\nimport { useApi } from \"../hooks/useApi\";\nimport {\n\tfetchTurns,\n\tfetchConversationTurns,\n\tfetchTurnIntents,\n\tpostFork,\n\tpostTurnIntent,\n} from \"../api/client\";\nimport type {\n\tTurnsResponse,\n\tConversationTurnsResponse,\n\tRewindIntentsResponse,\n\tTurnRow,\n\tConversationSummary,\n} from \"@contracts\";\n\nfunction fmtTs(ms: number): string {\n\tif (!ms) return \"—\";\n\treturn new Date(ms).toLocaleString();\n}\n\nfunction bandClass(band: TurnRow[\"pressureBand\"]): string {\n\tif (band === \"green\") return \"band band-green\";\n\tif (band === \"yellow\") return \"band band-yellow\";\n\tif (band === \"red\") return \"band band-red\";\n\treturn \"band\";\n}\n\nfunction sourceLabel(s: TurnRow[\"recall\"][number][\"source\"]): string {\n\tif (s === \"checkpoint\") return \"ckpt\";\n\tif (s === \"cluster_summary\") return \"raptor\";\n\treturn \"mem\";\n}\n\nexport default function TurnsTab(): React.ReactElement {\n\tconst {\n\t\tdata: turns,\n\t\tloading,\n\t\terror,\n\t} = useApi<TurnsResponse>(\n\t\tuseCallback(() => fetchTurns(), []),\n\t\t{\n\t\t\tpollInterval: 10_000,\n\t\t},\n\t);\n\tconst { data: intents } = useApi<RewindIntentsResponse>(\n\t\tuseCallback(() => fetchTurnIntents(), []),\n\t\t{ pollInterval: 5_000 },\n\t);\n\tconst [expanded, setExpanded] = useState<string | null>(null);\n\tconst [detail, setDetail] = useState<ConversationTurnsResponse | null>(null);\n\tconst [detailLoading, setDetailLoading] = useState(false);\n\tconst [busy, setBusy] = useState<string | null>(null);\n\tconst [notice, setNotice] = useState<string | null>(null);\n\n\tconst expand = useCallback(\n\t\tasync (conversationId: string) => {\n\t\t\tif (expanded === conversationId) {\n\t\t\t\tsetExpanded(null);\n\t\t\t\tsetDetail(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetExpanded(conversationId);\n\t\t\tsetDetailLoading(true);\n\t\t\tsetDetail(null);\n\t\t\ttry {\n\t\t\t\tconst d = await fetchConversationTurns(conversationId);\n\t\t\t\tsetDetail(d);\n\t\t\t} finally {\n\t\t\t\tsetDetailLoading(false);\n\t\t\t}\n\t\t},\n\t\t[expanded],\n\t);\n\n\tconst onFork = useCallback(\n\t\tasync (conversationId: string, turnIndex: number) => {\n\t\t\tsetBusy(`fork:${conversationId}:${turnIndex}`);\n\t\t\tsetNotice(null);\n\t\t\ttry {\n\t\t\t\tconst out = await postFork(conversationId, turnIndex);\n\t\t\t\tsetNotice(\n\t\t\t\t\t`Forked → ${out.childConversationId} (${out.recalledCount} recalled)`,\n\t\t\t\t);\n\t\t\t} catch (e) {\n\t\t\t\tsetNotice(`Fork failed: ${(e as Error).message}`);\n\t\t\t} finally {\n\t\t\t\tsetBusy(null);\n\t\t\t}\n\t\t},\n\t\t[],\n\t);\n\n\tconst onRewind = useCallback(\n\t\tasync (conversationId: string, turnIndex: number) => {\n\t\t\tsetBusy(`rewind:${conversationId}:${turnIndex}`);\n\t\t\tsetNotice(null);\n\t\t\ttry {\n\t\t\t\tawait postTurnIntent(conversationId, turnIndex);\n\t\t\t\tsetNotice(`Rewind intent queued for turn ${turnIndex}`);\n\t\t\t} catch (e) {\n\t\t\t\tsetNotice(`Rewind failed: ${(e as Error).message}`);\n\t\t\t} finally {\n\t\t\t\tsetBusy(null);\n\t\t\t}\n\t\t},\n\t\t[],\n\t);\n\n\tif (error && !turns) {\n\t\treturn <div className=\"tab-stub\">Error loading turns: {error.message}</div>;\n\t}\n\tif (loading && !turns) {\n\t\treturn <div className=\"tab-stub\">Loading turns…</div>;\n\t}\n\tif (!turns || turns.conversations.length === 0) {\n\t\treturn (\n\t\t\t<div className=\"tab-stub\">\n\t\t\t\t<h3>Turn-by-turn memory</h3>\n\t\t\t\t<p>\n\t\t\t\t\tNo turns recorded yet. Per-turn tracking starts when{\" \"}\n\t\t\t\t\t<code>MEGACOMPACT_TURNS_DB=1</code> and the session runs through a\n\t\t\t\t\tcompaction. Each turn records its context metrics + the checkpoints\n\t\t\t\t\trecalled into it.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"turns-tab\">\n\t\t\t<h3>Turn-by-turn memory tracking + recall</h3>\n\t\t\t{notice && <div className=\"turns-notice\">{notice}</div>}\n\n\t\t\t{intents && intents.intents.length > 0 && (\n\t\t\t\t<section className=\"turns-intents\">\n\t\t\t\t\t<h4>Pending rewind intents ({intents.intents.length})</h4>\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t{intents.intents.map((i) => (\n\t\t\t\t\t\t\t<li key={i.id}>\n\t\t\t\t\t\t\t\t{fmtTs(i.createdAt)} — rewind <code>{i.conversationId}</code> to\n\t\t\t\t\t\t\t\tturn {i.targetTurnIndex}\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</section>\n\t\t\t)}\n\n\t\t\t<section className=\"turns-conv-list\">\n\t\t\t\t<h4>Conversations ({turns.conversations.length})</h4>\n\t\t\t\t<table className=\"turns-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th>Conversation</th>\n\t\t\t\t\t\t\t<th>Turns</th>\n\t\t\t\t\t\t\t<th>Recall</th>\n\t\t\t\t\t\t\t<th>Epochs</th>\n\t\t\t\t\t\t\t<th>Avg ctx%</th>\n\t\t\t\t\t\t\t<th>Last turn</th>\n\t\t\t\t\t\t\t<th></th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{turns.conversations.map((c: ConversationSummary) => (\n\t\t\t\t\t\t\t<ConversationRow\n\t\t\t\t\t\t\t\tkey={c.conversationId}\n\t\t\t\t\t\t\t\tc={c}\n\t\t\t\t\t\t\t\tactive={turns.activeConversationId === c.conversationId}\n\t\t\t\t\t\t\t\texpanded={expanded === c.conversationId}\n\t\t\t\t\t\t\t\tonExpand={() => expand(c.conversationId)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t</section>\n\n\t\t\t{expanded && (\n\t\t\t\t<section className=\"turns-detail\">\n\t\t\t\t\t<h4>\n\t\t\t\t\t\tTurns in <code>{expanded}</code>\n\t\t\t\t\t</h4>\n\t\t\t\t\t{detailLoading ? (\n\t\t\t\t\t\t<div className=\"tab-stub\">Loading turns…</div>\n\t\t\t\t\t) : detail ? (\n\t\t\t\t\t\t<TurnDetail\n\t\t\t\t\t\t\tdetail={detail}\n\t\t\t\t\t\t\tbusy={busy}\n\t\t\t\t\t\t\tonFork={onFork}\n\t\t\t\t\t\t\tonRewind={onRewind}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<div className=\"tab-stub\">No detail.</div>\n\t\t\t\t\t)}\n\t\t\t\t</section>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nfunction ConversationRow({\n\tc,\n\tactive,\n\texpanded,\n\tonExpand,\n}: {\n\tc: ConversationSummary;\n\tactive: boolean;\n\texpanded: boolean;\n\tonExpand: () => void;\n}): React.ReactElement {\n\treturn (\n\t\t<>\n\t\t\t<tr\n\t\t\t\tclassName={active ? \"turns-row active\" : \"turns-row\"}\n\t\t\t\tonClick={onExpand}\n\t\t\t\tstyle={{ cursor: \"pointer\" }}\n\t\t\t>\n\t\t\t\t<td>\n\t\t\t\t\t{expanded ? \"▾\" : \"▸\"} <code>{c.conversationId}</code>\n\t\t\t\t\t{active && <span className=\"pill\">active</span>}\n\t\t\t\t</td>\n\t\t\t\t<td>{c.turnCount}</td>\n\t\t\t\t<td>{c.totalRecall}</td>\n\t\t\t\t<td>{c.epochCount}</td>\n\t\t\t\t<td>{(c.avgCtxPercent * 100).toFixed(0)}%</td>\n\t\t\t\t<td>{fmtTs(c.lastTurnAt)}</td>\n\t\t\t\t<td />\n\t\t\t</tr>\n\t\t</>\n\t);\n}\n\nfunction TurnDetail({\n\tdetail,\n\tbusy,\n\tonFork,\n\tonRewind,\n}: {\n\tdetail: ConversationTurnsResponse;\n\tbusy: string | null;\n\tonFork: (conversationId: string, turnIndex: number) => void;\n\tonRewind: (conversationId: string, turnIndex: number) => void;\n}): React.ReactElement {\n\treturn (\n\t\t<table className=\"turns-detail-table\">\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\t<th>#</th>\n\t\t\t\t\t<th>Role</th>\n\t\t\t\t\t<th>Ctx</th>\n\t\t\t\t\t<th>Band</th>\n\t\t\t\t\t<th>Epoch</th>\n\t\t\t\t\t<th>Recalled checkpoints (memory recall)</th>\n\t\t\t\t\t<th>Ended</th>\n\t\t\t\t\t<th>Actions</th>\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t{detail.turns.map((t) => (\n\t\t\t\t\t<tr key={`${t.conversationId}:${t.turnIndex}`}>\n\t\t\t\t\t\t<td>{t.turnIndex}</td>\n\t\t\t\t\t\t<td>{t.role}</td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t{t.ctxTokens ?? \"—\"}\n\t\t\t\t\t\t\t{t.ctxPercent != null && (\n\t\t\t\t\t\t\t\t<span className=\"muted\">\n\t\t\t\t\t\t\t\t\t{\" \"}\n\t\t\t\t\t\t\t\t\t· {(t.ctxPercent * 100).toFixed(0)}%\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<span className={bandClass(t.pressureBand)}>\n\t\t\t\t\t\t\t\t{t.pressureBand ?? \"—\"}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td>{t.epochId ? <code>{t.epochId.slice(0, 8)}</code> : \"—\"}</td>\n\t\t\t\t\t\t<td className=\"recall-cell\">\n\t\t\t\t\t\t\t{t.recall.length === 0 ? (\n\t\t\t\t\t\t\t\t<span className=\"muted\">—</span>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<ul className=\"recall-list\">\n\t\t\t\t\t\t\t\t\t{t.recall.map((r) => (\n\t\t\t\t\t\t\t\t\t\t<li key={r.checkpointId}>\n\t\t\t\t\t\t\t\t\t\t\t<code>{r.checkpointId.slice(0, 12)}</code>{\" \"}\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"muted\">\n\t\t\t\t\t\t\t\t\t\t\t\t{sourceLabel(r.source)} · {r.score.toFixed(2)}\n\t\t\t\t\t\t\t\t\t\t\t\t{r.raptorLevel != null ? ` · L${r.raptorLevel}` : \"\"}\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td>{fmtTs(t.endedAt)}</td>\n\t\t\t\t\t\t<td className=\"actions-cell\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"mini-btn\"\n\t\t\t\t\t\t\t\tdisabled={busy !== null}\n\t\t\t\t\t\t\t\tonClick={() => onFork(t.conversationId, t.turnIndex)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tfork\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"mini-btn\"\n\t\t\t\t\t\t\t\tdisabled={busy !== null}\n\t\t\t\t\t\t\t\tonClick={() => onRewind(t.conversationId, t.turnIndex)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\trewind\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t))}\n\t\t\t</tbody>\n\t\t</table>\n\t);\n}\n"],"names":["fmtTs","ms","bandClass","band","sourceLabel","s","TurnsTab","turns","loading","error","useApi","useCallback","fetchTurns","intents","fetchTurnIntents","expanded","setExpanded","useState","detail","setDetail","detailLoading","setDetailLoading","busy","setBusy","notice","setNotice","expand","conversationId","d","fetchConversationTurns","onFork","turnIndex","out","postFork","e","onRewind","postTurnIntent","jsxs","jsx","i","c","ConversationRow","TurnDetail","active","onExpand","Fragment","t","r"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TurnsTab-Cf5mGIdl.js","sources":["../../src/tabs/TurnsTab.tsx"],"sourcesContent":["/**\n * dashboard-client/src/tabs/TurnsTab.tsx — Turn-by-turn memory tracking + recall (S52).\n *\n * Fetches /api/turns (conversation list), expands the active conversation into\n * per-turn detail (/api/turns/conversation/:id), and renders:\n * - Conversation summary list (turn count, recall total, epochs, last turn).\n * - Per-turn rows: turn index, role, ctx tokens/percent + pressure band,\n * epoch id, and the injected-checkpoint recall set (the memory recalled\n * at each turn, with score + source).\n * - Pending rewind intents (S52A) + Fork action (S50C primitive).\n *\n * Read-mostly via /api/turns; fork/intent/prune via POST. No absolute URLs\n * (PREVENT-PI-004: loopback-only, same-origin static bundle).\n */\n\nimport type React from \"react\";\nimport { useCallback, useState } from \"react\";\nimport { useApi } from \"../hooks/useApi\";\nimport {\n\tfetchTurns,\n\tfetchConversationTurns,\n\tfetchTurnIntents,\n\tpostFork,\n\tpostTurnIntent,\n} from \"../api/client\";\nimport type {\n\tTurnsResponse,\n\tConversationTurnsResponse,\n\tRewindIntentsResponse,\n\tTurnRow,\n\tConversationSummary,\n} from \"@contracts\";\n\nfunction fmtTs(ms: number): string {\n\tif (!ms) return \"—\";\n\treturn new Date(ms).toLocaleString();\n}\n\nfunction bandClass(band: TurnRow[\"pressureBand\"]): string {\n\tif (band === \"green\") return \"band band-green\";\n\tif (band === \"yellow\") return \"band band-yellow\";\n\tif (band === \"red\") return \"band band-red\";\n\treturn \"band\";\n}\n\nfunction sourceLabel(s: TurnRow[\"recall\"][number][\"source\"]): string {\n\tif (s === \"checkpoint\") return \"ckpt\";\n\tif (s === \"cluster_summary\") return \"raptor\";\n\treturn \"mem\";\n}\n\nexport default function TurnsTab(): React.ReactElement {\n\tconst {\n\t\tdata: turns,\n\t\tloading,\n\t\terror,\n\t} = useApi<TurnsResponse>(\n\t\tuseCallback(() => fetchTurns(), []),\n\t\t{\n\t\t\tpollInterval: 10_000,\n\t\t},\n\t);\n\tconst { data: intents } = useApi<RewindIntentsResponse>(\n\t\tuseCallback(() => fetchTurnIntents(), []),\n\t\t{ pollInterval: 5_000 },\n\t);\n\tconst [expanded, setExpanded] = useState<string | null>(null);\n\tconst [detail, setDetail] = useState<ConversationTurnsResponse | null>(null);\n\tconst [detailLoading, setDetailLoading] = useState(false);\n\tconst [busy, setBusy] = useState<string | null>(null);\n\tconst [notice, setNotice] = useState<string | null>(null);\n\n\tconst expand = useCallback(\n\t\tasync (conversationId: string) => {\n\t\t\tif (expanded === conversationId) {\n\t\t\t\tsetExpanded(null);\n\t\t\t\tsetDetail(null);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsetExpanded(conversationId);\n\t\t\tsetDetailLoading(true);\n\t\t\tsetDetail(null);\n\t\t\ttry {\n\t\t\t\tconst d = await fetchConversationTurns(conversationId);\n\t\t\t\tsetDetail(d);\n\t\t\t} finally {\n\t\t\t\tsetDetailLoading(false);\n\t\t\t}\n\t\t},\n\t\t[expanded],\n\t);\n\n\tconst onFork = useCallback(\n\t\tasync (conversationId: string, turnIndex: number) => {\n\t\t\tsetBusy(`fork:${conversationId}:${turnIndex}`);\n\t\t\tsetNotice(null);\n\t\t\ttry {\n\t\t\t\tconst out = await postFork(conversationId, turnIndex);\n\t\t\t\tsetNotice(\n\t\t\t\t\t`Forked → ${out.childConversationId} (${out.recalledCount} recalled)`,\n\t\t\t\t);\n\t\t\t} catch (e) {\n\t\t\t\tsetNotice(`Fork failed: ${(e as Error).message}`);\n\t\t\t} finally {\n\t\t\t\tsetBusy(null);\n\t\t\t}\n\t\t},\n\t\t[],\n\t);\n\n\tconst onRewind = useCallback(\n\t\tasync (conversationId: string, turnIndex: number) => {\n\t\t\tsetBusy(`rewind:${conversationId}:${turnIndex}`);\n\t\t\tsetNotice(null);\n\t\t\ttry {\n\t\t\t\tawait postTurnIntent(conversationId, turnIndex);\n\t\t\t\tsetNotice(`Rewind intent queued for turn ${turnIndex}`);\n\t\t\t} catch (e) {\n\t\t\t\tsetNotice(`Rewind failed: ${(e as Error).message}`);\n\t\t\t} finally {\n\t\t\t\tsetBusy(null);\n\t\t\t}\n\t\t},\n\t\t[],\n\t);\n\n\tif (error && !turns) {\n\t\treturn <div className=\"tab-stub\">Error loading turns: {error.message}</div>;\n\t}\n\tif (loading && !turns) {\n\t\treturn <div className=\"tab-stub\">Loading turns…</div>;\n\t}\n\tif (!turns || turns.conversations.length === 0) {\n\t\treturn (\n\t\t\t<div className=\"tab-stub\">\n\t\t\t\t<h3>Turn-by-turn memory</h3>\n\t\t\t\t<p>\n\t\t\t\t\tNo turns recorded yet. Per-turn tracking starts when{\" \"}\n\t\t\t\t\t<code>MEGACOMPACT_TURNS_DB=1</code> and the session runs through a\n\t\t\t\t\tcompaction. Each turn records its context metrics + the checkpoints\n\t\t\t\t\trecalled into it.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t);\n\t}\n\n\treturn (\n\t\t<div className=\"turns-tab\">\n\t\t\t<h3>Turn-by-turn memory tracking + recall</h3>\n\t\t\t{notice && <div className=\"turns-notice\">{notice}</div>}\n\n\t\t\t{intents && intents.intents.length > 0 && (\n\t\t\t\t<section className=\"turns-intents\">\n\t\t\t\t\t<h4>Pending rewind intents ({intents.intents.length})</h4>\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t{intents.intents.map((i) => (\n\t\t\t\t\t\t\t<li key={i.id}>\n\t\t\t\t\t\t\t\t{fmtTs(i.createdAt)} — rewind <code>{i.conversationId}</code> to\n\t\t\t\t\t\t\t\tturn {i.targetTurnIndex}\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</section>\n\t\t\t)}\n\n\t\t\t<section className=\"turns-conv-list\">\n\t\t\t\t<h4>Conversations ({turns.conversations.length})</h4>\n\t\t\t\t<table className=\"turns-table\">\n\t\t\t\t\t<thead>\n\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t<th>Conversation</th>\n\t\t\t\t\t\t\t<th>Turns</th>\n\t\t\t\t\t\t\t<th>Recall</th>\n\t\t\t\t\t\t\t<th>Epochs</th>\n\t\t\t\t\t\t\t<th>Avg ctx%</th>\n\t\t\t\t\t\t\t<th>Last turn</th>\n\t\t\t\t\t\t\t<th></th>\n\t\t\t\t\t\t</tr>\n\t\t\t\t\t</thead>\n\t\t\t\t\t<tbody>\n\t\t\t\t\t\t{turns.conversations.map((c: ConversationSummary) => (\n\t\t\t\t\t\t\t<ConversationRow\n\t\t\t\t\t\t\t\tkey={c.conversationId}\n\t\t\t\t\t\t\t\tc={c}\n\t\t\t\t\t\t\t\tactive={turns.activeConversationId === c.conversationId}\n\t\t\t\t\t\t\t\texpanded={expanded === c.conversationId}\n\t\t\t\t\t\t\t\tonExpand={() => expand(c.conversationId)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</tbody>\n\t\t\t\t</table>\n\t\t\t</section>\n\n\t\t\t{expanded && (\n\t\t\t\t<section className=\"turns-detail\">\n\t\t\t\t\t<h4>\n\t\t\t\t\t\tTurns in <code>{expanded}</code>\n\t\t\t\t\t</h4>\n\t\t\t\t\t{detailLoading ? (\n\t\t\t\t\t\t<div className=\"tab-stub\">Loading turns…</div>\n\t\t\t\t\t) : detail ? (\n\t\t\t\t\t\t<TurnDetail\n\t\t\t\t\t\t\tdetail={detail}\n\t\t\t\t\t\t\tbusy={busy}\n\t\t\t\t\t\t\tonFork={onFork}\n\t\t\t\t\t\t\tonRewind={onRewind}\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<div className=\"tab-stub\">No detail.</div>\n\t\t\t\t\t)}\n\t\t\t\t</section>\n\t\t\t)}\n\t\t</div>\n\t);\n}\n\nfunction ConversationRow({\n\tc,\n\tactive,\n\texpanded,\n\tonExpand,\n}: {\n\tc: ConversationSummary;\n\tactive: boolean;\n\texpanded: boolean;\n\tonExpand: () => void;\n}): React.ReactElement {\n\treturn (\n\t\t<>\n\t\t\t<tr\n\t\t\t\tclassName={active ? \"turns-row active\" : \"turns-row\"}\n\t\t\t\tonClick={onExpand}\n\t\t\t\tstyle={{ cursor: \"pointer\" }}\n\t\t\t>\n\t\t\t\t<td>\n\t\t\t\t\t{expanded ? \"▾\" : \"▸\"} <code>{c.conversationId}</code>\n\t\t\t\t\t{active && <span className=\"pill\">active</span>}\n\t\t\t\t</td>\n\t\t\t\t<td>{c.turnCount}</td>\n\t\t\t\t<td>{c.totalRecall}</td>\n\t\t\t\t<td>{c.epochCount}</td>\n\t\t\t\t<td>{(c.avgCtxPercent * 100).toFixed(0)}%</td>\n\t\t\t\t<td>{fmtTs(c.lastTurnAt)}</td>\n\t\t\t\t<td />\n\t\t\t</tr>\n\t\t</>\n\t);\n}\n\nfunction TurnDetail({\n\tdetail,\n\tbusy,\n\tonFork,\n\tonRewind,\n}: {\n\tdetail: ConversationTurnsResponse;\n\tbusy: string | null;\n\tonFork: (conversationId: string, turnIndex: number) => void;\n\tonRewind: (conversationId: string, turnIndex: number) => void;\n}): React.ReactElement {\n\treturn (\n\t\t<table className=\"turns-detail-table\">\n\t\t\t<thead>\n\t\t\t\t<tr>\n\t\t\t\t\t<th>#</th>\n\t\t\t\t\t<th>Role</th>\n\t\t\t\t\t<th>Ctx</th>\n\t\t\t\t\t<th>Band</th>\n\t\t\t\t\t<th>Epoch</th>\n\t\t\t\t\t<th>Recalled checkpoints (memory recall)</th>\n\t\t\t\t\t<th>Ended</th>\n\t\t\t\t\t<th>Actions</th>\n\t\t\t\t</tr>\n\t\t\t</thead>\n\t\t\t<tbody>\n\t\t\t\t{detail.turns.map((t) => (\n\t\t\t\t\t<tr key={`${t.conversationId}:${t.turnIndex}`}>\n\t\t\t\t\t\t<td>{t.turnIndex}</td>\n\t\t\t\t\t\t<td>{t.role}</td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t{t.ctxTokens ?? \"—\"}\n\t\t\t\t\t\t\t{t.ctxPercent != null && (\n\t\t\t\t\t\t\t\t<span className=\"muted\">\n\t\t\t\t\t\t\t\t\t{\" \"}\n\t\t\t\t\t\t\t\t\t· {(t.ctxPercent * 100).toFixed(0)}%\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t<span className={bandClass(t.pressureBand)}>\n\t\t\t\t\t\t\t\t{t.pressureBand ?? \"—\"}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td>{t.epochId ? <code>{t.epochId.slice(0, 8)}</code> : \"—\"}</td>\n\t\t\t\t\t\t<td className=\"recall-cell\">\n\t\t\t\t\t\t\t{t.recall.length === 0 ? (\n\t\t\t\t\t\t\t\t<span className=\"muted\">—</span>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<ul className=\"recall-list\">\n\t\t\t\t\t\t\t\t\t{t.recall.map((r) => (\n\t\t\t\t\t\t\t\t\t\t<li key={r.checkpointId}>\n\t\t\t\t\t\t\t\t\t\t\t<code>{r.checkpointId.slice(0, 12)}</code>{\" \"}\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"muted\">\n\t\t\t\t\t\t\t\t\t\t\t\t{sourceLabel(r.source)} · {r.score.toFixed(2)}\n\t\t\t\t\t\t\t\t\t\t\t\t{r.raptorLevel != null ? ` · L${r.raptorLevel}` : \"\"}\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t</ul>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t\t<td>{fmtTs(t.endedAt)}</td>\n\t\t\t\t\t\t<td className=\"actions-cell\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"mini-btn\"\n\t\t\t\t\t\t\t\tdisabled={busy !== null}\n\t\t\t\t\t\t\t\tonClick={() => onFork(t.conversationId, t.turnIndex)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tfork\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclassName=\"mini-btn\"\n\t\t\t\t\t\t\t\tdisabled={busy !== null}\n\t\t\t\t\t\t\t\tonClick={() => onRewind(t.conversationId, t.turnIndex)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\trewind\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</td>\n\t\t\t\t\t</tr>\n\t\t\t\t))}\n\t\t\t</tbody>\n\t\t</table>\n\t);\n}\n"],"names":["fmtTs","ms","bandClass","band","sourceLabel","s","TurnsTab","turns","loading","error","useApi","useCallback","fetchTurns","intents","fetchTurnIntents","expanded","setExpanded","useState","detail","setDetail","detailLoading","setDetailLoading","busy","setBusy","notice","setNotice","expand","conversationId","d","fetchConversationTurns","onFork","turnIndex","out","postFork","e","onRewind","postTurnIntent","jsxs","jsx","i","c","ConversationRow","TurnDetail","active","onExpand","Fragment","t","r"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function u(t){const n=t??0;return n>=1048576?`${(n/1048576).toFixed(1)} MiB`:n>=1024?`${(n/1024).toFixed(1)} KiB`:`${n} B`}function f(t){const n=t??0;return n>=3600?`${(n/3600).toFixed(1)}h`:n>=60?`${Math.round(n/60)}m`:n>=1?`${n.toFixed(1)}s`:`${Math.round(n*1e3)}ms`}function a(t){const r=(t??0)*100;return r>=10?`${Math.round(r)}%`:`${r.toFixed(1)}%`}function c(t){if(!t)return"—";try{return new Date(t).toLocaleString()}catch{return"—"}}function s(t){return t==null?"—":t>=1e6?`${(t/1e6).toFixed(1)}M`:t>=1e3?`${Math.round(t/1e3)}K`:t.toLocaleString()}function m(t){return t==null?"—":`$${t.toFixed(4)}`}function $(t){if(!t)return"—";let n;try{if(n=new Date(t),isNaN(n.getTime()))return"—"}catch{return"—"}const r=Date.now()-n.getTime();if(r<0)return"just now";const o=Math.floor(r/1e3);if(o<60)return"just now";const e=Math.floor(o/60);if(e<60)return`${e}m ago`;const i=Math.floor(e/60);return i<24?`${i}h ago`:n.toLocaleDateString()}export{u as a,s as b,m as c,c as d,$ as e,a as f,f as g};
|
|
2
|
+
//# sourceMappingURL=format-COjDIVGj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-COjDIVGj.js","sources":["../../src/utils/format.ts"],"sourcesContent":["/**\n * dashboard-client/src/utils/format.ts — shared formatting helpers.\n *\n * Mirrors the format functions from the old static dashboard (html.ts)\n * so the React rewrite shows identical values.\n */\n\n/** Format bytes as KiB/MiB/B (matches html.ts fmtBytes). */\nexport function fmtBytes(b: number | null | undefined): string {\n\tconst n = b ?? 0;\n\tif (n >= 1_048_576) return `${(n / 1_048_576).toFixed(1)} MiB`;\n\tif (n >= 1024) return `${(n / 1024).toFixed(1)} KiB`;\n\treturn `${n} B`;\n}\n\n/** Format seconds as h/m/s/ms (matches html.ts fmtSec). */\nexport function fmtSec(s: number | null | undefined): string {\n\tconst n = s ?? 0;\n\tif (n >= 3600) return `${(n / 3600).toFixed(1)}h`;\n\tif (n >= 60) return `${Math.round(n / 60)}m`;\n\tif (n >= 1) return `${n.toFixed(1)}s`;\n\treturn `${Math.round(n * 1000)}ms`;\n}\n\n/**\n * Display a 0–1 fraction as a percentage string.\n * Uses one decimal place below 10%, rounded above (matches html.ts pct logic).\n */\nexport function fmtPctFromFraction(v: number | null | undefined): string {\n\tconst n = v ?? 0;\n\tconst pct = n * 100;\n\tif (pct >= 10) return `${Math.round(pct)}%`;\n\treturn `${pct.toFixed(1)}%`;\n}\n\n/** Round a 0–1 fraction to a one-decimal percentage (for trophy values). */\nexport function fmtPct(v: number | null | undefined): string {\n\tconst n = v ?? 0;\n\treturn `${Math.round(n * 10) / 10}%`;\n}\n\n/** Format milliseconds (matches html.ts fmtMs). */\nexport function fmtMs(v: number | null | undefined): string {\n\tif (v == null) return \"\\u2014\";\n\treturn v >= 100 ? `${Math.round(v)}ms` : `${v.toFixed(1)}ms`;\n}\n\n/** Format a number with fixed decimals or em-dash for null (matches fmtNum). */\nexport function fmtNum(v: number | null | undefined, dec: number): string {\n\tif (v == null || typeof v !== \"number\") return \"\\u2014\";\n\treturn v.toFixed(dec);\n}\n\n/** Collapse an array of numbers into a range string or single value. */\nexport function collapseNum(samples: number[]): string {\n\tif (samples.length === 0) return \"\\u2014\";\n\tconst lo = Math.min(...samples);\n\tconst hi = Math.max(...samples);\n\tif (lo === hi) return lo.toLocaleString();\n\treturn `${lo.toLocaleString()}\\u2013${hi.toLocaleString()}`;\n}\n\n/** Collapse an array of rates into a range string or single value. */\nexport function collapseRate(samples: number[]): string {\n\tif (samples.length === 0) return \"\\u2014\";\n\tconst lo = Math.min(...samples);\n\tconst hi = Math.max(...samples);\n\tif (lo === hi) return `$${lo.toFixed(6)}`;\n\treturn `$${lo.toFixed(6)}\\u2013$${hi.toFixed(6)}`;\n}\n\n/** Format a date string or null as locale string or em-dash. */\nexport function fmtDate(ts: string | number | null | undefined): string {\n\tif (!ts) return \"\\u2014\";\n\ttry {\n\t\treturn new Date(ts).toLocaleString();\n\t} catch {\n\t\treturn \"\\u2014\";\n\t}\n}\n\n/** Format tokens as human-readable (1.2M / 340K / 890 / —). */\nexport function fmtTokens(v: number | null | undefined): string {\n\tif (v == null) return \"\\u2014\";\n\tif (v >= 1_000_000) return `${(v / 1_000_000).toFixed(1)}M`;\n\tif (v >= 1_000) return `${Math.round(v / 1000)}K`;\n\treturn v.toLocaleString();\n}\n\n/** Format USD savings (always 4 decimals, null → em-dash). */\nexport function fmtDollars(v: number | null | undefined): string {\n\tif (v == null) return \"\\u2014\";\n\treturn `$${v.toFixed(4)}`;\n}\n\n/**\n * Format an ISO timestamp as relative time (\"2m ago\", \"3h ago\", \"just now\").\n * Falls back to locale date for times >24h or unparseable input.\n */\nexport function fmtRelativeTime(\n\tts: string | number | null | undefined,\n): string {\n\tif (!ts) return \"\\u2014\";\n\tlet date: Date;\n\ttry {\n\t\tdate = new Date(ts);\n\t\tif (isNaN(date.getTime())) return \"\\u2014\";\n\t} catch {\n\t\treturn \"\\u2014\";\n\t}\n\tconst diffMs = Date.now() - date.getTime();\n\tif (diffMs < 0) return \"just now\";\n\tconst sec = Math.floor(diffMs / 1000);\n\tif (sec < 60) return \"just now\";\n\tconst min = Math.floor(sec / 60);\n\tif (min < 60) return `${min}m ago`;\n\tconst hrs = Math.floor(min / 60);\n\tif (hrs < 24) return `${hrs}h ago`;\n\treturn date.toLocaleDateString();\n}\n"],"names":["fmtBytes","b","fmtSec","s","fmtPctFromFraction","v","pct","fmtDate","ts","fmtTokens","fmtDollars","fmtRelativeTime","date","diffMs","sec","min","hrs"],"mappings":"AAQO,SAASA,EAASC,EAAsC,CAC9D,MAAM,EAAIA,GAAK,EACf,OAAI,GAAK,QAAkB,IAAI,EAAI,SAAW,QAAQ,CAAC,CAAC,OACpD,GAAK,KAAa,IAAI,EAAI,MAAM,QAAQ,CAAC,CAAC,OACvC,GAAG,CAAC,IACZ,CAGO,SAASC,EAAOC,EAAsC,CAC5D,MAAM,EAAIA,GAAK,EACf,OAAI,GAAK,KAAa,IAAI,EAAI,MAAM,QAAQ,CAAC,CAAC,IAC1C,GAAK,GAAW,GAAG,KAAK,MAAM,EAAI,EAAE,CAAC,IACrC,GAAK,EAAU,GAAG,EAAE,QAAQ,CAAC,CAAC,IAC3B,GAAG,KAAK,MAAM,EAAI,GAAI,CAAC,IAC/B,CAMO,SAASC,EAAmBC,EAAsC,CAExE,MAAMC,GADID,GAAK,GACC,IAChB,OAAIC,GAAO,GAAW,GAAG,KAAK,MAAMA,CAAG,CAAC,IACjC,GAAGA,EAAI,QAAQ,CAAC,CAAC,GACzB,CAuCO,SAASC,EAAQC,EAAgD,CACvE,GAAI,CAACA,EAAI,MAAO,IAChB,GAAI,CACH,OAAO,IAAI,KAAKA,CAAE,EAAE,eAAA,CACrB,MAAQ,CACP,MAAO,GACR,CACD,CAGO,SAASC,EAAUJ,EAAsC,CAC/D,OAAIA,GAAK,KAAa,IAClBA,GAAK,IAAkB,IAAIA,EAAI,KAAW,QAAQ,CAAC,CAAC,IACpDA,GAAK,IAAc,GAAG,KAAK,MAAMA,EAAI,GAAI,CAAC,IACvCA,EAAE,eAAA,CACV,CAGO,SAASK,EAAWL,EAAsC,CAChE,OAAIA,GAAK,KAAa,IACf,IAAIA,EAAE,QAAQ,CAAC,CAAC,EACxB,CAMO,SAASM,EACfH,EACS,CACT,GAAI,CAACA,EAAI,MAAO,IAChB,IAAII,EACJ,GAAI,CAEH,GADAA,EAAO,IAAI,KAAKJ,CAAE,EACd,MAAMI,EAAK,QAAA,CAAS,EAAG,MAAO,GACnC,MAAQ,CACP,MAAO,GACR,CACA,MAAMC,EAAS,KAAK,IAAA,EAAQD,EAAK,QAAA,EACjC,GAAIC,EAAS,EAAG,MAAO,WACvB,MAAMC,EAAM,KAAK,MAAMD,EAAS,GAAI,EACpC,GAAIC,EAAM,GAAI,MAAO,WACrB,MAAMC,EAAM,KAAK,MAAMD,EAAM,EAAE,EAC/B,GAAIC,EAAM,GAAI,MAAO,GAAGA,CAAG,QAC3B,MAAMC,EAAM,KAAK,MAAMD,EAAM,EAAE,EAC/B,OAAIC,EAAM,GAAW,GAAGA,CAAG,QACpBJ,EAAK,mBAAA,CACb"}
|