thursday-agent 0.2.0 → 0.4.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 (541) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +5 -2
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +5 -5
  5. package/.next/routes-manifest.json +24 -6
  6. package/.next/server/app/_global-error/page.js +2 -2
  7. package/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/server/app/_global-error.html +1 -1
  10. package/.next/server/app/_global-error.rsc +2 -2
  11. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  13. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/server/app/_not-found/page.js +2 -2
  15. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  16. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  17. package/.next/server/app/_not-found.html +1 -1
  18. package/.next/server/app/_not-found.rsc +14 -14
  19. package/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  20. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
  21. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  22. package/.next/server/app/api/artifact/route.js +3 -3
  23. package/.next/server/app/api/artifact/route.js.nft.json +1 -1
  24. package/.next/server/app/api/bot/memory/files/route/app-paths-manifest.json +3 -0
  25. package/.next/server/app/api/bot/memory/files/route.js +10 -0
  26. package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -0
  27. package/.next/server/app/api/bot/memory/files/route_client-reference-manifest.js +3 -0
  28. package/.next/server/app/api/bot/memory/route/app-paths-manifest.json +3 -0
  29. package/.next/server/app/api/bot/memory/route.js +14 -0
  30. package/.next/server/app/api/bot/{notes → memory}/route.js.nft.json +1 -1
  31. package/.next/server/app/api/bot/memory/route_client-reference-manifest.js +3 -0
  32. package/.next/server/app/api/bot/route.js +6 -6
  33. package/.next/server/app/api/bot/route.js.nft.json +1 -1
  34. package/.next/server/app/api/bot/task/[id]/route.js +8 -8
  35. package/.next/server/app/api/bot/task/[id]/route.js.nft.json +1 -1
  36. package/.next/server/app/api/bot/task/route.js +8 -8
  37. package/.next/server/app/api/bot/task/route.js.nft.json +1 -1
  38. package/.next/server/app/api/config/route.js +5 -5
  39. package/.next/server/app/api/config/route.js.nft.json +1 -1
  40. package/.next/server/app/api/events/route.js +4 -5
  41. package/.next/server/app/api/events/route.js.nft.json +1 -1
  42. package/.next/server/app/api/file/[...path]/route.js +3 -3
  43. package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
  44. package/.next/server/app/api/llm-model/catalog/route.js +9 -8
  45. package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
  46. package/.next/server/app/api/llm-model/credits/route/app-paths-manifest.json +3 -0
  47. package/.next/server/app/api/llm-model/credits/route/build-manifest.json +12 -0
  48. package/.next/server/app/api/llm-model/credits/route/server-reference-manifest.json +4 -0
  49. package/.next/server/app/api/llm-model/credits/route.js +16 -0
  50. package/.next/server/app/api/llm-model/credits/route.js.map +5 -0
  51. package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -0
  52. package/.next/server/app/api/llm-model/credits/route_client-reference-manifest.js +3 -0
  53. package/.next/server/app/api/llm-model/route.js +10 -8
  54. package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
  55. package/.next/server/app/api/llm-model/subscription/route/app-paths-manifest.json +3 -0
  56. package/.next/server/app/api/llm-model/subscription/route/build-manifest.json +12 -0
  57. package/.next/server/app/api/llm-model/subscription/route/server-reference-manifest.json +4 -0
  58. package/.next/server/app/api/llm-model/subscription/route.js +15 -0
  59. package/.next/server/app/api/llm-model/subscription/route.js.map +5 -0
  60. package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -0
  61. package/.next/server/app/api/llm-model/subscription/route_client-reference-manifest.js +3 -0
  62. package/.next/server/app/api/mcp/[name]/route.js +4 -4
  63. package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
  64. package/.next/server/app/api/mcp/oauth/callback/route.js +5 -5
  65. package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
  66. package/.next/server/app/api/mcp/route.js +4 -4
  67. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  68. package/.next/server/app/api/mcp/tools/route.js +4 -4
  69. package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
  70. package/.next/server/app/api/memory/edit/route/app-paths-manifest.json +3 -0
  71. package/.next/server/app/api/memory/edit/route/build-manifest.json +12 -0
  72. package/.next/server/app/api/memory/edit/route/server-reference-manifest.json +4 -0
  73. package/.next/server/app/api/memory/edit/route.js +24 -0
  74. package/.next/server/app/api/memory/edit/route.js.map +5 -0
  75. package/.next/server/app/api/memory/edit/route.js.nft.json +1 -0
  76. package/.next/server/app/api/memory/{tidy → edit}/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/memory/route.js +6 -7
  78. package/.next/server/app/api/memory/route.js.nft.json +1 -1
  79. package/.next/server/app/api/skills/[source]/[name]/route.js +3 -3
  80. package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
  81. package/.next/server/app/api/skills/route.js +3 -3
  82. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  83. package/.next/server/app/api/thursday/call/route.js +9 -7
  84. package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
  85. package/.next/server/app/api/thursday/skills/route.js +9 -7
  86. package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
  87. package/.next/server/app/api/thursday/tool-call/route.js +17 -15
  88. package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
  89. package/.next/server/app/api/workspace/route.js +4 -5
  90. package/.next/server/app/api/workspace/route.js.nft.json +1 -1
  91. package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +1 -1
  92. package/.next/server/app/artifact/[...path]/page.js +5 -6
  93. package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
  94. package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
  95. package/.next/server/app/favicon.ico/route.js +3 -4
  96. package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  97. package/.next/server/app/favicon.ico.body +0 -0
  98. package/.next/server/app/page/server-reference-manifest.json +57 -90
  99. package/.next/server/app/page.js +10 -10
  100. package/.next/server/app/page.js.nft.json +1 -1
  101. package/.next/server/app/page_client-reference-manifest.js +1 -1
  102. package/.next/server/app-paths-manifest.json +5 -2
  103. package/.next/server/chunks/[externals]__0dzuk6_._.js +3 -0
  104. package/.next/server/chunks/[root-of-the-server]__01dkp4a._.js +3 -0
  105. package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +1 -1
  106. package/.next/server/chunks/[root-of-the-server]__02xjoto._.js +3 -0
  107. package/.next/server/chunks/[root-of-the-server]__04q--0f._.js +8 -0
  108. package/.next/server/chunks/[root-of-the-server]__0bl-e63._.js +3 -0
  109. package/.next/server/chunks/[root-of-the-server]__0ce8nf8._.js +5 -0
  110. package/.next/server/chunks/[root-of-the-server]__0ffbg85._.js +3 -0
  111. package/.next/server/chunks/[root-of-the-server]__0j7z0r3._.js +12 -0
  112. package/.next/server/chunks/[root-of-the-server]__0jq4ohy._.js +8 -0
  113. package/.next/server/chunks/[root-of-the-server]__0ls6_8y._.js +8 -0
  114. package/.next/server/chunks/[root-of-the-server]__0ncs9uu._.js +3 -0
  115. package/.next/server/chunks/[root-of-the-server]__0pa2n68._.js +3 -0
  116. package/.next/server/chunks/[root-of-the-server]__0q0vvt2._.js +5 -0
  117. package/.next/server/chunks/[root-of-the-server]__1-ga0kh._.js +5 -0
  118. package/.next/server/chunks/[root-of-the-server]__11n256_._.js +5 -0
  119. package/.next/server/chunks/[root-of-the-server]__12cabg9._.js +3 -0
  120. package/.next/server/chunks/[root-of-the-server]__1339jnv._.js +8 -0
  121. package/.next/server/chunks/[root-of-the-server]__15bjnu5._.js +5 -0
  122. package/.next/server/chunks/[root-of-the-server]__18_teo8._.js +8 -0
  123. package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +5 -0
  124. package/.next/server/chunks/[root-of-the-server]__1anc1p9._.js +3 -0
  125. package/.next/server/chunks/[root-of-the-server]__1ccon1w._.js +5 -5
  126. package/.next/server/chunks/[root-of-the-server]__1fizn31._.js +3 -0
  127. package/.next/server/chunks/[root-of-the-server]__1llj3-b._.js +3 -0
  128. package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +12 -0
  129. package/.next/server/chunks/[root-of-the-server]__1p8m3f4._.js +3 -0
  130. package/.next/server/chunks/[root-of-the-server]__1wa1k7r._.js +8 -0
  131. package/.next/server/chunks/_0-73of8._.js +5 -5
  132. package/.next/server/chunks/_0-fjql4._.js +26 -0
  133. package/.next/server/chunks/_00xh_q0._.js +25 -0
  134. package/.next/server/chunks/_051qh8u._.js +3 -0
  135. package/.next/server/chunks/{node_modules_next_04q-o58._.js → _05dla15._.js} +2 -2
  136. package/.next/server/chunks/_05h2cii._.js +1 -1
  137. package/.next/server/chunks/_0c9j6rb._.js +49 -0
  138. package/.next/server/chunks/_0fzqt2y._.js +134 -0
  139. package/.next/server/chunks/{_0vnutv9._.js → _0ioz3nd._.js} +1 -1
  140. package/.next/server/chunks/_0iwfby5._.js +3 -0
  141. package/.next/server/chunks/_0mecv0f._.js +26 -0
  142. package/.next/server/chunks/_0mh8j4m._.js +3 -0
  143. package/.next/server/chunks/_0n74zsf._.js +4 -4
  144. package/.next/server/chunks/_0obojvv._.js +3 -0
  145. package/.next/server/chunks/_0recufk._.js +49 -0
  146. package/.next/server/chunks/_0rnf-6n._.js +4 -4
  147. package/.next/server/chunks/_0sb7tlz._.js +3 -0
  148. package/.next/server/chunks/_0u10wmw._.js +5 -5
  149. package/.next/server/chunks/_0u4aiy2._.js +3 -0
  150. package/.next/server/chunks/_0wp4le3._.js +1 -1
  151. package/.next/server/chunks/_0y5fg-x._.js +1 -1
  152. package/.next/server/chunks/_1230wbx._.js +10 -0
  153. package/.next/server/chunks/_12nheja._.js +3 -0
  154. package/.next/server/chunks/_13510xh._.js +3 -0
  155. package/.next/server/chunks/_15hq89o._.js +1 -1
  156. package/.next/server/chunks/_17l5ygt._.js +49 -0
  157. package/.next/server/chunks/_18-1wcc._.js +5 -5
  158. package/.next/server/chunks/_1_5mnq4._.js +4 -4
  159. package/.next/server/chunks/_1_9mjx-._.js +3 -0
  160. package/.next/server/chunks/{_0pppbb5._.js → _1c78vw5._.js} +166 -37
  161. package/.next/server/chunks/_1d0j961._.js +6 -0
  162. package/.next/server/chunks/_1d5zmy8._.js +1 -1
  163. package/.next/server/chunks/_1drgfx4._.js +4 -4
  164. package/.next/server/chunks/_1f46eie._.js +3 -0
  165. package/.next/server/chunks/_1h5_8sk._.js +3 -0
  166. package/.next/server/chunks/_1hdnxb7._.js +3 -0
  167. package/.next/server/chunks/_1j8k_j5._.js +3 -0
  168. package/.next/server/chunks/_1krd9rf._.js +3 -0
  169. package/.next/server/chunks/_1nc0eui._.js +11 -0
  170. package/.next/server/chunks/_1nula3v._.js +3 -0
  171. package/.next/server/chunks/_1pf4qe-._.js +3 -0
  172. package/.next/server/chunks/_1php4eq._.js +1 -1
  173. package/.next/server/chunks/_1qxheoa._.js +3 -0
  174. package/.next/server/chunks/_1x6kd1r._.js +3 -0
  175. package/.next/server/chunks/_1yuv4vp._.js +1 -1
  176. package/.next/server/chunks/_1zjrdag._.js +3 -0
  177. package/.next/server/chunks/_next-internal_server_app_api_bot_memory_files_route_actions_1_xd_8f.js +3 -0
  178. package/.next/server/chunks/_next-internal_server_app_api_bot_memory_route_actions_1a8xfr7.js +3 -0
  179. package/.next/server/chunks/_next-internal_server_app_api_llm-model_credits_route_actions_0v424pb.js +3 -0
  180. package/.next/server/chunks/_next-internal_server_app_api_llm-model_subscription_route_actions_0-udcm5.js +3 -0
  181. package/.next/server/chunks/_next-internal_server_app_api_memory_edit_route_actions_02sfnmr.js +3 -0
  182. package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
  183. package/.next/server/chunks/features_0rpfxbk._.js +3 -0
  184. package/.next/server/chunks/features_1qf3cei._.js +3 -0
  185. package/.next/server/chunks/features_bot_0zt92oh._.js +3 -0
  186. package/.next/server/chunks/features_bot_bot_query_ts_12mgkl2._.js +3 -0
  187. package/.next/server/chunks/features_memory_1uqvksn._.js +6 -0
  188. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0a1rd09._.js → node_modules_consola_dist_chunks_prompt_mjs_0i7cvml._.js} +1 -1
  189. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_06067w6._.js → node_modules_consola_dist_chunks_prompt_mjs_0icqaqw._.js} +1 -1
  190. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_096ais_._.js → node_modules_consola_dist_chunks_prompt_mjs_0r28-sm._.js} +1 -1
  191. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_02s3hjt._.js → node_modules_consola_dist_chunks_prompt_mjs_0v_7drq._.js} +1 -1
  192. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1xoq2rl._.js +3 -0
  193. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0tvkfgh._.js → node_modules_consola_dist_chunks_prompt_mjs_1y49572._.js} +1 -1
  194. package/.next/server/chunks/ssr/[root-of-the-server]__092knlj._.js +3 -0
  195. package/.next/server/chunks/ssr/[root-of-the-server]__09q9med._.js +1 -1
  196. package/.next/server/chunks/ssr/[root-of-the-server]__0hg5gib._.js +1 -1
  197. package/.next/server/chunks/ssr/[root-of-the-server]__0i8ie7f._.js +3 -0
  198. package/.next/server/chunks/ssr/{[root-of-the-server]__0jsmmb-._.js → [root-of-the-server]__0mz33a7._.js} +1 -1
  199. package/.next/server/chunks/ssr/[root-of-the-server]__0s9dq5u._.js +3 -0
  200. package/.next/server/chunks/ssr/{[root-of-the-server]__0m1b5ky._.js → [root-of-the-server]__0s9l2sv._.js} +1 -1
  201. package/.next/server/chunks/ssr/[root-of-the-server]__0tbkdlx._.js +3 -0
  202. package/.next/server/chunks/ssr/[root-of-the-server]__0vnmv-s._.js +3 -0
  203. package/.next/server/chunks/ssr/{[root-of-the-server]__0f6s48x._.js → [root-of-the-server]__0xpcv9w._.js} +3 -3
  204. package/.next/server/chunks/ssr/[root-of-the-server]__0xsog8n._.js +3 -0
  205. package/.next/server/chunks/ssr/[root-of-the-server]__0xtssj3._.js +1 -1
  206. package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +61 -0
  207. package/.next/server/chunks/ssr/[root-of-the-server]__15_uhip._.js +3 -0
  208. package/.next/server/chunks/ssr/[root-of-the-server]__16jc196._.js +1 -1
  209. package/.next/server/chunks/ssr/[root-of-the-server]__1gtlw6v._.js +43 -0
  210. package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
  211. package/.next/server/chunks/ssr/[root-of-the-server]__1ox7hbk._.js +4 -0
  212. package/.next/server/chunks/ssr/{[root-of-the-server]__1qfqvmg._.js → [root-of-the-server]__202p40z._.js} +2 -2
  213. package/.next/server/chunks/ssr/{_1mznrxk._.js → _001_ms1._.js} +3 -3
  214. package/.next/server/chunks/ssr/_01n3o0m._.js +3 -0
  215. package/.next/server/chunks/ssr/_0ap2fzn._.js +3 -0
  216. package/.next/server/chunks/ssr/_0fz4mf_._.js +3 -0
  217. package/.next/server/chunks/ssr/_0gb4gmf._.js +3 -0
  218. package/.next/server/chunks/ssr/_0h42fze._.js +3 -0
  219. package/.next/server/chunks/ssr/_0h7zdni._.js +1 -1
  220. package/.next/server/chunks/ssr/_0i_6q1w._.js +41 -0
  221. package/.next/server/chunks/ssr/_0ilna52._.js +42 -0
  222. package/.next/server/chunks/ssr/_0n3toaw._.js +3 -0
  223. package/.next/server/chunks/ssr/{_13punpm._.js → _0q0zan6._.js} +2 -2
  224. package/.next/server/chunks/ssr/{_077-g6s._.js → _0s99bgb._.js} +3 -3
  225. package/.next/server/chunks/ssr/_0zcjrbg._.js +3 -0
  226. package/.next/server/chunks/ssr/_0zhoc3r._.js +3 -0
  227. package/.next/server/chunks/ssr/{_1lip4th._.js → _1-_etts._.js} +2 -2
  228. package/.next/server/chunks/ssr/_1-teee5._.js +3 -3
  229. package/.next/server/chunks/ssr/_13fke0x._.js +3 -0
  230. package/.next/server/chunks/ssr/_15j2_8f._.js +3 -0
  231. package/.next/server/chunks/ssr/_1b2mjwr._.js +3 -0
  232. package/.next/server/chunks/ssr/{_09ja_w1._.js → _1f-dg-6._.js} +2 -2
  233. package/.next/server/chunks/ssr/_1fojd41._.js +4 -0
  234. package/.next/server/chunks/ssr/_1gd8q8l._.js +3 -0
  235. package/.next/server/chunks/ssr/{_1m3bsfr._.js → _1h0rw11._.js} +2 -2
  236. package/.next/server/chunks/ssr/_1jhd09t._.js +3 -0
  237. package/.next/server/chunks/ssr/{_040sk32._.js → _1lz_cq2._.js} +84 -88
  238. package/.next/server/chunks/ssr/_1nnsk7z._.js +3 -0
  239. package/.next/server/chunks/ssr/_1sji22n._.js +3 -0
  240. package/.next/server/chunks/ssr/{_0x_nu5e._.js → _1vi_uo7._.js} +2 -2
  241. package/.next/server/chunks/ssr/_1vyd1ji._.js +1 -1
  242. package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +3 -0
  243. package/.next/server/chunks/ssr/features_config_components_config-setting_tsx_0xfwqdg._.js +1 -1
  244. package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
  245. package/.next/server/chunks/ssr/{node_modules_0kxz4gt._.js → node_modules_00etblx._.js} +1 -1
  246. package/.next/server/chunks/ssr/{node_modules_18_dk7_._.js → node_modules_04jf_m8._.js} +1 -1
  247. package/.next/server/chunks/ssr/{node_modules_0_n241r._.js → node_modules_08dhkiq._.js} +1 -1
  248. package/.next/server/chunks/ssr/{node_modules_0n1kj4p._.js → node_modules_0940ns5._.js} +1 -1
  249. package/.next/server/chunks/ssr/{node_modules_17lrt3y._.js → node_modules_09q35v_._.js} +1 -1
  250. package/.next/server/chunks/ssr/{node_modules_1toafc-._.js → node_modules_0_-_a--._.js} +1 -1
  251. package/.next/server/chunks/ssr/{node_modules_0lrjk5t._.js → node_modules_0arus10._.js} +1 -1
  252. package/.next/server/chunks/ssr/{node_modules_04n7mjs._.js → node_modules_0b__sgl._.js} +1 -1
  253. package/.next/server/chunks/ssr/{node_modules_0iz1rzd._.js → node_modules_0cxaxk9._.js} +1 -1
  254. package/.next/server/chunks/ssr/{node_modules_0ndvxub._.js → node_modules_0g7fzk3._.js} +1 -1
  255. package/.next/server/chunks/ssr/{node_modules_0kl7-tn._.js → node_modules_0had7xd._.js} +1 -1
  256. package/.next/server/chunks/ssr/{node_modules_19dp7ko._.js → node_modules_0pvd7q-._.js} +1 -1
  257. package/.next/server/chunks/ssr/node_modules_0x3-ply._.js +3 -0
  258. package/.next/server/chunks/ssr/{node_modules_1dwguw_._.js → node_modules_0yugy6m._.js} +1 -1
  259. package/.next/server/chunks/ssr/{node_modules_004qlr4._.js → node_modules_14om4ar._.js} +1 -1
  260. package/.next/server/chunks/ssr/{node_modules_1q0p85z._.js → node_modules_14q6g4n._.js} +1 -1
  261. package/.next/server/chunks/ssr/node_modules_17bwo43._.js +55 -0
  262. package/.next/server/chunks/ssr/{node_modules_1hd-5tv._.js → node_modules_198nmll._.js} +1 -1
  263. package/.next/server/chunks/ssr/{node_modules_0m93zeg._.js → node_modules_1_pc9kq._.js} +1 -1
  264. package/.next/server/chunks/ssr/{node_modules_1n5ygqe._.js → node_modules_1aaxuef._.js} +1 -1
  265. package/.next/server/chunks/ssr/{node_modules_01qnv-a._.js → node_modules_1cx_ql6._.js} +1 -1
  266. package/.next/server/chunks/ssr/{node_modules_1zu988w._.js → node_modules_1cz2hle._.js} +1 -1
  267. package/.next/server/chunks/ssr/{node_modules_1xyd7ov._.js → node_modules_1efrqxi._.js} +1 -1
  268. package/.next/server/chunks/ssr/{node_modules_13r44jq._.js → node_modules_1eg7m6c._.js} +1 -1
  269. package/.next/server/chunks/ssr/{node_modules_08d8bke._.js → node_modules_1gdh31p._.js} +1 -1
  270. package/.next/server/chunks/ssr/{node_modules_1hn8z1f._.js → node_modules_1hpopmo._.js} +1 -1
  271. package/.next/server/chunks/ssr/{node_modules_20yebtj._.js → node_modules_1qpjvy5._.js} +1 -1
  272. package/.next/server/chunks/ssr/{node_modules_09xhur7._.js → node_modules_1vh5ntv._.js} +1 -1
  273. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0m9a4y0._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1b748ic._.js} +1 -1
  274. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_13w_wy9._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1z4hm5e._.js} +1 -1
  275. package/.next/server/chunks/ssr/node_modules_@vercel_oidc_dist_06mk8id._.js +3 -0
  276. package/.next/server/chunks/ssr/{node_modules_next_dist_0w6mzq5._.js → node_modules_next_dist_0drixxt._.js} +4 -4
  277. package/.next/server/chunks/ssr/node_modules_next_dist_1n3w9lb._.js +2 -2
  278. package/.next/server/instrumentation.js +1 -1
  279. package/.next/server/middleware-build-manifest.js +3 -3
  280. package/.next/server/pages/404.html +1 -1
  281. package/.next/server/pages/500.html +1 -1
  282. package/.next/server/server-reference-manifest.js +1 -1
  283. package/.next/server/server-reference-manifest.json +58 -91
  284. package/.next/static/chunks/00rd4-v8r7axp.js +1 -0
  285. package/.next/static/chunks/08qe4as2q428z.js +3 -0
  286. package/.next/static/chunks/{31ttnjt6g35a0.js → 0ev4hyghq0mbb.js} +1 -1
  287. package/.next/static/chunks/0fl3gwe4-l6tz.js +1 -0
  288. package/.next/static/chunks/0gnqdjn2lvdad.js +2 -0
  289. package/.next/static/chunks/0hwap1-p0m5sa.js +1 -0
  290. package/.next/static/chunks/0r5qcctujhxli.js +1 -0
  291. package/.next/static/chunks/0w52rrrmuj9r9.js +1 -0
  292. package/.next/static/chunks/{07kl352c-lvcz.js → 0wcprt5ot5she.js} +1 -1
  293. package/.next/static/chunks/10teww7wt-f6h.js +1 -0
  294. package/.next/static/chunks/15m575979un5f.js +38 -0
  295. package/.next/static/chunks/17p6tk6k88dq6.js +1 -0
  296. package/.next/static/chunks/{3_h9txt3tq8t8.js → 1dkjg87pxk0n9.js} +1 -1
  297. package/.next/static/chunks/1jd09sxcjddu1.js +1 -0
  298. package/.next/static/chunks/1kq8h8wi_e0bc.js +53 -0
  299. package/.next/static/chunks/{18vhba44l1fc9.js → 1w73ece_6bheu.js} +1 -1
  300. package/.next/static/chunks/{3ard_noqapnw1.js → 214ya3n5gxeih.js} +1 -1
  301. package/.next/static/chunks/22_zkas21rpna.js +1 -0
  302. package/.next/static/chunks/2h0sd2vumhb15.js +1 -0
  303. package/.next/static/chunks/2t4vhi3m8ahya.js +1 -0
  304. package/.next/static/chunks/2tigdtz3dpcy8.js +1 -0
  305. package/.next/static/chunks/2u7xt6mxg44lf.js +1 -0
  306. package/.next/static/chunks/39j0fvpybzabl.js +40 -0
  307. package/.next/static/chunks/3akmqm77muj4-.js +1 -0
  308. package/.next/static/chunks/3cq5g494yuke8.css +1 -0
  309. package/.next/static/chunks/3woj-xd7ki5_i.js +1 -0
  310. package/.next/static/chunks/3xk7yqgomx7yq.js +1 -0
  311. package/.next/static/chunks/3zmcsnuo25zvq.js +1 -0
  312. package/.next/static/media/favicon.37o1pjldwi2uc.ico +0 -0
  313. package/README.md +47 -22
  314. package/app/api/bot/memory/files/route.ts +14 -0
  315. package/app/api/bot/memory/route.ts +5 -0
  316. package/app/api/events/app-event.ts +3 -7
  317. package/app/api/llm-model/credits/route.ts +11 -0
  318. package/app/api/llm-model/route.ts +6 -1
  319. package/app/api/llm-model/subscription/route.ts +11 -0
  320. package/app/api/memory/edit/route.ts +7 -0
  321. package/app/api/memory/route.ts +21 -0
  322. package/app/api/query-key.ts +19 -4
  323. package/bin/port.mjs +65 -0
  324. package/bin/thursday.mjs +5 -33
  325. package/components/ui/shiny-text.tsx +48 -134
  326. package/database/migrations/{20260909060813_optimal_sabretooth → 20260910173049_numerous_spirit}/migration.sql +24 -34
  327. package/database/migrations/{20260909060813_optimal_sabretooth → 20260910173049_numerous_spirit}/snapshot.json +71 -145
  328. package/database/migrations/20260911030320_opposite_jack_power/migration.sql +1 -0
  329. package/database/migrations/{20260909063821_bitter_tenebrous → 20260911030320_opposite_jack_power}/snapshot.json +57 -184
  330. package/docs/how-it-works.md +11 -7
  331. package/docs/images/face-dark.png +0 -0
  332. package/docs/images/face-light.png +0 -0
  333. package/docs/images/keeps-going.png +0 -0
  334. package/features/ai/chatgpt.ts +639 -0
  335. package/features/ai/components/chatgpt-sign-in.tsx +66 -0
  336. package/features/ai/components/model-picker.tsx +17 -1
  337. package/features/ai/components/provider-icon.tsx +1 -0
  338. package/features/ai/load-tools.ts +78 -56
  339. package/features/ai/model.schema.ts +232 -34
  340. package/features/ai/model.ts +169 -24
  341. package/features/ai/prompts/bot.prompt.ts +207 -114
  342. package/features/ai/prompts/memory-edit.prompt.ts +33 -0
  343. package/features/ai/prompts/prompt-helper.ts +45 -26
  344. package/features/ai/prompts/thursday.prompt.ts +57 -27
  345. package/features/ai/tools/bot.tool.ts +35 -52
  346. package/features/ai/tools/connected.ts +17 -4
  347. package/features/ai/tools/memory.tool.ts +181 -117
  348. package/features/ai/tools/search.tool.ts +136 -47
  349. package/features/ai/tools/tool-name.ts +2 -6
  350. package/features/ai/tools/workspace.tool.ts +5 -1
  351. package/features/bot/bot.action.ts +14 -19
  352. package/features/bot/bot.memory.ts +89 -0
  353. package/features/bot/bot.query.ts +37 -57
  354. package/features/bot/bot.run.ts +512 -242
  355. package/features/bot/bot.runner.ts +434 -120
  356. package/features/bot/bot.schema.ts +104 -19
  357. package/features/bot/bot.seed.ts +89 -16
  358. package/features/bot/components/bot-mark.tsx +122 -20
  359. package/features/bot/components/bot-room.tsx +214 -132
  360. package/features/bot/components/bot-setting.tsx +790 -402
  361. package/features/bot/components/bot-tool.tsx +2 -7
  362. package/features/bot/components/mark-palette.tsx +54 -0
  363. package/features/bot/components/path-chips.tsx +1 -1
  364. package/features/bot/components/task-badge.tsx +26 -6
  365. package/features/bot/components/task-reply.tsx +22 -33
  366. package/features/bot/components/task-setting.tsx +20 -17
  367. package/features/bot/task.query.ts +240 -34
  368. package/features/bot/task.store.ts +76 -13
  369. package/features/config/components/config-setting.tsx +265 -34
  370. package/features/config/components/models-badge.tsx +42 -0
  371. package/features/config/config.action.ts +12 -0
  372. package/features/config/config.const.ts +38 -2
  373. package/features/connectors/mcp.manager.ts +10 -2
  374. package/features/intro/components/intro.tsx +47 -46
  375. package/features/memory/components/memory-edit.tsx +340 -0
  376. package/features/memory/components/memory-setting.tsx +75 -77
  377. package/features/memory/memory.action.ts +3 -43
  378. package/features/memory/memory.edit.ts +87 -0
  379. package/features/memory/memory.query.ts +24 -42
  380. package/features/memory/memory.schema.ts +29 -106
  381. package/features/settings/components/settings.tsx +2 -0
  382. package/features/settings/settings.alert.ts +3 -1
  383. package/features/thursday/components/ascii-orb.tsx +106 -90
  384. package/features/thursday/components/boot.tsx +7 -0
  385. package/features/thursday/components/call-log.tsx +219 -92
  386. package/features/thursday/components/face.tsx +6 -4
  387. package/features/thursday/components/tab-state.tsx +97 -0
  388. package/features/thursday/components/thursday-mark.tsx +4 -1
  389. package/features/thursday/components/thursday-setting.tsx +17 -47
  390. package/features/thursday/components/thursday.tsx +208 -98
  391. package/features/thursday/thursday.action.ts +12 -17
  392. package/features/thursday/thursday.query.ts +61 -70
  393. package/features/thursday/thursday.schema.ts +20 -7
  394. package/features/thursday/tool-line.ts +85 -12
  395. package/features/thursday/use-thursday.ts +87 -60
  396. package/features/workspace/components/file-view.tsx +4 -2
  397. package/features/workspace/workspace.ts +110 -26
  398. package/lib/limits.ts +1 -1
  399. package/lib/oauth-page.ts +27 -0
  400. package/lib/realtime/openai.ts +2 -2
  401. package/lib/realtime/realtime.protocol.ts +1 -1
  402. package/lib/realtime/realtime.tap.ts +122 -0
  403. package/lib/sandbox.ts +59 -36
  404. package/package.json +1 -1
  405. package/skills/browser/SKILL.md +55 -34
  406. package/.next/server/app/api/bot/notes/route/app-paths-manifest.json +0 -3
  407. package/.next/server/app/api/bot/notes/route.js +0 -14
  408. package/.next/server/app/api/bot/notes/route_client-reference-manifest.js +0 -3
  409. package/.next/server/app/api/memory/tidy/route/app-paths-manifest.json +0 -3
  410. package/.next/server/app/api/memory/tidy/route.js +0 -22
  411. package/.next/server/app/api/memory/tidy/route.js.nft.json +0 -1
  412. package/.next/server/chunks/0d-b_next_dist_server_app-render_after-task-async-storage_external_0-exn7p.js +0 -3
  413. package/.next/server/chunks/[root-of-the-server]__0-npkh_._.js +0 -3
  414. package/.next/server/chunks/[root-of-the-server]__005var5._.js +0 -3
  415. package/.next/server/chunks/[root-of-the-server]__019dx9f._.js +0 -5
  416. package/.next/server/chunks/[root-of-the-server]__02_2sm-._.js +0 -5
  417. package/.next/server/chunks/[root-of-the-server]__04_8spk._.js +0 -3
  418. package/.next/server/chunks/[root-of-the-server]__05luceg._.js +0 -3
  419. package/.next/server/chunks/[root-of-the-server]__06t77t4._.js +0 -11
  420. package/.next/server/chunks/[root-of-the-server]__0bed6hu._.js +0 -8
  421. package/.next/server/chunks/[root-of-the-server]__0cro2dz._.js +0 -5
  422. package/.next/server/chunks/[root-of-the-server]__0dupqt7._.js +0 -5
  423. package/.next/server/chunks/[root-of-the-server]__0emr6go._.js +0 -3
  424. package/.next/server/chunks/[root-of-the-server]__0le4d-p._.js +0 -3
  425. package/.next/server/chunks/[root-of-the-server]__0m8ywyo._.js +0 -10
  426. package/.next/server/chunks/[root-of-the-server]__0nfuugi._.js +0 -5
  427. package/.next/server/chunks/[root-of-the-server]__0p32jfz._.js +0 -12
  428. package/.next/server/chunks/[root-of-the-server]__0phdgco._.js +0 -8
  429. package/.next/server/chunks/[root-of-the-server]__0wvgrsl._.js +0 -3
  430. package/.next/server/chunks/[root-of-the-server]__10qshki._.js +0 -3
  431. package/.next/server/chunks/[root-of-the-server]__11j52t0._.js +0 -5
  432. package/.next/server/chunks/[root-of-the-server]__1692zrv._.js +0 -3
  433. package/.next/server/chunks/[root-of-the-server]__16thabu._.js +0 -3
  434. package/.next/server/chunks/[root-of-the-server]__173nhwf._.js +0 -8
  435. package/.next/server/chunks/[root-of-the-server]__1_aoyr9._.js +0 -3
  436. package/.next/server/chunks/[root-of-the-server]__1bn73ih._.js +0 -10
  437. package/.next/server/chunks/[root-of-the-server]__1bqhuh9._.js +0 -8
  438. package/.next/server/chunks/[root-of-the-server]__1cqizfq._.js +0 -5
  439. package/.next/server/chunks/[root-of-the-server]__1e-ci13._.js +0 -3
  440. package/.next/server/chunks/[root-of-the-server]__1fboj2j._.js +0 -3
  441. package/.next/server/chunks/[root-of-the-server]__1lr7j9t._.js +0 -5
  442. package/.next/server/chunks/[root-of-the-server]__1oli73c._.js +0 -3
  443. package/.next/server/chunks/[root-of-the-server]__1txedx6._.js +0 -8
  444. package/.next/server/chunks/[root-of-the-server]__1untqv8._.js +0 -5
  445. package/.next/server/chunks/[root-of-the-server]__1zgpz1w._.js +0 -3
  446. package/.next/server/chunks/_00_584r._.js +0 -293
  447. package/.next/server/chunks/_012yhfm._.js +0 -39
  448. package/.next/server/chunks/_06mxlgn._.js +0 -3
  449. package/.next/server/chunks/_07rtlxv._.js +0 -3
  450. package/.next/server/chunks/_0a351g7._.js +0 -6
  451. package/.next/server/chunks/_0kjjmag._.js +0 -3
  452. package/.next/server/chunks/_0nn99o2._.js +0 -3
  453. package/.next/server/chunks/_0zuzmt_._.js +0 -39
  454. package/.next/server/chunks/_106co2o._.js +0 -3
  455. package/.next/server/chunks/_12bbv5i._.js +0 -100
  456. package/.next/server/chunks/_15q1pig._.js +0 -3
  457. package/.next/server/chunks/_19wg5yn._.js +0 -138
  458. package/.next/server/chunks/_1bt95p9._.js +0 -55
  459. package/.next/server/chunks/_1cbk7ms._.js +0 -26
  460. package/.next/server/chunks/_1drv2et._.js +0 -40
  461. package/.next/server/chunks/_1ic3bew._.js +0 -5
  462. package/.next/server/chunks/_1mxn_lb._.js +0 -3
  463. package/.next/server/chunks/_1rysr-r._.js +0 -10
  464. package/.next/server/chunks/_1u3rwbr._.js +0 -3
  465. package/.next/server/chunks/_1x7p319._.js +0 -6
  466. package/.next/server/chunks/_next-internal_server_app_api_bot_notes_route_actions_0qcsyu7.js +0 -3
  467. package/.next/server/chunks/_next-internal_server_app_api_memory_tidy_route_actions_0_cfuom.js +0 -3
  468. package/.next/server/chunks/features_bot_task_query_ts_11xuzl3._.js +0 -3
  469. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0gzvgfv._.js +0 -3
  470. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0vorg6w._.js +0 -3
  471. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1tpvamf._.js +0 -3
  472. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1vmaq9f._.js +0 -3
  473. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1y9-wcr._.js +0 -3
  474. package/.next/server/chunks/ssr/[externals]_node_crypto_1kn79-7._.js +0 -3
  475. package/.next/server/chunks/ssr/[root-of-the-server]__0iuoa-r._.js +0 -3
  476. package/.next/server/chunks/ssr/[root-of-the-server]__0un-erv._.js +0 -4
  477. package/.next/server/chunks/ssr/[root-of-the-server]__1-mnhyd._.js +0 -92
  478. package/.next/server/chunks/ssr/[root-of-the-server]__1bww500._.js +0 -3
  479. package/.next/server/chunks/ssr/[root-of-the-server]__1vcdast._.js +0 -3
  480. package/.next/server/chunks/ssr/[root-of-the-server]__1xwnu-h._.js +0 -3
  481. package/.next/server/chunks/ssr/_0-mc7ro._.js +0 -3
  482. package/.next/server/chunks/ssr/_01p5r6-._.js +0 -3
  483. package/.next/server/chunks/ssr/_03webdr._.js +0 -3
  484. package/.next/server/chunks/ssr/_09-0k3z._.js +0 -3
  485. package/.next/server/chunks/ssr/_0f_b_9s._.js +0 -3
  486. package/.next/server/chunks/ssr/_0fafgvl._.js +0 -3
  487. package/.next/server/chunks/ssr/_0sf1isi._.js +0 -3
  488. package/.next/server/chunks/ssr/_0su6_08._.js +0 -3
  489. package/.next/server/chunks/ssr/_0ti51xc._.js +0 -3
  490. package/.next/server/chunks/ssr/_0w5bgak._.js +0 -3
  491. package/.next/server/chunks/ssr/_0y84qo6._.js +0 -3
  492. package/.next/server/chunks/ssr/_1ciyoo3._.js +0 -3
  493. package/.next/server/chunks/ssr/_1e-dgz0._.js +0 -4
  494. package/.next/server/chunks/ssr/_1fq7zgb._.js +0 -3
  495. package/.next/server/chunks/ssr/_1g6l4uj._.js +0 -3
  496. package/.next/server/chunks/ssr/_1ruzehw._.js +0 -3
  497. package/.next/server/chunks/ssr/features_bot_components_bot-setting_tsx_01ajft6._.js +0 -4
  498. package/.next/server/chunks/ssr/features_config_components_14jqgy4._.js +0 -3
  499. package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +0 -4
  500. package/.next/server/chunks/ssr/node_modules_zod_v4_classic_external_15fmmz3.js +0 -55
  501. package/.next/static/chunks/05b6nx_o3_f_n.js +0 -1
  502. package/.next/static/chunks/0dmns-gi0raa4.js +0 -1
  503. package/.next/static/chunks/0f9sq-7q_yxyl.js +0 -1
  504. package/.next/static/chunks/0oc4_xoia77dg.css +0 -1
  505. package/.next/static/chunks/0pheo8m3a-rzi.js +0 -1
  506. package/.next/static/chunks/19i8h2t-5evjx.js +0 -1
  507. package/.next/static/chunks/1c5fcj473025q.js +0 -1
  508. package/.next/static/chunks/1pi_hbmjw-f-z.js +0 -1
  509. package/.next/static/chunks/1twt6k09vg4np.js +0 -1
  510. package/.next/static/chunks/1ytnip8wdng93.js +0 -1
  511. package/.next/static/chunks/28gotuisldmom.js +0 -1
  512. package/.next/static/chunks/2998p0y7k1c8z.js +0 -3
  513. package/.next/static/chunks/29gyb3nubj51j.js +0 -53
  514. package/.next/static/chunks/2l233xfycjpd8.js +0 -1
  515. package/.next/static/chunks/2p5n7pa3c40t-.js +0 -2
  516. package/.next/static/chunks/2ru1q132af7h7.js +0 -1
  517. package/.next/static/chunks/2t8wqycwg3y04.js +0 -2
  518. package/.next/static/chunks/2uxum7qbyeyxd.js +0 -1
  519. package/.next/static/chunks/32z_ypgtchw48.js +0 -1
  520. package/.next/static/chunks/33pyjb3xd1iez.js +0 -1
  521. package/.next/static/chunks/3omud5xunrk1f.js +0 -1
  522. package/.next/static/chunks/42dnrkbph9e-1.js +0 -1
  523. package/.next/static/media/favicon.2vob68tjqpejf.ico +0 -0
  524. package/database/migrations/20260909063821_bitter_tenebrous/migration.sql +0 -1
  525. package/features/ai/prompts/memory-tidy.prompt.ts +0 -129
  526. package/features/ai/tools/tidy.tool.ts +0 -22
  527. package/features/bot/bot.notes.ts +0 -120
  528. package/features/memory/components/memory-tidy.tsx +0 -395
  529. package/features/memory/components/memory-view.tsx +0 -84
  530. package/features/memory/memory.tidy.ts +0 -332
  531. package/features/memory/tidy.query.ts +0 -135
  532. package/features/thursday/use-call-title.ts +0 -31
  533. /package/.next/server/app/api/bot/{notes → memory/files}/route/build-manifest.json +0 -0
  534. /package/.next/server/app/api/bot/{notes → memory/files}/route/server-reference-manifest.json +0 -0
  535. /package/.next/server/app/api/bot/{notes → memory/files}/route.js.map +0 -0
  536. /package/.next/server/app/api/{memory/tidy → bot/memory}/route/build-manifest.json +0 -0
  537. /package/.next/server/app/api/{memory/tidy → bot/memory}/route/server-reference-manifest.json +0 -0
  538. /package/.next/server/app/api/{memory/tidy → bot/memory}/route.js.map +0 -0
  539. /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → kaTO0UHqF1bMnWgCDik2f}/_buildManifest.js +0 -0
  540. /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → kaTO0UHqF1bMnWgCDik2f}/_clientMiddlewareManifest.js +0 -0
  541. /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → kaTO0UHqF1bMnWgCDik2f}/_ssgManifest.js +0 -0
@@ -1,9 +1,20 @@
1
1
  import type { AssistantContent, ModelMessage, ToolContent } from "ai";
2
- import { and, desc, eq, inArray, isNull, lt, max, sql } from "drizzle-orm";
2
+ import {
3
+ and,
4
+ desc,
5
+ eq,
6
+ inArray,
7
+ isNotNull,
8
+ isNull,
9
+ lt,
10
+ max,
11
+ sql,
12
+ } from "drizzle-orm";
3
13
  import { appEvents } from "@/app/api/events/app-event.server";
14
+ import { INBOX_FINISHED } from "@/config";
4
15
  import { database } from "@/database/db";
5
16
  import { taskMessageTable, taskTable } from "@/database/tables";
6
- import { reportAccepted } from "@/features/ai/tools/bot.tool";
17
+ import { answerAccepted, isAnswerCall } from "@/features/ai/tools/bot.tool";
7
18
  import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
8
19
  import { clip } from "@/lib/utils";
9
20
  import {
@@ -11,8 +22,10 @@ import {
11
22
  TASK_HISTORY_PAGE,
12
23
  type Task,
13
24
  type TaskLine,
25
+ type TaskPending,
14
26
  type TaskStatus,
15
27
  type TokenUsage,
28
+ untagSpeaker,
16
29
  } from "./bot.schema";
17
30
 
18
31
  // Tasks and their threads. Bots themselves (roster, pinned tools) are bot.query.
@@ -29,7 +42,7 @@ const taskView = {
29
42
  status: taskTable.status,
30
43
  outcome: taskTable.outcome,
31
44
  pending: taskTable.pending,
32
- reported: taskTable.reported,
45
+ seen: taskTable.seen,
33
46
  inputTokens: taskTable.inputTokens,
34
47
  outputTokens: taskTable.outputTokens,
35
48
  contextTokens: taskTable.contextTokens,
@@ -45,8 +58,8 @@ type TaskRow = {
45
58
  request: string;
46
59
  status: TaskStatus;
47
60
  outcome: string | null;
48
- pending: { toolCallId: string | null; options: string[] } | null;
49
- reported: boolean;
61
+ pending: TaskPending | null;
62
+ seen: boolean;
50
63
  inputTokens: number;
51
64
  outputTokens: number;
52
65
  contextTokens: number;
@@ -55,12 +68,9 @@ type TaskRow = {
55
68
  updatedAt: Date;
56
69
  };
57
70
 
58
- /** How many finished tasks the inbox keeps; the rest live in Settings > Tasks. */
59
- const INBOX_RECENT_FINISHED = 3;
60
-
61
71
  /**
62
72
  * One row plus the thread's first message. `request` is what the screen shows;
63
- * `opening` is what the model reads (request plus recent call turns). The screen
73
+ * `opening` is what the model reads (who is who, the job, the call it came from). The screen
64
74
  * skips seq 0 and shows `request` instead (linesOf).
65
75
  */
66
76
  export async function insertTask(input: {
@@ -68,7 +78,7 @@ export async function insertTask(input: {
68
78
  label: string;
69
79
  request: string;
70
80
  callId?: string | null;
71
- opening: string;
81
+ opening: Extract<ModelMessage, { role: "user" }>["content"];
72
82
  }) {
73
83
  const { opening, ...row } = input;
74
84
  const [task] = await database
@@ -90,9 +100,11 @@ export async function updateTask(
90
100
  patch: Partial<{
91
101
  status: TaskStatus;
92
102
  outcome: string | null;
93
- pending: { toolCallId: string | null; options: string[] } | null;
94
- reported: boolean;
103
+ pending: TaskPending | null;
104
+ seen: boolean;
95
105
  endedAt: Date | null;
106
+ /** Where the job compacts from now on; also written at every step (addTaskUsage). */
107
+ contextBudget: number;
96
108
  }>,
97
109
  ) {
98
110
  await database
@@ -102,12 +114,12 @@ export async function updateTask(
102
114
  changed();
103
115
  }
104
116
 
105
- /** Bypasses `updateTask` on purpose: reporting is not movement and must not reorder the inbox by updatedAt. */
106
- export async function markReported(ids: string[]) {
117
+ /** Bypasses `updateTask` on purpose: being seen is not movement and must not reorder the inbox by updatedAt. */
118
+ export async function markSeen(ids: string[]) {
107
119
  if (ids.length === 0) return;
108
120
  await database
109
121
  .update(taskTable)
110
- .set({ reported: true })
122
+ .set({ seen: true })
111
123
  .where(inArray(taskTable.id, ids));
112
124
  changed();
113
125
  }
@@ -155,7 +167,7 @@ export async function findTask(id: string) {
155
167
  return task ?? null;
156
168
  }
157
169
 
158
- /** Inbox: everything running or waiting plus the most recently finished few, newest first. `reported` is not a filter here. */
170
+ /** Inbox: everything running or waiting plus the latest INBOX_FINISHED endings, newest first. `seen` is not a filter here. */
159
171
  export async function listInboxTasks(): Promise<Task[]> {
160
172
  const [open, finished] = await Promise.all([
161
173
  database
@@ -168,7 +180,7 @@ export async function listInboxTasks(): Promise<Task[]> {
168
180
  .from(taskTable)
169
181
  .where(inArray(taskTable.status, ["done", "failed"]))
170
182
  .orderBy(desc(taskTable.updatedAt))
171
- .limit(INBOX_RECENT_FINISHED),
183
+ .limit(INBOX_FINISHED),
172
184
  ]);
173
185
  const rows = [...open, ...finished].sort(
174
186
  (a, b) => b.updatedAt.getTime() - a.updatedAt.getTime(),
@@ -251,6 +263,177 @@ export async function listRunningTaskIds() {
251
263
  return rows.map((row) => row.id);
252
264
  }
253
265
 
266
+ /** Every job with what names its folder and whether it still keeps it (bot.runner sweepJobFiles). */
267
+ export async function listTaskFolders() {
268
+ return await database
269
+ .select({
270
+ id: taskTable.id,
271
+ label: taskTable.label,
272
+ status: taskTable.status,
273
+ endedAt: taskTable.endedAt,
274
+ updatedAt: taskTable.updatedAt,
275
+ })
276
+ .from(taskTable);
277
+ }
278
+
279
+ /** Jobs the app parked to pick back up by itself (bot.runner parkTask), and when each may go. */
280
+ export async function listAutoStoppedTasks() {
281
+ const rows = await database
282
+ .select({ id: taskTable.id, pending: taskTable.pending })
283
+ .from(taskTable)
284
+ .where(eq(taskTable.status, "waiting"));
285
+ return rows.flatMap((row) =>
286
+ row.pending?.auto
287
+ ? [{ id: row.id, retryAt: row.pending.retryAt ?? 0 }]
288
+ : [],
289
+ );
290
+ }
291
+
292
+ /**
293
+ * How many times the app has stopped this job since a person last said anything
294
+ * to it: the notes it left in the thread — a break, a park — back to the last row
295
+ * a person wrote: the opening, an answer, a word to a running job. Read off the
296
+ * rows rather than kept as a count, so it cannot drift from what the thread shows.
297
+ */
298
+ export async function countStopsSinceSpoken(taskId: string): Promise<number> {
299
+ const rows = await database
300
+ .select({
301
+ role: taskMessageTable.role,
302
+ bot: taskMessageTable.bot,
303
+ note: taskMessageTable.note,
304
+ compact: taskMessageTable.compact,
305
+ })
306
+ .from(taskMessageTable)
307
+ .where(
308
+ and(eq(taskMessageTable.taskId, taskId), isNull(taskMessageTable.parent)),
309
+ )
310
+ .orderBy(desc(taskMessageTable.seq));
311
+ let stops = 0;
312
+ for (const row of rows) {
313
+ if (row.note) {
314
+ if (!row.compact) stops += 1;
315
+ continue;
316
+ }
317
+ // A person: the opening and every answer are written with no bot, and a
318
+ // word to a running job is a user row in the bot's name
319
+ if (row.bot === null || row.role === "user") break;
320
+ }
321
+ return stops;
322
+ }
323
+
324
+ /** How much of a cut-off borrowed bot's prose a resume carries: its last few paragraphs. */
325
+ const TAIL = { texts: 3, chars: 600 };
326
+
327
+ /**
328
+ * What each borrowed bot had written when its `ask_bot` call stopped, by that
329
+ * call's id: its last few paragraphs, and the tool it reached for after them. A
330
+ * resumed run reads it where the call's result never arrived (bot.run
331
+ * resumeThread), so a part cut off half-way is carried on, not asked for afresh.
332
+ */
333
+ export async function listBorrowedTails(
334
+ taskId: string,
335
+ ): Promise<Map<string, { bot: string; tail: string }>> {
336
+ const rows = await database
337
+ .select({
338
+ parent: taskMessageTable.parent,
339
+ bot: taskMessageTable.bot,
340
+ content: taskMessageTable.content,
341
+ })
342
+ .from(taskMessageTable)
343
+ .where(
344
+ and(
345
+ eq(taskMessageTable.taskId, taskId),
346
+ isNotNull(taskMessageTable.parent),
347
+ eq(taskMessageTable.role, "assistant"),
348
+ ),
349
+ )
350
+ .orderBy(taskMessageTable.seq);
351
+
352
+ const calls = new Map<
353
+ string,
354
+ { bot: string; texts: string[]; then: string | null }
355
+ >();
356
+ for (const row of rows) {
357
+ if (!row.parent) continue;
358
+ const call = calls.get(row.parent) ?? {
359
+ bot: row.bot ?? "",
360
+ texts: [],
361
+ then: null,
362
+ };
363
+ const content = row.content as AssistantContent;
364
+ const parts =
365
+ typeof content === "string"
366
+ ? [{ type: "text" as const, text: content }]
367
+ : content;
368
+ for (const part of parts) {
369
+ if (part.type === "text" && part.text.trim()) {
370
+ call.texts.push(part.text.trim());
371
+ call.then = null;
372
+ } else if (part.type === "tool-call") {
373
+ call.then =
374
+ `${part.toolName} ${toolLine(part.toolName, part.input)}`.trim();
375
+ }
376
+ }
377
+ calls.set(row.parent, call);
378
+ }
379
+
380
+ const tails = new Map<string, { bot: string; tail: string }>();
381
+ for (const [id, call] of calls) {
382
+ const tail = [
383
+ ...call.texts.slice(-TAIL.texts).map((text) => clip(text, TAIL.chars)),
384
+ call.then ? `Then: ${call.then}` : "",
385
+ ]
386
+ .filter(Boolean)
387
+ .join("\n\n");
388
+ if (tail) tails.set(id, { bot: call.bot, tail });
389
+ }
390
+ return tails;
391
+ }
392
+
393
+ /**
394
+ * Paths a list of message contents gave `write_file`, oldest first and each once; a
395
+ * path written again moves to the end. A refused write is here too, so whoever shows
396
+ * them checks the disk (workspace.ts filesOnDisk).
397
+ */
398
+ export function writtenPathsIn(contents: unknown[]): string[] {
399
+ const paths = new Set<string>();
400
+ for (const content of contents) {
401
+ if (!Array.isArray(content)) continue;
402
+ for (const part of content as {
403
+ type?: unknown;
404
+ toolName?: unknown;
405
+ input?: unknown;
406
+ }[]) {
407
+ if (
408
+ part.type !== "tool-call" ||
409
+ part.toolName !== TOOL_NAMES.write_file
410
+ ) {
411
+ continue;
412
+ }
413
+ const path = (part.input as { path?: unknown } | null)?.path;
414
+ if (typeof path !== "string" || !path.trim()) continue;
415
+ paths.delete(path.trim());
416
+ paths.add(path.trim());
417
+ }
418
+ }
419
+ return [...paths];
420
+ }
421
+
422
+ /** Every path this job gave `write_file`: its own bot and each bot it borrowed (writtenPathsIn). */
423
+ export async function listWrittenPaths(taskId: string): Promise<string[]> {
424
+ const rows = await database
425
+ .select({ content: taskMessageTable.content })
426
+ .from(taskMessageTable)
427
+ .where(
428
+ and(
429
+ eq(taskMessageTable.taskId, taskId),
430
+ eq(taskMessageTable.role, "assistant"),
431
+ ),
432
+ )
433
+ .orderBy(taskMessageTable.seq);
434
+ return writtenPathsIn(rows.map((row) => row.content));
435
+ }
436
+
254
437
  /**
255
438
  * Finds a task by id or by exact label (case-insensitive). No looser matching:
256
439
  * a miss returns null and the caller lists recent tasks instead.
@@ -337,7 +520,8 @@ export async function lastSeq(taskId: string): Promise<number> {
337
520
  /**
338
521
  * The task's own thread as the model sees it: parent-less messages in order.
339
522
  * What a borrowed bot said inside an `ask_bot` call is not here; its result is.
340
- * Starts at the last compact row when there is one.
523
+ * After a compaction it is the opening, then the last compact row on: a summary
524
+ * replaces what came after the job and the call, never the job and the call.
341
525
  */
342
526
  export async function listThread(taskId: string): Promise<ModelMessage[]> {
343
527
  const rows = await database
@@ -352,9 +536,10 @@ export async function listThread(taskId: string): Promise<ModelMessage[]> {
352
536
  )
353
537
  .orderBy(taskMessageTable.seq);
354
538
  const from = rows.findLastIndex((row) => row.compact);
355
- return rows
356
- .slice(Math.max(from, 0))
357
- .map((row) => ({ role: row.role, content: row.content }) as ModelMessage);
539
+ const kept = from > 0 ? [rows[0], ...rows.slice(from)] : rows;
540
+ return kept.map(
541
+ (row) => ({ role: row.role, content: row.content }) as ModelMessage,
542
+ );
358
543
  }
359
544
 
360
545
  /** One row in the screen's shape; `pending` folds into `ask`. */
@@ -365,7 +550,11 @@ function viewOf(row: TaskRow, lines: TaskLine[]): Task {
365
550
  ...rest,
366
551
  ask:
367
552
  row.status === "waiting"
368
- ? { question: row.outcome ?? "", options: pending?.options ?? [] }
553
+ ? {
554
+ question: row.outcome ?? "",
555
+ options: pending?.options ?? [],
556
+ auto: pending?.auto === true,
557
+ }
369
558
  : null,
370
559
  tokens: { input: inputTokens, output: outputTokens },
371
560
  lines,
@@ -428,8 +617,7 @@ function labelOf(args: Record<string, unknown>): string | null {
428
617
  }
429
618
 
430
619
  /**
431
- * One tool call as one line. Shared by the screen and by the resumed bot's
432
- * re-read history (bot.run condenseThread). No per-tool summary table: the
620
+ * One tool call as one line, for the screen. No per-tool summary table: the
433
621
  * label is model-written (bash `description`), other tools use the first
434
622
  * telling argument, else the argument shape.
435
623
  */
@@ -501,6 +689,13 @@ export async function readToolResult(
501
689
  return null;
502
690
  }
503
691
 
692
+ /** Said to a resumed run after why it stopped. The screen shows only the why (linesOf). */
693
+ const IN_FLIGHT =
694
+ "Anything that was under way — a command, a page loading, a download — may not have finished: check before relying on it, then carry on.";
695
+
696
+ /** The thread line a stop the app made leaves (bot.runner parkTask). */
697
+ export const stopNote = (why: string) => `${why} ${IN_FLIGHT}`;
698
+
504
699
  type StoredMessage = typeof taskMessageTable.$inferSelect;
505
700
 
506
701
  /**
@@ -523,11 +718,17 @@ function linesOf(message: StoredMessage, owner: string): TaskLine[] {
523
718
  if (message.seq === 0) return [];
524
719
  const text = typeof content === "string" ? content : textOf(content);
525
720
  if (!text) return [];
526
- // The app's own line — a compaction marker, or why a run stopped — never
527
- // the user's words. `compact` is read too: rows written before `note` was.
528
- if (message.note || message.compact)
529
- return [{ ...base, id: id(0), kind: "note", text }];
530
- return [{ ...base, id: id(0), kind: "user", text }];
721
+ // The app's own lines, never the user's words. `compact` alone marks a
722
+ // compaction: rows written before `note` existed carry only that.
723
+ if (message.compact) return [{ ...base, id: id(0), kind: "note", text }];
724
+ if (message.note) {
725
+ const why = text.endsWith(IN_FLIGHT)
726
+ ? text.slice(0, -IN_FLIGHT.length).trimEnd()
727
+ : text;
728
+ return [{ ...base, id: id(0), kind: "stop", text: why }];
729
+ }
730
+ // Tagged with who said it for the bot (bot.schema tagSpeaker); the screen draws the words
731
+ return [{ ...base, id: id(0), kind: "user", text: untagSpeaker(text) }];
531
732
  }
532
733
 
533
734
  if (message.role === "assistant") {
@@ -560,8 +761,8 @@ function linesOf(message: StoredMessage, owner: string): TaskLine[] {
560
761
  question: String(args.question ?? ""),
561
762
  options: optionsOf(args.options),
562
763
  });
563
- } else if (part.toolName === TOOL_NAMES.report) {
564
- // The report is a tool call but draws as text: it is the last thing said
764
+ } else if (isAnswerCall(part.toolName)) {
765
+ // The answer is a tool call but draws as text: it is the last thing said
565
766
  // in the thread, and taskFromRow promotes it to the result line
566
767
  const text = String(args.result ?? "").trim();
567
768
  if (text) lines.push({ ...base, id: id(index), kind: "text", text });
@@ -620,8 +821,8 @@ function linesOf(message: StoredMessage, owner: string): TaskLine[] {
620
821
  const lines: TaskLine[] = [];
621
822
  (message.content as ToolContent).forEach((part, index) => {
622
823
  if (part.type !== "tool-result") return;
623
- if (part.toolName === TOOL_NAMES.report && reportAccepted(part.output)) {
624
- // An accepted report's result is only a confirmation; the report itself
824
+ if (isAnswerCall(part.toolName) && answerAccepted(part.output)) {
825
+ // An accepted answer's result is only a confirmation; the answer itself
625
826
  // was drawn from the call. A rejected one is drawn: it explains the next step
626
827
  return;
627
828
  }
@@ -630,7 +831,12 @@ function linesOf(message: StoredMessage, owner: string): TaskLine[] {
630
831
  const text = resultParts(part.output, RESULT_LINES)
631
832
  .flatMap((result) => (result.type === "text" ? [result.text] : []))
632
833
  .join("\n");
633
- lines.push({ ...base, id: id(index), kind: "user", text });
834
+ lines.push({
835
+ ...base,
836
+ id: id(index),
837
+ kind: "user",
838
+ text: untagSpeaker(text),
839
+ });
634
840
  } else if (
635
841
  part.toolName === TOOL_NAMES.ask_bot ||
636
842
  part.toolName === TOOL_NAMES.ask_back
@@ -1,6 +1,9 @@
1
1
  "use client";
2
2
 
3
- import { useSyncExternalStore } from "react";
3
+ import { useEffect, useRef, useSyncExternalStore } from "react";
4
+ import { queryKey } from "@/app/api/query-key";
5
+ import { toast } from "@/components/ui/toast";
6
+ import { markSeenAction } from "@/features/bot/bot.action";
4
7
  import type {
5
8
  Bot,
6
9
  BotIcon,
@@ -8,7 +11,10 @@ import type {
8
11
  Task,
9
12
  TokenUsage,
10
13
  } from "@/features/bot/bot.schema";
11
- import type { DateLike } from "@/lib/date-like";
14
+ import { type DateLike, toDate } from "@/lib/date-like";
15
+ import { unwrapResult } from "@/lib/protocol/result";
16
+ import { revalidate } from "@/lib/protocol/use-server-route";
17
+ import { errorToString } from "@/lib/utils";
12
18
 
13
19
  /**
14
20
  * Client mirror of tasks, keyed by task rather than as one message stream so
@@ -18,7 +24,11 @@ import type { DateLike } from "@/lib/date-like";
18
24
 
19
25
  export type BotRef = { name: string; icon?: BotIcon | null };
20
26
 
21
- /** `note` is a marker, not speech: a compaction summary (bot.run compact). Draw as a divider. */
27
+ /**
28
+ * `note` and `stop` are the app's markers, not speech. `note` is a compaction
29
+ * summary (bot.run compact), drawn as a divider; `stop` is where the app stopped
30
+ * the run (bot.runner parkTask), drawn muted in the bot's turn.
31
+ */
22
32
  export type ChatterKind =
23
33
  | "say"
24
34
  | "ask"
@@ -26,7 +36,8 @@ export type ChatterKind =
26
36
  | "user"
27
37
  | "result"
28
38
  | "error"
29
- | "note";
39
+ | "note"
40
+ | "stop";
30
41
 
31
42
  /** One tool call. `name` picks the renderer (components/bot-tool); `results` arrive after the call. */
32
43
  export type ToolUse = {
@@ -57,6 +68,8 @@ export type Chatter = {
57
68
  tool?: ToolUse;
58
69
  /** Options attached to a question; only on the line where the bot stopped to ask. */
59
70
  options?: string[];
71
+ /** When it was written; only for kind `stop`, whose repeats fold into one line. */
72
+ at?: DateLike;
60
73
  };
61
74
 
62
75
  /** `waiting`: the bot stopped to ask the user something. */
@@ -76,9 +89,9 @@ export type TaskView = {
76
89
  /** Text it came back with; only after it returned. */
77
90
  outcome: string | null;
78
91
  /** What it is asking while `waiting`. */
79
- ask: { question: string; options: string[] } | null;
80
- /** Whether it has been relayed to Thursday; otherwise the room shows a dot. */
81
- relayed: boolean;
92
+ ask: Task["ask"];
93
+ /** Whether the user has had the ending (Task `seen`). */
94
+ seen: boolean;
82
95
  /** Burned so far. */
83
96
  tokens: TokenUsage;
84
97
  /** Context read on the last step and the compaction threshold; the header meter is their ratio. Both 0 means no step ran yet. */
@@ -153,6 +166,16 @@ export function taskFromRow(row: Task, bots?: Bot[]): TaskView {
153
166
  case "note":
154
167
  lines.push({ id: line.id, bot, to, text: line.text, kind: "note" });
155
168
  break;
169
+ case "stop":
170
+ lines.push({
171
+ id: line.id,
172
+ bot,
173
+ to,
174
+ text: line.text,
175
+ kind: "stop",
176
+ at: line.at,
177
+ });
178
+ break;
156
179
  case "tool":
157
180
  openLines.set(line.callId, lines.length);
158
181
  lines.push({
@@ -219,9 +242,9 @@ export function taskFromRow(row: Task, bots?: Bot[]): TaskView {
219
242
  }
220
243
  }
221
244
 
222
- // The ending lives on the row, not in the thread: the report is the last text
245
+ // The ending lives on the row, not in the thread: the answer is the last text
223
246
  // said, failure exists only here. `waiting` is treated like done: a job that
224
- // stopped for budget reported first, so that line is a result.
247
+ // the app stopped answered first, so that line is a result.
225
248
  if (row.status === "failed" && row.outcome) {
226
249
  lines.push({
227
250
  id: `${row.id}-end`,
@@ -246,7 +269,7 @@ export function taskFromRow(row: Task, bots?: Bot[]): TaskView {
246
269
  status: row.status === "running" ? "working" : row.status,
247
270
  outcome: row.outcome,
248
271
  ask: row.ask,
249
- relayed: row.reported,
272
+ seen: row.seen,
250
273
  tokens: row.tokens,
251
274
  contextTokens: row.contextTokens,
252
275
  contextBudget: row.contextBudget,
@@ -258,7 +281,8 @@ export function taskFromRow(row: Task, bots?: Bot[]): TaskView {
258
281
  export function lastSaid(task: TaskView): Chatter | null {
259
282
  for (let at = task.lines.length - 1; at >= 0; at--) {
260
283
  const line = task.lines[at];
261
- if (line.kind !== "user" && line.kind !== "note") return line;
284
+ if (line.kind !== "user" && line.kind !== "note" && line.kind !== "stop")
285
+ return line;
262
286
  }
263
287
  return null;
264
288
  }
@@ -266,7 +290,7 @@ export function lastSaid(task: TaskView): Chatter | null {
266
290
  /**
267
291
  * What the screen did to a task. Announced so the call can hear it: a poll
268
292
  * cannot tell a screen answer from a voice answer, and a cancel is never relayed
269
- * (bot.runner cancelTask marks it reported).
293
+ * (bot.runner cancelTask marks it seen).
270
294
  */
271
295
  export type ScreenAct =
272
296
  /** Answered a waiting task, interjected into a running one, or continued a finished one. */
@@ -406,7 +430,8 @@ export function latestPerBot(list: TaskView[]): BotLine[] {
406
430
  byBot.set(task.bot.name, { bot: task.bot, task, line: null, open: 0 });
407
431
  }
408
432
  for (const line of task.lines) {
409
- if (line.kind === "user" || line.kind === "note") continue;
433
+ if (line.kind === "user" || line.kind === "note" || line.kind === "stop")
434
+ continue;
410
435
  byBot.set(line.bot.name, {
411
436
  bot: line.bot,
412
437
  task,
@@ -424,3 +449,41 @@ export function latestPerBot(list: TaskView[]): BotLine[] {
424
449
 
425
450
  return [...byBot.values()];
426
451
  }
452
+
453
+ /**
454
+ * Opening a job's detail is reading its ending: the thread in the room, a row
455
+ * expanded in Settings › Tasks. That is what clears its dot — a list scrolled
456
+ * past or a line heard on a call is not. Keyed by `updatedAt` as well, because a
457
+ * follow-up ends a job a second time and that ending is new again.
458
+ */
459
+ export function useSeenOnDetail(
460
+ task:
461
+ | { id: string; status: string; seen: boolean; updatedAt: DateLike }
462
+ | null
463
+ | undefined,
464
+ ) {
465
+ const sent = useRef(new Set<string>());
466
+ const id = task?.id ?? null;
467
+ const key = task ? `${task.id}@${toDate(task.updatedAt).getTime()}` : null;
468
+ const owed =
469
+ !!task &&
470
+ (task.status === "done" || task.status === "failed") &&
471
+ !task.seen;
472
+
473
+ useEffect(() => {
474
+ if (!id || !key || !owed || sent.current.has(key)) return;
475
+ sent.current.add(key);
476
+ void markSeenAction([id])
477
+ .then(unwrapResult)
478
+ .then(() => revalidate(queryKey.tasks))
479
+ .catch((cause) => {
480
+ // Released, so opening it again tries again
481
+ sent.current.delete(key);
482
+ toast.add({
483
+ type: "error",
484
+ title: "Could not mark the task as read",
485
+ description: errorToString(cause),
486
+ });
487
+ });
488
+ }, [id, key, owed]);
489
+ }