@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.
Files changed (651) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +6 -5
  3. package/.next/standalone/.next/build-manifest.json +2 -2
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/routes-manifest.json +8 -0
  6. package/.next/standalone/.next/server/app/_global-error/page.js +68 -68
  7. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page.js +76 -76
  14. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  16. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  17. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  18. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  19. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  21. package/.next/standalone/.next/server/app/api/v1/access/[identity]/route.js +93 -93
  22. package/.next/standalone/.next/server/app/api/v1/access/route.js +169 -169
  23. package/.next/standalone/.next/server/app/api/v1/agents/[id]/compact/route.js +82 -56
  24. package/.next/standalone/.next/server/app/api/v1/agents/[id]/compact/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/v1/agents/[id]/display-filters/route.js +122 -122
  26. package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js +100 -100
  27. package/.next/standalone/.next/server/app/api/v1/agents/[id]/thread/route.js +753 -753
  28. package/.next/standalone/.next/server/app/api/v1/agents/route.js +65 -65
  29. package/.next/standalone/.next/server/app/api/v1/allowed-sites/[hostname]/route.js +364 -364
  30. package/.next/standalone/.next/server/app/api/v1/allowed-sites/route.js +802 -802
  31. package/.next/standalone/.next/server/app/api/v1/artifacts/lifecycle/route.js +2 -2
  32. package/.next/standalone/.next/server/app/api/v1/attachments/files/route.js +49 -49
  33. package/.next/standalone/.next/server/app/api/v1/attachments/images/route.js +910 -910
  34. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js +589 -16
  35. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/ignores/[remote_jid]/route.js +23 -23
  37. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/ignores/route.js +30 -30
  38. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js +703 -130
  39. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js +708 -135
  41. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js +802 -229
  43. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/routes/[route_id]/route.js +739 -739
  45. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/routes/route.js +1035 -1035
  46. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js +679 -106
  47. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/v1/bridges/kinds/route.js +804 -804
  49. package/.next/standalone/.next/server/app/api/v1/bridges/route.js +700 -700
  50. package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js +9 -9
  51. package/.next/standalone/.next/server/app/api/v1/builtin-tools/route.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/api/v1/config/route.js +85 -85
  53. package/.next/standalone/.next/server/app/api/v1/credentials/[id]/route.js +709 -709
  54. package/.next/standalone/.next/server/app/api/v1/credentials/[id]/route.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/api/v1/credentials/route.js +2 -2
  56. package/.next/standalone/.next/server/app/api/v1/credentials/route.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/api/v1/dashboard/currency/route.js +10 -10
  58. package/.next/standalone/.next/server/app/api/v1/dashboard/metrics/route.js +784 -784
  59. package/.next/standalone/.next/server/app/api/v1/dashboard/pricing/route.js +23 -23
  60. package/.next/standalone/.next/server/app/api/v1/dashboard/pricing-task/route.js +86 -86
  61. package/.next/standalone/.next/server/app/api/v1/dashboard/pricing-task/route.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/api/v1/delegations/codex/[job_id]/route.js +57 -57
  63. package/.next/standalone/.next/server/app/api/v1/delegations/codex/[job_id]/route.js.nft.json +1 -1
  64. package/.next/standalone/.next/server/app/api/v1/documents/search/route.js +523 -523
  65. package/.next/standalone/.next/server/app/api/v1/documents/settings/route.js +44 -44
  66. package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/reindex/route.js +65 -65
  67. package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/reindex/route.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/route.js +122 -122
  69. package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/route.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/api/v1/documents/sources/route.js +37 -37
  71. package/.next/standalone/.next/server/app/api/v1/documents/sources/route.js.nft.json +1 -1
  72. package/.next/standalone/.next/server/app/api/v1/env/route.js +9 -9
  73. package/.next/standalone/.next/server/app/api/v1/env-sync/allowlist/route.js +368 -368
  74. package/.next/standalone/.next/server/app/api/v1/env-sync/route.js +44 -44
  75. package/.next/standalone/.next/server/app/api/v1/events/route.js +751 -178
  76. package/.next/standalone/.next/server/app/api/v1/events/route.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/api/v1/events/test/route.js +77 -77
  78. package/.next/standalone/.next/server/app/api/v1/extension/agents/route.js +763 -763
  79. package/.next/standalone/.next/server/app/api/v1/extension/agents/route.js.nft.json +1 -1
  80. package/.next/standalone/.next/server/app/api/v1/extension/browser/activate/route.js +44 -44
  81. package/.next/standalone/.next/server/app/api/v1/extension/browser/foreground/route.js +9 -9
  82. package/.next/standalone/.next/server/app/api/v1/extension/browser/history/route.js +65 -65
  83. package/.next/standalone/.next/server/app/api/v1/extension/browser/poll/route.js +34 -34
  84. package/.next/standalone/.next/server/app/api/v1/extension/browser/progress/route.js +204 -204
  85. package/.next/standalone/.next/server/app/api/v1/extension/browser/result/route.js +133 -133
  86. package/.next/standalone/.next/server/app/api/v1/extension/browser/retry/route.js +106 -106
  87. package/.next/standalone/.next/server/app/api/v1/extension/browser/status/route.js +114 -114
  88. package/.next/standalone/.next/server/app/api/v1/extension/browser/tabs/route.js +134 -134
  89. package/.next/standalone/.next/server/app/api/v1/extension/fill/route.js +690 -690
  90. package/.next/standalone/.next/server/app/api/v1/extension/fill/route.js.nft.json +1 -1
  91. package/.next/standalone/.next/server/app/api/v1/extension/refine/route.js +93 -93
  92. package/.next/standalone/.next/server/app/api/v1/extension/refine/route.js.nft.json +1 -1
  93. package/.next/standalone/.next/server/app/api/v1/extension/turn/route.js +9 -9
  94. package/.next/standalone/.next/server/app/api/v1/extension/turn/route.js.nft.json +1 -1
  95. package/.next/standalone/.next/server/app/api/v1/extensions/route.js +185 -185
  96. package/.next/standalone/.next/server/app/api/v1/extensions/route.js.nft.json +1 -1
  97. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/config/route.js +171 -171
  98. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/config/route.js.nft.json +1 -1
  99. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/route.js +396 -396
  100. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/route.js.nft.json +1 -1
  101. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js +212 -212
  102. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js.nft.json +1 -1
  103. package/.next/standalone/.next/server/app/api/v1/files/[name]/route.js +235 -235
  104. package/.next/standalone/.next/server/app/api/v1/fs/browse/route.js +26 -26
  105. package/.next/standalone/.next/server/app/api/v1/harnesses/[id]/route.js +221 -221
  106. package/.next/standalone/.next/server/app/api/v1/harnesses/default/route.js +58 -58
  107. package/.next/standalone/.next/server/app/api/v1/harnesses/route.js +72 -72
  108. package/.next/standalone/.next/server/app/api/v1/health/probes/route.js +9 -9
  109. package/.next/standalone/.next/server/app/api/v1/health/probes/route.js.nft.json +1 -1
  110. package/.next/standalone/.next/server/app/api/v1/health/route.js +772 -772
  111. package/.next/standalone/.next/server/app/api/v1/integrations/[name]/route.js +133 -133
  112. package/.next/standalone/.next/server/app/api/v1/integrations/[name]/test/route.js +9 -9
  113. package/.next/standalone/.next/server/app/api/v1/integrations/[name]/test/route.js.nft.json +1 -1
  114. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/callback/route.js +363 -363
  115. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/start/route.js +233 -233
  116. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/status/route.js +682 -682
  117. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/callback/route.js +879 -879
  118. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/start/route.js +108 -108
  119. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/status/route.js +952 -952
  120. package/.next/standalone/.next/server/app/api/v1/integrations/route.js +216 -216
  121. package/.next/standalone/.next/server/app/api/v1/lifecycle/adoption/route.js +864 -847
  122. package/.next/standalone/.next/server/app/api/v1/lifecycle/adoption/route.js.nft.json +1 -1
  123. package/.next/standalone/.next/server/app/api/v1/local-file/route.js +26 -26
  124. package/.next/standalone/.next/server/app/api/v1/logs/route.js +70 -70
  125. package/.next/standalone/.next/server/app/api/v1/maps/embed/route.js +72 -72
  126. package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js +979 -979
  127. package/.next/standalone/.next/server/app/api/v1/mcp-servers/registry/route.js +196 -196
  128. package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js +2 -2
  129. package/.next/standalone/.next/server/app/api/v1/memory/[namespace]/[key]/route.js +381 -381
  130. package/.next/standalone/.next/server/app/api/v1/memory/policy/route.js +79 -79
  131. package/.next/standalone/.next/server/app/api/v1/memory/route.js +51 -51
  132. package/.next/standalone/.next/server/app/api/v1/memory/search/route.js +131 -131
  133. package/.next/standalone/.next/server/app/api/v1/models/[name]/compact-threads/route.js +374 -369
  134. package/.next/standalone/.next/server/app/api/v1/models/[name]/compact-threads/route.js.nft.json +1 -1
  135. package/.next/standalone/.next/server/app/api/v1/models/[name]/route.js +143 -143
  136. package/.next/standalone/.next/server/app/api/v1/models/route.js +543 -543
  137. package/.next/standalone/.next/server/app/api/v1/packages/catalog/route.js +445 -445
  138. package/.next/standalone/.next/server/app/api/v1/packages/defaults/[id]/route.js +120 -120
  139. package/.next/standalone/.next/server/app/api/v1/packages/defaults/[id]/route.js.nft.json +1 -1
  140. package/.next/standalone/.next/server/app/api/v1/packages/install/[id]/route.js +234 -234
  141. package/.next/standalone/.next/server/app/api/v1/packages/install/[id]/route.js.nft.json +1 -1
  142. package/.next/standalone/.next/server/app/api/v1/packages/install/route.js +407 -407
  143. package/.next/standalone/.next/server/app/api/v1/packages/install/route.js.nft.json +1 -1
  144. package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/enabled/route.js +37 -37
  145. package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/enabled/route.js.nft.json +1 -1
  146. package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/route.js +107 -107
  147. package/.next/standalone/.next/server/app/api/v1/packages/manifests/[name]/route.js.nft.json +1 -1
  148. package/.next/standalone/.next/server/app/api/v1/packages/manifests/route.js +228 -228
  149. package/.next/standalone/.next/server/app/api/v1/packages/manifests/route.js.nft.json +1 -1
  150. package/.next/standalone/.next/server/app/api/v1/packages/reload/route.js +9 -9
  151. package/.next/standalone/.next/server/app/api/v1/packages/reload/route.js.nft.json +1 -1
  152. package/.next/standalone/.next/server/app/api/v1/packages/route.js +148 -148
  153. package/.next/standalone/.next/server/app/api/v1/packages/route.js.nft.json +1 -1
  154. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js +787 -787
  155. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js.nft.json +1 -1
  156. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js +507 -507
  157. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js.nft.json +1 -1
  158. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/deny/route.js +181 -181
  159. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/deny/route.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/api/v1/pending-actions/route.js +258 -258
  161. package/.next/standalone/.next/server/app/api/v1/pending-actions/route.js.nft.json +1 -1
  162. package/.next/standalone/.next/server/app/api/v1/profile/location/route.js +30 -30
  163. package/.next/standalone/.next/server/app/api/v1/profile/route.js +164 -164
  164. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js +44 -44
  165. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/probe/route.js +9 -9
  166. package/.next/standalone/.next/server/app/api/v1/providers/github-copilot/auth/route.js +164 -164
  167. package/.next/standalone/.next/server/app/api/v1/providers/route.js +94 -94
  168. package/.next/standalone/.next/server/app/api/v1/proxy-config/route.js +450 -450
  169. package/.next/standalone/.next/server/app/api/v1/redaction/init/route.js +37 -37
  170. package/.next/standalone/.next/server/app/api/v1/redaction/route.js +58 -58
  171. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/route.js +600 -600
  172. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/run/route.js +44 -44
  173. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/run/route.js.nft.json +1 -1
  174. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/route.js +732 -732
  175. package/.next/standalone/.next/server/app/api/v1/security/idle-timeout/route.js +359 -359
  176. package/.next/standalone/.next/server/app/api/v1/security/pin/route.js +197 -197
  177. package/.next/standalone/.next/server/app/api/v1/security/state/route.js +51 -51
  178. package/.next/standalone/.next/server/app/api/v1/security/unlock/route.js +176 -176
  179. package/.next/standalone/.next/server/app/api/v1/security/verify-pin/route.js +190 -190
  180. package/.next/standalone/.next/server/app/api/v1/setup/test-key/route.js +26 -26
  181. package/.next/standalone/.next/server/app/api/v1/skills/[id]/route.js +770 -770
  182. package/.next/standalone/.next/server/app/api/v1/skills/repos/[id]/route.js +115 -115
  183. package/.next/standalone/.next/server/app/api/v1/skills/repos/route.js +327 -327
  184. package/.next/standalone/.next/server/app/api/v1/skills/route.js +870 -870
  185. package/.next/standalone/.next/server/app/api/v1/system/abort/route.js +838 -808
  186. package/.next/standalone/.next/server/app/api/v1/system/restart/route.js +177 -177
  187. package/.next/standalone/.next/server/app/api/v1/system/restart/route.js.nft.json +1 -1
  188. package/.next/standalone/.next/server/app/api/v1/tailscale/route.js +164 -164
  189. package/.next/standalone/.next/server/app/api/v1/tasks/[agent_id]/route.js +115 -115
  190. package/.next/standalone/.next/server/app/api/v1/tasks/route.js +23 -23
  191. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route.js +1429 -0
  192. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route.js.nft.json +1 -0
  193. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route_client-reference-manifest.js +1 -0
  194. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/context-pin/route.js +635 -634
  195. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/context-pin/route.js.nft.json +1 -1
  196. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js +53 -439
  197. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js.nft.json +1 -1
  198. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js +172 -172
  199. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js.nft.json +1 -1
  200. package/.next/standalone/.next/server/app/api/v1/threads/route.js +908 -908
  201. package/.next/standalone/.next/server/app/api/v1/tools/route.js +2 -2
  202. package/.next/standalone/.next/server/app/api/v1/tools/route.js.nft.json +1 -1
  203. package/.next/standalone/.next/server/app/api/v1/update/apply/route.js +17 -17
  204. package/.next/standalone/.next/server/app/api/v1/update/apply/route.js.nft.json +1 -1
  205. package/.next/standalone/.next/server/app/api/v1/update/route.js +570 -570
  206. package/.next/standalone/.next/server/app/api/v1/voice/transcribe/route.js +224 -224
  207. package/.next/standalone/.next/server/app/api/v1/voice/tts/route.js +975 -975
  208. package/.next/standalone/.next/server/app/api/v1/watchers/[id]/route.js +23 -23
  209. package/.next/standalone/.next/server/app/api/v1/watchers/[id]/run/route.js +72 -72
  210. package/.next/standalone/.next/server/app/api/v1/watchers/[id]/run/route.js.nft.json +1 -1
  211. package/.next/standalone/.next/server/app/api/v1/watchers/reaction-scripts/route.js +128 -128
  212. package/.next/standalone/.next/server/app/api/v1/watchers/route.js +164 -164
  213. package/.next/standalone/.next/server/app/api/v1/watchers/route.js.nft.json +1 -1
  214. package/.next/standalone/.next/server/app/icon.svg/route.js +62 -62
  215. package/.next/standalone/.next/server/app/manifest.webmanifest/route.js +436 -436
  216. package/.next/standalone/.next/server/app/page.js +1243 -854
  217. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  218. package/.next/standalone/.next/server/app/setup/page.js +91 -91
  219. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  220. package/.next/standalone/.next/server/app-paths-manifest.json +6 -5
  221. package/.next/standalone/.next/server/chunks/{424.js → 1388.js} +335 -986
  222. package/.next/standalone/.next/server/chunks/1433.js +1 -1
  223. package/.next/standalone/.next/server/chunks/1638.js +1 -2
  224. package/.next/standalone/.next/server/chunks/1738.js +1 -1
  225. package/.next/standalone/.next/server/chunks/210.js +6 -6
  226. package/.next/standalone/.next/server/chunks/2151.js +31 -1
  227. package/.next/standalone/.next/server/chunks/2207.js +1 -0
  228. package/.next/standalone/.next/server/chunks/2471.js +28 -28
  229. package/.next/standalone/.next/server/chunks/2504.js +1 -1
  230. package/.next/standalone/.next/server/chunks/2695.js +17 -17
  231. package/.next/standalone/.next/server/chunks/3042.js +14 -8
  232. package/.next/standalone/.next/server/chunks/3399.js +1 -1
  233. package/.next/standalone/.next/server/chunks/3566.js +1 -1
  234. package/.next/standalone/.next/server/chunks/4189.js +946 -0
  235. package/.next/standalone/.next/server/chunks/{9590.js → 423.js} +8 -3
  236. package/.next/standalone/.next/server/chunks/4433.js +146 -146
  237. package/.next/standalone/.next/server/chunks/4508.js +1 -1
  238. package/.next/standalone/.next/server/chunks/4588.js +1 -0
  239. package/.next/standalone/.next/server/chunks/46.js +5 -0
  240. package/.next/standalone/.next/server/chunks/466.js +12 -0
  241. package/.next/standalone/.next/server/chunks/4868.js +206 -206
  242. package/.next/standalone/.next/server/chunks/4992.js +13 -0
  243. package/.next/standalone/.next/server/chunks/5120.js +963 -0
  244. package/.next/standalone/.next/server/chunks/5701.js +1 -1
  245. package/.next/standalone/.next/server/chunks/5900.js +1 -1
  246. package/.next/standalone/.next/server/chunks/6210.js +1 -0
  247. package/.next/standalone/.next/server/chunks/6213.js +1 -1
  248. package/.next/standalone/.next/server/chunks/6649.js +2 -2
  249. package/.next/standalone/.next/server/chunks/6703.js +3 -3
  250. package/.next/standalone/.next/server/chunks/7445.js +1 -0
  251. package/.next/standalone/.next/server/chunks/8067.js +12 -0
  252. package/.next/standalone/.next/server/chunks/8461.js +14 -9
  253. package/.next/standalone/.next/server/chunks/8558.js +1 -1
  254. package/.next/standalone/.next/server/chunks/8724.js +1 -1
  255. package/.next/standalone/.next/server/chunks/8849.js +91 -91
  256. package/.next/standalone/.next/server/chunks/9032.js +6 -5
  257. package/.next/standalone/.next/server/chunks/{2563.js → 9164.js} +33173 -31461
  258. package/.next/standalone/.next/server/chunks/9237.js +396 -396
  259. package/.next/standalone/.next/server/chunks/{9640.js → 9304.js} +1628 -570
  260. package/.next/standalone/.next/server/chunks/9406.js +1 -1
  261. package/.next/standalone/.next/server/chunks/9824.js +98 -98
  262. package/.next/standalone/.next/server/chunks/9826.js +1 -0
  263. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  264. package/.next/standalone/.next/server/middleware.js +415 -397
  265. package/.next/standalone/.next/server/pages/404.html +2 -2
  266. package/.next/standalone/.next/server/pages/500.html +1 -1
  267. package/.next/standalone/.next/server/preview-props.json +3 -3
  268. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  269. package/.next/standalone/.next/static/chunks/{1395-a340fb0a345382a4.js → 1395-e4a99912b8f83044.js} +13 -1
  270. package/.next/standalone/.next/static/chunks/app/_global-error/{page-36cb8b428b38b26a.js → page-6fc5f8e744c81802.js} +1 -1
  271. package/.next/standalone/.next/static/chunks/app/api/v1/access/[identity]/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
  272. package/.next/standalone/.next/static/chunks/app/api/v1/access/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
  273. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/compact/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
  274. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/display-filters/route-6fc5f8e744c81802.js +17 -0
  275. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/route-6fc5f8e744c81802.js +17 -0
  276. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/thread/route-6fc5f8e744c81802.js +17 -0
  277. package/.next/standalone/.next/static/chunks/app/api/v1/agents/route-6fc5f8e744c81802.js +17 -0
  278. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/[hostname]/route-6fc5f8e744c81802.js +17 -0
  279. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/route-6fc5f8e744c81802.js +17 -0
  280. package/.next/standalone/.next/static/chunks/app/api/v1/artifacts/lifecycle/route-6fc5f8e744c81802.js +17 -0
  281. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/files/route-6fc5f8e744c81802.js +17 -0
  282. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/images/route-6fc5f8e744c81802.js +17 -0
  283. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/chats/route-6fc5f8e744c81802.js +17 -0
  284. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/[remote_jid]/route-6fc5f8e744c81802.js +17 -0
  285. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/route-6fc5f8e744c81802.js +17 -0
  286. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/lookup/route-6fc5f8e744c81802.js +17 -0
  287. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/pair/route-6fc5f8e744c81802.js +17 -0
  288. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/route-6fc5f8e744c81802.js +17 -0
  289. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/[route_id]/route-6fc5f8e744c81802.js +17 -0
  290. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/route-6fc5f8e744c81802.js +17 -0
  291. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/status/route-6fc5f8e744c81802.js +17 -0
  292. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/kinds/route-6fc5f8e744c81802.js +17 -0
  293. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/route-6fc5f8e744c81802.js +17 -0
  294. package/.next/standalone/.next/static/chunks/app/api/v1/builtin-tools/route-6fc5f8e744c81802.js +17 -0
  295. package/.next/standalone/.next/static/chunks/app/api/v1/config/route-6fc5f8e744c81802.js +17 -0
  296. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/[id]/route-6fc5f8e744c81802.js +17 -0
  297. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/route-6fc5f8e744c81802.js +17 -0
  298. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/currency/route-6fc5f8e744c81802.js +17 -0
  299. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/metrics/route-6fc5f8e744c81802.js +17 -0
  300. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing/route-6fc5f8e744c81802.js +17 -0
  301. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing-task/route-6fc5f8e744c81802.js +17 -0
  302. package/.next/standalone/.next/static/chunks/app/api/v1/delegations/codex/[job_id]/route-6fc5f8e744c81802.js +17 -0
  303. package/.next/standalone/.next/static/chunks/app/api/v1/documents/search/route-6fc5f8e744c81802.js +17 -0
  304. package/.next/standalone/.next/static/chunks/app/api/v1/documents/settings/route-6fc5f8e744c81802.js +17 -0
  305. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/reindex/route-6fc5f8e744c81802.js +17 -0
  306. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/route-6fc5f8e744c81802.js +17 -0
  307. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/route-6fc5f8e744c81802.js +17 -0
  308. package/.next/standalone/.next/static/chunks/app/api/v1/env/route-6fc5f8e744c81802.js +17 -0
  309. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/allowlist/route-6fc5f8e744c81802.js +17 -0
  310. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/route-6fc5f8e744c81802.js +17 -0
  311. package/.next/standalone/.next/static/chunks/app/api/v1/events/route-6fc5f8e744c81802.js +17 -0
  312. package/.next/standalone/.next/static/chunks/app/api/v1/events/test/route-6fc5f8e744c81802.js +17 -0
  313. package/.next/standalone/.next/static/chunks/app/api/v1/extension/agents/route-6fc5f8e744c81802.js +17 -0
  314. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/activate/route-6fc5f8e744c81802.js +17 -0
  315. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/foreground/route-6fc5f8e744c81802.js +17 -0
  316. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/history/route-6fc5f8e744c81802.js +17 -0
  317. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/poll/route-6fc5f8e744c81802.js +17 -0
  318. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/progress/route-6fc5f8e744c81802.js +17 -0
  319. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/result/route-6fc5f8e744c81802.js +17 -0
  320. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/retry/route-6fc5f8e744c81802.js +17 -0
  321. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/status/route-6fc5f8e744c81802.js +17 -0
  322. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/tabs/route-6fc5f8e744c81802.js +17 -0
  323. package/.next/standalone/.next/static/chunks/app/api/v1/extension/fill/route-6fc5f8e744c81802.js +17 -0
  324. package/.next/standalone/.next/static/chunks/app/api/v1/extension/refine/route-6fc5f8e744c81802.js +17 -0
  325. package/.next/standalone/.next/static/chunks/app/api/v1/extension/turn/route-6fc5f8e744c81802.js +17 -0
  326. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/route-6fc5f8e744c81802.js +17 -0
  327. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/config/route-6fc5f8e744c81802.js +17 -0
  328. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/route-6fc5f8e744c81802.js +17 -0
  329. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/secrets/route-6fc5f8e744c81802.js +17 -0
  330. package/.next/standalone/.next/static/chunks/app/api/v1/files/[name]/route-6fc5f8e744c81802.js +17 -0
  331. package/.next/standalone/.next/static/chunks/app/api/v1/fs/browse/route-6fc5f8e744c81802.js +17 -0
  332. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/[id]/route-6fc5f8e744c81802.js +17 -0
  333. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/default/route-6fc5f8e744c81802.js +17 -0
  334. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/route-6fc5f8e744c81802.js +17 -0
  335. package/.next/standalone/.next/static/chunks/app/api/v1/health/probes/route-6fc5f8e744c81802.js +17 -0
  336. package/.next/standalone/.next/static/chunks/app/api/v1/health/route-6fc5f8e744c81802.js +17 -0
  337. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/route-6fc5f8e744c81802.js +17 -0
  338. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/test/route-6fc5f8e744c81802.js +17 -0
  339. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/callback/route-6fc5f8e744c81802.js +17 -0
  340. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/start/route-6fc5f8e744c81802.js +17 -0
  341. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/status/route-6fc5f8e744c81802.js +17 -0
  342. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/callback/route-6fc5f8e744c81802.js +17 -0
  343. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/start/route-6fc5f8e744c81802.js +17 -0
  344. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/status/route-6fc5f8e744c81802.js +17 -0
  345. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/route-6fc5f8e744c81802.js +17 -0
  346. package/.next/standalone/.next/static/chunks/app/api/v1/lifecycle/adoption/route-6fc5f8e744c81802.js +17 -0
  347. package/.next/standalone/.next/static/chunks/app/api/v1/local-file/route-6fc5f8e744c81802.js +17 -0
  348. package/.next/standalone/.next/static/chunks/app/api/v1/logs/route-6fc5f8e744c81802.js +17 -0
  349. package/.next/standalone/.next/static/chunks/app/api/v1/maps/embed/route-6fc5f8e744c81802.js +17 -0
  350. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/[name]/route-6fc5f8e744c81802.js +17 -0
  351. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/registry/route-6fc5f8e744c81802.js +17 -0
  352. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/route-6fc5f8e744c81802.js +17 -0
  353. package/.next/standalone/.next/static/chunks/app/api/v1/memory/[namespace]/[key]/route-6fc5f8e744c81802.js +17 -0
  354. package/.next/standalone/.next/static/chunks/app/api/v1/memory/policy/route-6fc5f8e744c81802.js +17 -0
  355. package/.next/standalone/.next/static/chunks/app/api/v1/memory/route-6fc5f8e744c81802.js +17 -0
  356. package/.next/standalone/.next/static/chunks/app/api/v1/memory/search/route-6fc5f8e744c81802.js +17 -0
  357. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/compact-threads/route-6fc5f8e744c81802.js +17 -0
  358. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/route-6fc5f8e744c81802.js +17 -0
  359. package/.next/standalone/.next/static/chunks/app/api/v1/models/route-6fc5f8e744c81802.js +17 -0
  360. package/.next/standalone/.next/static/chunks/app/api/v1/packages/catalog/route-6fc5f8e744c81802.js +17 -0
  361. package/.next/standalone/.next/static/chunks/app/api/v1/packages/defaults/[id]/route-6fc5f8e744c81802.js +17 -0
  362. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/[id]/route-6fc5f8e744c81802.js +17 -0
  363. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/route-6fc5f8e744c81802.js +17 -0
  364. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/enabled/route-6fc5f8e744c81802.js +17 -0
  365. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/route-6fc5f8e744c81802.js +17 -0
  366. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/route-6fc5f8e744c81802.js +17 -0
  367. package/.next/standalone/.next/static/chunks/app/api/v1/packages/reload/route-6fc5f8e744c81802.js +17 -0
  368. package/.next/standalone/.next/static/chunks/app/api/v1/packages/route-6fc5f8e744c81802.js +17 -0
  369. package/.next/standalone/.next/static/chunks/app/api/v1/page-capture/route-6fc5f8e744c81802.js +17 -0
  370. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/approve/route-6fc5f8e744c81802.js +17 -0
  371. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/deny/route-6fc5f8e744c81802.js +17 -0
  372. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/route-6fc5f8e744c81802.js +17 -0
  373. package/.next/standalone/.next/static/chunks/app/api/v1/profile/location/route-6fc5f8e744c81802.js +17 -0
  374. package/.next/standalone/.next/static/chunks/app/api/v1/profile/route-6fc5f8e744c81802.js +17 -0
  375. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/models/route-6fc5f8e744c81802.js +17 -0
  376. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/probe/route-6fc5f8e744c81802.js +17 -0
  377. package/.next/standalone/.next/static/chunks/app/api/v1/providers/github-copilot/auth/route-6fc5f8e744c81802.js +17 -0
  378. package/.next/standalone/.next/static/chunks/app/api/v1/providers/route-6fc5f8e744c81802.js +17 -0
  379. package/.next/standalone/.next/static/chunks/app/api/v1/proxy-config/route-6fc5f8e744c81802.js +17 -0
  380. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/init/route-6fc5f8e744c81802.js +17 -0
  381. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/route-6fc5f8e744c81802.js +17 -0
  382. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/route-6fc5f8e744c81802.js +17 -0
  383. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/run/route-6fc5f8e744c81802.js +17 -0
  384. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/route-6fc5f8e744c81802.js +17 -0
  385. package/.next/standalone/.next/static/chunks/app/api/v1/security/idle-timeout/route-6fc5f8e744c81802.js +17 -0
  386. package/.next/standalone/.next/static/chunks/app/api/v1/security/pin/route-6fc5f8e744c81802.js +17 -0
  387. package/.next/standalone/.next/static/chunks/app/api/v1/security/state/route-6fc5f8e744c81802.js +17 -0
  388. package/.next/standalone/.next/static/chunks/app/api/v1/security/unlock/route-6fc5f8e744c81802.js +17 -0
  389. package/.next/standalone/.next/static/chunks/app/api/v1/security/verify-pin/route-6fc5f8e744c81802.js +17 -0
  390. package/.next/standalone/.next/static/chunks/app/api/v1/setup/test-key/route-6fc5f8e744c81802.js +17 -0
  391. package/.next/standalone/.next/static/chunks/app/api/v1/skills/[id]/route-6fc5f8e744c81802.js +17 -0
  392. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/[id]/route-6fc5f8e744c81802.js +17 -0
  393. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/route-6fc5f8e744c81802.js +17 -0
  394. package/.next/standalone/.next/static/chunks/app/api/v1/skills/route-6fc5f8e744c81802.js +17 -0
  395. package/.next/standalone/.next/static/chunks/app/api/v1/system/abort/route-6fc5f8e744c81802.js +17 -0
  396. package/.next/standalone/.next/static/chunks/app/api/v1/system/restart/route-6fc5f8e744c81802.js +17 -0
  397. package/.next/standalone/.next/static/chunks/app/api/v1/tailscale/route-6fc5f8e744c81802.js +17 -0
  398. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/[agent_id]/route-6fc5f8e744c81802.js +17 -0
  399. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/route-6fc5f8e744c81802.js +17 -0
  400. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/activity/route-6fc5f8e744c81802.js +17 -0
  401. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/context-pin/route-6fc5f8e744c81802.js +17 -0
  402. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/route-6fc5f8e744c81802.js +17 -0
  403. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/run/route-6fc5f8e744c81802.js +17 -0
  404. package/.next/standalone/.next/static/chunks/app/api/v1/threads/route-6fc5f8e744c81802.js +17 -0
  405. package/.next/standalone/.next/static/chunks/app/api/v1/tools/route-6fc5f8e744c81802.js +17 -0
  406. package/.next/standalone/.next/static/chunks/app/api/v1/update/apply/route-6fc5f8e744c81802.js +17 -0
  407. package/.next/standalone/.next/static/chunks/app/api/v1/update/route-6fc5f8e744c81802.js +17 -0
  408. package/.next/standalone/.next/static/chunks/app/api/v1/voice/transcribe/route-6fc5f8e744c81802.js +17 -0
  409. package/.next/standalone/.next/static/chunks/app/api/v1/voice/tts/route-6fc5f8e744c81802.js +17 -0
  410. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/route-6fc5f8e744c81802.js +17 -0
  411. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/run/route-6fc5f8e744c81802.js +17 -0
  412. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/reaction-scripts/route-6fc5f8e744c81802.js +17 -0
  413. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/route-6fc5f8e744c81802.js +17 -0
  414. package/.next/standalone/.next/static/chunks/app/manifest.webmanifest/route-6fc5f8e744c81802.js +17 -0
  415. package/.next/standalone/.next/static/chunks/app/{page-7017f07f8a7a083c.js → page-213a623b37226452.js} +1041 -652
  416. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-6fc5f8e744c81802.js +17 -0
  417. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-6fc5f8e744c81802.js +17 -0
  418. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-6fc5f8e744c81802.js +17 -0
  419. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-6fc5f8e744c81802.js +17 -0
  420. package/.next/standalone/.next/static/css/{d80058f0b9b41c09.css → 312542a5725ba0d5.css} +2 -2
  421. package/.next/standalone/docs/adoption/changesets.json +309 -0
  422. package/.next/standalone/lib/skills/builtins/memory-organization/SKILL.md +16 -0
  423. package/.next/standalone/package.json +3 -3
  424. package/CHANGELOG.md +25 -0
  425. package/api/client.ts +9 -0
  426. package/api/types.ts +29 -0
  427. package/app/api/v1/lifecycle/adoption/route.ts +14 -2
  428. package/app/api/v1/models/[name]/compact-threads/route.ts +14 -11
  429. package/app/api/v1/threads/[thread_id]/activity/route.ts +19 -0
  430. package/app/api/v1/threads/[thread_id]/context-pin/route.test.ts +1 -0
  431. package/app/api/v1/threads/[thread_id]/context-pin/route.ts +2 -1
  432. package/app/api/v1/threads/[thread_id]/route.ts +5 -1
  433. package/components/chat/ChatView.tsx +52 -11
  434. package/components/chat/ContextBoundary.test.tsx +68 -1
  435. package/components/chat/ContextBoundary.tsx +92 -13
  436. package/components/chat/MessageList.test.tsx +31 -0
  437. package/components/chat/MessageList.tsx +49 -28
  438. package/components/chat/ToolList.test.tsx +92 -16
  439. package/components/chat/ToolList.tsx +59 -4
  440. package/components/chat/chat-helpers.test.tsx +24 -1
  441. package/components/chat/chat-helpers.ts +47 -4
  442. package/components/chat/useThreadActivity.test.tsx +113 -0
  443. package/components/chat/useThreadActivity.ts +94 -0
  444. package/components/chat/useThreadData.ts +16 -16
  445. package/components/chat/workflow-step-retry.ts +25 -0
  446. package/components/ui/BootScreen.tsx +17 -0
  447. package/components/ui/WorkflowChecklist.tsx +71 -33
  448. package/hooks/useSSE.ts +28 -3
  449. package/lib/agents/compaction-pipeline.test.ts +202 -0
  450. package/lib/agents/compaction-pipeline.ts +483 -0
  451. package/lib/agents/conversation-summary.ts +37 -21
  452. package/lib/agents/prepare/history-window.test.ts +18 -0
  453. package/lib/agents/prepare/history-window.ts +11 -2
  454. package/lib/agents/prepare/request.ts +4 -0
  455. package/lib/agents/prepare/system-prompt.test.ts +39 -0
  456. package/lib/agents/prepare/system-prompt.ts +8 -3
  457. package/lib/agents/prompt-registry.test.ts +5 -140
  458. package/lib/agents/prompt-registry.ts +45 -1
  459. package/lib/agents/prompt-variants.ts +146 -0
  460. package/lib/agents/run-registry.test.ts +22 -0
  461. package/lib/agents/run-registry.ts +29 -0
  462. package/lib/agents/run-thread.retry.test.ts +67 -1
  463. package/lib/agents/run-thread.ts +86 -1
  464. package/lib/agents/thread-activity.test.ts +31 -0
  465. package/lib/agents/thread-activity.ts +27 -0
  466. package/lib/agents/thread-compaction-state.test.ts +82 -0
  467. package/lib/agents/thread-compaction-state.ts +121 -0
  468. package/lib/agents/thread-compaction.test.ts +83 -4
  469. package/lib/agents/thread-compaction.ts +34 -11
  470. package/lib/agents/warm-summary-background.test.ts +219 -5
  471. package/lib/agents/warm-summary-background.ts +325 -142
  472. package/lib/agents/warm-topics.test.ts +37 -0
  473. package/lib/agents/warm-topics.ts +297 -0
  474. package/lib/agents/workflow-step-retry.test.ts +96 -0
  475. package/lib/agents/workflow-step-retry.ts +216 -0
  476. package/lib/api/browser-control.ts +0 -3
  477. package/lib/db/migrations.ts +5 -0
  478. package/lib/env/config.ts +2 -0
  479. package/lib/env/schema.ts +12 -0
  480. package/lib/lifecycle/changeset-build.test.ts +93 -0
  481. package/lib/lifecycle/changeset-build.ts +210 -0
  482. package/lib/lifecycle/changesets.test.ts +101 -0
  483. package/lib/lifecycle/changesets.ts +166 -0
  484. package/lib/lifecycle/surface-collect.test.ts +88 -0
  485. package/lib/lifecycle/surface-collect.ts +64 -0
  486. package/lib/lifecycle/surface-snapshot.test.ts +104 -0
  487. package/lib/lifecycle/surface-snapshot.ts +210 -0
  488. package/lib/memory/record.ts +0 -2
  489. package/lib/providers/external.ts +0 -2
  490. package/lib/skills/builtins/memory-organization/SKILL.md +16 -0
  491. package/lib/stores/threads.test.ts +9 -0
  492. package/lib/stores/threads.ts +21 -11
  493. package/lib/stores/version-adoption.test.ts +96 -0
  494. package/lib/stores/version-adoption.ts +239 -26
  495. package/lib/stores/workflow-progress.ts +3 -0
  496. package/lib/tools/communications/ms-todo.ts +0 -7
  497. package/lib/tools/general/memory.ts +1 -1
  498. package/lib/tools/general/workflow-progress.ts +2 -0
  499. package/lib/tools/runtime/catalog.ts +1 -25
  500. package/lib/triggers/registry.ts +0 -4
  501. package/package.json +3 -3
  502. package/scripts/install-to-system.ps1 +39 -11
  503. package/scripts/install-to-system.sh +37 -3
  504. package/.next/standalone/.next/server/chunks/3979.js +0 -581
  505. package/.next/standalone/.next/server/chunks/5936.js +0 -594
  506. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/display-filters/route-36cb8b428b38b26a.js +0 -17
  507. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/route-36cb8b428b38b26a.js +0 -17
  508. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/thread/route-36cb8b428b38b26a.js +0 -17
  509. package/.next/standalone/.next/static/chunks/app/api/v1/agents/route-36cb8b428b38b26a.js +0 -17
  510. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/[hostname]/route-36cb8b428b38b26a.js +0 -17
  511. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/route-36cb8b428b38b26a.js +0 -17
  512. package/.next/standalone/.next/static/chunks/app/api/v1/artifacts/lifecycle/route-36cb8b428b38b26a.js +0 -17
  513. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/files/route-36cb8b428b38b26a.js +0 -17
  514. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/images/route-36cb8b428b38b26a.js +0 -17
  515. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/chats/route-36cb8b428b38b26a.js +0 -17
  516. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/[remote_jid]/route-36cb8b428b38b26a.js +0 -17
  517. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/route-36cb8b428b38b26a.js +0 -17
  518. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/lookup/route-36cb8b428b38b26a.js +0 -17
  519. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/pair/route-36cb8b428b38b26a.js +0 -17
  520. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/route-36cb8b428b38b26a.js +0 -17
  521. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/[route_id]/route-36cb8b428b38b26a.js +0 -17
  522. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/route-36cb8b428b38b26a.js +0 -17
  523. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/status/route-36cb8b428b38b26a.js +0 -17
  524. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/kinds/route-36cb8b428b38b26a.js +0 -17
  525. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/route-36cb8b428b38b26a.js +0 -17
  526. package/.next/standalone/.next/static/chunks/app/api/v1/builtin-tools/route-36cb8b428b38b26a.js +0 -17
  527. package/.next/standalone/.next/static/chunks/app/api/v1/config/route-36cb8b428b38b26a.js +0 -17
  528. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/[id]/route-36cb8b428b38b26a.js +0 -17
  529. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/route-36cb8b428b38b26a.js +0 -17
  530. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/currency/route-36cb8b428b38b26a.js +0 -17
  531. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/metrics/route-36cb8b428b38b26a.js +0 -17
  532. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing/route-36cb8b428b38b26a.js +0 -17
  533. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing-task/route-36cb8b428b38b26a.js +0 -17
  534. package/.next/standalone/.next/static/chunks/app/api/v1/delegations/codex/[job_id]/route-36cb8b428b38b26a.js +0 -17
  535. package/.next/standalone/.next/static/chunks/app/api/v1/documents/search/route-36cb8b428b38b26a.js +0 -17
  536. package/.next/standalone/.next/static/chunks/app/api/v1/documents/settings/route-36cb8b428b38b26a.js +0 -17
  537. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/reindex/route-36cb8b428b38b26a.js +0 -17
  538. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/route-36cb8b428b38b26a.js +0 -17
  539. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/route-36cb8b428b38b26a.js +0 -17
  540. package/.next/standalone/.next/static/chunks/app/api/v1/env/route-36cb8b428b38b26a.js +0 -17
  541. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/allowlist/route-36cb8b428b38b26a.js +0 -17
  542. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/route-36cb8b428b38b26a.js +0 -17
  543. package/.next/standalone/.next/static/chunks/app/api/v1/events/route-36cb8b428b38b26a.js +0 -17
  544. package/.next/standalone/.next/static/chunks/app/api/v1/events/test/route-36cb8b428b38b26a.js +0 -17
  545. package/.next/standalone/.next/static/chunks/app/api/v1/extension/agents/route-36cb8b428b38b26a.js +0 -17
  546. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/activate/route-36cb8b428b38b26a.js +0 -17
  547. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/foreground/route-36cb8b428b38b26a.js +0 -17
  548. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/history/route-36cb8b428b38b26a.js +0 -17
  549. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/poll/route-36cb8b428b38b26a.js +0 -17
  550. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/progress/route-36cb8b428b38b26a.js +0 -17
  551. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/result/route-36cb8b428b38b26a.js +0 -17
  552. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/retry/route-36cb8b428b38b26a.js +0 -17
  553. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/status/route-36cb8b428b38b26a.js +0 -17
  554. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/tabs/route-36cb8b428b38b26a.js +0 -17
  555. package/.next/standalone/.next/static/chunks/app/api/v1/extension/fill/route-36cb8b428b38b26a.js +0 -17
  556. package/.next/standalone/.next/static/chunks/app/api/v1/extension/refine/route-36cb8b428b38b26a.js +0 -17
  557. package/.next/standalone/.next/static/chunks/app/api/v1/extension/turn/route-36cb8b428b38b26a.js +0 -17
  558. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/route-36cb8b428b38b26a.js +0 -17
  559. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/config/route-36cb8b428b38b26a.js +0 -17
  560. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/route-36cb8b428b38b26a.js +0 -17
  561. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/secrets/route-36cb8b428b38b26a.js +0 -17
  562. package/.next/standalone/.next/static/chunks/app/api/v1/files/[name]/route-36cb8b428b38b26a.js +0 -17
  563. package/.next/standalone/.next/static/chunks/app/api/v1/fs/browse/route-36cb8b428b38b26a.js +0 -17
  564. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/[id]/route-36cb8b428b38b26a.js +0 -17
  565. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/default/route-36cb8b428b38b26a.js +0 -17
  566. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/route-36cb8b428b38b26a.js +0 -17
  567. package/.next/standalone/.next/static/chunks/app/api/v1/health/probes/route-36cb8b428b38b26a.js +0 -17
  568. package/.next/standalone/.next/static/chunks/app/api/v1/health/route-36cb8b428b38b26a.js +0 -17
  569. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/route-36cb8b428b38b26a.js +0 -17
  570. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/test/route-36cb8b428b38b26a.js +0 -17
  571. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/callback/route-36cb8b428b38b26a.js +0 -17
  572. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/start/route-36cb8b428b38b26a.js +0 -17
  573. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/status/route-36cb8b428b38b26a.js +0 -17
  574. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/callback/route-36cb8b428b38b26a.js +0 -17
  575. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/start/route-36cb8b428b38b26a.js +0 -17
  576. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/status/route-36cb8b428b38b26a.js +0 -17
  577. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/route-36cb8b428b38b26a.js +0 -17
  578. package/.next/standalone/.next/static/chunks/app/api/v1/lifecycle/adoption/route-36cb8b428b38b26a.js +0 -17
  579. package/.next/standalone/.next/static/chunks/app/api/v1/local-file/route-36cb8b428b38b26a.js +0 -17
  580. package/.next/standalone/.next/static/chunks/app/api/v1/logs/route-36cb8b428b38b26a.js +0 -17
  581. package/.next/standalone/.next/static/chunks/app/api/v1/maps/embed/route-36cb8b428b38b26a.js +0 -17
  582. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/[name]/route-36cb8b428b38b26a.js +0 -17
  583. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/registry/route-36cb8b428b38b26a.js +0 -17
  584. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/route-36cb8b428b38b26a.js +0 -17
  585. package/.next/standalone/.next/static/chunks/app/api/v1/memory/[namespace]/[key]/route-36cb8b428b38b26a.js +0 -17
  586. package/.next/standalone/.next/static/chunks/app/api/v1/memory/policy/route-36cb8b428b38b26a.js +0 -17
  587. package/.next/standalone/.next/static/chunks/app/api/v1/memory/route-36cb8b428b38b26a.js +0 -17
  588. package/.next/standalone/.next/static/chunks/app/api/v1/memory/search/route-36cb8b428b38b26a.js +0 -17
  589. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/compact-threads/route-36cb8b428b38b26a.js +0 -17
  590. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/route-36cb8b428b38b26a.js +0 -17
  591. package/.next/standalone/.next/static/chunks/app/api/v1/models/route-36cb8b428b38b26a.js +0 -17
  592. package/.next/standalone/.next/static/chunks/app/api/v1/packages/catalog/route-36cb8b428b38b26a.js +0 -17
  593. package/.next/standalone/.next/static/chunks/app/api/v1/packages/defaults/[id]/route-36cb8b428b38b26a.js +0 -17
  594. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/[id]/route-36cb8b428b38b26a.js +0 -17
  595. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/route-36cb8b428b38b26a.js +0 -17
  596. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/enabled/route-36cb8b428b38b26a.js +0 -17
  597. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/route-36cb8b428b38b26a.js +0 -17
  598. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/route-36cb8b428b38b26a.js +0 -17
  599. package/.next/standalone/.next/static/chunks/app/api/v1/packages/reload/route-36cb8b428b38b26a.js +0 -17
  600. package/.next/standalone/.next/static/chunks/app/api/v1/packages/route-36cb8b428b38b26a.js +0 -17
  601. package/.next/standalone/.next/static/chunks/app/api/v1/page-capture/route-36cb8b428b38b26a.js +0 -17
  602. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/approve/route-36cb8b428b38b26a.js +0 -17
  603. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/deny/route-36cb8b428b38b26a.js +0 -17
  604. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/route-36cb8b428b38b26a.js +0 -17
  605. package/.next/standalone/.next/static/chunks/app/api/v1/profile/location/route-36cb8b428b38b26a.js +0 -17
  606. package/.next/standalone/.next/static/chunks/app/api/v1/profile/route-36cb8b428b38b26a.js +0 -17
  607. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/models/route-36cb8b428b38b26a.js +0 -17
  608. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/probe/route-36cb8b428b38b26a.js +0 -17
  609. package/.next/standalone/.next/static/chunks/app/api/v1/providers/github-copilot/auth/route-36cb8b428b38b26a.js +0 -17
  610. package/.next/standalone/.next/static/chunks/app/api/v1/providers/route-36cb8b428b38b26a.js +0 -17
  611. package/.next/standalone/.next/static/chunks/app/api/v1/proxy-config/route-36cb8b428b38b26a.js +0 -17
  612. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/init/route-36cb8b428b38b26a.js +0 -17
  613. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/route-36cb8b428b38b26a.js +0 -17
  614. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/route-36cb8b428b38b26a.js +0 -17
  615. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/run/route-36cb8b428b38b26a.js +0 -17
  616. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/route-36cb8b428b38b26a.js +0 -17
  617. package/.next/standalone/.next/static/chunks/app/api/v1/security/idle-timeout/route-36cb8b428b38b26a.js +0 -17
  618. package/.next/standalone/.next/static/chunks/app/api/v1/security/pin/route-36cb8b428b38b26a.js +0 -17
  619. package/.next/standalone/.next/static/chunks/app/api/v1/security/state/route-36cb8b428b38b26a.js +0 -17
  620. package/.next/standalone/.next/static/chunks/app/api/v1/security/unlock/route-36cb8b428b38b26a.js +0 -17
  621. package/.next/standalone/.next/static/chunks/app/api/v1/security/verify-pin/route-36cb8b428b38b26a.js +0 -17
  622. package/.next/standalone/.next/static/chunks/app/api/v1/setup/test-key/route-36cb8b428b38b26a.js +0 -17
  623. package/.next/standalone/.next/static/chunks/app/api/v1/skills/[id]/route-36cb8b428b38b26a.js +0 -17
  624. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/[id]/route-36cb8b428b38b26a.js +0 -17
  625. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/route-36cb8b428b38b26a.js +0 -17
  626. package/.next/standalone/.next/static/chunks/app/api/v1/skills/route-36cb8b428b38b26a.js +0 -17
  627. package/.next/standalone/.next/static/chunks/app/api/v1/system/abort/route-36cb8b428b38b26a.js +0 -17
  628. package/.next/standalone/.next/static/chunks/app/api/v1/system/restart/route-36cb8b428b38b26a.js +0 -17
  629. package/.next/standalone/.next/static/chunks/app/api/v1/tailscale/route-36cb8b428b38b26a.js +0 -17
  630. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/[agent_id]/route-36cb8b428b38b26a.js +0 -17
  631. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/route-36cb8b428b38b26a.js +0 -17
  632. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/context-pin/route-36cb8b428b38b26a.js +0 -17
  633. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/route-36cb8b428b38b26a.js +0 -17
  634. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/run/route-36cb8b428b38b26a.js +0 -17
  635. package/.next/standalone/.next/static/chunks/app/api/v1/threads/route-36cb8b428b38b26a.js +0 -17
  636. package/.next/standalone/.next/static/chunks/app/api/v1/tools/route-36cb8b428b38b26a.js +0 -17
  637. package/.next/standalone/.next/static/chunks/app/api/v1/update/apply/route-36cb8b428b38b26a.js +0 -17
  638. package/.next/standalone/.next/static/chunks/app/api/v1/update/route-36cb8b428b38b26a.js +0 -17
  639. package/.next/standalone/.next/static/chunks/app/api/v1/voice/transcribe/route-36cb8b428b38b26a.js +0 -17
  640. package/.next/standalone/.next/static/chunks/app/api/v1/voice/tts/route-36cb8b428b38b26a.js +0 -17
  641. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/route-36cb8b428b38b26a.js +0 -17
  642. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/run/route-36cb8b428b38b26a.js +0 -17
  643. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/reaction-scripts/route-36cb8b428b38b26a.js +0 -17
  644. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/route-36cb8b428b38b26a.js +0 -17
  645. package/.next/standalone/.next/static/chunks/app/manifest.webmanifest/route-36cb8b428b38b26a.js +0 -17
  646. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-36cb8b428b38b26a.js +0 -17
  647. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-36cb8b428b38b26a.js +0 -17
  648. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-36cb8b428b38b26a.js +0 -17
  649. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-36cb8b428b38b26a.js +0 -17
  650. /package/.next/standalone/.next/static/{NUrC9xax1sp1Q70nlFqS6 → bMRK5y3ruT7c3WtBfCQOG}/_buildManifest.js +0 -0
  651. /package/.next/standalone/.next/static/{NUrC9xax1sp1Q70nlFqS6 → bMRK5y3ruT7c3WtBfCQOG}/_ssgManifest.js +0 -0
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { useCallback, useEffect, useRef, useState } from "react";
3
3
  import { api } from "@/api/client";
4
- import type { Message, SummaryTopicSegment } from "@/api/types";
5
- import { applyThreadMeta, type SystemNotice, type ThreadMetaApplier } from "./chat-helpers";
4
+ import type { Message, SummaryTopicSegment, WarmChannelSummary } from "@/api/types";
5
+ import { applyThreadMeta, type ThreadMetaApplier } from "./chat-helpers";
6
6
 
7
7
  interface Params {
8
8
  threadId: string | null;
@@ -13,9 +13,6 @@ export interface ThreadDataApi {
13
13
  messages: Message[];
14
14
  setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
15
15
  messagesRef: React.MutableRefObject<Message[]>;
16
- notices: SystemNotice[];
17
- setNotices: React.Dispatch<React.SetStateAction<SystemNotice[]>>;
18
- addNotice: (text: string) => void;
19
16
  hasMore: boolean;
20
17
  setHasMore: React.Dispatch<React.SetStateAction<boolean>>;
21
18
  loadingMore: boolean;
@@ -30,8 +27,10 @@ export interface ThreadDataApi {
30
27
  warmSummarySourceMessages: number | null;
31
28
  warmSummarySourceChars: number | null;
32
29
  warmSummaryTopics: SummaryTopicSegment[] | null;
30
+ warmChannelSummaries: WarmChannelSummary[];
33
31
  warmSummaryPending: boolean;
34
32
  compactionPending: boolean;
33
+ manualCompactionPending: boolean;
35
34
  contextWindowTokens: number | null;
36
35
  metaApplier: ThreadMetaApplier;
37
36
  loadOlder: () => Promise<void>;
@@ -40,7 +39,6 @@ export interface ThreadDataApi {
40
39
 
41
40
  export function useThreadData({ threadId, attach }: Params): ThreadDataApi {
42
41
  const [messages, setMessages] = useState<Message[]>([]);
43
- const [notices, setNotices] = useState<SystemNotice[]>([]);
44
42
  const [hasMore, setHasMore] = useState(false);
45
43
  const [loadingMore, setLoadingMore] = useState(false);
46
44
  const [messagesLoading, setMessagesLoading] = useState(false);
@@ -54,8 +52,10 @@ export function useThreadData({ threadId, attach }: Params): ThreadDataApi {
54
52
  const [warmSummarySourceMessages, setWarmSummarySourceMessages] = useState<number | null>(null);
55
53
  const [warmSummarySourceChars, setWarmSummarySourceChars] = useState<number | null>(null);
56
54
  const [warmSummaryTopics, setWarmSummaryTopics] = useState<SummaryTopicSegment[] | null>(null);
55
+ const [warmChannelSummaries, setWarmChannelSummaries] = useState<WarmChannelSummary[]>([]);
57
56
  const [warmSummaryPending, setWarmSummaryPending] = useState(false);
58
57
  const [compactionPending, setCompactionPending] = useState(false);
58
+ const [manualCompactionPending, setManualCompactionPending] = useState(false);
59
59
  const [contextWindowTokens, setContextWindowTokens] = useState<number | null>(null);
60
60
 
61
61
  const messagesRef = useRef<Message[]>([]);
@@ -66,18 +66,13 @@ export function useThreadData({ threadId, attach }: Params): ThreadDataApi {
66
66
  setHotSince, setHotSinceSeq, setWarmSummary, setWarmSummaryBefore, setWarmSummaryBeforeSeq,
67
67
  setWarmSummaryComputedAt, setWarmSummarySourceMessages,
68
68
  setWarmSummarySourceChars, setContextWindowTokens, setWarmSummaryPending,
69
- setCompactionPending, setWarmSummaryTopics,
69
+ setCompactionPending, setManualCompactionPending, setWarmSummaryTopics, setWarmChannelSummaries,
70
70
  };
71
71
 
72
- const addNotice = useCallback((text: string) => {
73
- setNotices((p) => [...p, { id: `notice-${Date.now()}`, text }]);
74
- }, []);
75
-
76
72
  useEffect(() => {
77
73
  if (!threadId) {
78
74
  setMetadataThreadId(null);
79
75
  setMessages([]);
80
- setNotices([]);
81
76
  setHasMore(false);
82
77
  setMessagesLoading(false);
83
78
  setHotSince(null);
@@ -89,8 +84,10 @@ export function useThreadData({ threadId, attach }: Params): ThreadDataApi {
89
84
  setWarmSummarySourceMessages(null);
90
85
  setWarmSummarySourceChars(null);
91
86
  setWarmSummaryTopics(null);
87
+ setWarmChannelSummaries([]);
92
88
  setWarmSummaryPending(false);
93
89
  setCompactionPending(false);
90
+ setManualCompactionPending(false);
94
91
  setContextWindowTokens(null);
95
92
  return;
96
93
  }
@@ -108,8 +105,10 @@ export function useThreadData({ threadId, attach }: Params): ThreadDataApi {
108
105
  setWarmSummarySourceMessages(null);
109
106
  setWarmSummarySourceChars(null);
110
107
  setWarmSummaryTopics(null);
108
+ setWarmChannelSummaries([]);
111
109
  setWarmSummaryPending(false);
112
110
  setCompactionPending(false);
111
+ setManualCompactionPending(false);
113
112
  setContextWindowTokens(null);
114
113
  api.threads.get(threadId).then((d) => {
115
114
  if (cancelled) return;
@@ -150,6 +149,7 @@ export function useThreadData({ threadId, attach }: Params): ThreadDataApi {
150
149
  setWarmSummarySourceMessages(updated.warm_summary_source_messages);
151
150
  setWarmSummarySourceChars(updated.warm_summary_source_chars);
152
151
  setWarmSummaryTopics(updated.warm_summary_topics);
152
+ setWarmChannelSummaries(updated.warm_channel_summaries ?? []);
153
153
  setCompactionPending(updated.pending_hot_since_seq != null);
154
154
  const summaryFresh = updated.hot_since_seq != null
155
155
  && updated.warm_summary_before_seq === updated.hot_since_seq;
@@ -167,7 +167,7 @@ export function useThreadData({ threadId, attach }: Params): ThreadDataApi {
167
167
  if (!threadId) return;
168
168
  const summaryFresh = hotSinceSeq !== null && warmSummaryBeforeSeq === hotSinceSeq;
169
169
  const summaryStale = warmSummaryPending && hotSinceSeq !== null && !summaryFresh;
170
- if (!summaryStale && !compactionPending) {
170
+ if (!summaryStale && !compactionPending && !manualCompactionPending) {
171
171
  if (warmSummaryPending && hotSinceSeq !== null && summaryFresh) setWarmSummaryPending(false);
172
172
  return;
173
173
  }
@@ -190,7 +190,7 @@ export function useThreadData({ threadId, attach }: Params): ThreadDataApi {
190
190
  window.clearInterval(timer);
191
191
  };
192
192
  // eslint-disable-next-line react-hooks/exhaustive-deps
193
- }, [threadId, warmSummaryPending, compactionPending, hotSince, hotSinceSeq, warmSummaryBefore, warmSummaryBeforeSeq]);
193
+ }, [threadId, warmSummaryPending, compactionPending, manualCompactionPending, hotSince, hotSinceSeq, warmSummaryBefore, warmSummaryBeforeSeq]);
194
194
 
195
195
  const loadOlder = useCallback(async () => {
196
196
  if (!threadId || loadingMore || !hasMore || messages.length === 0) return;
@@ -211,13 +211,13 @@ export function useThreadData({ threadId, attach }: Params): ThreadDataApi {
211
211
  }, [threadId, loadingMore, hasMore, messages.length]);
212
212
 
213
213
  return {
214
- messages, setMessages, messagesRef, notices, setNotices, addNotice,
214
+ messages, setMessages, messagesRef,
215
215
  hasMore, setHasMore, loadingMore, messagesLoading,
216
216
  hotSince: metadataMatchesThread ? hotSince : null,
217
217
  hotSinceSeq: metadataMatchesThread ? hotSinceSeq : null,
218
218
  hotSinceSeqForRun: metadataMatchesThread ? hotSinceSeq : undefined,
219
219
  warmSummary, warmSummaryBefore, warmSummaryBeforeSeq, warmSummaryComputedAt,
220
- warmSummarySourceMessages, warmSummarySourceChars, warmSummaryTopics, warmSummaryPending, compactionPending, contextWindowTokens,
220
+ warmSummarySourceMessages, warmSummarySourceChars, warmSummaryTopics, warmChannelSummaries, warmSummaryPending, compactionPending, manualCompactionPending, contextWindowTokens,
221
221
  metaApplier, loadOlder, setContextPin,
222
222
  };
223
223
  }
@@ -0,0 +1,25 @@
1
+ import { createContext, useContext } from "react";
2
+
3
+ export interface WorkflowStepRetryRequest {
4
+ workflowId: string;
5
+ itemId: string;
6
+ label: string;
7
+ }
8
+
9
+ /** Sends a retry request for one workflow step; null when the surface cannot send messages. */
10
+ export const WorkflowStepRetryContext = createContext<((request: WorkflowStepRetryRequest) => void) | null>(null);
11
+
12
+ export function useWorkflowStepRetry() {
13
+ return useContext(WorkflowStepRetryContext);
14
+ }
15
+
16
+ export function workflowStepRetryMessage({ workflowId, itemId, label }: WorkflowStepRetryRequest): string {
17
+ const progressUpdate = workflowId === "version_adoption"
18
+ ? `Call \`workflow_progress\` with \`workflow_id: "version_adoption"\`, \`item_id: "${itemId}"\`, and \`status: "checking"\``
19
+ : `Call \`workflow_progress\` for workflow \`${workflowId}\` with the complete items snapshot, setting this step to \`checking\``;
20
+ return [
21
+ `Retry workflow step "${label}" (item \`${itemId}\`) in workflow \`${workflowId}\`.`,
22
+ `${progressUpdate}, then redo the step from its stated input and run its validation again.`,
23
+ "Finally mark it `done` with newly observed `validation_evidence`, or `needs_attention` with the reason. Leave the other steps unchanged.",
24
+ ].join(" ");
25
+ }
@@ -344,6 +344,20 @@ export function BootScreen({ agents, agentsLoaded, activeAgentId, onPickAgent, s
344
344
  }
345
345
  }
346
346
 
347
+ async function handleAdoptionItemRetry(itemId: string) {
348
+ if (adoptionBusy || adoption?.status === "running") return;
349
+ setAdoptionBusy("retry");
350
+ try {
351
+ const next = await api.lifecycle.adoption.retryItem(itemId);
352
+ setAdoption(next);
353
+ adoptionRunStartedRef.current = null;
354
+ } catch {
355
+ setAdoption((prev) => prev ? { ...prev, error: "Could not retry that step." } : prev);
356
+ } finally {
357
+ setAdoptionBusy(null);
358
+ }
359
+ }
360
+
347
361
  // The agent rendered in the centered tile. During `loading` and
348
362
  // `pick` it's the default (so the user sees the same artwork as soon
349
363
  // as agents resolve). During `opening` it's whatever was picked.
@@ -539,6 +553,9 @@ export function BootScreen({ agents, agentsLoaded, activeAgentId, onPickAgent, s
539
553
  summary={adoptionLiveLabel ?? adoption.summary}
540
554
  items={adoption.checklist}
541
555
  error={adoption.error}
556
+ onRetryItem={(item) => void handleAdoptionItemRetry(item.id)}
557
+ canRetryItem={(item) => item.id !== "fetch-changes"}
558
+ retryDisabled={adoptionBusy !== null || adoption.status === "running"}
542
559
  >
543
560
  {adoption.status === "done" && (
544
561
  <p className="mt-2 rounded-lg border border-border/50 bg-surface px-2 py-1 text-[10px] leading-snug text-fg-muted">
@@ -1,4 +1,4 @@
1
- import { AlertTriangle, Check, LoaderCircle, Minus } from "lucide-react";
1
+ import { AlertTriangle, Check, LoaderCircle, Minus, RotateCcw } from "lucide-react";
2
2
  import type { ReactNode } from "react";
3
3
 
4
4
  export type WorkflowChecklistStatus = "pending" | "checking" | "done" | "needs_attention" | "skipped";
@@ -12,6 +12,8 @@ export interface WorkflowChecklistItemView {
12
12
  output?: string;
13
13
  validation?: string;
14
14
  validation_evidence?: string;
15
+ /** Times this step has been started; shown when greater than one. */
16
+ attempts?: number;
15
17
  }
16
18
 
17
19
  interface Props {
@@ -22,9 +24,25 @@ interface Props {
22
24
  items: WorkflowChecklistItemView[];
23
25
  error?: string | null;
24
26
  compact?: boolean;
27
+ /** Retries a single finished or failed step; omitted hides the per-step retry button. */
28
+ onRetryItem?: (item: WorkflowChecklistItemView) => void;
29
+ canRetryItem?: (item: WorkflowChecklistItemView) => boolean;
30
+ retryDisabled?: boolean;
25
31
  children?: ReactNode;
26
32
  }
27
33
 
34
+ const RETRYABLE_STATUSES: ReadonlySet<WorkflowChecklistStatus> = new Set(["done", "needs_attention", "skipped"]);
35
+
36
+ export function isWorkflowItemRetryable(item: WorkflowChecklistItemView): boolean {
37
+ return RETRYABLE_STATUSES.has(item.status);
38
+ }
39
+
40
+ function statusLabel(status: WorkflowChecklistStatus): string {
41
+ if (status === "done") return "verified";
42
+ if (status === "needs_attention") return "needs attention";
43
+ return status;
44
+ }
45
+
28
46
  function StatusIcon({ status }: { status: WorkflowChecklistStatus }) {
29
47
  if (status === "done") return <Check className="h-3 w-3" aria-hidden />;
30
48
  if (status === "checking") return <LoaderCircle className="h-3 w-3 animate-spin" aria-hidden />;
@@ -41,12 +59,19 @@ function statusClass(status: WorkflowChecklistStatus): string {
41
59
  return "border-border/60 bg-surface text-fg-faint";
42
60
  }
43
61
 
44
- export function WorkflowChecklist({ eyebrow, title, phaseLabel, summary, items, error, compact = false, children }: Props) {
62
+ function itemTooltip(item: WorkflowChecklistItemView): string {
63
+ const note = item.status === "done" ? item.validation_evidence : item.reason;
64
+ return note ? `${item.label}\n${statusLabel(item.status)}: ${note}` : item.label;
65
+ }
66
+
67
+ export function WorkflowChecklist({ eyebrow, title, phaseLabel, summary, items, error, compact = false, onRetryItem, canRetryItem, retryDisabled = false, children }: Props) {
45
68
  return (
46
69
  <div className={compact ? "flex flex-col gap-1.5" : "absolute inset-x-0 top-0 flex flex-col gap-2 transition-opacity duration-300"}>
47
- <p className="text-[10px] text-fg-faint uppercase tracking-wider text-center">
48
- {eyebrow}
49
- </p>
70
+ {!compact && (
71
+ <p className="text-[10px] text-fg-faint uppercase tracking-wider text-center">
72
+ {eyebrow}
73
+ </p>
74
+ )}
50
75
  <div className={compact
51
76
  ? "w-full rounded border border-border/40 bg-surface/60 px-2 py-1.5 text-left"
52
77
  : "w-full rounded-xl border border-border/60 bg-surface-2/70 px-3 py-2 text-left shadow-lg shadow-black/5"}>
@@ -56,39 +81,52 @@ export function WorkflowChecklist({ eyebrow, title, phaseLabel, summary, items,
56
81
  {phaseLabel}
57
82
  </span>
58
83
  </div>
59
- <p className="mt-1 text-[11px] leading-snug text-fg-muted line-clamp-2">
60
- {summary}
61
- </p>
62
- <div className={compact
63
- ? "mt-1.5 flex max-h-32 flex-col gap-1 overflow-y-auto pr-1"
84
+ {!compact && summary && (
85
+ <p className="mt-1 text-[11px] leading-snug text-fg-muted line-clamp-2">
86
+ {summary}
87
+ </p>
88
+ )}
89
+ <ul className={compact
90
+ ? "mt-1.5 flex max-h-48 flex-col gap-0.5 overflow-y-auto pr-1"
64
91
  : "mt-2 flex max-h-32 flex-col gap-1 overflow-y-auto pr-1"}>
65
- {items.map((item) => (
66
- <div key={item.id} className={compact
67
- ? "rounded border border-border/30 bg-surface-2/40 px-1.5 py-1 text-[10px] leading-tight text-fg-muted"
68
- : "text-[10px] leading-tight text-fg-muted"}>
69
- <div className="flex items-start gap-1.5">
92
+ {items.map((item) => {
93
+ const retryable = !!onRetryItem && isWorkflowItemRetryable(item) && (canRetryItem ? canRetryItem(item) : true);
94
+ return (
95
+ <li key={item.id} className="group flex items-center gap-1.5 text-[10px] leading-tight text-fg-muted">
70
96
  <span
71
- aria-label={item.status}
72
- className={["mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded border", statusClass(item.status)].join(" ")}
97
+ role="img"
98
+ aria-label={statusLabel(item.status)}
99
+ className={["flex h-4 w-4 shrink-0 items-center justify-center rounded border", statusClass(item.status)].join(" ")}
73
100
  >
74
101
  <StatusIcon status={item.status} />
75
102
  </span>
76
- <span className={compact ? "min-w-0 flex-1 truncate" : "line-clamp-2"} title={item.label}>{item.label}</span>
77
- </div>
78
- {(item.input || item.output || item.validation || item.validation_evidence) && (
79
- <details className="mt-1 pl-5">
80
- <summary className="cursor-pointer text-fg-faint">Step contract</summary>
81
- <dl className="mt-1 grid grid-cols-[auto_minmax(0,1fr)] gap-x-2 gap-y-1">
82
- {item.input && <><dt className="text-fg-faint">Input</dt><dd className="break-words">{item.input}</dd></>}
83
- {item.output && <><dt className="text-fg-faint">Output</dt><dd className="break-words">{item.output}</dd></>}
84
- {item.validation && <><dt className="text-fg-faint">Validation</dt><dd className="break-words">{item.validation}</dd></>}
85
- {item.validation_evidence && <><dt className="text-fg-faint">Evidence</dt><dd className="break-words">{item.validation_evidence}</dd></>}
86
- </dl>
87
- </details>
88
- )}
89
- </div>
90
- ))}
91
- </div>
103
+ <span className={compact ? "min-w-0 flex-1 truncate" : "min-w-0 flex-1 line-clamp-2"} title={itemTooltip(item)}>
104
+ {item.label}
105
+ </span>
106
+ {(item.attempts ?? 0) > 1 && (
107
+ <span className="shrink-0 text-[9px] tabular-nums text-fg-faint" title={`Attempt ${item.attempts}`}>
108
+ attempt {item.attempts}
109
+ </span>
110
+ )}
111
+ {retryable && (
112
+ <button
113
+ type="button"
114
+ onClick={() => onRetryItem(item)}
115
+ disabled={retryDisabled}
116
+ aria-label={`Retry ${item.label}`}
117
+ title={`Retry ${item.label}`}
118
+ className={[
119
+ "flex h-4 w-4 shrink-0 items-center justify-center rounded text-fg-faint hover:bg-surface-3 hover:text-fg disabled:opacity-40",
120
+ item.status === "needs_attention" ? "" : "opacity-0 focus:opacity-100 group-hover:opacity-100",
121
+ ].join(" ")}
122
+ >
123
+ <RotateCcw className="h-3 w-3" aria-hidden />
124
+ </button>
125
+ )}
126
+ </li>
127
+ );
128
+ })}
129
+ </ul>
92
130
  {error && (
93
131
  <p className="mt-2 text-[10px] leading-tight text-red-400">{error}</p>
94
132
  )}
package/hooks/useSSE.ts CHANGED
@@ -32,6 +32,10 @@ type UseSSECommands = {
32
32
  ) => Promise<{ accepted: boolean }>;
33
33
  stop: () => void;
34
34
  attach: (threadId: string) => Promise<void>;
35
+ /** True from the moment start()/attach() opens a stream until it settles. */
36
+ isLive: () => boolean;
37
+ /** Epoch ms when the last stream settled (0 if none yet). */
38
+ lastSettledAt: () => number;
35
39
  clearStreamingContent: () => void;
36
40
  clearToolEvents: () => void;
37
41
  // ADR-0080 — arm with the steering message's id before the PATCH so a
@@ -228,6 +232,18 @@ export function useSSE(onDone?: () => void): UnifiedHookResult<UseSSEState, UseS
228
232
  // Cleared on every new start()/attach().
229
233
  const [authError, setAuthError] = useState<AuthError>(null);
230
234
  const abortRef = useRef<AbortController | null>(null);
235
+ // Synchronous view of whether start()/attach() owns a live stream, and when
236
+ // the last one settled. React's `streaming` lags a render behind, so the
237
+ // activity poller reads this to avoid aborting a stream that just opened
238
+ // or re-attaching a run whose stream has only just ended.
239
+ const liveRef = useRef<{ busy: boolean; settledAt: number }>({ busy: false, settledAt: 0 });
240
+ const markLive = useCallback(() => { liveRef.current.busy = true; }, []);
241
+ const markSettled = useCallback((ctrl: AbortController | null) => {
242
+ if (ctrl && abortRef.current !== ctrl) return;
243
+ liveRef.current = { busy: false, settledAt: Date.now() };
244
+ }, []);
245
+ const isLive = useCallback(() => liveRef.current.busy, []);
246
+ const lastSettledAt = useCallback(() => liveRef.current.settledAt, []);
231
247
  const threadIdRef = useRef<string | null>(null);
232
248
  // ADR-0080 — id of the steering message currently armed for a possible
233
249
  // continuation break, or null. Set eagerly (before the steer PATCH
@@ -379,6 +395,7 @@ export function useSSE(onDone?: () => void): UnifiedHookResult<UseSSEState, UseS
379
395
  abortRef.current?.abort();
380
396
  const ctrl = new AbortController();
381
397
  abortRef.current = ctrl;
398
+ markLive();
382
399
  threadIdRef.current = threadId;
383
400
  resetBuffer();
384
401
  setStreaming(true);
@@ -424,8 +441,9 @@ export function useSSE(onDone?: () => void): UnifiedHookResult<UseSSEState, UseS
424
441
  // them.
425
442
  setStreaming(false);
426
443
  closeActivity();
444
+ markSettled(ctrl);
427
445
  }
428
- }, [closeActivity, consume, openActivity, resetBuffer]);
446
+ }, [closeActivity, consume, markLive, markSettled, openActivity, resetBuffer]);
429
447
 
430
448
  // Stop the active run. Three-part: (1) tell the server to abort the
431
449
  // agent stream so the LangGraph loop unwinds; (2) tear down local
@@ -448,9 +466,10 @@ export function useSSE(onDone?: () => void): UnifiedHookResult<UseSSEState, UseS
448
466
  // start()/attach() — same pattern as the `done` branch in consume().
449
467
  closeActivity();
450
468
  abortRef.current?.abort();
469
+ markSettled(null);
451
470
  steeredContinuationIdRef.current = null;
452
471
  onDone?.();
453
- }, [closeActivity, flushPending, onDone]);
472
+ }, [closeActivity, flushPending, markSettled, onDone]);
454
473
 
455
474
  // Attach to an in-flight run for the given thread (server-side run kept
456
475
  // going because the user switched away, or because this is a fresh
@@ -463,6 +482,7 @@ export function useSSE(onDone?: () => void): UnifiedHookResult<UseSSEState, UseS
463
482
  abortRef.current?.abort();
464
483
  const ctrl = new AbortController();
465
484
  abortRef.current = ctrl;
485
+ markLive();
466
486
  threadIdRef.current = threadId;
467
487
  resetBuffer();
468
488
  setStreaming(true);
@@ -491,8 +511,9 @@ export function useSSE(onDone?: () => void): UnifiedHookResult<UseSSEState, UseS
491
511
  // hangs in the composer and the "Reconnecting…" badge never clears.
492
512
  setStreaming(false);
493
513
  closeActivity();
514
+ markSettled(ctrl);
494
515
  }
495
- }, [closeActivity, consume, onDone, openActivity, resetBuffer]);
516
+ }, [closeActivity, consume, markLive, markSettled, onDone, openActivity, resetBuffer]);
496
517
 
497
518
  // Called by the consumer after a refetch lands, so the streaming bubble
498
519
  // gets swapped for the persisted assistant message in a single render.
@@ -529,6 +550,8 @@ export function useSSE(onDone?: () => void): UnifiedHookResult<UseSSEState, UseS
529
550
  start,
530
551
  stop,
531
552
  attach,
553
+ isLive,
554
+ lastSettledAt,
532
555
  clearStreamingContent,
533
556
  clearToolEvents,
534
557
  armSteeredContinuation,
@@ -549,6 +572,8 @@ export function useSSE(onDone?: () => void): UnifiedHookResult<UseSSEState, UseS
549
572
  start,
550
573
  stop,
551
574
  attach,
575
+ isLive,
576
+ lastSettledAt,
552
577
  clearStreamingContent,
553
578
  clearToolEvents,
554
579
  armSteeredContinuation,
@@ -0,0 +1,202 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ assembleFreshTopics,
4
+ buildTopicGroupingMessages,
5
+ buildTopicRecapMessages,
6
+ runCompactionPipeline,
7
+ validateTopicGroups,
8
+ validateTopicRecap,
9
+ type PipelineSourceRow,
10
+ } from "./compaction-pipeline";
11
+ import type { SummaryTopicSegment } from "./conversation-summary";
12
+ import type { ProviderMessage } from "@/lib/providers/types";
13
+
14
+ const row = (seq: number, role = seq % 2 === 0 ? "user" : "assistant", tool_events: string | null = null): PipelineSourceRow => ({
15
+ seq,
16
+ role,
17
+ content: `message ${seq}`,
18
+ created_at: `2026-10-09T10:00:${String(seq).padStart(2, "0")}.000Z`,
19
+ tool_events,
20
+ });
21
+
22
+ const prior: SummaryTopicSegment[] = [{
23
+ title: "Release plan",
24
+ start_seq: 1,
25
+ end_seq: 4,
26
+ start_at: "2026-10-09T09:00:00.000Z",
27
+ end_at: "2026-10-09T09:00:04.000Z",
28
+ recap: "Planned the 2.2.2 patch.",
29
+ facts: [{ subject: "Release cadence", content: "Patch releases ship weekly.", tags: [], confidence: "explicit", key: "facts/release-cadence", origin: "compaction" }],
30
+ message_count: 4,
31
+ source_chars: 40,
32
+ }];
33
+
34
+ const groups = (value: unknown) => JSON.stringify({ groups: value });
35
+
36
+ function scriptedProvider(script: (messages: ProviderMessage[], call: number) => string) {
37
+ let call = 0;
38
+ const calls: ProviderMessage[][] = [];
39
+ return {
40
+ calls,
41
+ provider: {
42
+ chat: async (_model: string, messages: ProviderMessage[]) => {
43
+ calls.push(messages);
44
+ const text = script(messages, call++);
45
+ return { stream: (async function* () { yield text; })() };
46
+ },
47
+ } as never,
48
+ };
49
+ }
50
+
51
+ describe("source-aware prompts", () => {
52
+ const group = { title: "T", continues: null, seqs: [1, 2] };
53
+ const sources = ["chat", "scheduled_task", "watcher", "bridge"] as const;
54
+
55
+ it("describes each message stream differently in both steps", () => {
56
+ const firstLines = sources.map((source) => [
57
+ String(buildTopicGroupingMessages("x", [], source)[0].content).split("\n")[0],
58
+ String(buildTopicRecapMessages(group, null, "x", source)[0].content).split("\n")[0],
59
+ ]);
60
+ expect(new Set(firstLines.map(([grouping]) => grouping)).size).toBe(sources.length);
61
+ expect(new Set(firstLines.map(([, recap]) => recap)).size).toBe(sources.length);
62
+ });
63
+
64
+ it("asks only chat to extract facts; automation channels must return an empty list", () => {
65
+ for (const source of sources) {
66
+ const system = String(buildTopicRecapMessages(group, null, "x", source)[0].content);
67
+ expect(system.includes('"confidence"')).toBe(source === "chat");
68
+ expect(system.includes('Leave "facts" as []')).toBe(source !== "chat");
69
+ expect(system).toMatch(/\n1\. [\s\S]*\n2\. [\s\S]*\n3\. /);
70
+ }
71
+ });
72
+ });
73
+
74
+ describe("step 1 — validateTopicGroups", () => {
75
+ const rows = [10, 11, 12, 13, 14, 15].map((seq) => row(seq));
76
+
77
+ it("rejects seqs that were not supplied, overlaps and unknown topic ids, so the model retries", () => {
78
+ expect(validateTopicGroups("not json", rows, prior)).toMatchObject({ ok: false });
79
+ const bad = validateTopicGroups(groups([
80
+ { start_seq: 9, end_seq: 12, title: "a" },
81
+ { start_seq: 12, end_seq: 15, continues: "t7", title: "b" },
82
+ ]), rows, prior);
83
+ expect(bad.ok).toBe(false);
84
+ if (!bad.ok) {
85
+ expect(bad.errors.join(" ")).toContain("start_seq 9 is not a supplied message seq");
86
+ expect(bad.errors.join(" ")).toContain('continues "t7" is not an existing topic id');
87
+ }
88
+ const overlap = validateTopicGroups(groups([
89
+ { start_seq: 10, end_seq: 12, title: "a" },
90
+ { start_seq: 12, end_seq: 15, title: "b" },
91
+ ]), rows, prior);
92
+ expect(overlap.ok).toBe(false);
93
+ });
94
+
95
+ it("repairs gaps, single-message groups and duplicate continuations in code", () => {
96
+ const result = validateTopicGroups(groups([
97
+ { start_seq: 10, end_seq: 11, continues: "t1", title: "" },
98
+ { start_seq: 13, end_seq: 13, title: "stray" },
99
+ { start_seq: 14, end_seq: 15, continues: "t1", title: "Release plan again" },
100
+ ]), rows, prior);
101
+ expect(result.ok).toBe(true);
102
+ if (!result.ok) return;
103
+ // seq 12 was ungrouped and joined the first group; the stray single folds
104
+ // in; the second continuation of t1 coalesces into the first.
105
+ expect(result.value).toEqual([{ title: "Release plan", continues: "t1", seqs: [10, 11, 12, 13, 14, 15] }]);
106
+ expect(result.repairs?.length).toBeGreaterThan(0);
107
+ });
108
+ });
109
+
110
+ describe("step 2 — validateTopicRecap", () => {
111
+ const group = { title: "Topic", seqs: [10, 11] };
112
+
113
+ it("requires a non-empty recap and rejects a bare sentinel", () => {
114
+ expect(validateTopicRecap("NO_REPLY", group).ok).toBe(false);
115
+ expect(validateTopicRecap(JSON.stringify({ recap: "" }), group).ok).toBe(false);
116
+ expect(validateTopicRecap(JSON.stringify({ recap: "x".repeat(4_001) }), group).ok).toBe(false);
117
+ });
118
+
119
+ it("accepts fenced JSON, defaults the title and drops malformed facts", () => {
120
+ const result = validateTopicRecap("```json\n" + JSON.stringify({
121
+ recap: "Newest first.",
122
+ facts: [
123
+ { subject: "Pref", content: "Uses pnpm.", tags: ["tooling"], confidence: "explicit" },
124
+ { subject: "Bad", content: "no confidence" },
125
+ ],
126
+ }) + "\n```", group);
127
+ expect(result).toMatchObject({ ok: true, value: { title: "Topic", recap: "Newest first.", facts: [{ subject: "Pref" }] } });
128
+ });
129
+ });
130
+
131
+ describe("step 3 — assembleFreshTopics", () => {
132
+ it("fails when a supplied message lands in no topic", () => {
133
+ const rows = [row(10), row(11), row(12)];
134
+ const result = assembleFreshTopics([{ title: "a", seqs: [10, 11] }], [{ title: "a", recap: "r", facts: [] }], rows);
135
+ expect(result).toMatchObject({ ok: false, errors: ["seq 12 is in no topic."] });
136
+ });
137
+ });
138
+
139
+ describe("runCompactionPipeline", () => {
140
+ const saved = JSON.stringify([
141
+ { id: "c1", phase: "call", name: "memory_upsert", payload: { namespace: "facts", key: "deploy-target", record: { subject: "Deploy target", content: "Deploys go to staging first.", confidence: "explicit" } } },
142
+ { id: "c1", phase: "result", name: "memory_upsert", payload: { kwargs: { content: JSON.stringify({ ok: true, namespace: "facts", key: "deploy-target" }) } } },
143
+ ]);
144
+ const rows = [row(10), row(11, "assistant", saved), row(12), row(13)];
145
+
146
+ it("groups, recaps each topic, and merges into the stored topics newest last", async () => {
147
+ const { provider, calls } = scriptedProvider((messages) => {
148
+ const system = String(messages[0].content);
149
+ if (system.includes("step 1 of 3")) {
150
+ return groups([
151
+ { start_seq: 10, end_seq: 11, continues: "t1", title: "Release plan" },
152
+ { start_seq: 12, end_seq: 13, continues: null, title: "Deploy" },
153
+ ]);
154
+ }
155
+ return String(messages[1].content).includes("Topic: Release plan")
156
+ ? JSON.stringify({ title: "Release plan", recap: "Tagged 2.2.2. Earlier: planned the patch.", facts: [] })
157
+ : JSON.stringify({ title: "Deploy", recap: "Discussed deploy.", facts: [{ subject: "Region", content: "Deploy to eu-west.", tags: [], confidence: "explicit" }] });
158
+ });
159
+
160
+ const result = await runCompactionPipeline({ provider, modelId: "m", params: {}, rows, priorTopics: prior, messageLimit: 50 });
161
+
162
+ expect(calls).toHaveLength(3);
163
+ expect(result?.topics.map((topic) => [topic.title, topic.message_count])).toEqual([["Release plan", 6], ["Deploy", 2]]);
164
+ const continued = result!.topics[0];
165
+ expect(continued.start_seq).toBe(1);
166
+ expect(continued.end_seq).toBe(11);
167
+ expect(continued.recap).toBe("Tagged 2.2.2. Earlier: planned the patch.");
168
+ // Prior memorized items stay; agent-saved memory is attributed by code.
169
+ expect(continued.facts.map((fact) => fact.key)).toEqual(["facts/release-cadence", "facts/deploy-target"]);
170
+ expect(result!.topics[1].facts[0]).toMatchObject({ key: "facts/region", origin: "compaction" });
171
+ expect(result!.freshTopics.every((topic) => !("continues" in topic))).toBe(true);
172
+ expect(result!.sourceMessages).toBe(8);
173
+ });
174
+
175
+ it("retries a step with the validation errors, then succeeds", async () => {
176
+ const { provider, calls } = scriptedProvider((messages, call) => {
177
+ if (call === 0) return groups([{ start_seq: 99, end_seq: 13, title: "x" }]);
178
+ if (String(messages[0].content).includes("step 1 of 3")) return groups([{ start_seq: 10, end_seq: 13, title: "All" }]);
179
+ return JSON.stringify({ recap: "Everything.", facts: [] });
180
+ });
181
+ const result = await runCompactionPipeline({ provider, modelId: "m", params: {}, rows, priorTopics: [], messageLimit: 50 });
182
+ expect(result?.topics).toHaveLength(1);
183
+ const retry = calls[1];
184
+ expect(String(retry[retry.length - 1].content)).toContain("start_seq 99 is not a supplied message seq");
185
+ });
186
+
187
+ it("returns null after a step fails twice, so the caller falls back", async () => {
188
+ const { provider, calls } = scriptedProvider(() => "no json here");
189
+ const result = await runCompactionPipeline({ provider, modelId: "m", params: {}, rows, priorTopics: [], messageLimit: 50 });
190
+ expect(result).toBeNull();
191
+ expect(calls).toHaveLength(2);
192
+ });
193
+
194
+ it("evicts the oldest topics once the merged topics exceed the message limit", async () => {
195
+ const { provider } = scriptedProvider((messages) => String(messages[0].content).includes("step 1 of 3")
196
+ ? groups([{ start_seq: 10, end_seq: 13, title: "New" }])
197
+ : JSON.stringify({ recap: "New work.", facts: [] }));
198
+ const result = await runCompactionPipeline({ provider, modelId: "m", params: {}, rows, priorTopics: prior, messageLimit: 5 });
199
+ expect(result?.topics.map((topic) => topic.title)).toEqual(["New"]);
200
+ expect(result?.evicted).toBe(1);
201
+ });
202
+ });