@circuitwall/jarela 2.2.0 → 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 (683) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +4 -3
  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 +204 -163
  136. package/.next/standalone/.next/server/app/api/v1/models/route.js +548 -546
  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 +71 -68
  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 +1170 -719
  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 +4 -3
  221. package/.next/standalone/.next/server/chunks/{424.js → 1388.js} +345 -991
  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 +45 -45
  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 +10695 -10695
  233. package/.next/standalone/.next/server/chunks/3524.js +5 -33
  234. package/.next/standalone/.next/server/chunks/3566.js +1 -1
  235. package/.next/standalone/.next/server/chunks/4189.js +946 -0
  236. package/.next/standalone/.next/server/chunks/{9590.js → 423.js} +116 -49
  237. package/.next/standalone/.next/server/chunks/4433.js +146 -146
  238. package/.next/standalone/.next/server/chunks/4508.js +3 -3
  239. package/.next/standalone/.next/server/chunks/4588.js +1 -0
  240. package/.next/standalone/.next/server/chunks/46.js +116 -46
  241. package/.next/standalone/.next/server/chunks/466.js +100 -13
  242. package/.next/standalone/.next/server/chunks/4868.js +206 -206
  243. package/.next/standalone/.next/server/chunks/4992.js +13 -0
  244. package/.next/standalone/.next/server/chunks/5120.js +963 -0
  245. package/.next/standalone/.next/server/chunks/5701.js +1 -1
  246. package/.next/standalone/.next/server/chunks/5900.js +1 -1
  247. package/.next/standalone/.next/server/chunks/6210.js +1 -0
  248. package/.next/standalone/.next/server/chunks/6213.js +1 -1
  249. package/.next/standalone/.next/server/chunks/6649.js +3 -3
  250. package/.next/standalone/.next/server/chunks/6703.js +3 -3
  251. package/.next/standalone/.next/server/chunks/7445.js +1 -0
  252. package/.next/standalone/.next/server/chunks/8067.js +12 -0
  253. package/.next/standalone/.next/server/chunks/8461.js +14 -9
  254. package/.next/standalone/.next/server/chunks/8558.js +1 -1
  255. package/.next/standalone/.next/server/chunks/8724.js +1 -1
  256. package/.next/standalone/.next/server/chunks/8849.js +91 -91
  257. package/.next/standalone/.next/server/chunks/9032.js +6 -5
  258. package/.next/standalone/.next/server/chunks/{2563.js → 9164.js} +33106 -31420
  259. package/.next/standalone/.next/server/chunks/9237.js +396 -396
  260. package/.next/standalone/.next/server/chunks/{9640.js → 9304.js} +1628 -573
  261. package/.next/standalone/.next/server/chunks/9406.js +1 -1
  262. package/.next/standalone/.next/server/chunks/9824.js +98 -98
  263. package/.next/standalone/.next/server/chunks/9826.js +1 -0
  264. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  265. package/.next/standalone/.next/server/middleware.js +519 -442
  266. package/.next/standalone/.next/server/pages/404.html +2 -2
  267. package/.next/standalone/.next/server/pages/500.html +1 -1
  268. package/.next/standalone/.next/server/preview-props.json +3 -3
  269. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  270. package/.next/standalone/.next/static/chunks/{1395-f201e3e2e1f57715.js → 1395-e4a99912b8f83044.js} +101 -14
  271. package/.next/standalone/.next/static/chunks/{4576-13f7546a145a3624.js → 7045-8bc2f14e430ca661.js} +58 -2
  272. package/.next/standalone/.next/static/chunks/app/_global-error/{page-36cb8b428b38b26a.js → page-6fc5f8e744c81802.js} +1 -1
  273. package/.next/standalone/.next/static/chunks/app/api/v1/access/[identity]/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
  274. package/.next/standalone/.next/static/chunks/app/api/v1/access/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
  275. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/compact/{route-36cb8b428b38b26a.js → route-6fc5f8e744c81802.js} +1 -1
  276. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/display-filters/route-6fc5f8e744c81802.js +17 -0
  277. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/route-6fc5f8e744c81802.js +17 -0
  278. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/thread/route-6fc5f8e744c81802.js +17 -0
  279. package/.next/standalone/.next/static/chunks/app/api/v1/agents/route-6fc5f8e744c81802.js +17 -0
  280. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/[hostname]/route-6fc5f8e744c81802.js +17 -0
  281. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/route-6fc5f8e744c81802.js +17 -0
  282. package/.next/standalone/.next/static/chunks/app/api/v1/artifacts/lifecycle/route-6fc5f8e744c81802.js +17 -0
  283. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/files/route-6fc5f8e744c81802.js +17 -0
  284. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/images/route-6fc5f8e744c81802.js +17 -0
  285. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/chats/route-6fc5f8e744c81802.js +17 -0
  286. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/[remote_jid]/route-6fc5f8e744c81802.js +17 -0
  287. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/route-6fc5f8e744c81802.js +17 -0
  288. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/lookup/route-6fc5f8e744c81802.js +17 -0
  289. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/pair/route-6fc5f8e744c81802.js +17 -0
  290. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/route-6fc5f8e744c81802.js +17 -0
  291. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/[route_id]/route-6fc5f8e744c81802.js +17 -0
  292. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/route-6fc5f8e744c81802.js +17 -0
  293. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/status/route-6fc5f8e744c81802.js +17 -0
  294. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/kinds/route-6fc5f8e744c81802.js +17 -0
  295. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/route-6fc5f8e744c81802.js +17 -0
  296. package/.next/standalone/.next/static/chunks/app/api/v1/builtin-tools/route-6fc5f8e744c81802.js +17 -0
  297. package/.next/standalone/.next/static/chunks/app/api/v1/config/route-6fc5f8e744c81802.js +17 -0
  298. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/[id]/route-6fc5f8e744c81802.js +17 -0
  299. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/route-6fc5f8e744c81802.js +17 -0
  300. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/currency/route-6fc5f8e744c81802.js +17 -0
  301. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/metrics/route-6fc5f8e744c81802.js +17 -0
  302. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing/route-6fc5f8e744c81802.js +17 -0
  303. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing-task/route-6fc5f8e744c81802.js +17 -0
  304. package/.next/standalone/.next/static/chunks/app/api/v1/delegations/codex/[job_id]/route-6fc5f8e744c81802.js +17 -0
  305. package/.next/standalone/.next/static/chunks/app/api/v1/documents/search/route-6fc5f8e744c81802.js +17 -0
  306. package/.next/standalone/.next/static/chunks/app/api/v1/documents/settings/route-6fc5f8e744c81802.js +17 -0
  307. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/reindex/route-6fc5f8e744c81802.js +17 -0
  308. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/route-6fc5f8e744c81802.js +17 -0
  309. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/route-6fc5f8e744c81802.js +17 -0
  310. package/.next/standalone/.next/static/chunks/app/api/v1/env/route-6fc5f8e744c81802.js +17 -0
  311. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/allowlist/route-6fc5f8e744c81802.js +17 -0
  312. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/route-6fc5f8e744c81802.js +17 -0
  313. package/.next/standalone/.next/static/chunks/app/api/v1/events/route-6fc5f8e744c81802.js +17 -0
  314. package/.next/standalone/.next/static/chunks/app/api/v1/events/test/route-6fc5f8e744c81802.js +17 -0
  315. package/.next/standalone/.next/static/chunks/app/api/v1/extension/agents/route-6fc5f8e744c81802.js +17 -0
  316. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/activate/route-6fc5f8e744c81802.js +17 -0
  317. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/foreground/route-6fc5f8e744c81802.js +17 -0
  318. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/history/route-6fc5f8e744c81802.js +17 -0
  319. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/poll/route-6fc5f8e744c81802.js +17 -0
  320. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/progress/route-6fc5f8e744c81802.js +17 -0
  321. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/result/route-6fc5f8e744c81802.js +17 -0
  322. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/retry/route-6fc5f8e744c81802.js +17 -0
  323. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/status/route-6fc5f8e744c81802.js +17 -0
  324. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/tabs/route-6fc5f8e744c81802.js +17 -0
  325. package/.next/standalone/.next/static/chunks/app/api/v1/extension/fill/route-6fc5f8e744c81802.js +17 -0
  326. package/.next/standalone/.next/static/chunks/app/api/v1/extension/refine/route-6fc5f8e744c81802.js +17 -0
  327. package/.next/standalone/.next/static/chunks/app/api/v1/extension/turn/route-6fc5f8e744c81802.js +17 -0
  328. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/route-6fc5f8e744c81802.js +17 -0
  329. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/config/route-6fc5f8e744c81802.js +17 -0
  330. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/route-6fc5f8e744c81802.js +17 -0
  331. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/secrets/route-6fc5f8e744c81802.js +17 -0
  332. package/.next/standalone/.next/static/chunks/app/api/v1/files/[name]/route-6fc5f8e744c81802.js +17 -0
  333. package/.next/standalone/.next/static/chunks/app/api/v1/fs/browse/route-6fc5f8e744c81802.js +17 -0
  334. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/[id]/route-6fc5f8e744c81802.js +17 -0
  335. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/default/route-6fc5f8e744c81802.js +17 -0
  336. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/route-6fc5f8e744c81802.js +17 -0
  337. package/.next/standalone/.next/static/chunks/app/api/v1/health/probes/route-6fc5f8e744c81802.js +17 -0
  338. package/.next/standalone/.next/static/chunks/app/api/v1/health/route-6fc5f8e744c81802.js +17 -0
  339. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/route-6fc5f8e744c81802.js +17 -0
  340. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/test/route-6fc5f8e744c81802.js +17 -0
  341. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/callback/route-6fc5f8e744c81802.js +17 -0
  342. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/start/route-6fc5f8e744c81802.js +17 -0
  343. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/status/route-6fc5f8e744c81802.js +17 -0
  344. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/callback/route-6fc5f8e744c81802.js +17 -0
  345. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/start/route-6fc5f8e744c81802.js +17 -0
  346. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/status/route-6fc5f8e744c81802.js +17 -0
  347. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/route-6fc5f8e744c81802.js +17 -0
  348. package/.next/standalone/.next/static/chunks/app/api/v1/lifecycle/adoption/route-6fc5f8e744c81802.js +17 -0
  349. package/.next/standalone/.next/static/chunks/app/api/v1/local-file/route-6fc5f8e744c81802.js +17 -0
  350. package/.next/standalone/.next/static/chunks/app/api/v1/logs/route-6fc5f8e744c81802.js +17 -0
  351. package/.next/standalone/.next/static/chunks/app/api/v1/maps/embed/route-6fc5f8e744c81802.js +17 -0
  352. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/[name]/route-6fc5f8e744c81802.js +17 -0
  353. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/registry/route-6fc5f8e744c81802.js +17 -0
  354. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/route-6fc5f8e744c81802.js +17 -0
  355. package/.next/standalone/.next/static/chunks/app/api/v1/memory/[namespace]/[key]/route-6fc5f8e744c81802.js +17 -0
  356. package/.next/standalone/.next/static/chunks/app/api/v1/memory/policy/route-6fc5f8e744c81802.js +17 -0
  357. package/.next/standalone/.next/static/chunks/app/api/v1/memory/route-6fc5f8e744c81802.js +17 -0
  358. package/.next/standalone/.next/static/chunks/app/api/v1/memory/search/route-6fc5f8e744c81802.js +17 -0
  359. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/compact-threads/route-6fc5f8e744c81802.js +17 -0
  360. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/route-6fc5f8e744c81802.js +17 -0
  361. package/.next/standalone/.next/static/chunks/app/api/v1/models/route-6fc5f8e744c81802.js +17 -0
  362. package/.next/standalone/.next/static/chunks/app/api/v1/packages/catalog/route-6fc5f8e744c81802.js +17 -0
  363. package/.next/standalone/.next/static/chunks/app/api/v1/packages/defaults/[id]/route-6fc5f8e744c81802.js +17 -0
  364. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/[id]/route-6fc5f8e744c81802.js +17 -0
  365. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/route-6fc5f8e744c81802.js +17 -0
  366. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/enabled/route-6fc5f8e744c81802.js +17 -0
  367. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/route-6fc5f8e744c81802.js +17 -0
  368. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/route-6fc5f8e744c81802.js +17 -0
  369. package/.next/standalone/.next/static/chunks/app/api/v1/packages/reload/route-6fc5f8e744c81802.js +17 -0
  370. package/.next/standalone/.next/static/chunks/app/api/v1/packages/route-6fc5f8e744c81802.js +17 -0
  371. package/.next/standalone/.next/static/chunks/app/api/v1/page-capture/route-6fc5f8e744c81802.js +17 -0
  372. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/approve/route-6fc5f8e744c81802.js +17 -0
  373. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/deny/route-6fc5f8e744c81802.js +17 -0
  374. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/route-6fc5f8e744c81802.js +17 -0
  375. package/.next/standalone/.next/static/chunks/app/api/v1/profile/location/route-6fc5f8e744c81802.js +17 -0
  376. package/.next/standalone/.next/static/chunks/app/api/v1/profile/route-6fc5f8e744c81802.js +17 -0
  377. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/models/route-6fc5f8e744c81802.js +17 -0
  378. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/probe/route-6fc5f8e744c81802.js +17 -0
  379. package/.next/standalone/.next/static/chunks/app/api/v1/providers/github-copilot/auth/route-6fc5f8e744c81802.js +17 -0
  380. package/.next/standalone/.next/static/chunks/app/api/v1/providers/route-6fc5f8e744c81802.js +17 -0
  381. package/.next/standalone/.next/static/chunks/app/api/v1/proxy-config/route-6fc5f8e744c81802.js +17 -0
  382. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/init/route-6fc5f8e744c81802.js +17 -0
  383. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/route-6fc5f8e744c81802.js +17 -0
  384. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/route-6fc5f8e744c81802.js +17 -0
  385. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/run/route-6fc5f8e744c81802.js +17 -0
  386. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/route-6fc5f8e744c81802.js +17 -0
  387. package/.next/standalone/.next/static/chunks/app/api/v1/security/idle-timeout/route-6fc5f8e744c81802.js +17 -0
  388. package/.next/standalone/.next/static/chunks/app/api/v1/security/pin/route-6fc5f8e744c81802.js +17 -0
  389. package/.next/standalone/.next/static/chunks/app/api/v1/security/state/route-6fc5f8e744c81802.js +17 -0
  390. package/.next/standalone/.next/static/chunks/app/api/v1/security/unlock/route-6fc5f8e744c81802.js +17 -0
  391. package/.next/standalone/.next/static/chunks/app/api/v1/security/verify-pin/route-6fc5f8e744c81802.js +17 -0
  392. package/.next/standalone/.next/static/chunks/app/api/v1/setup/test-key/route-6fc5f8e744c81802.js +17 -0
  393. package/.next/standalone/.next/static/chunks/app/api/v1/skills/[id]/route-6fc5f8e744c81802.js +17 -0
  394. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/[id]/route-6fc5f8e744c81802.js +17 -0
  395. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/route-6fc5f8e744c81802.js +17 -0
  396. package/.next/standalone/.next/static/chunks/app/api/v1/skills/route-6fc5f8e744c81802.js +17 -0
  397. package/.next/standalone/.next/static/chunks/app/api/v1/system/abort/route-6fc5f8e744c81802.js +17 -0
  398. package/.next/standalone/.next/static/chunks/app/api/v1/system/restart/route-6fc5f8e744c81802.js +17 -0
  399. package/.next/standalone/.next/static/chunks/app/api/v1/tailscale/route-6fc5f8e744c81802.js +17 -0
  400. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/[agent_id]/route-6fc5f8e744c81802.js +17 -0
  401. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/route-6fc5f8e744c81802.js +17 -0
  402. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/activity/route-6fc5f8e744c81802.js +17 -0
  403. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/context-pin/route-6fc5f8e744c81802.js +17 -0
  404. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/route-6fc5f8e744c81802.js +17 -0
  405. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/run/route-6fc5f8e744c81802.js +17 -0
  406. package/.next/standalone/.next/static/chunks/app/api/v1/threads/route-6fc5f8e744c81802.js +17 -0
  407. package/.next/standalone/.next/static/chunks/app/api/v1/tools/route-6fc5f8e744c81802.js +17 -0
  408. package/.next/standalone/.next/static/chunks/app/api/v1/update/apply/route-6fc5f8e744c81802.js +17 -0
  409. package/.next/standalone/.next/static/chunks/app/api/v1/update/route-6fc5f8e744c81802.js +17 -0
  410. package/.next/standalone/.next/static/chunks/app/api/v1/voice/transcribe/route-6fc5f8e744c81802.js +17 -0
  411. package/.next/standalone/.next/static/chunks/app/api/v1/voice/tts/route-6fc5f8e744c81802.js +17 -0
  412. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/route-6fc5f8e744c81802.js +17 -0
  413. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/run/route-6fc5f8e744c81802.js +17 -0
  414. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/reaction-scripts/route-6fc5f8e744c81802.js +17 -0
  415. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/route-6fc5f8e744c81802.js +17 -0
  416. package/.next/standalone/.next/static/chunks/app/manifest.webmanifest/route-6fc5f8e744c81802.js +17 -0
  417. package/.next/standalone/.next/static/chunks/app/{page-c6e972a7fd13dae8.js → page-213a623b37226452.js} +1012 -604
  418. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-6fc5f8e744c81802.js +17 -0
  419. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-6fc5f8e744c81802.js +17 -0
  420. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-6fc5f8e744c81802.js +17 -0
  421. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-6fc5f8e744c81802.js +17 -0
  422. package/.next/standalone/.next/static/css/{d80058f0b9b41c09.css → 312542a5725ba0d5.css} +2 -2
  423. package/.next/standalone/docs/adoption/changesets.json +309 -0
  424. package/.next/standalone/lib/skills/builtins/memory-organization/SKILL.md +16 -0
  425. package/.next/standalone/package.json +3 -3
  426. package/CHANGELOG.md +33 -0
  427. package/api/client.models.test.ts +31 -0
  428. package/api/client.ts +25 -1
  429. package/api/types.ts +37 -0
  430. package/app/api/v1/lifecycle/adoption/route.ts +14 -2
  431. package/app/api/v1/models/[name]/compact-threads/route.ts +14 -11
  432. package/app/api/v1/models/[name]/route.test.ts +89 -0
  433. package/app/api/v1/models/[name]/route.ts +54 -3
  434. package/app/api/v1/models/route.ts +4 -2
  435. package/app/api/v1/providers/[provider]/models/route.test.ts +53 -0
  436. package/app/api/v1/providers/[provider]/models/route.ts +27 -16
  437. package/app/api/v1/threads/[thread_id]/activity/route.ts +19 -0
  438. package/app/api/v1/threads/[thread_id]/context-pin/route.test.ts +1 -0
  439. package/app/api/v1/threads/[thread_id]/context-pin/route.ts +2 -1
  440. package/app/api/v1/threads/[thread_id]/route.ts +5 -1
  441. package/components/agents/agent-editor/AdvancedSection.tsx +8 -2
  442. package/components/agents/agent-editor/ModelSection.tsx +6 -3
  443. package/components/chat/ChatView.tsx +52 -11
  444. package/components/chat/ContextBoundary.test.tsx +68 -1
  445. package/components/chat/ContextBoundary.tsx +92 -13
  446. package/components/chat/MessageList.test.tsx +31 -0
  447. package/components/chat/MessageList.tsx +49 -28
  448. package/components/chat/ToolList.test.tsx +92 -16
  449. package/components/chat/ToolList.tsx +59 -4
  450. package/components/chat/chat-helpers.test.tsx +24 -1
  451. package/components/chat/chat-helpers.ts +47 -4
  452. package/components/chat/useThreadActivity.test.tsx +113 -0
  453. package/components/chat/useThreadActivity.ts +94 -0
  454. package/components/chat/useThreadData.ts +16 -16
  455. package/components/chat/workflow-step-retry.ts +25 -0
  456. package/components/models/ModelEditor.tsx +1 -1
  457. package/components/models/ModelsPanel.tsx +34 -8
  458. package/components/models/model-editor/GitHubCopilotAuth.tsx +1 -1
  459. package/components/models/model-editor/save-helpers.ts +2 -2
  460. package/components/models/model-editor/useModelEditorForm.ts +1 -1
  461. package/components/models/model-editor/useModelSaveHandlers.ts +1 -1
  462. package/components/setup/wizard/StepCredentials.tsx +1 -1
  463. package/components/setup/wizard/StepModel.tsx +3 -8
  464. package/components/ui/BootScreen.tsx +17 -0
  465. package/components/ui/WorkflowChecklist.tsx +71 -33
  466. package/hooks/useModels.ts +17 -1
  467. package/hooks/useSSE.ts +28 -3
  468. package/lib/agents/compaction-pipeline.test.ts +202 -0
  469. package/lib/agents/compaction-pipeline.ts +483 -0
  470. package/lib/agents/conversation-summary.ts +37 -21
  471. package/lib/agents/effective-model.test.ts +45 -0
  472. package/lib/agents/effective-model.ts +11 -5
  473. package/lib/agents/llm.ts +2 -2
  474. package/lib/agents/prepare/history-window.test.ts +18 -0
  475. package/lib/agents/prepare/history-window.ts +11 -2
  476. package/lib/agents/prepare/request.ts +4 -0
  477. package/lib/agents/prepare/system-prompt.test.ts +39 -0
  478. package/lib/agents/prepare/system-prompt.ts +8 -3
  479. package/lib/agents/prompt-registry.test.ts +5 -140
  480. package/lib/agents/prompt-registry.ts +45 -1
  481. package/lib/agents/prompt-variants.ts +146 -0
  482. package/lib/agents/run-registry.test.ts +22 -0
  483. package/lib/agents/run-registry.ts +29 -0
  484. package/lib/agents/run-thread.retry.test.ts +67 -1
  485. package/lib/agents/run-thread.ts +96 -6
  486. package/lib/agents/thread-activity.test.ts +31 -0
  487. package/lib/agents/thread-activity.ts +27 -0
  488. package/lib/agents/thread-compaction-state.test.ts +82 -0
  489. package/lib/agents/thread-compaction-state.ts +121 -0
  490. package/lib/agents/thread-compaction.test.ts +83 -4
  491. package/lib/agents/thread-compaction.ts +34 -11
  492. package/lib/agents/warm-summary-background.test.ts +220 -7
  493. package/lib/agents/warm-summary-background.ts +329 -149
  494. package/lib/agents/warm-topics.test.ts +37 -0
  495. package/lib/agents/warm-topics.ts +297 -0
  496. package/lib/agents/workflow-step-retry.test.ts +96 -0
  497. package/lib/agents/workflow-step-retry.ts +216 -0
  498. package/lib/api/browser-control.ts +0 -3
  499. package/lib/db/migrations.ts +15 -0
  500. package/lib/env/config.ts +2 -0
  501. package/lib/env/schema.ts +12 -0
  502. package/lib/health/probes.test.ts +8 -11
  503. package/lib/health/probes.ts +5 -31
  504. package/lib/lifecycle/changeset-build.test.ts +93 -0
  505. package/lib/lifecycle/changeset-build.ts +210 -0
  506. package/lib/lifecycle/changesets.test.ts +101 -0
  507. package/lib/lifecycle/changesets.ts +166 -0
  508. package/lib/lifecycle/surface-collect.test.ts +88 -0
  509. package/lib/lifecycle/surface-collect.ts +64 -0
  510. package/lib/lifecycle/surface-snapshot.test.ts +104 -0
  511. package/lib/lifecycle/surface-snapshot.ts +210 -0
  512. package/lib/memory/record.ts +0 -2
  513. package/lib/models/editor-payload.ts +1 -1
  514. package/lib/providers/external.ts +0 -2
  515. package/lib/providers/github-copilot-auth.ts +2 -3
  516. package/lib/providers/github-copilot.test.ts +27 -0
  517. package/lib/providers/github-copilot.ts +21 -44
  518. package/lib/skills/builtins/memory-organization/SKILL.md +16 -0
  519. package/lib/stores/integrations.test.ts +7 -0
  520. package/lib/stores/integrations.ts +4 -4
  521. package/lib/stores/model-config.test.ts +88 -0
  522. package/lib/stores/model-config.ts +90 -8
  523. package/lib/stores/threads.test.ts +9 -0
  524. package/lib/stores/threads.ts +21 -11
  525. package/lib/stores/version-adoption.test.ts +96 -0
  526. package/lib/stores/version-adoption.ts +239 -26
  527. package/lib/stores/workflow-progress.ts +3 -0
  528. package/lib/tools/communications/ms-todo.ts +0 -7
  529. package/lib/tools/general/memory.ts +1 -1
  530. package/lib/tools/general/workflow-progress.ts +2 -0
  531. package/lib/tools/runtime/catalog.ts +1 -25
  532. package/lib/triggers/registry.ts +0 -4
  533. package/package.json +3 -3
  534. package/scripts/install-to-system.ps1 +39 -11
  535. package/scripts/install-to-system.sh +37 -3
  536. package/.next/standalone/.next/server/chunks/3979.js +0 -581
  537. package/.next/standalone/.next/server/chunks/5936.js +0 -594
  538. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/display-filters/route-36cb8b428b38b26a.js +0 -17
  539. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/route-36cb8b428b38b26a.js +0 -17
  540. package/.next/standalone/.next/static/chunks/app/api/v1/agents/[id]/thread/route-36cb8b428b38b26a.js +0 -17
  541. package/.next/standalone/.next/static/chunks/app/api/v1/agents/route-36cb8b428b38b26a.js +0 -17
  542. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/[hostname]/route-36cb8b428b38b26a.js +0 -17
  543. package/.next/standalone/.next/static/chunks/app/api/v1/allowed-sites/route-36cb8b428b38b26a.js +0 -17
  544. package/.next/standalone/.next/static/chunks/app/api/v1/artifacts/lifecycle/route-36cb8b428b38b26a.js +0 -17
  545. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/files/route-36cb8b428b38b26a.js +0 -17
  546. package/.next/standalone/.next/static/chunks/app/api/v1/attachments/images/route-36cb8b428b38b26a.js +0 -17
  547. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/chats/route-36cb8b428b38b26a.js +0 -17
  548. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/[remote_jid]/route-36cb8b428b38b26a.js +0 -17
  549. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/ignores/route-36cb8b428b38b26a.js +0 -17
  550. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/lookup/route-36cb8b428b38b26a.js +0 -17
  551. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/pair/route-36cb8b428b38b26a.js +0 -17
  552. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/route-36cb8b428b38b26a.js +0 -17
  553. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/[route_id]/route-36cb8b428b38b26a.js +0 -17
  554. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/routes/route-36cb8b428b38b26a.js +0 -17
  555. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/[id]/status/route-36cb8b428b38b26a.js +0 -17
  556. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/kinds/route-36cb8b428b38b26a.js +0 -17
  557. package/.next/standalone/.next/static/chunks/app/api/v1/bridges/route-36cb8b428b38b26a.js +0 -17
  558. package/.next/standalone/.next/static/chunks/app/api/v1/builtin-tools/route-36cb8b428b38b26a.js +0 -17
  559. package/.next/standalone/.next/static/chunks/app/api/v1/config/route-36cb8b428b38b26a.js +0 -17
  560. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/[id]/route-36cb8b428b38b26a.js +0 -17
  561. package/.next/standalone/.next/static/chunks/app/api/v1/credentials/route-36cb8b428b38b26a.js +0 -17
  562. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/currency/route-36cb8b428b38b26a.js +0 -17
  563. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/metrics/route-36cb8b428b38b26a.js +0 -17
  564. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing/route-36cb8b428b38b26a.js +0 -17
  565. package/.next/standalone/.next/static/chunks/app/api/v1/dashboard/pricing-task/route-36cb8b428b38b26a.js +0 -17
  566. package/.next/standalone/.next/static/chunks/app/api/v1/delegations/codex/[job_id]/route-36cb8b428b38b26a.js +0 -17
  567. package/.next/standalone/.next/static/chunks/app/api/v1/documents/search/route-36cb8b428b38b26a.js +0 -17
  568. package/.next/standalone/.next/static/chunks/app/api/v1/documents/settings/route-36cb8b428b38b26a.js +0 -17
  569. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/reindex/route-36cb8b428b38b26a.js +0 -17
  570. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/[id]/route-36cb8b428b38b26a.js +0 -17
  571. package/.next/standalone/.next/static/chunks/app/api/v1/documents/sources/route-36cb8b428b38b26a.js +0 -17
  572. package/.next/standalone/.next/static/chunks/app/api/v1/env/route-36cb8b428b38b26a.js +0 -17
  573. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/allowlist/route-36cb8b428b38b26a.js +0 -17
  574. package/.next/standalone/.next/static/chunks/app/api/v1/env-sync/route-36cb8b428b38b26a.js +0 -17
  575. package/.next/standalone/.next/static/chunks/app/api/v1/events/route-36cb8b428b38b26a.js +0 -17
  576. package/.next/standalone/.next/static/chunks/app/api/v1/events/test/route-36cb8b428b38b26a.js +0 -17
  577. package/.next/standalone/.next/static/chunks/app/api/v1/extension/agents/route-36cb8b428b38b26a.js +0 -17
  578. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/activate/route-36cb8b428b38b26a.js +0 -17
  579. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/foreground/route-36cb8b428b38b26a.js +0 -17
  580. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/history/route-36cb8b428b38b26a.js +0 -17
  581. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/poll/route-36cb8b428b38b26a.js +0 -17
  582. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/progress/route-36cb8b428b38b26a.js +0 -17
  583. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/result/route-36cb8b428b38b26a.js +0 -17
  584. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/retry/route-36cb8b428b38b26a.js +0 -17
  585. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/status/route-36cb8b428b38b26a.js +0 -17
  586. package/.next/standalone/.next/static/chunks/app/api/v1/extension/browser/tabs/route-36cb8b428b38b26a.js +0 -17
  587. package/.next/standalone/.next/static/chunks/app/api/v1/extension/fill/route-36cb8b428b38b26a.js +0 -17
  588. package/.next/standalone/.next/static/chunks/app/api/v1/extension/refine/route-36cb8b428b38b26a.js +0 -17
  589. package/.next/standalone/.next/static/chunks/app/api/v1/extension/turn/route-36cb8b428b38b26a.js +0 -17
  590. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/route-36cb8b428b38b26a.js +0 -17
  591. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/config/route-36cb8b428b38b26a.js +0 -17
  592. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/route-36cb8b428b38b26a.js +0 -17
  593. package/.next/standalone/.next/static/chunks/app/api/v1/extensions/tools/[name]/secrets/route-36cb8b428b38b26a.js +0 -17
  594. package/.next/standalone/.next/static/chunks/app/api/v1/files/[name]/route-36cb8b428b38b26a.js +0 -17
  595. package/.next/standalone/.next/static/chunks/app/api/v1/fs/browse/route-36cb8b428b38b26a.js +0 -17
  596. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/[id]/route-36cb8b428b38b26a.js +0 -17
  597. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/default/route-36cb8b428b38b26a.js +0 -17
  598. package/.next/standalone/.next/static/chunks/app/api/v1/harnesses/route-36cb8b428b38b26a.js +0 -17
  599. package/.next/standalone/.next/static/chunks/app/api/v1/health/probes/route-36cb8b428b38b26a.js +0 -17
  600. package/.next/standalone/.next/static/chunks/app/api/v1/health/route-36cb8b428b38b26a.js +0 -17
  601. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/route-36cb8b428b38b26a.js +0 -17
  602. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/[name]/test/route-36cb8b428b38b26a.js +0 -17
  603. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/callback/route-36cb8b428b38b26a.js +0 -17
  604. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/start/route-36cb8b428b38b26a.js +0 -17
  605. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/gmail/oauth/status/route-36cb8b428b38b26a.js +0 -17
  606. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/callback/route-36cb8b428b38b26a.js +0 -17
  607. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/start/route-36cb8b428b38b26a.js +0 -17
  608. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/outlook/oauth/status/route-36cb8b428b38b26a.js +0 -17
  609. package/.next/standalone/.next/static/chunks/app/api/v1/integrations/route-36cb8b428b38b26a.js +0 -17
  610. package/.next/standalone/.next/static/chunks/app/api/v1/lifecycle/adoption/route-36cb8b428b38b26a.js +0 -17
  611. package/.next/standalone/.next/static/chunks/app/api/v1/local-file/route-36cb8b428b38b26a.js +0 -17
  612. package/.next/standalone/.next/static/chunks/app/api/v1/logs/route-36cb8b428b38b26a.js +0 -17
  613. package/.next/standalone/.next/static/chunks/app/api/v1/maps/embed/route-36cb8b428b38b26a.js +0 -17
  614. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/[name]/route-36cb8b428b38b26a.js +0 -17
  615. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/registry/route-36cb8b428b38b26a.js +0 -17
  616. package/.next/standalone/.next/static/chunks/app/api/v1/mcp-servers/route-36cb8b428b38b26a.js +0 -17
  617. package/.next/standalone/.next/static/chunks/app/api/v1/memory/[namespace]/[key]/route-36cb8b428b38b26a.js +0 -17
  618. package/.next/standalone/.next/static/chunks/app/api/v1/memory/policy/route-36cb8b428b38b26a.js +0 -17
  619. package/.next/standalone/.next/static/chunks/app/api/v1/memory/route-36cb8b428b38b26a.js +0 -17
  620. package/.next/standalone/.next/static/chunks/app/api/v1/memory/search/route-36cb8b428b38b26a.js +0 -17
  621. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/compact-threads/route-36cb8b428b38b26a.js +0 -17
  622. package/.next/standalone/.next/static/chunks/app/api/v1/models/[name]/route-36cb8b428b38b26a.js +0 -17
  623. package/.next/standalone/.next/static/chunks/app/api/v1/models/route-36cb8b428b38b26a.js +0 -17
  624. package/.next/standalone/.next/static/chunks/app/api/v1/packages/catalog/route-36cb8b428b38b26a.js +0 -17
  625. package/.next/standalone/.next/static/chunks/app/api/v1/packages/defaults/[id]/route-36cb8b428b38b26a.js +0 -17
  626. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/[id]/route-36cb8b428b38b26a.js +0 -17
  627. package/.next/standalone/.next/static/chunks/app/api/v1/packages/install/route-36cb8b428b38b26a.js +0 -17
  628. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/enabled/route-36cb8b428b38b26a.js +0 -17
  629. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/[name]/route-36cb8b428b38b26a.js +0 -17
  630. package/.next/standalone/.next/static/chunks/app/api/v1/packages/manifests/route-36cb8b428b38b26a.js +0 -17
  631. package/.next/standalone/.next/static/chunks/app/api/v1/packages/reload/route-36cb8b428b38b26a.js +0 -17
  632. package/.next/standalone/.next/static/chunks/app/api/v1/packages/route-36cb8b428b38b26a.js +0 -17
  633. package/.next/standalone/.next/static/chunks/app/api/v1/page-capture/route-36cb8b428b38b26a.js +0 -17
  634. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/approve/route-36cb8b428b38b26a.js +0 -17
  635. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/[id]/deny/route-36cb8b428b38b26a.js +0 -17
  636. package/.next/standalone/.next/static/chunks/app/api/v1/pending-actions/route-36cb8b428b38b26a.js +0 -17
  637. package/.next/standalone/.next/static/chunks/app/api/v1/profile/location/route-36cb8b428b38b26a.js +0 -17
  638. package/.next/standalone/.next/static/chunks/app/api/v1/profile/route-36cb8b428b38b26a.js +0 -17
  639. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/models/route-36cb8b428b38b26a.js +0 -17
  640. package/.next/standalone/.next/static/chunks/app/api/v1/providers/[provider]/probe/route-36cb8b428b38b26a.js +0 -17
  641. package/.next/standalone/.next/static/chunks/app/api/v1/providers/github-copilot/auth/route-36cb8b428b38b26a.js +0 -17
  642. package/.next/standalone/.next/static/chunks/app/api/v1/providers/route-36cb8b428b38b26a.js +0 -17
  643. package/.next/standalone/.next/static/chunks/app/api/v1/proxy-config/route-36cb8b428b38b26a.js +0 -17
  644. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/init/route-36cb8b428b38b26a.js +0 -17
  645. package/.next/standalone/.next/static/chunks/app/api/v1/redaction/route-36cb8b428b38b26a.js +0 -17
  646. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/route-36cb8b428b38b26a.js +0 -17
  647. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/[id]/run/route-36cb8b428b38b26a.js +0 -17
  648. package/.next/standalone/.next/static/chunks/app/api/v1/scheduled-tasks/route-36cb8b428b38b26a.js +0 -17
  649. package/.next/standalone/.next/static/chunks/app/api/v1/security/idle-timeout/route-36cb8b428b38b26a.js +0 -17
  650. package/.next/standalone/.next/static/chunks/app/api/v1/security/pin/route-36cb8b428b38b26a.js +0 -17
  651. package/.next/standalone/.next/static/chunks/app/api/v1/security/state/route-36cb8b428b38b26a.js +0 -17
  652. package/.next/standalone/.next/static/chunks/app/api/v1/security/unlock/route-36cb8b428b38b26a.js +0 -17
  653. package/.next/standalone/.next/static/chunks/app/api/v1/security/verify-pin/route-36cb8b428b38b26a.js +0 -17
  654. package/.next/standalone/.next/static/chunks/app/api/v1/setup/test-key/route-36cb8b428b38b26a.js +0 -17
  655. package/.next/standalone/.next/static/chunks/app/api/v1/skills/[id]/route-36cb8b428b38b26a.js +0 -17
  656. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/[id]/route-36cb8b428b38b26a.js +0 -17
  657. package/.next/standalone/.next/static/chunks/app/api/v1/skills/repos/route-36cb8b428b38b26a.js +0 -17
  658. package/.next/standalone/.next/static/chunks/app/api/v1/skills/route-36cb8b428b38b26a.js +0 -17
  659. package/.next/standalone/.next/static/chunks/app/api/v1/system/abort/route-36cb8b428b38b26a.js +0 -17
  660. package/.next/standalone/.next/static/chunks/app/api/v1/system/restart/route-36cb8b428b38b26a.js +0 -17
  661. package/.next/standalone/.next/static/chunks/app/api/v1/tailscale/route-36cb8b428b38b26a.js +0 -17
  662. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/[agent_id]/route-36cb8b428b38b26a.js +0 -17
  663. package/.next/standalone/.next/static/chunks/app/api/v1/tasks/route-36cb8b428b38b26a.js +0 -17
  664. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/context-pin/route-36cb8b428b38b26a.js +0 -17
  665. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/route-36cb8b428b38b26a.js +0 -17
  666. package/.next/standalone/.next/static/chunks/app/api/v1/threads/[thread_id]/run/route-36cb8b428b38b26a.js +0 -17
  667. package/.next/standalone/.next/static/chunks/app/api/v1/threads/route-36cb8b428b38b26a.js +0 -17
  668. package/.next/standalone/.next/static/chunks/app/api/v1/tools/route-36cb8b428b38b26a.js +0 -17
  669. package/.next/standalone/.next/static/chunks/app/api/v1/update/apply/route-36cb8b428b38b26a.js +0 -17
  670. package/.next/standalone/.next/static/chunks/app/api/v1/update/route-36cb8b428b38b26a.js +0 -17
  671. package/.next/standalone/.next/static/chunks/app/api/v1/voice/transcribe/route-36cb8b428b38b26a.js +0 -17
  672. package/.next/standalone/.next/static/chunks/app/api/v1/voice/tts/route-36cb8b428b38b26a.js +0 -17
  673. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/route-36cb8b428b38b26a.js +0 -17
  674. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/[id]/run/route-36cb8b428b38b26a.js +0 -17
  675. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/reaction-scripts/route-36cb8b428b38b26a.js +0 -17
  676. package/.next/standalone/.next/static/chunks/app/api/v1/watchers/route-36cb8b428b38b26a.js +0 -17
  677. package/.next/standalone/.next/static/chunks/app/manifest.webmanifest/route-36cb8b428b38b26a.js +0 -17
  678. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-36cb8b428b38b26a.js +0 -17
  679. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-36cb8b428b38b26a.js +0 -17
  680. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-36cb8b428b38b26a.js +0 -17
  681. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-36cb8b428b38b26a.js +0 -17
  682. /package/.next/standalone/.next/static/{e2NV1wk6mWg3SIeELXevg → bMRK5y3ruT7c3WtBfCQOG}/_buildManifest.js +0 -0
  683. /package/.next/standalone/.next/static/{e2NV1wk6mWg3SIeELXevg → bMRK5y3ruT7c3WtBfCQOG}/_ssgManifest.js +0 -0
@@ -1,5 +1,9 @@
1
1
  import { afterEach, describe, it, expect, vi } from "vitest";
2
2
  import type AnthropicNS from "@anthropic-ai/sdk";
3
+
4
+ // Keep routing tests off the developer's real data directory: no stored OAuth token.
5
+ vi.mock("./github-copilot-auth", () => ({ getStoredOAuthToken: () => null }));
6
+
3
7
  import { githubCopilotProvider, isCopilotClaudeModel } from "./github-copilot";
4
8
 
5
9
  afterEach(() => vi.unstubAllGlobals());
@@ -113,4 +117,27 @@ describe("Claude-via-Copilot routing", () => {
113
117
  }, [])).rejects.toMatchObject({ status: 429 });
114
118
  expect(fetch).toHaveBeenCalledTimes(1);
115
119
  });
120
+ it.each(["ghp_synthetic", "github_pat_synthetic"])("rejects PAT %s without network access", async (apiKey) => {
121
+ const fetch = vi.fn(async () => new Response("{}", { status: 503 }));
122
+ vi.stubGlobal("fetch", fetch);
123
+
124
+ await expect(githubCopilotProvider.invoke!("gpt-4o", [{ role: "user", content: "synthetic" }], {
125
+ api_key: apiKey,
126
+ }, [])).rejects.toThrow(/PAT route used GitHub Models.*retired/i);
127
+ expect(fetch).not.toHaveBeenCalled();
128
+ });
129
+
130
+ it("routes explicit session tokens through the Copilot Chat endpoint", async () => {
131
+ const urls: string[] = [];
132
+ const fetch = vi.fn(async (input: RequestInfo | URL) => {
133
+ urls.push(input instanceof Request ? input.url : input.toString());
134
+ return new Response("{}", { status: 503 });
135
+ });
136
+ vi.stubGlobal("fetch", fetch);
137
+
138
+ await expect(githubCopilotProvider.invoke!("gpt-4o", [{ role: "user", content: "synthetic" }], {
139
+ copilot_session_token: "synthetic-session-token",
140
+ }, [])).rejects.toThrow();
141
+ expect(urls).toEqual(["https://api.githubcopilot.com/chat/completions"]);
142
+ });
116
143
  });
@@ -55,19 +55,19 @@ interface SessionToken {
55
55
 
56
56
  const tokenCache = new Map<string, SessionToken>();
57
57
 
58
- function isLikelyGitHubPat(token: string): boolean {
59
- return token.startsWith("ghp_") || token.startsWith("github_pat_") || token.startsWith("gho_");
58
+ function isGitHubPat(token: string): boolean {
59
+ return token.startsWith("ghp_") || token.startsWith("github_pat_");
60
60
  }
61
61
 
62
- async function getCopilotToken(pat: string): Promise<string> {
63
- if (!pat) throw new Error("GitHub Copilot: no API key configured for token exchange.");
64
- const cached = tokenCache.get(pat);
62
+ async function exchangeCopilotSessionToken(githubToken: string): Promise<string> {
63
+ if (!githubToken) throw new Error("GitHub Copilot: no API key configured for token exchange.");
64
+ const cached = tokenCache.get(githubToken);
65
65
  if (cached && cached.expiresAt - Date.now() > 60_000) return cached.token;
66
- tokenCache.delete(pat);
66
+ tokenCache.delete(githubToken);
67
67
 
68
68
  const res = await fetch("https://api.github.com/copilot_internal/v2/token", {
69
69
  headers: {
70
- Authorization: `token ${pat}`,
70
+ Authorization: `token ${githubToken}`,
71
71
  "User-Agent": "Jarela/1.0",
72
72
  },
73
73
  signal: AbortSignal.timeout(30_000),
@@ -78,15 +78,14 @@ async function getCopilotToken(pat: string): Promise<string> {
78
78
  if (res.status === 401) {
79
79
  throw new Error(
80
80
  `GitHub Copilot: token exchange failed (401). ` +
81
- `Ensure your PAT has the "copilot" scope and that you have an active Copilot subscription. ` +
81
+ `Check that this GitHub account has an active Copilot subscription and the credential is valid. ` +
82
82
  `Details: ${body}`,
83
83
  );
84
84
  }
85
85
  if (res.status === 404) {
86
86
  throw new Error(
87
- "GitHub Copilot token exchange endpoint was not found for this credential. " +
88
- "Personal Access Tokens are not accepted directly by Copilot chat. " +
89
- "Use a Copilot session token in params.copilot_session_token, or a credential that supports token exchange.",
87
+ "GitHub Copilot could not exchange this credential for a session token. " +
88
+ "Use the in-app device-flow sign-in or set params.copilot_session_token.",
90
89
  );
91
90
  }
92
91
  throw new Error(`GitHub Copilot: token exchange failed (${res.status}): ${body}`);
@@ -96,7 +95,7 @@ async function getCopilotToken(pat: string): Promise<string> {
96
95
  if (!json.token) throw new Error("GitHub Copilot: token exchange returned no token");
97
96
 
98
97
  const expiresAt = json.expires_at ? new Date(json.expires_at).getTime() : Date.now() + 28 * 60_000;
99
- tokenCache.set(pat, { token: json.token, expiresAt });
98
+ tokenCache.set(githubToken, { token: json.token, expiresAt });
100
99
  return json.token;
101
100
  }
102
101
 
@@ -119,14 +118,8 @@ async function resolvedClient(params: ProviderParams): Promise<OpenAI> {
119
118
  });
120
119
  }
121
120
 
122
- // Returns the auth + transport details needed to talk to GitHub Copilot. The
123
- // session-token + native-Messages-API path is preferred because it preserves
124
- // Anthropic `cache_control` markers; the legacy PAT path falls back to
125
- // GitHub Models REST (OpenAI-shaped, no Claude Messages support, capped at
126
- // ~8K input tokens) and is incompatible with Anthropic routing.
127
- type CopilotAuth =
128
- | { kind: "copilot-api"; baseURL: string; apiKey: string; headers: Record<string, string> }
129
- | { kind: "models-rest"; baseURL: string; apiKey: string; headers: Record<string, string> };
121
+ // Resolves credentials for Copilot's OpenAI-compatible and native Messages APIs.
122
+ type CopilotAuth = { baseURL: string; apiKey: string; headers: Record<string, string> };
130
123
 
131
124
  async function resolveCopilotAuth(params: ProviderParams): Promise<CopilotAuth> {
132
125
  const apiKey = (params.api_key as string | undefined) ?? "";
@@ -134,7 +127,6 @@ async function resolveCopilotAuth(params: ProviderParams): Promise<CopilotAuth>
134
127
 
135
128
  if (explicitSessionToken && explicitSessionToken.length > 0) {
136
129
  return {
137
- kind: "copilot-api",
138
130
  baseURL: params.base_url ?? "https://api.githubcopilot.com",
139
131
  apiKey: explicitSessionToken,
140
132
  headers: { ...FIXED_HEADERS },
@@ -143,25 +135,19 @@ async function resolveCopilotAuth(params: ProviderParams): Promise<CopilotAuth>
143
135
 
144
136
  const oauthToken = getStoredOAuthToken();
145
137
  if (oauthToken) {
146
- const token = await getCopilotToken(oauthToken);
138
+ const token = await exchangeCopilotSessionToken(oauthToken);
147
139
  return {
148
- kind: "copilot-api",
149
140
  baseURL: params.base_url ?? "https://api.githubcopilot.com",
150
141
  apiKey: token,
151
142
  headers: { ...FIXED_HEADERS },
152
143
  };
153
144
  }
154
145
 
155
- if (apiKey && isLikelyGitHubPat(apiKey)) {
156
- return {
157
- kind: "models-rest",
158
- baseURL: params.base_url ?? "https://models.github.ai/inference",
159
- apiKey,
160
- headers: {
161
- Accept: "application/vnd.github+json",
162
- "X-GitHub-Api-Version": "2026-03-10",
163
- },
164
- };
146
+ if (apiKey && isGitHubPat(apiKey)) {
147
+ throw new Error(
148
+ "GitHub Copilot: this provider's GitHub PAT route used GitHub Models, which has been retired. " +
149
+ "Use the in-app device-flow sign-in or set copilot_session_token.",
150
+ );
165
151
  }
166
152
 
167
153
  if (!apiKey) {
@@ -169,9 +155,8 @@ async function resolveCopilotAuth(params: ProviderParams): Promise<CopilotAuth>
169
155
  "GitHub Copilot: not signed in. Use the in-app device-flow login, or set api_key / copilot_session_token.",
170
156
  );
171
157
  }
172
- const token = await getCopilotToken(apiKey);
158
+ const token = await exchangeCopilotSessionToken(apiKey);
173
159
  return {
174
- kind: "copilot-api",
175
160
  baseURL: params.base_url ?? "https://api.githubcopilot.com",
176
161
  apiKey: token,
177
162
  headers: { ...FIXED_HEADERS },
@@ -181,17 +166,9 @@ async function resolveCopilotAuth(params: ProviderParams): Promise<CopilotAuth>
181
166
  // Anthropic SDK client pointed at Copilot's native `/v1/messages` endpoint.
182
167
  // Copilot accepts the Anthropic request shape (including `cache_control`
183
168
  // ephemeral breakpoints) for Claude-family models when called with a
184
- // session token. The PAT-only `models.github.ai` fallback does NOT expose
185
- // this endpoint, so we surface a clear error there instead of silently
186
- // downgrading to a path that strips the cache markers.
169
+ // Copilot session token.
187
170
  async function resolvedAnthropicClient(params: ProviderParams): Promise<Anthropic> {
188
171
  const auth = await resolveCopilotAuth(params);
189
- if (auth.kind !== "copilot-api") {
190
- throw new Error(
191
- "GitHub Copilot: Claude models require a Copilot session token (OAuth or copilot_session_token). " +
192
- "Personal Access Tokens route to GitHub Models REST, which does not expose the native Messages API.",
193
- );
194
- }
195
172
  return new Anthropic({
196
173
  // The SDK requires an apiKey field; we authenticate via authToken
197
174
  // (Authorization: Bearer ...) per Copilot's contract. The empty
@@ -37,6 +37,22 @@ Every update to an existing key keeps a dated snapshot of the prior record in
37
37
  its `history`, and older free-form or v1 entries are upgraded to the current
38
38
  schema automatically the first time they're read — no manual migration step.
39
39
 
40
+ ## Proactive Saving
41
+
42
+ Memory is shared by every Jarela agent, so save durable information in the
43
+ turn it appears instead of relying on background compaction, which runs later
44
+ and can miss details.
45
+
46
+ 1. **Trigger:** the user states a preference, fact, decision, constraint, or
47
+ correction; or a tool result verifies a durable fact.
48
+ 2. **Check:** search for an existing record on the same subject and reuse its
49
+ key.
50
+ 3. **Write:** call `memory_upsert` before the final reply.
51
+ 4. **Validate:** the result must contain `ok: true` and the key you sent;
52
+ retry once on failure, then tell the user it was not saved.
53
+ 5. **Cite:** end the reply with `Saved to memory: facts/<key>` for each saved
54
+ key.
55
+
40
56
  ## Retrieval And Consolidation
41
57
 
42
58
  1. Let proactive recall supply matching facts on normal user turns. Use
@@ -175,6 +175,13 @@ describe("integrations store (credentials-backed)", () => {
175
175
  // And no credential was created as a side effect of the failed write.
176
176
  expect(listCredentials({ type: "integration", provider: "anthropic" }).length).toBe(0);
177
177
  });
178
+
179
+ it("does not create a configured row from an empty optional credential field", () => {
180
+ const result = saveIntegration("github-copilot", { api_key: "" });
181
+ expect("error" in result).toBe(true);
182
+ expect(getIntegrationStatus("github-copilot")?.configured).toBe(false);
183
+ expect(listCredentials({ type: "integration", provider: "github-copilot" })).toHaveLength(0);
184
+ });
178
185
  });
179
186
 
180
187
  describe("integrations store: multi-instance + ALS routing", () => {
@@ -176,11 +176,10 @@ export const INTEGRATIONS = {
176
176
  label: "GitHub Copilot",
177
177
  category: "llm" as IntegrationCategory,
178
178
  description:
179
- "Routes chat-completion requests through your Copilot subscription. Paste a GitHub PAT " +
180
- "with `copilot` scope from github.com/settings/tokens, or run the device-flow sign-in in " +
181
- "the Models panel.",
179
+ "Routes chat-completion requests through your Copilot subscription. Use the device-flow " +
180
+ "sign-in in the Models panel; legacy GitHub PAT authentication is no longer supported.",
182
181
  fields: [
183
- { key: "api_key", label: "GitHub PAT", placeholder: "ghp_… or github_pat_…", secret: true, required: true },
182
+ { key: "api_key", label: "Legacy GitHub PAT (unsupported)", placeholder: "Use Models panel sign-in", secret: true, required: false },
184
183
  ],
185
184
  },
186
185
  gmail: {
@@ -437,6 +436,7 @@ export function saveIntegration(name: string, incoming: Record<string, string>):
437
436
  else if (f.required) return { error: `missing required secret "${f.key}"` };
438
437
  } else {
439
438
  if (f.required && !v.trim()) return { error: `"${f.key}" cannot be empty` };
439
+ if (!v.trim()) continue;
440
440
  merged[f.key] = v;
441
441
  if (existing[f.key] !== v) touched.push(f.key);
442
442
  }
@@ -118,3 +118,91 @@ describe("deleteModelConfig auto-promotes default", () => {
118
118
  deleteModelConfig("keep-default");
119
119
  });
120
120
  });
121
+
122
+ describe("model config enable/disable and atomic default", () => {
123
+ async function load() {
124
+ return import("./model-config");
125
+ }
126
+
127
+ function reset(names: string[]) {
128
+ for (const n of names) deleteModelConfig(n);
129
+ }
130
+
131
+ it("new rows are enabled and upsert without is_default preserves the default flag", async () => {
132
+ const { isModelConfigEnabled } = await load();
133
+ upsertModelConfig("ena-a", "anthropic", "claude-x", {}, true);
134
+ const saved = upsertModelConfig("ena-a", "anthropic", "claude-x", { temperature: 0.2 }, undefined);
135
+ expect(saved.is_default).toBe(1);
136
+ expect(isModelConfigEnabled(saved)).toBe(true);
137
+ reset(["ena-a"]);
138
+ });
139
+
140
+ it("setDefaultModelConfig leaves exactly one default", async () => {
141
+ const { setDefaultModelConfig, listModelConfigs } = await load();
142
+ upsertModelConfig("def-a", "anthropic", "claude-x", {}, true);
143
+ upsertModelConfig("def-b", "anthropic", "claude-y", {}, false);
144
+ const row = setDefaultModelConfig("def-b");
145
+ expect(row.is_default).toBe(1);
146
+ expect(listModelConfigs().filter((r) => r.is_default === 1).map((r) => r.name)).toEqual(["def-b"]);
147
+ // Params are untouched by a default switch.
148
+ expect(getModelConfig("def-a")?.params).toBe(JSON.stringify({}));
149
+ reset(["def-a", "def-b"]);
150
+ });
151
+
152
+ it("setDefaultModelConfig rejects unknown and disabled configs without changing the default", async () => {
153
+ const { setDefaultModelConfig, setModelConfigEnabled, ModelConfigStateError } = await load();
154
+ upsertModelConfig("rej-a", "anthropic", "claude-x", {}, true);
155
+ upsertModelConfig("rej-b", "anthropic", "claude-y", {}, false);
156
+ setModelConfigEnabled("rej-b", false);
157
+ expect(() => setDefaultModelConfig("missing-model")).toThrow(ModelConfigStateError);
158
+ expect(() => setDefaultModelConfig("rej-b")).toThrow(/disabled/);
159
+ expect(getDefaultModelConfig()?.name).toBe("rej-a");
160
+ reset(["rej-a", "rej-b"]);
161
+ });
162
+
163
+ it("disabling the default promotes another enabled config in the same step", async () => {
164
+ const { setModelConfigEnabled, listModelConfigs } = await load();
165
+ upsertModelConfig("dis-a", "anthropic", "claude-x", {}, true);
166
+ upsertModelConfig("dis-b", "anthropic", "claude-y", {}, false);
167
+ const disabled = setModelConfigEnabled("dis-a", false);
168
+ expect(disabled.enabled).toBe(0);
169
+ expect(disabled.is_default).toBe(0);
170
+ const defaults = listModelConfigs().filter((r) => r.is_default === 1);
171
+ expect(defaults).toHaveLength(1);
172
+ expect(defaults[0].enabled).toBe(1);
173
+ expect(getDefaultModelConfig()?.name).not.toBe("dis-a");
174
+ reset(["dis-a", "dis-b"]);
175
+ });
176
+
177
+ it("refuses to disable the last enabled config", async () => {
178
+ const { setModelConfigEnabled, listModelConfigs } = await load();
179
+ for (const r of listModelConfigs()) deleteModelConfig(r.name);
180
+ upsertModelConfig("only-one", "anthropic", "claude-x", {}, true);
181
+ expect(() => setModelConfigEnabled("only-one", false)).toThrow(/at least one/i);
182
+ expect(getModelConfig("only-one")?.enabled).toBe(1);
183
+ reset(["only-one"]);
184
+ });
185
+
186
+ it("disabled configs are skipped by default fallback and runnable resolution", async () => {
187
+ const { setModelConfigEnabled, resolveRunnableModelConfig, listEnabledModelConfigs } = await load();
188
+ upsertModelConfig("run-a", "anthropic", "claude-x", {}, true);
189
+ upsertModelConfig("run-b", "anthropic", "claude-y", {}, false);
190
+ setModelConfigEnabled("run-b", false);
191
+ expect(listEnabledModelConfigs().map((r) => r.name)).not.toContain("run-b");
192
+ expect(resolveRunnableModelConfig("run-b")?.name).toBe("run-a");
193
+ setModelConfigEnabled("run-b", true);
194
+ expect(resolveRunnableModelConfig("run-b")?.name).toBe("run-b");
195
+ reset(["run-a", "run-b"]);
196
+ });
197
+
198
+ it("making a disabled config the default via upsert re-enables it", async () => {
199
+ const { setModelConfigEnabled } = await load();
200
+ upsertModelConfig("up-a", "anthropic", "claude-x", {}, true);
201
+ upsertModelConfig("up-b", "anthropic", "claude-y", {}, false);
202
+ setModelConfigEnabled("up-b", false);
203
+ const row = upsertModelConfig("up-b", "anthropic", "claude-y", {}, true);
204
+ expect(row.enabled).toBe(1);
205
+ expect(getDefaultModelConfig()?.name).toBe("up-b");
206
+ reset(["up-a", "up-b"]);
207
+ });
208
+ });
@@ -17,6 +17,9 @@ export function withModelConfigMutation<T>(
17
17
  export interface ModelConfigRow {
18
18
  name: string; provider: string; model_id: string;
19
19
  params: string; is_default: number;
20
+ // ADR-0102: 0 hides the config from model selection, routing, and the
21
+ // default fallback without deleting it. Optional for rows built in tests.
22
+ enabled?: number;
20
23
  // ADR forthcoming ??? first-class credentials. NULL until the row is
21
24
  // explicitly bound (or until the auto-migration in lib/db/migrations.ts
22
25
  // lifts an inline api_key into a credential row).
@@ -24,6 +27,16 @@ export interface ModelConfigRow {
24
27
  created_at: string; updated_at: string;
25
28
  }
26
29
 
30
+ export class ModelConfigStateError extends Error {
31
+ constructor(message: string, readonly status: 404 | 409) {
32
+ super(message);
33
+ }
34
+ }
35
+
36
+ export function isModelConfigEnabled(cfg: Pick<ModelConfigRow, "enabled"> | null | undefined): boolean {
37
+ return !!cfg && cfg.enabled !== 0;
38
+ }
39
+
27
40
  // `params` holds the provider API key alongside hyperparameters and is
28
41
  // stored encrypted at rest (ADR-0005). Decrypt before returning rows.
29
42
  function decryptRow<T extends { params: string }>(row: T): T {
@@ -37,6 +50,11 @@ export function listModelConfigs(): ModelConfigRow[] {
37
50
  return rows.map(decryptRow);
38
51
  }
39
52
 
53
+ /** Model configs that may be offered for selection or routing. */
54
+ export function listEnabledModelConfigs(): ModelConfigRow[] {
55
+ return listModelConfigs().filter(isModelConfigEnabled);
56
+ }
57
+
40
58
  export function getModelConfig(name: string): ModelConfigRow | null {
41
59
  const row = (getDb().prepare("SELECT * FROM model_configs WHERE name=?").get(name) as unknown as ModelConfigRow) ?? null;
42
60
  return row ? decryptRow(row) : null;
@@ -44,15 +62,77 @@ export function getModelConfig(name: string): ModelConfigRow | null {
44
62
 
45
63
  export function getDefaultModelConfig(): ModelConfigRow | null {
46
64
  const db = getDb();
47
- const row = (db.prepare("SELECT * FROM model_configs WHERE is_default=1 LIMIT 1").get() as unknown as ModelConfigRow) ?? null;
65
+ const row = (db.prepare("SELECT * FROM model_configs WHERE is_default=1 AND enabled=1 LIMIT 1").get() as unknown as ModelConfigRow) ?? null;
48
66
  if (row) return decryptRow(row);
49
- const fallback = (db.prepare("SELECT * FROM model_configs ORDER BY name ASC LIMIT 1").get() as unknown as ModelConfigRow) ?? null;
67
+ const fallback = (db.prepare("SELECT * FROM model_configs WHERE enabled=1 ORDER BY name ASC LIMIT 1").get() as unknown as ModelConfigRow) ?? null;
50
68
  return fallback ? decryptRow(fallback) : null;
51
69
  }
52
70
 
71
+ /**
72
+ * Resolve the config a run should use: the named config when it exists and is
73
+ * enabled, otherwise the workspace default. A disabled assignment therefore
74
+ * falls back without being cleared, so re-enabling restores it.
75
+ */
76
+ export function resolveRunnableModelConfig(name: string | null | undefined): ModelConfigRow | null {
77
+ const named = name ? getModelConfig(name) : null;
78
+ if (named && isModelConfigEnabled(named)) return named;
79
+ return getDefaultModelConfig();
80
+ }
81
+
82
+ /** Atomically make `name` the only default model config. */
83
+ export function setDefaultModelConfig(name: string): ModelConfigRow {
84
+ return withDbTransaction(() => {
85
+ const db = getDb();
86
+ const target = getModelConfig(name);
87
+ if (!target) throw new ModelConfigStateError(`Model config "${name}" not found`, 404);
88
+ if (!isModelConfigEnabled(target)) {
89
+ throw new ModelConfigStateError(`Model config "${name}" is disabled; enable it before making it the default`, 409);
90
+ }
91
+ const t = now();
92
+ db.prepare("UPDATE model_configs SET is_default=0, updated_at=? WHERE is_default=1 AND name<>?").run(t, name);
93
+ db.prepare("UPDATE model_configs SET is_default=1, updated_at=? WHERE name=?").run(t, name);
94
+ return getModelConfig(name)!;
95
+ });
96
+ }
97
+
98
+ /**
99
+ * Enable or disable a model config. Disabling the default promotes the
100
+ * alphabetically-first other enabled config in the same transaction, and the
101
+ * last enabled config cannot be disabled so runs always have a model.
102
+ */
103
+ export function setModelConfigEnabled(name: string, enabled: boolean): ModelConfigRow {
104
+ return withDbTransaction(() => {
105
+ const db = getDb();
106
+ const target = getModelConfig(name);
107
+ if (!target) throw new ModelConfigStateError(`Model config "${name}" not found`, 404);
108
+ if (isModelConfigEnabled(target) === enabled) return target;
109
+ const t = now();
110
+ if (enabled) {
111
+ db.prepare("UPDATE model_configs SET enabled=1, updated_at=? WHERE name=?").run(t, name);
112
+ return getModelConfig(name)!;
113
+ }
114
+ const next = db.prepare(
115
+ "SELECT name FROM model_configs WHERE enabled=1 AND name<>? ORDER BY name ASC LIMIT 1",
116
+ ).get(name) as { name?: string } | undefined;
117
+ if (!next?.name) {
118
+ throw new ModelConfigStateError("At least one model config must stay enabled", 409);
119
+ }
120
+ db.prepare("UPDATE model_configs SET enabled=0, is_default=0, updated_at=? WHERE name=?").run(t, name);
121
+ if (target.is_default === 1) {
122
+ db.prepare("UPDATE model_configs SET is_default=1, updated_at=? WHERE name=?").run(t, next.name);
123
+ }
124
+ return getModelConfig(name)!;
125
+ });
126
+ }
127
+
128
+ /**
129
+ * Insert or update a model config. `is_default` undefined keeps the current
130
+ * flag (false for new rows); true atomically clears every other default and
131
+ * re-enables the row, because the default must always be selectable.
132
+ */
53
133
  export function upsertModelConfig(
54
134
  name: string, provider: string, model_id: string,
55
- params: Record<string, unknown>, is_default: boolean,
135
+ params: Record<string, unknown>, is_default: boolean | undefined,
56
136
  credential_id: string | null = null,
57
137
  ): ModelConfigRow {
58
138
  return withDbTransaction(() => {
@@ -67,11 +147,13 @@ export function upsertModelConfig(
67
147
  // other field a custom provider relies on (e.g. custom-provider.js's
68
148
  // username/password auth) on every save.
69
149
  const mergedParams = { ...decodeInlineParams(existing), ...params };
150
+ const finalDefault = is_default ?? existing?.is_default === 1;
151
+ const finalEnabled = finalDefault || !existing || isModelConfigEnabled(existing);
70
152
  const db = getDb();
71
- if (is_default) db.prepare("UPDATE model_configs SET is_default=0").run();
153
+ if (finalDefault) db.prepare("UPDATE model_configs SET is_default=0 WHERE name<>?").run(name);
72
154
  db.prepare(
73
- "INSERT OR REPLACE INTO model_configs (name,provider,model_id,params,is_default,credential_id,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?)"
74
- ).run(name, provider, model_id, encrypt(JSON.stringify(mergedParams)), is_default ? 1 : 0, finalCredId, created_at, t);
155
+ "INSERT OR REPLACE INTO model_configs (name,provider,model_id,params,is_default,enabled,credential_id,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?)"
156
+ ).run(name, provider, model_id, encrypt(JSON.stringify(mergedParams)), finalDefault ? 1 : 0, finalEnabled ? 1 : 0, finalCredId, created_at, t);
75
157
  return getModelConfig(name)!;
76
158
  });
77
159
  }
@@ -85,10 +167,10 @@ export function deleteModelConfig(name: string): boolean {
85
167
  // Automatically reset any agent pointing to this deleted model config to NULL (automatic / default model)
86
168
  db.prepare("UPDATE agent_configs SET model_config_name = NULL WHERE model_config_name = ?").run(name);
87
169
  // Avoid the "no default" state: if the deleted row was the default and any
88
- // other rows remain, promote the alphabetically-first remaining row so
170
+ // other enabled rows remain, promote the alphabetically-first one so
89
171
  // agents that fall back to the default keep working.
90
172
  if (wasDefault) {
91
- const next = db.prepare("SELECT name FROM model_configs ORDER BY name ASC LIMIT 1").get() as { name?: string } | undefined;
173
+ const next = db.prepare("SELECT name FROM model_configs WHERE enabled=1 ORDER BY name ASC LIMIT 1").get() as { name?: string } | undefined;
92
174
  if (next?.name) db.prepare("UPDATE model_configs SET is_default=1 WHERE name=?").run(next.name);
93
175
  }
94
176
  return true;
@@ -692,6 +692,15 @@ describe("thread channel summaries (ADR-0044)", () => {
692
692
  expect(getThreadChannelSummary(t.thread_id, "watcher")?.summary).toBe("watcher recap");
693
693
  expect(getThreadChannelSummary(t.thread_id, "bridge")?.summary).toBe("bridge recap");
694
694
  });
695
+
696
+ it("round-trips stored channel topics and clears them when a later commit omits them", () => {
697
+ const t = createThread("agent-chsum-4");
698
+ const topics = JSON.stringify([{ title: "Nightly backup", start_seq: 1, end_seq: 2, recap: "r", facts: [], message_count: 2 }]);
699
+ commitThreadChannelSummary(t.thread_id, "scheduled_task", { summary: "recap", summaryBefore: null, summaryBeforeSeq: 3, topics });
700
+ expect(getThreadChannelSummary(t.thread_id, "scheduled_task")?.topics).toBe(topics);
701
+ commitThreadChannelSummary(t.thread_id, "scheduled_task", { summary: "fallback", summaryBefore: null, summaryBeforeSeq: 4 });
702
+ expect(getThreadChannelSummary(t.thread_id, "scheduled_task")?.topics).toBeNull();
703
+ });
695
704
  });
696
705
 
697
706
  describe("getRecentlyUsedToolNames", () => {
@@ -671,6 +671,8 @@ export interface ThreadChannelSummaryRow {
671
671
  summary_before: string | null;
672
672
  summary_before_seq: number | null;
673
673
  computed_at: string;
674
+ /** JSON array of SummaryTopicSegment, or null for summaries without topics. */
675
+ topics: string | null;
674
676
  }
675
677
 
676
678
  // ADR-0044 — one cached warm summary per (thread, automation channel),
@@ -682,27 +684,34 @@ export interface ThreadChannelSummaryRow {
682
684
  // hot/warm boundary move, there's no cross-field invariant to protect here.
683
685
  export function getThreadChannelSummary(threadId: string, channel: string): ThreadChannelSummaryRow | null {
684
686
  return (getDb()
685
- .prepare("SELECT thread_id, channel, summary, summary_before, summary_before_seq, computed_at FROM thread_channel_summaries WHERE thread_id=? AND channel=?")
687
+ .prepare("SELECT thread_id, channel, summary, summary_before, summary_before_seq, computed_at, topics FROM thread_channel_summaries WHERE thread_id=? AND channel=?")
686
688
  .get(threadId, channel) as ThreadChannelSummaryRow | undefined) ?? null;
687
689
  }
688
690
 
691
+ export function listThreadChannelSummaries(threadId: string): ThreadChannelSummaryRow[] {
692
+ return getDb()
693
+ .prepare("SELECT thread_id, channel, summary, summary_before, summary_before_seq, computed_at, topics FROM thread_channel_summaries WHERE thread_id=?")
694
+ .all(threadId) as unknown as ThreadChannelSummaryRow[];
695
+ }
696
+
689
697
  export function commitThreadChannelSummary(
690
698
  threadId: string,
691
699
  channel: string,
692
- input: { summary: string; summaryBefore: string | null; summaryBeforeSeq?: number | null },
700
+ input: { summary: string; summaryBefore: string | null; summaryBeforeSeq?: number | null; topics?: string | null },
693
701
  ): void {
694
702
  if (input.summaryBefore !== null && input.summaryBeforeSeq == null) {
695
703
  throw new Error("summaryBeforeSeq is required for a boundary summary");
696
704
  }
697
705
  getDb()
698
706
  .prepare(
699
- `INSERT INTO thread_channel_summaries (thread_id, channel, summary, summary_before, summary_before_seq, computed_at)
700
- VALUES (?, ?, ?, ?, ?, ?)
707
+ `INSERT INTO thread_channel_summaries (thread_id, channel, summary, summary_before, summary_before_seq, computed_at, topics)
708
+ VALUES (?, ?, ?, ?, ?, ?, ?)
701
709
  ON CONFLICT(thread_id, channel) DO UPDATE SET
702
710
  summary=excluded.summary, summary_before=excluded.summary_before,
703
- summary_before_seq=excluded.summary_before_seq, computed_at=excluded.computed_at`,
711
+ summary_before_seq=excluded.summary_before_seq, computed_at=excluded.computed_at,
712
+ topics=excluded.topics`,
704
713
  )
705
- .run(threadId, channel, input.summary, input.summaryBefore, input.summaryBeforeSeq ?? null, now());
714
+ .run(threadId, channel, input.summary, input.summaryBefore, input.summaryBeforeSeq ?? null, now(), input.topics ?? null);
706
715
  }
707
716
 
708
717
  export function touchThread(thread_id: string, firstMsg?: string): void {
@@ -746,7 +755,7 @@ export interface ThreadWarmContextCommit {
746
755
  /** Reject the commit if another compactor refreshed the same boundary. */
747
756
  expectedWarmSummary?: string | null;
748
757
  autoBoundaryLockedUntilMessageCount?: number;
749
- channelSummaries?: Array<{ channel: string; summary: string }>;
758
+ channelSummaries?: Array<{ channel: string; summary: string; topics?: string | null }>;
750
759
  }
751
760
 
752
761
  // A warm recap is only valid for the exact boundary it replaced. Commit both
@@ -790,14 +799,15 @@ export function commitThreadWarmContext(
790
799
  thread_id,
791
800
  );
792
801
  const upsertChannel = db.prepare(
793
- `INSERT INTO thread_channel_summaries (thread_id, channel, summary, summary_before, summary_before_seq, computed_at)
794
- VALUES (?, ?, ?, ?, ?, ?)
802
+ `INSERT INTO thread_channel_summaries (thread_id, channel, summary, summary_before, summary_before_seq, computed_at, topics)
803
+ VALUES (?, ?, ?, ?, ?, ?, ?)
795
804
  ON CONFLICT(thread_id, channel) DO UPDATE SET
796
805
  summary=excluded.summary, summary_before=excluded.summary_before,
797
- summary_before_seq=excluded.summary_before_seq, computed_at=excluded.computed_at`,
806
+ summary_before_seq=excluded.summary_before_seq, computed_at=excluded.computed_at,
807
+ topics=excluded.topics`,
798
808
  );
799
809
  for (const channelSummary of input.channelSummaries ?? []) {
800
- upsertChannel.run(thread_id, channelSummary.channel, channelSummary.summary, input.hotSince, hotSinceSeq, now());
810
+ upsertChannel.run(thread_id, channelSummary.channel, channelSummary.summary, input.hotSince, hotSinceSeq, now(), channelSummary.topics ?? null);
801
811
  }
802
812
  db.exec("COMMIT");
803
813
  return getThread(thread_id);