@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,6 +1,8 @@
1
1
  import { getProvider } from "@/lib/providers";
2
2
  import type { ModelProvider, ProviderParams } from "@/lib/providers/types";
3
- import { summarizeTranscript, transcriptText, extractTopicSegments, validateTopicSegments, type SummaryTopicSegment } from "@/lib/agents/conversation-summary";
3
+ import { summarizeTranscript, transcriptText, extractTopicSegments, validateTopicSegments, parseStoredTopics, type SummaryTopicSegment } from "@/lib/agents/conversation-summary";
4
+ import { canMergeIntoTopics, finalizeFreshTopics, mergeWarmTopics, renderTopicRecaps, slugifyForMemoryKey } from "@/lib/agents/warm-topics";
5
+ import { formatTranscriptRow, runCompactionPipeline, type CompactionSource, type PipelineSourceRow } from "@/lib/agents/compaction-pipeline";
4
6
  import { takeRecentWarmMessages, warmSummaryMessageLimit, wrapWarmSummary, AUTOMATION_CHANNEL_ORDER } from "@/lib/agents/prepare/history-window";
5
7
  import { getAgentConfig, getAgentTierProportions } from "@/lib/stores/agent-configs";
6
8
  import { getModelParams, resolveRunnableModelConfig } from "@/lib/stores/model-config";
@@ -13,15 +15,42 @@ import {
13
15
  getThread,
14
16
  getThreadMessageBySeq,
15
17
  getThreadChannelSummary,
18
+ listThreadChannelSummaries,
16
19
  } from "@/lib/stores/threads";
20
+ import { getOrCreateGlobal } from "@/lib/utils/global-state";
21
+ import {
22
+ getCompactionAttempt,
23
+ isCompactionRunning,
24
+ runTrackedCompaction,
25
+ type CompactionAttempt,
26
+ } from "@/lib/agents/thread-compaction-state";
27
+
28
+ /** Automation-channel recaps committed at the thread's current boundary. */
29
+ export function currentChannelSummaries(
30
+ threadId: string,
31
+ hotSinceSeq: number | null | undefined,
32
+ ): Array<{ channel: string; summary: string; computed_at: string; topics: SummaryTopicSegment[] | null }> {
33
+ if (hotSinceSeq == null) return [];
34
+ const order: readonly string[] = AUTOMATION_CHANNEL_ORDER;
35
+ return listThreadChannelSummaries(threadId)
36
+ .filter((row) => row.summary_before_seq === hotSinceSeq && row.summary.trim().length > 0)
37
+ .sort((a, b) => order.indexOf(a.channel) - order.indexOf(b.channel))
38
+ .map((row) => ({
39
+ channel: row.channel,
40
+ summary: row.summary,
41
+ computed_at: row.computed_at,
42
+ topics: parseStoredTopics(row.topics),
43
+ }));
44
+ }
17
45
 
18
46
  const MAX_TOPIC_PREVIEW_CHARS = 24_000;
19
47
 
20
- const activeRefreshes = new Set<string>();
21
- // Boundaries an automatic compaction has proposed but not yet committed.
22
- // The pin only moves once the recap that replaces the cut-off messages is
23
- // stored, so the turn that proposes it still runs on the old boundary.
24
- const pendingBoundaries = new Map<string, number>();
48
+ // Automatic ("auto"), summary-refresh ("refresh") and manual /compact
49
+ // ("manual") attempts are tracked per thread in thread-compaction-state, so
50
+ // every route bundle reports the same compaction and each one has a deadline.
51
+ // An auto boundary is proposed but not committed until its recap is stored,
52
+ // so the turn that proposes it still runs on the old boundary.
53
+ //
25
54
  // A boundary request that arrived while a prior one for the same thread was
26
55
  // still in flight. Last-write-wins: kickBoundaryCompaction used to silently
27
56
  // drop any request that arrived while one was already running (dragging
@@ -31,19 +60,23 @@ const pendingBoundaries = new Map<string, number>();
31
60
  // later request was ignored. Queuing the latest one and re-running it once
32
61
  // the in-flight commit settles makes the boundary always converge on what
33
62
  // the caller most recently asked for.
34
- const queuedBoundaries = new Map<string, {
63
+ const queuedBoundaries = getOrCreateGlobal("__jarela_queued_compaction_boundaries", () => new Map<string, {
35
64
  boundarySeq: number;
36
65
  options: Pick<WarmContextCompactionOptions, "autoBoundaryLockedUntilMessageCount">;
37
- }>();
66
+ }>());
67
+
68
+ function backgroundCompactionRunning(threadId: string): boolean {
69
+ return isCompactionRunning(threadId, "auto") || isCompactionRunning(threadId, "refresh");
70
+ }
38
71
 
39
72
  export function kickWarmSummaryRefresh(threadId: string): void {
40
- if (!threadId || activeRefreshes.has(threadId)) return;
41
- activeRefreshes.add(threadId);
42
- queueMicrotask(() => {
43
- void refreshWarmSummary(threadId).finally(() => {
44
- activeRefreshes.delete(threadId);
45
- });
46
- });
73
+ if (!threadId || backgroundCompactionRunning(threadId)) return;
74
+ const thread = getThread(threadId);
75
+ void runTrackedCompaction(threadId, "refresh", thread?.hot_since_seq ?? null, async (attempt) => {
76
+ await Promise.resolve();
77
+ await refreshWarmSummary(threadId, attempt);
78
+ }).catch((err) => console.warn(`[warm-summary] refresh failed thread=${threadId}: ${String(err)}`))
79
+ .finally(() => drainQueuedBoundary(threadId));
47
80
  }
48
81
 
49
82
  /**
@@ -59,26 +92,27 @@ export function pendingCompactionBoundary(threadId: string): string | null {
59
92
 
60
93
  export function pendingCompactionBoundarySeq(threadId: string): number | null {
61
94
  return queuedBoundaries.get(threadId)?.boundarySeq
62
- ?? pendingBoundaries.get(threadId)
63
- ?? manualBoundaries.get(threadId)
95
+ ?? getCompactionAttempt(threadId, "auto")?.boundarySeq
96
+ ?? getCompactionAttempt(threadId, "manual")?.boundarySeq
64
97
  ?? null;
65
98
  }
66
99
 
67
- // Manual /compact runs outside the auto-compaction queue; track it so a
68
- // client that reloads the thread mid-compaction still sees it pending.
69
- const manualBoundaries = new Map<string, number>();
100
+ /** A manual /compact holds the thread (the UI queues sends); auto ones don't. */
101
+ export function isManualCompactionRunning(threadId: string): boolean {
102
+ return isCompactionRunning(threadId, "manual");
103
+ }
70
104
 
71
- export async function trackManualCompaction<T>(
105
+ /**
106
+ * Run a manual /compact as the thread's single manual attempt. Pass the
107
+ * attempt to compactThreadWarmContext so a result that arrives after the
108
+ * deadline is discarded rather than committed.
109
+ */
110
+ export function trackManualCompaction<T>(
72
111
  threadId: string,
73
112
  boundarySeq: number,
74
- run: () => Promise<T>,
113
+ run: (attempt: CompactionAttempt) => Promise<T>,
75
114
  ): Promise<T> {
76
- manualBoundaries.set(threadId, boundarySeq);
77
- try {
78
- return await run();
79
- } finally {
80
- if (manualBoundaries.get(threadId) === boundarySeq) manualBoundaries.delete(threadId);
81
- }
115
+ return runTrackedCompaction(threadId, "manual", boundarySeq, run);
82
116
  }
83
117
 
84
118
  /**
@@ -99,13 +133,29 @@ export function kickBoundaryCompaction(
99
133
  options: Pick<WarmContextCompactionOptions, "autoBoundaryLockedUntilMessageCount"> = {},
100
134
  ): void {
101
135
  if (!threadId || !Number.isSafeInteger(boundarySeq) || boundarySeq <= 0) return;
102
- if (activeRefreshes.has(threadId) || pendingBoundaries.has(threadId)) {
136
+ if (backgroundCompactionRunning(threadId)) {
103
137
  queuedBoundaries.set(threadId, { boundarySeq, options });
104
138
  return;
105
139
  }
106
140
  runBoundaryCompaction(threadId, boundarySeq, options);
107
141
  }
108
142
 
143
+ // Called whenever a background attempt settles. A queued boundary that a
144
+ // summary refresh was blocking used to be stranded here forever, which kept
145
+ // the thread reporting a pending compaction until restart.
146
+ function drainQueuedBoundary(threadId: string): void {
147
+ if (backgroundCompactionRunning(threadId)) return;
148
+ const queued = queuedBoundaries.get(threadId);
149
+ if (!queued) return;
150
+ queuedBoundaries.delete(threadId);
151
+ // Skip a no-op re-run if the boundary that just committed already
152
+ // matches what was queued — the queued request was superseded by
153
+ // the very commit it was waiting behind.
154
+ const settled = getThread(threadId);
155
+ const alreadySettled = queued.boundarySeq === (settled?.hot_since_seq ?? null);
156
+ if (!alreadySettled) runBoundaryCompaction(threadId, queued.boundarySeq, queued.options);
157
+ }
158
+
109
159
  function runBoundaryCompaction(
110
160
  threadId: string,
111
161
  boundarySeq: number,
@@ -113,38 +163,26 @@ function runBoundaryCompaction(
113
163
  ): void {
114
164
  const baseThread = getThread(threadId);
115
165
  const basePinSeq = baseThread?.hot_since_seq ?? null;
116
- pendingBoundaries.set(threadId, boundarySeq);
117
- activeRefreshes.add(threadId);
118
- queueMicrotask(() => {
119
- void commitBoundaryCompaction(threadId, boundarySeq, basePinSeq, options)
120
- .catch((err) => console.warn(`[context-boundary:auto] compaction failed thread=${threadId}: ${String(err)}`))
121
- .finally(() => {
122
- pendingBoundaries.delete(threadId);
123
- activeRefreshes.delete(threadId);
124
- const queued = queuedBoundaries.get(threadId);
125
- if (!queued) return;
126
- queuedBoundaries.delete(threadId);
127
- // Skip a no-op re-run if the boundary that just committed already
128
- // matches what was queued — the queued request was superseded by
129
- // the very commit it was waiting behind.
130
- const settled = getThread(threadId);
131
- const alreadySettled = queued.boundarySeq === (settled?.hot_since_seq ?? null);
132
- if (!alreadySettled) runBoundaryCompaction(threadId, queued.boundarySeq, queued.options);
133
- });
134
- });
166
+ void runTrackedCompaction(threadId, "auto", boundarySeq, async (attempt) => {
167
+ await Promise.resolve();
168
+ await commitBoundaryCompaction(threadId, boundarySeq, basePinSeq, options, attempt);
169
+ })
170
+ .catch((err) => console.warn(`[context-boundary:auto] compaction failed thread=${threadId}: ${String(err)}`))
171
+ .finally(() => drainQueuedBoundary(threadId));
135
172
  }
136
-
137
173
  async function commitBoundaryCompaction(
138
174
  threadId: string,
139
175
  boundarySeq: number,
140
176
  basePinSeq: number | null,
141
177
  options: Pick<WarmContextCompactionOptions, "autoBoundaryLockedUntilMessageCount">,
178
+ attempt?: CompactionAttempt,
142
179
  ): Promise<void> {
143
180
  const committed = await compactThreadWarmContext(threadId, boundarySeq, {
144
181
  expectedHotSinceSeq: basePinSeq,
145
182
  alignTopicBoundary: true,
146
183
  allowEmptySummary: true,
147
184
  ...options,
185
+ attempt,
148
186
  });
149
187
  if (!committed) return;
150
188
  console.info(
@@ -223,13 +261,14 @@ export async function findTopicBoundary(threadId: string, boundarySeq: number):
223
261
  }
224
262
  }
225
263
 
226
- export async function refreshWarmSummary(threadId: string): Promise<void> {
264
+ export async function refreshWarmSummary(threadId: string, attempt?: CompactionAttempt): Promise<void> {
227
265
  const thread = getThread(threadId);
228
266
  if (!thread?.hot_since_seq) return;
229
267
  await compactThreadWarmContext(threadId, thread.hot_since_seq, {
230
268
  expectedHotSinceSeq: thread.hot_since_seq,
231
269
  alignTopicBoundary: false,
232
270
  allowEmptySummary: true,
271
+ attempt,
233
272
  });
234
273
  }
235
274
 
@@ -241,6 +280,9 @@ interface BuiltSummary {
241
280
  // Per-topic segmentation of the same range (see SummaryTopicSegment). Empty
242
281
  // when the summarizer didn't return a `jarela-topics` fence.
243
282
  topics: SummaryTopicSegment[];
283
+ // Topics produced by this pass only; their extracted facts get uplifted.
284
+ // Stored topics merged in earlier were uplifted when they were fresh.
285
+ freshTopics: SummaryTopicSegment[];
244
286
  }
245
287
 
246
288
  export interface CommittedWarmContext {
@@ -250,6 +292,8 @@ export interface CommittedWarmContext {
250
292
  sourceMessages: number;
251
293
  sourceChars: number;
252
294
  topics: SummaryTopicSegment[];
295
+ /** Per automation channel (ADR-0044), committed at the same boundary. */
296
+ channels: Array<{ channel: string; summary: string; sourceMessages: number }>;
253
297
  }
254
298
 
255
299
  export interface WarmContextCompactionOptions {
@@ -258,6 +302,9 @@ export interface WarmContextCompactionOptions {
258
302
  alignTopicBoundary?: boolean;
259
303
  allowEmptySummary?: boolean;
260
304
  autoBoundaryLockedUntilMessageCount?: number;
305
+ /** The tracked attempt this compaction runs under; once it is no longer
306
+ * current (deadline passed or replaced) the result is not committed. */
307
+ attempt?: Pick<CompactionAttempt, "isCurrent">;
261
308
  providerOverride?: {
262
309
  provider: Pick<ModelProvider, "chat">;
263
310
  modelId: string;
@@ -289,13 +336,24 @@ export async function compactThreadWarmContext(
289
336
  if (!boundaryRow) return null;
290
337
  const boundary = boundaryRow.created_at;
291
338
  const built = await buildSummaryBefore(threadId, boundary, boundarySeq, options.providerOverride);
292
- if (!built || (!built.summary && !options.allowEmptySummary)) return null;
339
+ if (!built) return null;
340
+ if (options.attempt && !options.attempt.isCurrent()) return null;
293
341
 
294
342
  const channelSummaries = await Promise.all(AUTOMATION_CHANNEL_ORDER.map(async (channel) => {
295
343
  const channelSummary = await buildAutomationChannelSummaryBefore(threadId, channel, boundarySeq, options.providerOverride);
296
344
  if (!channelSummary) throw new Error(`Could not build ${channel} warm summary`);
297
- return { channel, summary: channelSummary.summary };
345
+ return {
346
+ channel,
347
+ summary: channelSummary.summary,
348
+ sourceMessages: channelSummary.sourceMessages,
349
+ topics: channelSummary.topics ? JSON.stringify(channelSummary.topics) : null,
350
+ };
298
351
  }));
352
+ // A thread whose only activity is automation (e.g. a bridge-only agent) has
353
+ // an empty chat summary but real channel recaps — that is still a result.
354
+ const anySummary = !!built.summary || channelSummaries.some((c) => !!c.summary);
355
+ if (!anySummary && !options.allowEmptySummary) return null;
356
+ if (options.attempt && !options.attempt.isCurrent()) return null;
299
357
 
300
358
  const committed = commitThreadWarmContext(threadId, {
301
359
  hotSince: boundary,
@@ -311,11 +369,13 @@ export async function compactThreadWarmContext(
311
369
  ? options.expectedWarmSummary
312
370
  : (baseThread.warm_summary ?? null),
313
371
  autoBoundaryLockedUntilMessageCount: options.autoBoundaryLockedUntilMessageCount,
314
- channelSummaries,
372
+ channelSummaries: channelSummaries.map(({ channel, summary, topics }) => ({ channel, summary, topics })),
315
373
  });
316
374
  if (!committed) return null;
317
- upliftTopicFacts(built.topics);
318
- return { boundary, boundarySeq, ...built };
375
+ upliftTopicFacts(built.freshTopics);
376
+ const { freshTopics: _fresh, ...context } = built;
377
+ const channels = channelSummaries.map(({ channel, summary, sourceMessages }) => ({ channel, summary, sourceMessages }));
378
+ return { boundary, boundarySeq, ...context, channels };
319
379
  }
320
380
 
321
381
  /**
@@ -351,40 +411,55 @@ async function buildSummaryBefore(
351
411
  ? providerParams.context_window_tokens
352
412
  : 32768;
353
413
  const summaryInputChars = Math.max(4000, Math.min(120000, Math.round(contextTokens * 3)));
354
- const eligibleRows = takeRecentWarmMessages(rows.filter((m) => m.seq < boundarySeq), agent.warm_summary_limit);
355
- const selectedRows: typeof eligibleRows = [];
356
- const selectedTranscript: string[] = [];
357
- let selectedTranscriptChars = 0;
358
- for (let index = eligibleRows.length - 1; index >= 0; index -= 1) {
359
- const row = eligibleRows[index];
360
- const formatted = `[seq=${row.seq}] [${row.created_at}] ${row.role === "user" ? "User" : "Assistant"}: ${transcriptText(row.content)}`;
361
- const addedChars = formatted.length + (selectedTranscript.length > 0 ? 2 : 0);
362
- if (selectedTranscriptChars + addedChars > summaryInputChars) break;
363
- selectedRows.unshift(row);
364
- selectedTranscript.unshift(formatted);
365
- selectedTranscriptChars += addedChars;
414
+ const provider = providerOverride?.provider ?? getProvider(modelCfg.provider);
415
+ const modelId = providerOverride?.modelId ?? modelCfg.model_id;
416
+ const summaryParams = providerParams.max_tokens
417
+ ? providerParams
418
+ : { ...providerParams, max_tokens: 1024 };
419
+
420
+ const outcome = await runTopicCompaction({
421
+ threadId,
422
+ source: "chat",
423
+ rows,
424
+ storedTopics: parseStoredTopics(thread.warm_summary_topics),
425
+ storedBeforeSeq: thread.warm_summary_before_seq,
426
+ boundarySeq,
427
+ warmSummaryLimit: agent.warm_summary_limit,
428
+ summaryInputChars,
429
+ provider,
430
+ modelId,
431
+ params: summaryParams,
432
+ });
433
+ if (outcome.status === "empty") {
434
+ return { summary: "", sourceMessages: outcome.sourceMessages, sourceChars: outcome.sourceChars, topics: [], freshTopics: [] };
366
435
  }
436
+ if (outcome.status === "topics") {
437
+ return {
438
+ summary: wrapTopicSummary(outcome.topics),
439
+ sourceMessages: outcome.sourceMessages,
440
+ sourceChars: outcome.sourceChars,
441
+ topics: outcome.topics,
442
+ freshTopics: outcome.freshTopics,
443
+ };
444
+ }
445
+ console.warn(`[warm-summary] thread=${threadId} compaction pipeline failed validation; using single-call summary`);
446
+
447
+ const eligibleRows = takeRecentWarmMessages(rows.filter((m) => m.seq < boundarySeq), agent.warm_summary_limit);
448
+ const { selectedRows, transcript } = selectTranscriptRows(eligibleRows, summaryInputChars);
367
449
  const selectedSourceChars = selectedRows.reduce((total, row) => total + transcriptText(row.content).length, 0);
368
450
  if (selectedSourceChars < 24 || selectedRows.length < 2) {
369
- return { summary: "", sourceMessages: selectedRows.length, sourceChars: selectedSourceChars, topics: [] };
451
+ return { summary: "", sourceMessages: selectedRows.length, sourceChars: selectedSourceChars, topics: [], freshTopics: [] };
370
452
  }
371
453
 
372
- const transcript = selectedTranscript.join("\n\n").trim();
373
454
  if (!transcript) return null;
374
455
 
375
- const provider = providerOverride?.provider ?? getProvider(modelCfg.provider);
376
- const modelId = providerOverride?.modelId ?? modelCfg.model_id;
377
- const summaryParams = providerParams.max_tokens
378
- ? providerParams
379
- : { ...providerParams, max_tokens: 1024 };
380
-
381
456
  const raw = (await summarizeTranscript(provider, modelId, summaryParams, transcript)).trim();
382
457
  if (!raw) return null;
383
458
  const { body, topics } = extractTopicSegments(raw);
384
- const validatedTopics = validateTopicSegments(topics, rows, selectedRows, {
459
+ const validatedTopics = finalizeFreshTopics(validateTopicSegments(topics, rows, selectedRows, {
385
460
  boundarySeq,
386
461
  allowPartialStart: true,
387
- });
462
+ }), selectedRows);
388
463
  const summarizedSeqs = new Set(validatedTopics.flatMap((topic) =>
389
464
  selectedRows
390
465
  .filter((row) => row.seq >= topic.start_seq! && row.seq <= topic.end_seq!)
@@ -393,31 +468,119 @@ async function buildSummaryBefore(
393
468
  const summarizedRows = validatedTopics.length > 0
394
469
  ? selectedRows.filter((row) => summarizedSeqs.has(row.seq))
395
470
  : selectedRows;
396
- const summary = validatedTopics.length > 0
397
- ? renderTopicRecaps(validatedTopics)
398
- : body;
399
- if (!summary) return null;
471
+ if (validatedTopics.length === 0 && !body) return null;
400
472
  const sourceMessages = summarizedRows.length;
401
473
  const sourceChars = summarizedRows.reduce((total, row) => total + transcriptText(row.content).length, 0);
402
474
 
403
475
  return {
404
- summary: [
405
- "--- Warm context summary ---",
406
- "Compressed recap of recent messages immediately before the hot window:",
407
- summary,
408
- ].join("\n"),
476
+ summary: validatedTopics.length > 0 ? wrapTopicSummary(validatedTopics) : wrapTopicSummary(null, body),
409
477
  sourceMessages,
410
478
  sourceChars,
411
479
  topics: validatedTopics,
480
+ freshTopics: validatedTopics,
481
+ };
482
+ }
483
+
484
+ type TopicCompactionOutcome =
485
+ | { status: "empty"; sourceMessages: number; sourceChars: number }
486
+ | { status: "topics"; topics: SummaryTopicSegment[]; freshTopics: SummaryTopicSegment[]; sourceMessages: number; sourceChars: number }
487
+ | { status: "failed" };
488
+
489
+ interface TopicCompactionInput<T extends PipelineSourceRow> {
490
+ threadId: string;
491
+ source: CompactionSource;
492
+ /** Every row of this message stream, ascending by seq. */
493
+ rows: readonly T[];
494
+ storedTopics: SummaryTopicSegment[] | null;
495
+ storedBeforeSeq: number | null | undefined;
496
+ boundarySeq: number;
497
+ warmSummaryLimit: number | null | undefined;
498
+ summaryInputChars: number;
499
+ provider: Pick<ModelProvider, "chat">;
500
+ modelId: string;
501
+ params: ProviderParams;
502
+ }
503
+
504
+ /**
505
+ * Shared by chat and every automation channel: run the compaction pipeline
506
+ * (lib/agents/compaction-pipeline.ts) over one message stream. Incremental
507
+ * when the stored topics can be extended — only rows that aged out of hot
508
+ * since the last pass are folded in; otherwise the recent warm window is
509
+ * regrouped from scratch. "failed" tells the caller to use its single-call
510
+ * fallback.
511
+ */
512
+ async function runTopicCompaction<T extends PipelineSourceRow>(input: TopicCompactionInput<T>): Promise<TopicCompactionOutcome> {
513
+ const { threadId, source, rows, storedTopics, storedBeforeSeq, boundarySeq } = input;
514
+ const messageLimit = warmSummaryMessageLimit(input.warmSummaryLimit);
515
+ const incremental = messageLimit > 0 && canMergeIntoTopics(storedTopics, storedBeforeSeq, boundarySeq);
516
+ const priorTopics = incremental ? storedTopics! : [];
517
+ const candidates = incremental
518
+ ? rows.filter((m) => m.seq >= storedBeforeSeq! && m.seq < boundarySeq)
519
+ : takeRecentWarmMessages(rows.filter((m) => m.seq < boundarySeq), input.warmSummaryLimit);
520
+ const { selectedRows } = selectTranscriptRows(candidates, input.summaryInputChars);
521
+ if (incremental && selectedRows.length === 0) {
522
+ const kept = mergeWarmTopics(priorTopics, [], messageLimit);
523
+ return { status: "topics", topics: kept.topics, freshTopics: [], sourceMessages: kept.sourceMessages, sourceChars: kept.sourceChars };
524
+ }
525
+ const selectedChars = selectedRows.reduce((total, row) => total + transcriptText(row.content).length, 0);
526
+ if (!incremental && (selectedChars < 24 || selectedRows.length < 2)) {
527
+ return { status: "empty", sourceMessages: selectedRows.length, sourceChars: selectedChars };
528
+ }
529
+ const firstSeq = selectedRows[0]?.seq ?? boundarySeq;
530
+ const label = `[warm-summary] thread=${threadId} source=${source} ${incremental ? "merge" : "rebuild"}`;
531
+ const pipeline = await runCompactionPipeline({
532
+ provider: input.provider,
533
+ modelId: input.modelId,
534
+ params: input.params,
535
+ rows: selectedRows,
536
+ priorTopics,
537
+ messageLimit: messageLimit > 0 ? messageLimit : selectedRows.length,
538
+ partialStart: !incremental && rows.some((m) => m.seq < firstSeq),
539
+ source,
540
+ log: (message) => console.info(`${label} ${message}`),
541
+ }).catch((err: unknown) => {
542
+ console.warn(`${label} compaction pipeline threw:`, err);
543
+ return null;
544
+ });
545
+ if (!pipeline) return { status: "failed" };
546
+ return {
547
+ status: "topics",
548
+ topics: pipeline.topics,
549
+ freshTopics: pipeline.freshTopics,
550
+ sourceMessages: pipeline.sourceMessages,
551
+ sourceChars: pipeline.sourceChars,
412
552
  };
413
553
  }
414
554
 
415
- function renderTopicRecaps(topics: readonly SummaryTopicSegment[]): string {
416
- return topics.map((topic) =>
417
- `### ${topic.title}${topic.partial_start ? " (partial; earlier messages omitted)" : ""}\n${topic.recap}`,
418
- ).join("\n\n");
555
+ function selectTranscriptRows<T extends { seq: number; created_at: string; role: string; content: string }>(
556
+ rows: readonly T[],
557
+ budgetChars: number,
558
+ ): { selectedRows: T[]; transcript: string } {
559
+ // Newest first, so a budget overflow drops the oldest messages.
560
+ const selectedRows: T[] = [];
561
+ const parts: string[] = [];
562
+ let chars = 0;
563
+ for (let index = rows.length - 1; index >= 0; index -= 1) {
564
+ const row = rows[index];
565
+ const formatted = formatTranscriptRow(row);
566
+ const added = formatted.length + (parts.length > 0 ? 2 : 0);
567
+ if (chars + added > budgetChars) break;
568
+ selectedRows.unshift(row);
569
+ parts.unshift(formatted);
570
+ chars += added;
571
+ }
572
+ return { selectedRows, transcript: parts.join("\n\n").trim() };
573
+ }
574
+
575
+ function wrapTopicSummary(topics: readonly SummaryTopicSegment[] | null, body = ""): string {
576
+ return [
577
+ "--- Warm context summary ---",
578
+ "Compressed recap of recent messages immediately before the hot window:",
579
+ topics ? renderTopicRecaps(topics) : body,
580
+ ].join("\n");
419
581
  }
420
582
 
583
+
421
584
  // Batched uplift (once per compaction pass, covering every topic segment
422
585
  // together — not fired per-segment as each is identified). Direct writes,
423
586
  // same as the agent-facing memory_upsert tool: background compaction has
@@ -428,7 +591,9 @@ export function upliftTopicFacts(topics: readonly SummaryTopicSegment[]): void {
428
591
  const seenKeys = new Set<string>();
429
592
  for (const topic of topics) {
430
593
  for (const fact of topic.facts) {
431
- const key = slugifyForMemoryKey(fact.subject);
594
+ // The agent already saved this one during the turn; don't overwrite it.
595
+ if (fact.origin === "agent") continue;
596
+ const key = fact.key?.startsWith("facts/") ? fact.key.slice("facts/".length) : slugifyForMemoryKey(fact.subject);
432
597
  if (!key || seenKeys.has(key)) continue;
433
598
  seenKeys.add(key);
434
599
  putMemory("facts", key, {
@@ -449,34 +614,45 @@ export function upliftTopicFacts(topics: readonly SummaryTopicSegment[]): void {
449
614
  }
450
615
  }
451
616
 
452
- function slugifyForMemoryKey(subject: string): string {
453
- return subject
454
- .toLowerCase()
455
- .replace(/[^a-z0-9]+/g, "-")
456
- .replace(/^-+|-+$/g, "")
457
- .slice(0, 80);
458
- }
459
-
460
617
  export interface BuiltChannelSummary {
461
618
  /** "" when there was too little automation activity to summarise. */
462
619
  summary: string;
463
620
  sourceMessages: number;
464
621
  sourceChars: number;
622
+ /** Stored topics when the compaction pipeline produced them; null for the single-call fallback. */
623
+ topics: SummaryTopicSegment[] | null;
624
+ }
625
+
626
+ const AUTOMATION_COMPACTION_SOURCES: readonly CompactionSource[] = ["scheduled_task", "watcher", "bridge"];
627
+
628
+ function automationCompactionSource(channel: string): CompactionSource {
629
+ return (AUTOMATION_COMPACTION_SOURCES as readonly string[]).includes(channel) ? channel as CompactionSource : "scheduled_task";
630
+ }
631
+
632
+ // ADR-0044 channels never uplift facts to memory, so the only facts a channel
633
+ // topic keeps are memory the agent itself saved there (verified in code).
634
+ function keepSavedFactsOnly(topics: readonly SummaryTopicSegment[]): SummaryTopicSegment[] {
635
+ return topics.map((topic) => ({ ...topic, facts: topic.facts.filter((fact) => fact.origin === "agent") }));
636
+ }
637
+
638
+ function wrapChannelSummary(channel: string, body: string): string {
639
+ return [
640
+ `--- ${channel} activity summary ---`,
641
+ "Compressed recap of automation activity outside the hot window:",
642
+ body,
643
+ ].join("\n");
465
644
  }
466
645
 
467
646
  // ADR-0044 — the automation-channel counterpart to buildSummaryBefore. Chat
468
- // keeps using buildSummaryBefore/compactThreadWarmContext unchanged (the
469
- // legacy threads.warm_summary* columns ARE the "chat" channel's summary,
470
- // per the ADR's fallback design); this covers scheduled_task/watcher/bridge,
471
- // each cached in its own thread_channel_summaries row.
647
+ // keeps using buildSummaryBefore/compactThreadWarmContext (the legacy
648
+ // threads.warm_summary* columns ARE the "chat" channel's summary, per the
649
+ // ADR's fallback design); this covers scheduled_task/watcher/bridge, each
650
+ // cached in its own thread_channel_summaries row.
472
651
  //
473
- // Deliberately simpler than buildSummaryBefore: no extend-prior-summary
474
- // optimisation (thread_channel_summaries has no source_messages/source_chars
475
- // columns to carry a running count across calls) and no topic-fact uplift —
476
- // automation activity logs are far lower volume than interactive chat and
477
- // far less likely to carry durable personal facts worth extracting. Every
478
- // call re-summarises the full channel history below the boundary from
479
- // scratch; acceptable given the expected message counts.
652
+ // Same compaction pipeline as chat (group -> recap -> merge, incremental into
653
+ // the channel's stored topics), with source-specific prompt wording. Unlike
654
+ // chat there is no topic-fact uplift: automation logs rarely carry durable
655
+ // personal facts, so channel topics only keep memory the agent saved itself.
480
656
  async function buildAutomationChannelSummaryBefore(
481
657
  threadId: string,
482
658
  channel: string,
@@ -497,43 +673,52 @@ async function buildAutomationChannelSummaryBefore(
497
673
  const providerParams = tier ? { ...baseParams, context_tier_proportions: tier } : baseParams;
498
674
 
499
675
  const rows = getMessagesByAutomationCategory(threadId, channel);
500
- const eligibleRows = rows.filter((m) => m.seq < boundarySeq);
501
- const warmRows = takeRecentWarmMessages(
502
- eligibleRows,
503
- agent.warm_summary_limit,
504
- );
505
-
506
676
  const contextTokens = typeof providerParams.context_window_tokens === "number"
507
677
  ? providerParams.context_window_tokens
508
678
  : 32768;
509
679
  const summaryInputChars = Math.max(4000, Math.min(120000, Math.round(contextTokens * 3)));
680
+ const provider = providerOverride?.provider ?? getProvider(modelCfg.provider);
681
+ const modelId = providerOverride?.modelId ?? modelCfg.model_id;
682
+ const summaryParams = providerParams.max_tokens
683
+ ? providerParams
684
+ : { ...providerParams, max_tokens: 1024 };
510
685
 
511
- const selectedRows: typeof warmRows = [];
512
- const selectedTranscript: string[] = [];
513
- let selectedTranscriptChars = 0;
514
- for (let index = warmRows.length - 1; index >= 0; index -= 1) {
515
- const row = warmRows[index];
516
- const formatted = `[seq=${row.seq}] [${row.created_at}] ${row.role === "user" ? "User" : "Assistant"}: ${transcriptText(row.content)}`;
517
- const addedChars = formatted.length + (selectedTranscript.length > 0 ? 2 : 0);
518
- if (selectedTranscriptChars + addedChars > summaryInputChars) break;
519
- selectedRows.unshift(row);
520
- selectedTranscript.unshift(formatted);
521
- selectedTranscriptChars += addedChars;
686
+ const stored = getThreadChannelSummary(threadId, channel);
687
+ const outcome = await runTopicCompaction({
688
+ threadId,
689
+ source: automationCompactionSource(channel),
690
+ rows,
691
+ storedTopics: parseStoredTopics(stored?.topics ?? null),
692
+ storedBeforeSeq: stored?.summary_before_seq,
693
+ boundarySeq,
694
+ warmSummaryLimit: agent.warm_summary_limit,
695
+ summaryInputChars,
696
+ provider,
697
+ modelId,
698
+ params: summaryParams,
699
+ });
700
+ if (outcome.status === "empty") {
701
+ return { summary: "", sourceMessages: outcome.sourceMessages, sourceChars: outcome.sourceChars, topics: null };
702
+ }
703
+ if (outcome.status === "topics") {
704
+ const topics = keepSavedFactsOnly(outcome.topics);
705
+ return {
706
+ summary: topics.length > 0 ? wrapChannelSummary(channel, renderTopicRecaps(topics)) : "",
707
+ sourceMessages: outcome.sourceMessages,
708
+ sourceChars: outcome.sourceChars,
709
+ topics,
710
+ };
522
711
  }
712
+ console.warn(`[warm-summary] thread=${threadId} ${channel} compaction pipeline failed validation; using single-call summary`);
713
+
714
+ const eligibleRows = takeRecentWarmMessages(rows.filter((m) => m.seq < boundarySeq), agent.warm_summary_limit);
715
+ const { selectedRows, transcript } = selectTranscriptRows(eligibleRows, summaryInputChars);
523
716
  const sourceChars = selectedRows.reduce((total, row) => total + transcriptText(row.content).length, 0);
524
717
  if (sourceChars < 24 || selectedRows.length < 2) {
525
- return { summary: "", sourceMessages: selectedRows.length, sourceChars };
718
+ return { summary: "", sourceMessages: selectedRows.length, sourceChars, topics: null };
526
719
  }
527
-
528
- const transcript = selectedTranscript.join("\n\n").trim();
529
720
  if (!transcript) return null;
530
721
 
531
- const provider = providerOverride?.provider ?? getProvider(modelCfg.provider);
532
- const modelId = providerOverride?.modelId ?? modelCfg.model_id;
533
- const summaryParams = providerParams.max_tokens
534
- ? providerParams
535
- : { ...providerParams, max_tokens: 1024 };
536
-
537
722
  const raw = (await summarizeTranscript(provider, modelId, summaryParams, transcript)).trim();
538
723
  if (!raw) return null;
539
724
  const { body, topics } = extractTopicSegments(raw);
@@ -542,7 +727,7 @@ async function buildAutomationChannelSummaryBefore(
542
727
  allowPartialStart: true,
543
728
  });
544
729
  const summary = validatedTopics.length > 0
545
- ? renderTopicRecaps(validatedTopics)
730
+ ? renderTopicRecaps(validatedTopics.map((topic) => ({ ...topic, facts: [] })))
546
731
  : body;
547
732
  if (!summary) return null;
548
733
  const summarizedSeqs = new Set(validatedTopics.flatMap((topic) =>
@@ -556,13 +741,10 @@ async function buildAutomationChannelSummaryBefore(
556
741
  const summarizedChars = summarizedRows.reduce((total, row) => total + transcriptText(row.content).length, 0);
557
742
 
558
743
  return {
559
- summary: [
560
- `--- ${channel} activity summary ---`,
561
- "Compressed recap of automation activity outside the hot window:",
562
- summary,
563
- ].join("\n"),
744
+ summary: wrapChannelSummary(channel, summary),
564
745
  sourceMessages: summarizedRows.length,
565
746
  sourceChars: summarizedChars,
747
+ topics: null,
566
748
  };
567
749
  }
568
750
 
@@ -586,6 +768,7 @@ export async function compactAutomationChannelWarmContext(
586
768
  summary: built.summary,
587
769
  summaryBefore: boundary,
588
770
  summaryBeforeSeq: boundarySeq,
771
+ topics: built.topics ? JSON.stringify(built.topics) : null,
589
772
  });
590
773
  return built;
591
774
  }