@circuitwall/jarela 2.2.1 → 2.3.0
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +6 -5
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/routes-manifest.json +8 -0
- package/.next/standalone/.next/server/app/_global-error/page.js +68 -68
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js +76 -76
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +2 -2
- package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/v1/access/[identity]/route.js +93 -93
- package/.next/standalone/.next/server/app/api/v1/access/route.js +169 -169
- package/.next/standalone/.next/server/app/api/v1/agents/[id]/compact/route.js +82 -56
- package/.next/standalone/.next/server/app/api/v1/agents/[id]/compact/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/agents/[id]/display-filters/route.js +122 -122
- package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js +100 -100
- package/.next/standalone/.next/server/app/api/v1/agents/[id]/thread/route.js +753 -753
- package/.next/standalone/.next/server/app/api/v1/agents/route.js +65 -65
- package/.next/standalone/.next/server/app/api/v1/allowed-sites/[hostname]/route.js +364 -364
- package/.next/standalone/.next/server/app/api/v1/allowed-sites/route.js +802 -802
- package/.next/standalone/.next/server/app/api/v1/artifacts/lifecycle/route.js +2 -2
- package/.next/standalone/.next/server/app/api/v1/attachments/files/route.js +49 -49
- package/.next/standalone/.next/server/app/api/v1/attachments/images/route.js +910 -910
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js +589 -16
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/ignores/[remote_jid]/route.js +23 -23
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/ignores/route.js +30 -30
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js +703 -130
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js +708 -135
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js +802 -229
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/routes/[route_id]/route.js +739 -739
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/routes/route.js +1035 -1035
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js +679 -106
- package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/bridges/kinds/route.js +804 -804
- package/.next/standalone/.next/server/app/api/v1/bridges/route.js +700 -700
- package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js +9 -9
- package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/config/route.js +85 -85
- package/.next/standalone/.next/server/app/api/v1/credentials/[id]/route.js +709 -709
- package/.next/standalone/.next/server/app/api/v1/credentials/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/credentials/route.js +2 -2
- package/.next/standalone/.next/server/app/api/v1/credentials/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/dashboard/currency/route.js +10 -10
- package/.next/standalone/.next/server/app/api/v1/dashboard/metrics/route.js +784 -784
- package/.next/standalone/.next/server/app/api/v1/dashboard/pricing/route.js +23 -23
- package/.next/standalone/.next/server/app/api/v1/dashboard/pricing-task/route.js +86 -86
- package/.next/standalone/.next/server/app/api/v1/dashboard/pricing-task/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/delegations/codex/[job_id]/route.js +57 -57
- package/.next/standalone/.next/server/app/api/v1/delegations/codex/[job_id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/documents/search/route.js +523 -523
- package/.next/standalone/.next/server/app/api/v1/documents/settings/route.js +44 -44
- package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/reindex/route.js +65 -65
- package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/reindex/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/route.js +122 -122
- package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/documents/sources/route.js +37 -37
- package/.next/standalone/.next/server/app/api/v1/documents/sources/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/env/route.js +9 -9
- package/.next/standalone/.next/server/app/api/v1/env-sync/allowlist/route.js +368 -368
- package/.next/standalone/.next/server/app/api/v1/env-sync/route.js +44 -44
- package/.next/standalone/.next/server/app/api/v1/events/route.js +751 -178
- package/.next/standalone/.next/server/app/api/v1/events/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/events/test/route.js +77 -77
- package/.next/standalone/.next/server/app/api/v1/extension/agents/route.js +763 -763
- package/.next/standalone/.next/server/app/api/v1/extension/agents/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/extension/browser/activate/route.js +44 -44
- package/.next/standalone/.next/server/app/api/v1/extension/browser/foreground/route.js +9 -9
- package/.next/standalone/.next/server/app/api/v1/extension/browser/history/route.js +65 -65
- package/.next/standalone/.next/server/app/api/v1/extension/browser/poll/route.js +34 -34
- package/.next/standalone/.next/server/app/api/v1/extension/browser/progress/route.js +204 -204
- package/.next/standalone/.next/server/app/api/v1/extension/browser/result/route.js +133 -133
- package/.next/standalone/.next/server/app/api/v1/extension/browser/retry/route.js +106 -106
- package/.next/standalone/.next/server/app/api/v1/extension/browser/status/route.js +114 -114
- package/.next/standalone/.next/server/app/api/v1/extension/browser/tabs/route.js +134 -134
- package/.next/standalone/.next/server/app/api/v1/extension/fill/route.js +690 -690
- package/.next/standalone/.next/server/app/api/v1/extension/fill/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/extension/refine/route.js +93 -93
- package/.next/standalone/.next/server/app/api/v1/extension/refine/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/extension/turn/route.js +9 -9
- package/.next/standalone/.next/server/app/api/v1/extension/turn/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/extensions/route.js +185 -185
- package/.next/standalone/.next/server/app/api/v1/extensions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/config/route.js +171 -171
- package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/config/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/route.js +396 -396
- package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js +212 -212
- package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/files/[name]/route.js +235 -235
- package/.next/standalone/.next/server/app/api/v1/fs/browse/route.js +26 -26
- package/.next/standalone/.next/server/app/api/v1/harnesses/[id]/route.js +221 -221
- package/.next/standalone/.next/server/app/api/v1/harnesses/default/route.js +58 -58
- package/.next/standalone/.next/server/app/api/v1/harnesses/route.js +72 -72
- package/.next/standalone/.next/server/app/api/v1/health/probes/route.js +9 -9
- package/.next/standalone/.next/server/app/api/v1/health/probes/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/health/route.js +772 -772
- package/.next/standalone/.next/server/app/api/v1/integrations/[name]/route.js +133 -133
- package/.next/standalone/.next/server/app/api/v1/integrations/[name]/test/route.js +9 -9
- package/.next/standalone/.next/server/app/api/v1/integrations/[name]/test/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/callback/route.js +363 -363
- package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/start/route.js +233 -233
- package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/status/route.js +682 -682
- package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/callback/route.js +879 -879
- package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/start/route.js +108 -108
- package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/status/route.js +952 -952
- package/.next/standalone/.next/server/app/api/v1/integrations/route.js +216 -216
- package/.next/standalone/.next/server/app/api/v1/lifecycle/adoption/route.js +864 -847
- package/.next/standalone/.next/server/app/api/v1/lifecycle/adoption/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/local-file/route.js +26 -26
- package/.next/standalone/.next/server/app/api/v1/logs/route.js +70 -70
- package/.next/standalone/.next/server/app/api/v1/maps/embed/route.js +72 -72
- package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js +979 -979
- package/.next/standalone/.next/server/app/api/v1/mcp-servers/registry/route.js +196 -196
- package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js +2 -2
- package/.next/standalone/.next/server/app/api/v1/memory/[namespace]/[key]/route.js +381 -381
- package/.next/standalone/.next/server/app/api/v1/memory/policy/route.js +79 -79
- package/.next/standalone/.next/server/app/api/v1/memory/route.js +51 -51
- package/.next/standalone/.next/server/app/api/v1/memory/search/route.js +131 -131
- package/.next/standalone/.next/server/app/api/v1/models/[name]/compact-threads/route.js +374 -369
- package/.next/standalone/.next/server/app/api/v1/models/[name]/compact-threads/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/models/[name]/route.js +143 -143
- package/.next/standalone/.next/server/app/api/v1/models/route.js +543 -543
- package/.next/standalone/.next/server/app/api/v1/packages/catalog/route.js +445 -445
- package/.next/standalone/.next/server/app/api/v1/packages/defaults/[id]/route.js +120 -120
- package/.next/standalone/.next/server/app/api/v1/packages/defaults/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/packages/install/[id]/route.js +234 -234
- package/.next/standalone/.next/server/app/api/v1/packages/install/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/packages/install/route.js +407 -407
- package/.next/standalone/.next/server/app/api/v1/packages/install/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/enabled/route.js +37 -37
- package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/enabled/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/route.js +107 -107
- package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/packages/manifests/route.js +228 -228
- package/.next/standalone/.next/server/app/api/v1/packages/manifests/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/packages/reload/route.js +9 -9
- package/.next/standalone/.next/server/app/api/v1/packages/reload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/packages/route.js +148 -148
- package/.next/standalone/.next/server/app/api/v1/packages/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/page-capture/route.js +787 -787
- package/.next/standalone/.next/server/app/api/v1/page-capture/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js +507 -507
- package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/deny/route.js +181 -181
- package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/deny/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/pending-actions/route.js +258 -258
- package/.next/standalone/.next/server/app/api/v1/pending-actions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/profile/location/route.js +30 -30
- package/.next/standalone/.next/server/app/api/v1/profile/route.js +164 -164
- package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js +44 -44
- package/.next/standalone/.next/server/app/api/v1/providers/[provider]/probe/route.js +9 -9
- package/.next/standalone/.next/server/app/api/v1/providers/github-copilot/auth/route.js +164 -164
- package/.next/standalone/.next/server/app/api/v1/providers/route.js +94 -94
- package/.next/standalone/.next/server/app/api/v1/proxy-config/route.js +450 -450
- package/.next/standalone/.next/server/app/api/v1/redaction/init/route.js +37 -37
- package/.next/standalone/.next/server/app/api/v1/redaction/route.js +58 -58
- package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/route.js +600 -600
- package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/run/route.js +44 -44
- package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/route.js +732 -732
- package/.next/standalone/.next/server/app/api/v1/security/idle-timeout/route.js +359 -359
- package/.next/standalone/.next/server/app/api/v1/security/pin/route.js +197 -197
- package/.next/standalone/.next/server/app/api/v1/security/state/route.js +51 -51
- package/.next/standalone/.next/server/app/api/v1/security/unlock/route.js +176 -176
- package/.next/standalone/.next/server/app/api/v1/security/verify-pin/route.js +190 -190
- package/.next/standalone/.next/server/app/api/v1/setup/test-key/route.js +26 -26
- package/.next/standalone/.next/server/app/api/v1/skills/[id]/route.js +770 -770
- package/.next/standalone/.next/server/app/api/v1/skills/repos/[id]/route.js +115 -115
- package/.next/standalone/.next/server/app/api/v1/skills/repos/route.js +327 -327
- package/.next/standalone/.next/server/app/api/v1/skills/route.js +870 -870
- package/.next/standalone/.next/server/app/api/v1/system/abort/route.js +838 -808
- package/.next/standalone/.next/server/app/api/v1/system/restart/route.js +177 -177
- package/.next/standalone/.next/server/app/api/v1/system/restart/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/tailscale/route.js +164 -164
- package/.next/standalone/.next/server/app/api/v1/tasks/[agent_id]/route.js +115 -115
- package/.next/standalone/.next/server/app/api/v1/tasks/route.js +23 -23
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route.js +1429 -0
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route_client-reference-manifest.js +1 -0
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/context-pin/route.js +635 -634
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/context-pin/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js +53 -439
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js +172 -172
- package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/threads/route.js +908 -908
- package/.next/standalone/.next/server/app/api/v1/tools/route.js +2 -2
- package/.next/standalone/.next/server/app/api/v1/tools/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/update/apply/route.js +17 -17
- package/.next/standalone/.next/server/app/api/v1/update/apply/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/update/route.js +570 -570
- package/.next/standalone/.next/server/app/api/v1/voice/transcribe/route.js +224 -224
- package/.next/standalone/.next/server/app/api/v1/voice/tts/route.js +975 -975
- package/.next/standalone/.next/server/app/api/v1/watchers/[id]/route.js +23 -23
- package/.next/standalone/.next/server/app/api/v1/watchers/[id]/run/route.js +72 -72
- package/.next/standalone/.next/server/app/api/v1/watchers/[id]/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/v1/watchers/reaction-scripts/route.js +128 -128
- package/.next/standalone/.next/server/app/api/v1/watchers/route.js +164 -164
- package/.next/standalone/.next/server/app/api/v1/watchers/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/icon.svg/route.js +62 -62
- package/.next/standalone/.next/server/app/manifest.webmanifest/route.js +436 -436
- package/.next/standalone/.next/server/app/page.js +1243 -854
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/setup/page.js +91 -91
- package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +6 -5
- package/.next/standalone/.next/server/chunks/{424.js → 1388.js} +335 -986
- package/.next/standalone/.next/server/chunks/1433.js +1 -1
- package/.next/standalone/.next/server/chunks/1638.js +1 -2
- package/.next/standalone/.next/server/chunks/1738.js +1 -1
- package/.next/standalone/.next/server/chunks/210.js +6 -6
- package/.next/standalone/.next/server/chunks/2151.js +31 -1
- package/.next/standalone/.next/server/chunks/2207.js +1 -0
- package/.next/standalone/.next/server/chunks/2471.js +28 -28
- package/.next/standalone/.next/server/chunks/2504.js +1 -1
- package/.next/standalone/.next/server/chunks/2695.js +17 -17
- package/.next/standalone/.next/server/chunks/3042.js +14 -8
- package/.next/standalone/.next/server/chunks/3399.js +1 -1
- package/.next/standalone/.next/server/chunks/3566.js +1 -1
- package/.next/standalone/.next/server/chunks/4189.js +946 -0
- package/.next/standalone/.next/server/chunks/{9590.js → 423.js} +8 -3
- package/.next/standalone/.next/server/chunks/4433.js +146 -146
- package/.next/standalone/.next/server/chunks/4508.js +1 -1
- package/.next/standalone/.next/server/chunks/4588.js +1 -0
- package/.next/standalone/.next/server/chunks/46.js +5 -0
- package/.next/standalone/.next/server/chunks/466.js +12 -0
- package/.next/standalone/.next/server/chunks/4868.js +206 -206
- package/.next/standalone/.next/server/chunks/4992.js +13 -0
- package/.next/standalone/.next/server/chunks/5120.js +963 -0
- package/.next/standalone/.next/server/chunks/5701.js +1 -1
- package/.next/standalone/.next/server/chunks/5900.js +1 -1
- package/.next/standalone/.next/server/chunks/6210.js +1 -0
- package/.next/standalone/.next/server/chunks/6213.js +1 -1
- package/.next/standalone/.next/server/chunks/6649.js +2 -2
- package/.next/standalone/.next/server/chunks/6703.js +3 -3
- package/.next/standalone/.next/server/chunks/7445.js +1 -0
- package/.next/standalone/.next/server/chunks/8067.js +12 -0
- package/.next/standalone/.next/server/chunks/8461.js +14 -9
- package/.next/standalone/.next/server/chunks/8558.js +1 -1
- package/.next/standalone/.next/server/chunks/8724.js +1 -1
- package/.next/standalone/.next/server/chunks/8849.js +91 -91
- package/.next/standalone/.next/server/chunks/9032.js +6 -5
- package/.next/standalone/.next/server/chunks/{2563.js → 9164.js} +33173 -31461
- package/.next/standalone/.next/server/chunks/9237.js +396 -396
- package/.next/standalone/.next/server/chunks/{9640.js → 9304.js} +1628 -570
- package/.next/standalone/.next/server/chunks/9406.js +1 -1
- package/.next/standalone/.next/server/chunks/9824.js +98 -98
- package/.next/standalone/.next/server/chunks/9826.js +1 -0
- package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
- package/.next/standalone/.next/server/middleware.js +415 -397
- package/.next/standalone/.next/server/pages/404.html +2 -2
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/preview-props.json +3 -3
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/{1395-a340fb0a345382a4.js → 1395-e4a99912b8f83044.js} +13 -1
- package/.next/standalone/.next/static/chunks/app/_global-error/{page-36cb8b428b38b26a.js → page-6fc5f8e744c81802.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/api/v1/access/[identity]/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/api/v1/access/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/compact/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
- package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/display-filters/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/thread/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/agents/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/[hostname]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/artifacts/lifecycle/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/attachments/files/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/attachments/images/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/chats/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/[remote_jid]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/lookup/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/pair/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/[route_id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/status/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/kinds/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/builtin-tools/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/config/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/credentials/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/credentials/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/currency/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/metrics/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing-task/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/delegations/codex/[job_id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/documents/search/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/documents/settings/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/reindex/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/env/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/allowlist/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/events/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/events/test/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/agents/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/activate/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/foreground/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/history/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/poll/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/progress/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/result/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/retry/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/status/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/tabs/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/fill/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/refine/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/turn/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extensions/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/config/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/secrets/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/files/[name]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/fs/browse/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/default/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/health/probes/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/health/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/test/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/callback/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/start/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/status/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/callback/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/start/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/status/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/lifecycle/adoption/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/local-file/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/logs/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/maps/embed/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/[name]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/registry/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/memory/[namespace]/[key]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/memory/policy/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/memory/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/memory/search/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/compact-threads/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/models/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/catalog/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/defaults/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/enabled/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/reload/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/page-capture/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/approve/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/deny/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/profile/location/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/profile/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/models/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/probe/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/providers/github-copilot/auth/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/providers/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/proxy-config/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/redaction/init/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/redaction/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/run/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/security/idle-timeout/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/security/pin/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/security/state/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/security/unlock/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/security/verify-pin/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/setup/test-key/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/skills/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/skills/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/system/abort/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/system/restart/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/tailscale/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/tasks/[agent_id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/tasks/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/activity/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/context-pin/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/run/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/threads/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/tools/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/update/apply/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/update/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/voice/transcribe/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/voice/tts/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/run/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/watchers/reaction-scripts/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/api/v1/watchers/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/manifest.webmanifest/route-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/app/{page-7017f07f8a7a083c.js → page-213a623b37226452.js} +1041 -652
- package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-6fc5f8e744c81802.js +17 -0
- package/.next/standalone/.next/static/css/{d80058f0b9b41c09.css → 312542a5725ba0d5.css} +2 -2
- package/.next/standalone/docs/adoption/changesets.json +309 -0
- package/.next/standalone/lib/skills/builtins/memory-organization/SKILL.md +16 -0
- package/.next/standalone/package.json +3 -3
- package/CHANGELOG.md +25 -0
- package/api/client.ts +9 -0
- package/api/types.ts +29 -0
- package/app/api/v1/lifecycle/adoption/route.ts +14 -2
- package/app/api/v1/models/[name]/compact-threads/route.ts +14 -11
- package/app/api/v1/threads/[thread_id]/activity/route.ts +19 -0
- package/app/api/v1/threads/[thread_id]/context-pin/route.test.ts +1 -0
- package/app/api/v1/threads/[thread_id]/context-pin/route.ts +2 -1
- package/app/api/v1/threads/[thread_id]/route.ts +5 -1
- package/components/chat/ChatView.tsx +52 -11
- package/components/chat/ContextBoundary.test.tsx +68 -1
- package/components/chat/ContextBoundary.tsx +92 -13
- package/components/chat/MessageList.test.tsx +31 -0
- package/components/chat/MessageList.tsx +49 -28
- package/components/chat/ToolList.test.tsx +92 -16
- package/components/chat/ToolList.tsx +59 -4
- package/components/chat/chat-helpers.test.tsx +24 -1
- package/components/chat/chat-helpers.ts +47 -4
- package/components/chat/useThreadActivity.test.tsx +113 -0
- package/components/chat/useThreadActivity.ts +94 -0
- package/components/chat/useThreadData.ts +16 -16
- package/components/chat/workflow-step-retry.ts +25 -0
- package/components/ui/BootScreen.tsx +17 -0
- package/components/ui/WorkflowChecklist.tsx +71 -33
- package/hooks/useSSE.ts +28 -3
- package/lib/agents/compaction-pipeline.test.ts +202 -0
- package/lib/agents/compaction-pipeline.ts +483 -0
- package/lib/agents/conversation-summary.ts +37 -21
- package/lib/agents/prepare/history-window.test.ts +18 -0
- package/lib/agents/prepare/history-window.ts +11 -2
- package/lib/agents/prepare/request.ts +4 -0
- package/lib/agents/prepare/system-prompt.test.ts +39 -0
- package/lib/agents/prepare/system-prompt.ts +8 -3
- package/lib/agents/prompt-registry.test.ts +5 -140
- package/lib/agents/prompt-registry.ts +45 -1
- package/lib/agents/prompt-variants.ts +146 -0
- package/lib/agents/run-registry.test.ts +22 -0
- package/lib/agents/run-registry.ts +29 -0
- package/lib/agents/run-thread.retry.test.ts +67 -1
- package/lib/agents/run-thread.ts +86 -1
- package/lib/agents/thread-activity.test.ts +31 -0
- package/lib/agents/thread-activity.ts +27 -0
- package/lib/agents/thread-compaction-state.test.ts +82 -0
- package/lib/agents/thread-compaction-state.ts +121 -0
- package/lib/agents/thread-compaction.test.ts +83 -4
- package/lib/agents/thread-compaction.ts +34 -11
- package/lib/agents/warm-summary-background.test.ts +219 -5
- package/lib/agents/warm-summary-background.ts +325 -142
- package/lib/agents/warm-topics.test.ts +37 -0
- package/lib/agents/warm-topics.ts +297 -0
- package/lib/agents/workflow-step-retry.test.ts +96 -0
- package/lib/agents/workflow-step-retry.ts +216 -0
- package/lib/api/browser-control.ts +0 -3
- package/lib/db/migrations.ts +5 -0
- package/lib/env/config.ts +2 -0
- package/lib/env/schema.ts +12 -0
- package/lib/lifecycle/changeset-build.test.ts +93 -0
- package/lib/lifecycle/changeset-build.ts +210 -0
- package/lib/lifecycle/changesets.test.ts +101 -0
- package/lib/lifecycle/changesets.ts +166 -0
- package/lib/lifecycle/surface-collect.test.ts +88 -0
- package/lib/lifecycle/surface-collect.ts +64 -0
- package/lib/lifecycle/surface-snapshot.test.ts +104 -0
- package/lib/lifecycle/surface-snapshot.ts +210 -0
- package/lib/memory/record.ts +0 -2
- package/lib/providers/external.ts +0 -2
- package/lib/skills/builtins/memory-organization/SKILL.md +16 -0
- package/lib/stores/threads.test.ts +9 -0
- package/lib/stores/threads.ts +21 -11
- package/lib/stores/version-adoption.test.ts +96 -0
- package/lib/stores/version-adoption.ts +239 -26
- package/lib/stores/workflow-progress.ts +3 -0
- package/lib/tools/communications/ms-todo.ts +0 -7
- package/lib/tools/general/memory.ts +1 -1
- package/lib/tools/general/workflow-progress.ts +2 -0
- package/lib/tools/runtime/catalog.ts +1 -25
- package/lib/triggers/registry.ts +0 -4
- package/package.json +3 -3
- package/scripts/install-to-system.ps1 +39 -11
- package/scripts/install-to-system.sh +37 -3
- package/.next/standalone/.next/server/chunks/3979.js +0 -581
- package/.next/standalone/.next/server/chunks/5936.js +0 -594
- package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/display-filters/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/thread/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/agents/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/[hostname]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/artifacts/lifecycle/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/attachments/files/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/attachments/images/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/chats/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/[remote_jid]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/lookup/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/pair/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/[route_id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/status/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/kinds/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/bridges/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/builtin-tools/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/config/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/credentials/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/credentials/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/currency/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/metrics/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing-task/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/delegations/codex/[job_id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/documents/search/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/documents/settings/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/reindex/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/env/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/allowlist/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/events/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/events/test/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/agents/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/activate/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/foreground/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/history/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/poll/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/progress/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/result/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/retry/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/status/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/tabs/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/fill/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/refine/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extension/turn/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extensions/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/config/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/secrets/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/files/[name]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/fs/browse/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/default/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/health/probes/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/health/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/test/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/callback/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/start/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/status/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/callback/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/start/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/status/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/integrations/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/lifecycle/adoption/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/local-file/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/logs/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/maps/embed/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/[name]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/registry/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/memory/[namespace]/[key]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/memory/policy/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/memory/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/memory/search/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/compact-threads/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/models/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/catalog/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/defaults/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/enabled/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/reload/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/packages/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/page-capture/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/approve/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/deny/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/profile/location/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/profile/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/models/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/probe/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/providers/github-copilot/auth/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/providers/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/proxy-config/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/redaction/init/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/redaction/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/run/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/security/idle-timeout/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/security/pin/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/security/state/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/security/unlock/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/security/verify-pin/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/setup/test-key/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/skills/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/skills/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/system/abort/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/system/restart/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/tailscale/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/tasks/[agent_id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/tasks/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/context-pin/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/run/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/threads/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/tools/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/update/apply/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/update/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/voice/transcribe/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/voice/tts/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/run/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/watchers/reaction-scripts/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/api/v1/watchers/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/app/manifest.webmanifest/route-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-36cb8b428b38b26a.js +0 -17
- package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-36cb8b428b38b26a.js +0 -17
- /package/.next/standalone/.next/static/{NUrC9xax1sp1Q70nlFqS6 → bMRK5y3ruT7c3WtBfCQOG}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{NUrC9xax1sp1Q70nlFqS6 → bMRK5y3ruT7c3WtBfCQOG}/_ssgManifest.js +0 -0
|
@@ -6,15 +6,18 @@ import { useSSE } from "@/hooks/useSSE";
|
|
|
6
6
|
import { useMessageFilters } from "@/hooks/useMessageFilters";
|
|
7
7
|
import { useAppContext } from "@/contexts/AppContext";
|
|
8
8
|
import { useTrackLoading, useActivityWhile } from "@/lib/ui/loading";
|
|
9
|
+
import { pushToast } from "@/lib/ui/toasts";
|
|
10
|
+
import { pushErrorToast } from "@/lib/ui/error-report";
|
|
9
11
|
import { ApprovalsBanner } from "@/components/proposals/ApprovalsBanner";
|
|
10
12
|
import { AuthErrorBanner } from "./AuthErrorBanner";
|
|
11
13
|
import { InputBar } from "./InputBar";
|
|
12
14
|
import { MessageList } from "./MessageList";
|
|
13
|
-
import { applyThreadMeta, makeQueuedId, parseWarmSummaryTopics } from "./chat-helpers";
|
|
15
|
+
import { applyThreadMeta, compactionOutcomeToast, makeQueuedId, parseWarmSummaryTopics, type CompactionOutcome } from "./chat-helpers";
|
|
14
16
|
import { useChatErrorReporting } from "./useChatErrorReporting";
|
|
15
17
|
import { useChatQueue, type ChatQueueApi } from "./useChatQueue";
|
|
16
18
|
import { useThreadCrossDeviceSync } from "./useThreadCrossDeviceSync";
|
|
17
19
|
import { useThreadData } from "./useThreadData";
|
|
20
|
+
import { useThreadActivity } from "./useThreadActivity";
|
|
18
21
|
import { useUserProfileAndAgent } from "./useUserProfileAndAgent";
|
|
19
22
|
import { composerPlaceholder, finalizeRunFromServer } from "./chat-run-utils";
|
|
20
23
|
import { useChatSubmitHandlers } from "./useChatSubmitHandlers";
|
|
@@ -84,11 +87,27 @@ export function ChatView({ threadId, agentId, sessionLoading, sessionError, onMe
|
|
|
84
87
|
attachRef.current = sse.attach;
|
|
85
88
|
clearStreamingRef.current = sse.clearStreamingContent;
|
|
86
89
|
clearToolEventsRef.current = sse.clearToolEvents;
|
|
90
|
+
// `compacting` lives in this component, which remounts per agent; the
|
|
91
|
+
// server flag keeps a /compact started before an agent switch visible.
|
|
92
|
+
const sessionCompacting = compacting || thread.manualCompactionPending;
|
|
93
|
+
|
|
94
|
+
const activity = useThreadActivity({
|
|
95
|
+
threadId,
|
|
96
|
+
attach: stableAttach,
|
|
97
|
+
isLive: sse.isLive,
|
|
98
|
+
lastSettledAt: sse.lastSettledAt,
|
|
99
|
+
metaApplier: thread.metaApplier,
|
|
100
|
+
});
|
|
101
|
+
// Run phases come through the attached stream; background compaction
|
|
102
|
+
// outside a run has no stream, so label it from the polled activity.
|
|
103
|
+
const backgroundCompaction = !sse.streaming && !sessionCompacting ? activity?.compaction?.kind ?? null : null;
|
|
87
104
|
|
|
88
105
|
useChatErrorReporting({ sessionError, streamError: sse.error, authError: sse.authError, agentId, threadId });
|
|
89
106
|
|
|
90
107
|
const streamingRef = useRef(false);
|
|
91
108
|
streamingRef.current = sse.streaming;
|
|
109
|
+
const currentThreadIdRef = useRef(threadId);
|
|
110
|
+
currentThreadIdRef.current = threadId;
|
|
92
111
|
|
|
93
112
|
// Auto compaction starts server-side during a run; poll so the banner shows live.
|
|
94
113
|
useEffect(() => {
|
|
@@ -117,11 +136,14 @@ export function ChatView({ threadId, agentId, sessionLoading, sessionError, onMe
|
|
|
117
136
|
|
|
118
137
|
useTrackLoading(!!sessionLoading);
|
|
119
138
|
useTrackLoading(sse.streaming);
|
|
120
|
-
useTrackLoading(
|
|
139
|
+
useTrackLoading(sessionCompacting);
|
|
121
140
|
useTrackLoading(thread.loadingMore);
|
|
122
141
|
useTrackLoading(thread.messagesLoading);
|
|
123
142
|
useTrackLoading(agentConfigLoading);
|
|
124
143
|
|
|
144
|
+
useActivityWhile(sessionCompacting, "Compacting session…");
|
|
145
|
+
useActivityWhile(backgroundCompaction === "auto", "Compacting earlier messages…");
|
|
146
|
+
useActivityWhile(backgroundCompaction === "refresh", "Updating summary…");
|
|
125
147
|
useActivityWhile(thread.messagesLoading, "Loading chat history…");
|
|
126
148
|
useActivityWhile(agentConfigLoading, "Loading agent…");
|
|
127
149
|
useActivityWhile(profileLoading, "Loading profile…");
|
|
@@ -197,16 +219,32 @@ export function ChatView({ threadId, agentId, sessionLoading, sessionError, onMe
|
|
|
197
219
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
198
220
|
}, [threadId]);
|
|
199
221
|
|
|
200
|
-
const queue = useChatQueue({ threadId, streaming: sse.streaming, compacting, launchRun });
|
|
222
|
+
const queue = useChatQueue({ threadId, streaming: sse.streaming, compacting: sessionCompacting, launchRun });
|
|
201
223
|
queueApiRef.current = queue;
|
|
202
224
|
drainQueueRef.current = queue.drainQueueRef.current;
|
|
203
225
|
|
|
204
226
|
async function handleCompact() {
|
|
205
227
|
if (!agentId) return;
|
|
228
|
+
const notifyCompaction = (result: CompactionOutcome) => {
|
|
229
|
+
const toast = compactionOutcomeToast(result);
|
|
230
|
+
pushToast({
|
|
231
|
+
...toast,
|
|
232
|
+
source: "system",
|
|
233
|
+
sourceLabel: "Chat",
|
|
234
|
+
agent_id: agentId,
|
|
235
|
+
thread_id: threadId,
|
|
236
|
+
ttl: 5000,
|
|
237
|
+
dedupeKey: `compact:${agentId}`,
|
|
238
|
+
});
|
|
239
|
+
};
|
|
206
240
|
setCompacting(true);
|
|
207
241
|
try {
|
|
208
242
|
const result = await api.agents.compact(agentId, { resetContext: true });
|
|
209
|
-
|
|
243
|
+
// The thread may have changed while compaction ran; never apply its
|
|
244
|
+
// result to a different thread's view.
|
|
245
|
+
const compactedThreadId = threadId;
|
|
246
|
+
const stillCurrent = () => compactedThreadId !== null && currentThreadIdRef.current === compactedThreadId;
|
|
247
|
+
if (result.compacted && compactedThreadId !== null && stillCurrent()) {
|
|
210
248
|
// Server moved the hot/warm pin to just after the last existing
|
|
211
249
|
// message and persisted the warm summary. Mirror that in-place so
|
|
212
250
|
// the warm card shows the fresh summary without wiping the visible
|
|
@@ -218,16 +256,19 @@ export function ChatView({ threadId, agentId, sessionLoading, sessionError, onMe
|
|
|
218
256
|
thread.metaApplier.setWarmSummary(result.warm_summary ?? null);
|
|
219
257
|
thread.metaApplier.setWarmSummaryBefore(result.warm_summary_before ?? null);
|
|
220
258
|
thread.metaApplier.setWarmSummaryBeforeSeq(result.warm_summary_before_seq ?? null);
|
|
221
|
-
thread.metaApplier.setWarmSummaryBeforeSeq(result.warm_summary_before_seq ?? null);
|
|
222
259
|
thread.metaApplier.setWarmSummaryComputedAt(result.warm_summary_computed_at ?? null);
|
|
223
260
|
thread.metaApplier.setWarmSummarySourceMessages(result.warm_summary_source_messages ?? null);
|
|
224
261
|
thread.metaApplier.setWarmSummarySourceChars(result.warm_summary_source_chars ?? null);
|
|
225
262
|
thread.metaApplier.setWarmSummaryTopics?.(parseWarmSummaryTopics(result.warm_summary_topics));
|
|
226
|
-
|
|
227
|
-
|
|
263
|
+
// The compact response carries only the chat recap; channel recaps
|
|
264
|
+
// (bridge, watcher, scheduled task) come with the thread metadata.
|
|
265
|
+
void api.threads.get(compactedThreadId, { limit: 1 })
|
|
266
|
+
.then((d) => { if (stillCurrent()) applyThreadMeta(thread.metaApplier, d); })
|
|
267
|
+
.catch(() => { /* best-effort */ });
|
|
228
268
|
}
|
|
269
|
+
notifyCompaction(result);
|
|
229
270
|
} catch (err) {
|
|
230
|
-
|
|
271
|
+
pushErrorToast({ title: "Compaction failed", error: err, context: { panel: "chat", action: "compact", agent_id: agentId } });
|
|
231
272
|
} finally {
|
|
232
273
|
setCompacting(false);
|
|
233
274
|
queue.drainQueueRef.current();
|
|
@@ -260,7 +301,6 @@ export function ChatView({ threadId, agentId, sessionLoading, sessionError, onMe
|
|
|
260
301
|
threadId={threadId}
|
|
261
302
|
messages={thread.messages}
|
|
262
303
|
steeredSegments={sse.steeredSegments}
|
|
263
|
-
notices={thread.notices}
|
|
264
304
|
agentConfig={agentConfig}
|
|
265
305
|
userProfile={userProfile}
|
|
266
306
|
// streamingContent stays visible past `streaming=false` so the bubble
|
|
@@ -287,8 +327,9 @@ export function ChatView({ threadId, agentId, sessionLoading, sessionError, onMe
|
|
|
287
327
|
warmSummarySourceMessages={thread.warmSummarySourceMessages}
|
|
288
328
|
warmSummarySourceChars={thread.warmSummarySourceChars}
|
|
289
329
|
warmSummaryTopics={thread.warmSummaryTopics}
|
|
330
|
+
warmChannelSummaries={thread.warmChannelSummaries}
|
|
290
331
|
warmSummaryPending={thread.warmSummaryPending}
|
|
291
|
-
compactionPending={thread.compactionPending ||
|
|
332
|
+
compactionPending={thread.compactionPending || sessionCompacting}
|
|
292
333
|
onSetContextPin={thread.setContextPin}
|
|
293
334
|
streaming={sse.streaming}
|
|
294
335
|
contextWindowTokens={thread.contextWindowTokens}
|
|
@@ -313,7 +354,7 @@ export function ChatView({ threadId, agentId, sessionLoading, sessionError, onMe
|
|
|
313
354
|
onVoiceTranscript={handleVoiceTranscript}
|
|
314
355
|
disabled={!agentId}
|
|
315
356
|
placeholder={composerPlaceholder({
|
|
316
|
-
compacting,
|
|
357
|
+
compacting: sessionCompacting,
|
|
317
358
|
sessionLoading: !!sessionLoading,
|
|
318
359
|
streaming: sse.streaming,
|
|
319
360
|
})}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @vitest-environment jsdom
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
3
|
import { fireEvent, render, screen } from "@testing-library/react";
|
|
4
|
-
import { WarmSummaryCard } from "./ContextBoundary";
|
|
4
|
+
import { topicsFromSummarySections, WarmSummaryCard } from "./ContextBoundary";
|
|
5
5
|
import type { SummaryTopicSegment } from "@/api/types";
|
|
6
6
|
|
|
7
7
|
const topics: SummaryTopicSegment[] = [
|
|
@@ -66,4 +66,71 @@ describe("WarmSummaryCard topic preview", () => {
|
|
|
66
66
|
expect(screen.getByText("Flat prose fallback.")).toBeTruthy();
|
|
67
67
|
expect(screen.queryByRole("button", { name: /Pricing extraction/ })).toBeNull();
|
|
68
68
|
});
|
|
69
|
+
|
|
70
|
+
it("groups a sectioned summary without stored topics into collapsed topic rows", () => {
|
|
71
|
+
const legacy = [
|
|
72
|
+
"<!-- jarela:warm-scope=foreground -->",
|
|
73
|
+
"--- Warm context summary ---",
|
|
74
|
+
"Compressed recap of recent messages immediately before the hot window:",
|
|
75
|
+
"## Context",
|
|
76
|
+
"Weighing **three offers** against each other.",
|
|
77
|
+
"## User facts & preferences",
|
|
78
|
+
"- Will not relocate",
|
|
79
|
+
"- Wants numerical answers",
|
|
80
|
+
].join("\n");
|
|
81
|
+
render(<WarmSummaryCard olderCount={46} summary={legacy} summaryBeforeSeq={10} hotSinceSeq={10} computedAt={null} streaming={false} topics={null} />);
|
|
82
|
+
|
|
83
|
+
expect(screen.queryByText(/jarela:warm-scope/)).toBeNull();
|
|
84
|
+
expect(screen.queryByText(/Warm context summary/)).toBeNull();
|
|
85
|
+
const context = screen.getByRole("button", { name: /^Context/ });
|
|
86
|
+
expect(context.getAttribute("aria-expanded")).toBe("false");
|
|
87
|
+
expect(screen.getByRole("button", { name: /User facts & preferences/ })).toBeTruthy();
|
|
88
|
+
expect(screen.getByText("three offers").tagName).toBe("STRONG");
|
|
89
|
+
expect(screen.queryByRole("button", { name: /Show more/ })).toBeNull();
|
|
90
|
+
|
|
91
|
+
fireEvent.click(screen.getByRole("button", { name: /User facts & preferences/ }));
|
|
92
|
+
expect(screen.getAllByText("Will not relocate")).toHaveLength(1);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe("WarmSummaryCard automation-only boundary", () => {
|
|
97
|
+
const bridgeRecap = {
|
|
98
|
+
channel: "bridge",
|
|
99
|
+
summary: "<!-- jarela:warm-scope=bridge -->\nRelayed **deployment alerts** from the ops channel.",
|
|
100
|
+
computed_at: "2026-10-14T09:30:00.000Z",
|
|
101
|
+
topics: null,
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
it("shows the bridge recap instead of a never-arriving chat summary", () => {
|
|
105
|
+
render(<WarmSummaryCard olderCount={50} summary="" summaryBeforeSeq={10} hotSinceSeq={10} computedAt="2026-10-14T09:30:00.000Z" streaming={false} topics={null} channelSummaries={[bridgeRecap]} />);
|
|
106
|
+
|
|
107
|
+
expect(screen.getByText("Bridge")).toBeTruthy();
|
|
108
|
+
expect(screen.getByRole("button", { name: /Recap/ }).getAttribute("aria-expanded")).toBe("false");
|
|
109
|
+
expect(screen.getByText("deployment alerts").tagName).toBe("STRONG");
|
|
110
|
+
expect(screen.queryByText(/jarela:warm-scope/)).toBeNull();
|
|
111
|
+
expect(screen.queryByText(/Summary will appear/)).toBeNull();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("says nothing needed summarising when the committed boundary has no recaps at all", () => {
|
|
115
|
+
render(<WarmSummaryCard olderCount={3} summary="" summaryBeforeSeq={10} hotSinceSeq={10} computedAt="2026-10-14T09:30:00.000Z" streaming={false} topics={null} />);
|
|
116
|
+
expect(screen.getByText("No earlier chat messages needed summarising.")).toBeTruthy();
|
|
117
|
+
expect(screen.queryByText(/Summary will appear/)).toBeNull();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("keeps the placeholder while the boundary has no committed summary yet", () => {
|
|
121
|
+
render(<WarmSummaryCard olderCount={3} summary={null} summaryBeforeSeq={null} hotSinceSeq={10} computedAt={null} streaming={false} topics={null} />);
|
|
122
|
+
expect(screen.getByText("Summary will appear after your next reply.")).toBeTruthy();
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
describe("topicsFromSummarySections", () => {
|
|
127
|
+
it("keeps unstructured or single-section summaries as prose", () => {
|
|
128
|
+
expect(topicsFromSummarySections("Just a short recap.")).toBeNull();
|
|
129
|
+
expect(topicsFromSummarySections("## Only\nOne section.")).toBeNull();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("keeps intro text before the first heading as an overview section", () => {
|
|
133
|
+
const sections = topicsFromSummarySections("Intro line.\n## Decisions\n- Chose A");
|
|
134
|
+
expect(sections?.map((s) => [s.title, s.recap])).toEqual([["Overview", "Intro line."], ["Decisions", "- Chose A"]]);
|
|
135
|
+
});
|
|
69
136
|
});
|
|
@@ -11,7 +11,7 @@ import ReactMarkdown from "react-markdown";
|
|
|
11
11
|
import { StatusDot } from "@/components/ui/StatusDot";
|
|
12
12
|
import { MetaRow } from "@/components/ui/MetaRow";
|
|
13
13
|
import { CollapseChevron } from "@/components/ui/CollapseChevron";
|
|
14
|
-
import type { SummaryTopicSegment } from "@/api/types";
|
|
14
|
+
import type { SummaryTopicSegment, WarmChannelSummary } from "@/api/types";
|
|
15
15
|
|
|
16
16
|
interface WarmSummaryCardProps {
|
|
17
17
|
/** Number of messages older than the boundary that the summary covers. */
|
|
@@ -26,8 +26,16 @@ interface WarmSummaryCardProps {
|
|
|
26
26
|
streaming: boolean;
|
|
27
27
|
/** Per-topic segmentation of the same warm range, if the summarizer returned one. */
|
|
28
28
|
topics?: SummaryTopicSegment[] | null;
|
|
29
|
+
/** Automation-channel recaps (bridge, watcher, scheduled task) at this boundary. */
|
|
30
|
+
channelSummaries?: WarmChannelSummary[];
|
|
29
31
|
}
|
|
30
32
|
|
|
33
|
+
const CHANNEL_LABELS: Record<string, string> = {
|
|
34
|
+
bridge: "Bridge",
|
|
35
|
+
watcher: "Watchers",
|
|
36
|
+
scheduled_task: "Scheduled tasks",
|
|
37
|
+
};
|
|
38
|
+
|
|
31
39
|
export function WarmSummaryCard({
|
|
32
40
|
olderCount,
|
|
33
41
|
summary,
|
|
@@ -36,19 +44,25 @@ export function WarmSummaryCard({
|
|
|
36
44
|
computedAt,
|
|
37
45
|
streaming,
|
|
38
46
|
topics,
|
|
47
|
+
channelSummaries = [],
|
|
39
48
|
}: WarmSummaryCardProps) {
|
|
40
49
|
const [expanded, setExpanded] = useState(false);
|
|
41
|
-
const
|
|
50
|
+
const committed = hotSinceSeq != null && summaryBeforeSeq === hotSinceSeq;
|
|
51
|
+
const fresh = !!summary && committed;
|
|
42
52
|
const stale = !!summary && !fresh;
|
|
43
53
|
const computing = stale && streaming;
|
|
44
|
-
|
|
54
|
+
// Summaries stored before topic segmentation still read as topics: their
|
|
55
|
+
// markdown sections render through the same collapsible rows.
|
|
56
|
+
const summaryTopics = summary
|
|
57
|
+
? (topics && topics.length > 0 ? topics : topicsFromSummarySections(summary))
|
|
58
|
+
: null;
|
|
45
59
|
|
|
46
60
|
return (
|
|
47
61
|
<div
|
|
48
62
|
className={[
|
|
49
63
|
"relative my-4 rounded-2xl border bg-gradient-to-br shadow-sm",
|
|
50
64
|
"from-accent/[0.06] via-surface-2 to-surface-2",
|
|
51
|
-
fresh ? "border-accent/30" : "border-border",
|
|
65
|
+
fresh || committed ? "border-accent/30" : "border-border",
|
|
52
66
|
].join(" ")}
|
|
53
67
|
>
|
|
54
68
|
<div className="flex items-center gap-2 px-4 pt-3 pb-1.5">
|
|
@@ -82,6 +96,10 @@ export function WarmSummaryCard({
|
|
|
82
96
|
>
|
|
83
97
|
<ReactMarkdown>{stripWarmHeader(summary!)}</ReactMarkdown>
|
|
84
98
|
</div>
|
|
99
|
+
) : !summary && committed ? (
|
|
100
|
+
channelSummaries.length === 0 && (
|
|
101
|
+
<div className="text-xs text-fg-faint italic">No earlier chat messages needed summarising.</div>
|
|
102
|
+
)
|
|
85
103
|
) : !summary ? (
|
|
86
104
|
<div className="flex items-center gap-2 text-xs text-fg-faint italic">
|
|
87
105
|
{computing && (
|
|
@@ -95,6 +113,10 @@ export function WarmSummaryCard({
|
|
|
95
113
|
</div>
|
|
96
114
|
) : null}
|
|
97
115
|
|
|
116
|
+
{channelSummaries.map((channel) => (
|
|
117
|
+
<ChannelSummarySection key={channel.channel} channel={channel} />
|
|
118
|
+
))}
|
|
119
|
+
|
|
98
120
|
{stale && (
|
|
99
121
|
<div className="mt-2 inline-flex items-center gap-2 text-[11px] text-fg-faint">
|
|
100
122
|
{computing ? <StatusDot tone="accent" size="sm" pulse /> : <StatusDot tone="neutral" size="sm" />}
|
|
@@ -121,6 +143,25 @@ export function WarmSummaryCard({
|
|
|
121
143
|
);
|
|
122
144
|
}
|
|
123
145
|
|
|
146
|
+
function ChannelSummarySection({ channel }: { channel: WarmChannelSummary }) {
|
|
147
|
+
const topics = channel.topics && channel.topics.length > 0
|
|
148
|
+
? channel.topics
|
|
149
|
+
: topicsFromSummarySections(channel.summary)
|
|
150
|
+
?? [{ title: "Recap", start_at: "", end_at: "", recap: stripWarmHeader(channel.summary), facts: [] }];
|
|
151
|
+
return (
|
|
152
|
+
<div className="mt-2">
|
|
153
|
+
<div className="mb-1 text-[9px] uppercase tracking-wide text-fg-faint">
|
|
154
|
+
{CHANNEL_LABELS[channel.channel] ?? channel.channel}
|
|
155
|
+
</div>
|
|
156
|
+
<div className="flex flex-col gap-1">
|
|
157
|
+
{topics.map((topic, i) => (
|
|
158
|
+
<TopicSegmentRow key={`${channel.channel}-${topic.title}-${i}`} topic={topic} />
|
|
159
|
+
))}
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
124
165
|
function TopicSegmentRow({ topic }: { topic: SummaryTopicSegment }) {
|
|
125
166
|
const [open, setOpen] = useState(false);
|
|
126
167
|
const range = formatTopicRange(topic.start_at, topic.end_at);
|
|
@@ -130,9 +171,14 @@ function TopicSegmentRow({ topic }: { topic: SummaryTopicSegment }) {
|
|
|
130
171
|
<CollapseChevron open={open} size={9} />
|
|
131
172
|
<span className="font-medium text-fg-muted truncate">{topic.title}</span>
|
|
132
173
|
{range && <span className="text-fg-faint shrink-0">· {range}</span>}
|
|
174
|
+
{typeof topic.message_count === "number" && topic.message_count > 0 && (
|
|
175
|
+
<span className="text-fg-faint shrink-0">
|
|
176
|
+
· {topic.message_count} {topic.message_count === 1 ? "msg" : "msgs"}
|
|
177
|
+
</span>
|
|
178
|
+
)}
|
|
133
179
|
{topic.facts.length > 0 && (
|
|
134
180
|
<span className="ml-auto shrink-0 text-[9px] uppercase tracking-wide text-accent">
|
|
135
|
-
{topic.facts.length}
|
|
181
|
+
{topic.facts.length} memorized
|
|
136
182
|
</span>
|
|
137
183
|
)}
|
|
138
184
|
</MetaRow>
|
|
@@ -149,13 +195,17 @@ function TopicSegmentRow({ topic }: { topic: SummaryTopicSegment }) {
|
|
|
149
195
|
</div>
|
|
150
196
|
)}
|
|
151
197
|
{topic.facts.length > 0 && (
|
|
152
|
-
<
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
198
|
+
<div>
|
|
199
|
+
<div className="text-[9px] uppercase tracking-wide text-fg-faint">Memorized</div>
|
|
200
|
+
<ul className="space-y-0.5">
|
|
201
|
+
{topic.facts.map((fact, i) => (
|
|
202
|
+
<li key={`${fact.key ?? fact.subject}-${i}`} className="text-[11px] text-fg-faint">
|
|
203
|
+
<span className="font-medium text-fg-muted">{fact.subject}:</span> {fact.content}
|
|
204
|
+
{fact.key && <code className="ml-1 text-[10px] text-fg-faint">{fact.key}</code>}
|
|
205
|
+
</li>
|
|
206
|
+
))}
|
|
207
|
+
</ul>
|
|
208
|
+
</div>
|
|
159
209
|
)}
|
|
160
210
|
</div>
|
|
161
211
|
)}
|
|
@@ -313,11 +363,40 @@ function formatBytes(n: number): string {
|
|
|
313
363
|
// awkwardly inside a card that already has its own header. Strip them.
|
|
314
364
|
function stripWarmHeader(raw: string): string {
|
|
315
365
|
return raw
|
|
366
|
+
.replace(/\r\n/g, "\n")
|
|
367
|
+
.replace(/^\s*(<!--[\s\S]*?-->\s*)+/, "")
|
|
316
368
|
.replace(/^--- Warm context summary ---\n/, "")
|
|
317
|
-
.replace(/^Compressed recap of
|
|
369
|
+
.replace(/^Compressed recap of [^\n]*:\n/, "")
|
|
318
370
|
.trimStart();
|
|
319
371
|
}
|
|
320
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Splits a markdown summary into topic segments at its headings. Returns
|
|
375
|
+
* null when there are fewer than two sections, so short or unstructured
|
|
376
|
+
* summaries keep the plain prose rendering.
|
|
377
|
+
*/
|
|
378
|
+
export function topicsFromSummarySections(raw: string): SummaryTopicSegment[] | null {
|
|
379
|
+
const sections: SummaryTopicSegment[] = [];
|
|
380
|
+
let title: string | null = null;
|
|
381
|
+
let body: string[] = [];
|
|
382
|
+
const flush = () => {
|
|
383
|
+
const recap = body.join("\n").trim();
|
|
384
|
+
if (title !== null || recap) sections.push({ title: title ?? "Overview", start_at: "", end_at: "", recap, facts: [] });
|
|
385
|
+
};
|
|
386
|
+
for (const line of stripWarmHeader(raw).split("\n")) {
|
|
387
|
+
const heading = /^#{1,3}\s+(.+?)\s*#*\s*$/.exec(line);
|
|
388
|
+
if (heading) {
|
|
389
|
+
flush();
|
|
390
|
+
title = heading[1];
|
|
391
|
+
body = [];
|
|
392
|
+
} else {
|
|
393
|
+
body.push(line);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
flush();
|
|
397
|
+
return sections.length >= 2 ? sections : null;
|
|
398
|
+
}
|
|
399
|
+
|
|
321
400
|
function summaryLong(raw: string): boolean {
|
|
322
401
|
// Heuristic: more than 6 lines or > 600 chars after the header strip.
|
|
323
402
|
const stripped = stripWarmHeader(raw);
|
|
@@ -584,4 +584,35 @@ describe("MessageList conversation focus", () => {
|
|
|
584
584
|
fireEvent.click(enabledButton);
|
|
585
585
|
expect(scrollIntoView).toHaveBeenCalled();
|
|
586
586
|
});
|
|
587
|
+
|
|
588
|
+
it("keeps a near-bottom boundary locate from snapping back to the bottom", () => {
|
|
589
|
+
const messages = [
|
|
590
|
+
mkMessage("m1", "user", "older", "2026-08-09T10:00:00.000Z"),
|
|
591
|
+
mkMessage("m2", "assistant", "newer", "2026-08-09T10:00:01.000Z"),
|
|
592
|
+
mkMessage("m3", "assistant", "latest", "2026-08-09T10:00:02.000Z"),
|
|
593
|
+
];
|
|
594
|
+
const props = { threadId: "thread-1", onSetContextPin: vi.fn(), hotSinceSeq: 2 };
|
|
595
|
+
const { container, rerender } = render(<MessageList {...props} messages={messages} />);
|
|
596
|
+
|
|
597
|
+
const scroller = container.querySelector(".panel-scrollbar") as HTMLDivElement;
|
|
598
|
+
Object.defineProperty(scroller, "scrollHeight", { configurable: true, value: 2000 });
|
|
599
|
+
Object.defineProperty(scroller, "clientHeight", { configurable: true, value: 500 });
|
|
600
|
+
Object.defineProperty(scroller, "scrollTop", { configurable: true, writable: true, value: 1500 });
|
|
601
|
+
fireEvent.scroll(scroller);
|
|
602
|
+
|
|
603
|
+
// Simulate the first smooth-scroll frame: still within 100px of the bottom.
|
|
604
|
+
const boundaryEl = document.querySelector("[data-focus-boundary='1']") as HTMLElement;
|
|
605
|
+
boundaryEl.scrollIntoView = vi.fn(() => {
|
|
606
|
+
scroller.scrollTop = 1450;
|
|
607
|
+
fireEvent.scroll(scroller);
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
fireEvent.click(screen.getByRole("button", { name: /filters & focus/i }));
|
|
611
|
+
fireEvent.click(screen.getByRole("button", { name: "Locate boundary line" }));
|
|
612
|
+
expect(boundaryEl.scrollIntoView).toHaveBeenCalledWith({ behavior: "smooth", block: "center" });
|
|
613
|
+
expect(boundaryEl.classList.contains("jarela-deep-link-flash")).toBe(true);
|
|
614
|
+
|
|
615
|
+
rerender(<MessageList {...props} messages={[...messages]} />);
|
|
616
|
+
expect(scroller.scrollTop).toBe(1450);
|
|
617
|
+
});
|
|
587
618
|
});
|
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { Brain, ChevronRight, Hourglass, X, ArrowDown, Eye, EyeOff } from "lucide-react";
|
|
4
|
-
import type { AgentConfig, AutomationActivityMetadata, ContentPart, Message, SummaryTopicSegment, UserProfile } from "@/api/types";
|
|
4
|
+
import type { AgentConfig, AutomationActivityMetadata, ContentPart, Message, SummaryTopicSegment, UserProfile, WarmChannelSummary } from "@/api/types";
|
|
5
5
|
import { ToolList, type ToolEvent } from "./ToolList";
|
|
6
6
|
import { MessageBubble } from "./MessageBubble";
|
|
7
7
|
import { ContextBoundaryDivider, WarmSummaryCard } from "./ContextBoundary";
|
|
8
|
+
import { WorkflowStepRetryContext, workflowStepRetryMessage, type WorkflowStepRetryRequest } from "./workflow-step-retry";
|
|
8
9
|
import { MESSAGE_FILTER_KEYS, type MessageFilterKey } from "@/hooks/useMessageFilters";
|
|
9
10
|
import { CollapseChevron } from "@/components/ui/CollapseChevron";
|
|
10
11
|
import { MetaRow } from "@/components/ui/MetaRow";
|
|
11
12
|
import { StatusDot } from "@/components/ui/StatusDot";
|
|
12
13
|
import { Dialog } from "@/components/ui/Dialog";
|
|
13
14
|
|
|
14
|
-
interface SystemNotice {
|
|
15
|
-
id: string;
|
|
16
|
-
text: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
15
|
interface QueuedMessageView {
|
|
20
16
|
id: string;
|
|
21
17
|
text: string;
|
|
@@ -31,7 +27,6 @@ interface Props {
|
|
|
31
27
|
threadId?: string | null;
|
|
32
28
|
messages: Message[];
|
|
33
29
|
steeredSegments?: SteeredSegment[];
|
|
34
|
-
notices?: SystemNotice[];
|
|
35
30
|
agentConfig?: AgentConfig | null;
|
|
36
31
|
userProfile?: UserProfile | null;
|
|
37
32
|
streamingContent?: string;
|
|
@@ -53,6 +48,8 @@ interface Props {
|
|
|
53
48
|
warmSummarySourceMessages?: number | null;
|
|
54
49
|
warmSummarySourceChars?: number | null;
|
|
55
50
|
warmSummaryTopics?: SummaryTopicSegment[] | null;
|
|
51
|
+
/** Automation-channel recaps committed at the current boundary. */
|
|
52
|
+
warmChannelSummaries?: WarmChannelSummary[];
|
|
56
53
|
warmSummaryPending?: boolean;
|
|
57
54
|
/** An automatic compaction is summarising earlier messages right now. */
|
|
58
55
|
compactionPending?: boolean;
|
|
@@ -78,8 +75,9 @@ interface Props {
|
|
|
78
75
|
const ALL_FILTERS_SHOWN: Record<MessageFilterKey, boolean> = Object.fromEntries(
|
|
79
76
|
MESSAGE_FILTER_KEYS.map((k) => [k, true]),
|
|
80
77
|
) as Record<MessageFilterKey, boolean>;
|
|
78
|
+
const NO_CHANNEL_SUMMARIES: WarmChannelSummary[] = [];
|
|
81
79
|
|
|
82
|
-
export function MessageList({ threadId, messages, steeredSegments,
|
|
80
|
+
export function MessageList({ threadId, messages, steeredSegments, agentConfig, userProfile, streamingContent, thinkingContent, toolEvents, hasMore, loadingMore, onLoadMore, queuedMessages, onRemoveQueued, hotSinceSeq, warmSummary, warmSummaryBeforeSeq, warmSummaryComputedAt, warmSummarySourceMessages, warmSummarySourceChars, warmSummaryTopics, warmChannelSummaries = NO_CHANNEL_SUMMARIES, warmSummaryPending = false, compactionPending = false, onSetContextPin, streaming, contextWindowTokens, onRetryMessage, filters = ALL_FILTERS_SHOWN, onToggleFilter: toggle = () => {}, onResetFilters: reset = () => {} }: Props) {
|
|
83
81
|
const hostRef = useRef<HTMLDivElement>(null);
|
|
84
82
|
const maskRegionRef = useRef<HTMLDivElement>(null);
|
|
85
83
|
const scrollRef = useRef<HTMLDivElement>(null);
|
|
@@ -104,6 +102,13 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
104
102
|
const [pendingHotSinceSeq, setPendingHotSinceSeq] = useState<number | null>(null);
|
|
105
103
|
const [topControlsOpen, setTopControlsOpen] = useState(false);
|
|
106
104
|
const [summaryPopoverOpen, setSummaryPopoverOpen] = useState(false);
|
|
105
|
+
|
|
106
|
+
const retryWorkflowStep = useMemo(
|
|
107
|
+
() => onRetryMessage
|
|
108
|
+
? (request: WorkflowStepRetryRequest) => onRetryMessage(workflowStepRetryMessage(request), [])
|
|
109
|
+
: null,
|
|
110
|
+
[onRetryMessage],
|
|
111
|
+
);
|
|
107
112
|
|
|
108
113
|
// Apply category filter. Messages with no `category` (NULL = ordinary
|
|
109
114
|
// chat) are always shown; tagged messages are gated by their toggle.
|
|
@@ -503,9 +508,15 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
503
508
|
? nextHotCount < currentHotCount
|
|
504
509
|
: false;
|
|
505
510
|
const hasWarmSummary = !!warmSummary;
|
|
511
|
+
// A committed boundary whose chat range had nothing to summarise (e.g. a
|
|
512
|
+
// bridge-only agent): the recap, if any, lives in the channel summaries.
|
|
513
|
+
const summaryCommittedEmpty = !hasWarmSummary
|
|
514
|
+
&& effectiveHotSinceSeq !== null
|
|
515
|
+
&& warmSummaryBeforeSeq === effectiveHotSinceSeq;
|
|
506
516
|
const summaryFresh = hasWarmSummary
|
|
507
517
|
&& effectiveHotSinceSeq !== null
|
|
508
518
|
&& warmSummaryBeforeSeq === effectiveHotSinceSeq;
|
|
519
|
+
const summaryReady = summaryFresh || summaryCommittedEmpty;
|
|
509
520
|
const summaryUpdating = hasWarmSummary && !summaryFresh && !!streaming;
|
|
510
521
|
const summaryStale = hasWarmSummary && !summaryFresh && !summaryUpdating;
|
|
511
522
|
|
|
@@ -593,10 +604,25 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
593
604
|
boundaryAnchorRef.current = null;
|
|
594
605
|
}, []);
|
|
595
606
|
|
|
607
|
+
// While a programmatic smooth scroll (locate boundary, deep link) animates
|
|
608
|
+
// away from the bottom, its first frames are still "near bottom". Without
|
|
609
|
+
// this lock, scroll sync re-arms bottom-follow and the post-render snap
|
|
610
|
+
// cancels the animation, so the target is never reached.
|
|
611
|
+
const programmaticScrollUntilRef = useRef(0);
|
|
596
612
|
const syncScrollButton = useCallback((el: HTMLDivElement) => {
|
|
597
613
|
const isAtBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 100;
|
|
598
|
-
|
|
599
|
-
|
|
614
|
+
const locked = Date.now() < programmaticScrollUntilRef.current;
|
|
615
|
+
atBottomRef.current = isAtBottom && !locked;
|
|
616
|
+
setShowScrollButton(!atBottomRef.current && hasScrollTarget);
|
|
617
|
+
}, [hasScrollTarget]);
|
|
618
|
+
|
|
619
|
+
const scrollTargetIntoView = useCallback((target: HTMLElement) => {
|
|
620
|
+
programmaticScrollUntilRef.current = Date.now() + PROGRAMMATIC_SCROLL_LOCK_MS;
|
|
621
|
+
atBottomRef.current = false;
|
|
622
|
+
setShowScrollButton(hasScrollTarget);
|
|
623
|
+
target.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
624
|
+
target.classList.add("jarela-deep-link-flash");
|
|
625
|
+
window.setTimeout(() => target.classList.remove("jarela-deep-link-flash"), 1600);
|
|
600
626
|
}, [hasScrollTarget]);
|
|
601
627
|
|
|
602
628
|
// Anchor for older-message pagination. When the user scrolls near the top
|
|
@@ -715,11 +741,7 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
715
741
|
const safe = id.replace(/"/g, '\\"');
|
|
716
742
|
const el = root.querySelector(`[data-message-id="${safe}"]`) as HTMLElement | null;
|
|
717
743
|
if (!el) return;
|
|
718
|
-
|
|
719
|
-
setShowScrollButton(hasScrollTarget);
|
|
720
|
-
el.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
721
|
-
el.classList.add("jarela-deep-link-flash");
|
|
722
|
-
setTimeout(() => el.classList.remove("jarela-deep-link-flash"), 1600);
|
|
744
|
+
scrollTargetIntoView(el);
|
|
723
745
|
// Strip the hash so the next streaming message / list-length change
|
|
724
746
|
// doesn't yank the view back to this anchor. replaceState avoids
|
|
725
747
|
// triggering a hashchange event (which would re-enter this handler).
|
|
@@ -730,7 +752,7 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
730
752
|
scrollToHashTarget();
|
|
731
753
|
window.addEventListener("hashchange", scrollToHashTarget);
|
|
732
754
|
return () => window.removeEventListener("hashchange", scrollToHashTarget);
|
|
733
|
-
}, [messages.length,
|
|
755
|
+
}, [messages.length, scrollTargetIntoView]);
|
|
734
756
|
|
|
735
757
|
// Handle orientation changes and resizes to maintain scroll position
|
|
736
758
|
useEffect(() => {
|
|
@@ -765,12 +787,11 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
765
787
|
? document.getElementById(`context-boundary-${effectiveHotSinceSeq}`)
|
|
766
788
|
: root.querySelector("[data-focus-boundary='1']") as HTMLElement | null;
|
|
767
789
|
if (!boundary) return;
|
|
768
|
-
|
|
769
|
-
setShowScrollButton(hasScrollTarget);
|
|
770
|
-
boundary.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
790
|
+
scrollTargetIntoView(boundary);
|
|
771
791
|
}
|
|
772
792
|
|
|
773
793
|
return (
|
|
794
|
+
<WorkflowStepRetryContext.Provider value={retryWorkflowStep}>
|
|
774
795
|
<div ref={hostRef} className="flex-1 flex flex-col min-h-0 relative">
|
|
775
796
|
{visibleMessages.length > 0 && (
|
|
776
797
|
<div className="shrink-0 px-4 pt-[calc(var(--app-safe-top)+3rem)] pb-1">
|
|
@@ -1014,13 +1035,6 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
1014
1035
|
))}
|
|
1015
1036
|
</div>
|
|
1016
1037
|
)}
|
|
1017
|
-
{notices?.map((n) => (
|
|
1018
|
-
<div key={n.id} className="flex justify-center my-3">
|
|
1019
|
-
<span className="text-xs italic text-fg-faint bg-surface-2 px-3 py-1 rounded-full border border-border">
|
|
1020
|
-
{n.text}
|
|
1021
|
-
</span>
|
|
1022
|
-
</div>
|
|
1023
|
-
))}
|
|
1024
1038
|
</div>
|
|
1025
1039
|
|
|
1026
1040
|
<div
|
|
@@ -1079,7 +1093,7 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
1079
1093
|
className={[
|
|
1080
1094
|
"text-[10px] px-1.5 py-px rounded border inline-flex items-center gap-1",
|
|
1081
1095
|
summaryUpdating ? "border-accent/40 bg-accent/10 text-accent" :
|
|
1082
|
-
|
|
1096
|
+
summaryReady ? "border-emerald-500/30 bg-emerald-500/10 text-emerald-600 dark:text-emerald-400" :
|
|
1083
1097
|
summaryStale ? "border-amber-500/30 bg-amber-500/10 text-amber-700 dark:text-amber-400" :
|
|
1084
1098
|
"border-border bg-surface-2 text-fg-faint",
|
|
1085
1099
|
].join(" ")}
|
|
@@ -1088,7 +1102,7 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
1088
1102
|
<span className="h-2 w-2 rounded-full bg-accent animate-pulse" aria-label="Summary updating" />
|
|
1089
1103
|
)}
|
|
1090
1104
|
<span>
|
|
1091
|
-
{summaryUpdating ? "updating" :
|
|
1105
|
+
{summaryUpdating ? "updating" : summaryReady ? "ready" : summaryStale ? "needs refresh" : "pending"}
|
|
1092
1106
|
</span>
|
|
1093
1107
|
</span>
|
|
1094
1108
|
</div>
|
|
@@ -1096,6 +1110,10 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
1096
1110
|
<p className="text-[11px] text-fg-faint">
|
|
1097
1111
|
{summaryFresh
|
|
1098
1112
|
? "Showing the latest summary for messages above the boundary line."
|
|
1113
|
+
: summaryCommittedEmpty
|
|
1114
|
+
? (warmChannelSummaries.length > 0
|
|
1115
|
+
? "No chat messages above the boundary line; automation activity there is summarised below."
|
|
1116
|
+
: "Nothing above the boundary line needed summarising.")
|
|
1099
1117
|
: summaryStale
|
|
1100
1118
|
? "This summary is from an older focus and will refresh after the next reply."
|
|
1101
1119
|
: "No summary yet. It will appear after the next reply."}
|
|
@@ -1109,6 +1127,7 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
1109
1127
|
computedAt={warmSummaryComputedAt ?? null}
|
|
1110
1128
|
streaming={!!streaming}
|
|
1111
1129
|
topics={warmSummaryTopics ?? null}
|
|
1130
|
+
channelSummaries={warmChannelSummaries}
|
|
1112
1131
|
/>
|
|
1113
1132
|
</div>
|
|
1114
1133
|
</Dialog>
|
|
@@ -1157,6 +1176,7 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
1157
1176
|
</div>
|
|
1158
1177
|
</Dialog>
|
|
1159
1178
|
</div>
|
|
1179
|
+
</WorkflowStepRetryContext.Provider>
|
|
1160
1180
|
);
|
|
1161
1181
|
}
|
|
1162
1182
|
|
|
@@ -1165,6 +1185,7 @@ export function MessageList({ threadId, messages, steeredSegments, notices, agen
|
|
|
1165
1185
|
// activeChannels + lib/agents/prepare/history-window.ts). The rest
|
|
1166
1186
|
// (extension, page_capture, synthetic, tool_use, thinking) are display-only.
|
|
1167
1187
|
const CHANNEL_SCOPED_FILTER_KEYS = new Set<MessageFilterKey>(["scheduled_task", "watcher", "bridge"]);
|
|
1188
|
+
const PROGRAMMATIC_SCROLL_LOCK_MS = 1500;
|
|
1168
1189
|
|
|
1169
1190
|
const CHIP_LABELS: Record<MessageFilterKey, string> = {
|
|
1170
1191
|
scheduled_task: "scheduled",
|