thursday-agent 0.1.2 → 0.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 (573) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +5 -1
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +5 -5
  5. package/.next/routes-manifest.json +27 -3
  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.html +1 -1
  9. package/.next/server/app/_global-error.rsc +2 -2
  10. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  12. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/server/app/_not-found/page.js +2 -2
  14. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  15. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/server/app/_not-found.html +1 -1
  17. package/.next/server/app/_not-found.rsc +14 -14
  18. package/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  19. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
  20. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  21. package/.next/server/app/api/artifact/route.js +3 -3
  22. package/.next/server/app/api/artifact/route.js.nft.json +1 -1
  23. package/.next/server/app/api/bot/memory/files/route/app-paths-manifest.json +3 -0
  24. package/.next/server/app/api/bot/memory/files/route.js +10 -0
  25. package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -0
  26. package/.next/server/app/api/bot/memory/files/route_client-reference-manifest.js +3 -0
  27. package/.next/server/app/api/bot/memory/route/app-paths-manifest.json +3 -0
  28. package/.next/server/app/api/bot/memory/route/build-manifest.json +12 -0
  29. package/.next/server/app/api/bot/memory/route/server-reference-manifest.json +4 -0
  30. package/.next/server/app/api/bot/memory/route.js +14 -0
  31. package/.next/server/app/api/bot/memory/route.js.map +5 -0
  32. package/.next/server/app/api/bot/memory/route.js.nft.json +1 -0
  33. package/.next/server/app/api/bot/memory/route_client-reference-manifest.js +3 -0
  34. package/.next/server/app/api/bot/route.js +7 -7
  35. package/.next/server/app/api/bot/route.js.nft.json +1 -1
  36. package/.next/server/app/api/bot/task/[id]/route.js +9 -9
  37. package/.next/server/app/api/bot/task/[id]/route.js.nft.json +1 -1
  38. package/.next/server/app/api/bot/task/route.js +8 -8
  39. package/.next/server/app/api/bot/task/route.js.nft.json +1 -1
  40. package/.next/server/app/api/config/route.js +6 -6
  41. package/.next/server/app/api/config/route.js.nft.json +1 -1
  42. package/.next/server/app/api/events/route.js +4 -5
  43. package/.next/server/app/api/events/route.js.nft.json +1 -1
  44. package/.next/server/app/api/file/[...path]/route.js +3 -3
  45. package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
  46. package/.next/server/app/api/llm-model/catalog/route.js +10 -9
  47. package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
  48. package/.next/server/app/api/llm-model/credits/route/app-paths-manifest.json +3 -0
  49. package/.next/server/app/api/llm-model/credits/route/build-manifest.json +12 -0
  50. package/.next/server/app/api/llm-model/credits/route/server-reference-manifest.json +4 -0
  51. package/.next/server/app/api/llm-model/credits/route.js +16 -0
  52. package/.next/server/app/api/llm-model/credits/route.js.map +5 -0
  53. package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -0
  54. package/.next/server/app/api/llm-model/credits/route_client-reference-manifest.js +3 -0
  55. package/.next/server/app/api/llm-model/route.js +10 -8
  56. package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
  57. package/.next/server/app/api/llm-model/subscription/route/app-paths-manifest.json +3 -0
  58. package/.next/server/app/api/llm-model/subscription/route/build-manifest.json +12 -0
  59. package/.next/server/app/api/llm-model/subscription/route/server-reference-manifest.json +4 -0
  60. package/.next/server/app/api/llm-model/subscription/route.js +15 -0
  61. package/.next/server/app/api/llm-model/subscription/route.js.map +5 -0
  62. package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -0
  63. package/.next/server/app/api/llm-model/subscription/route_client-reference-manifest.js +3 -0
  64. package/.next/server/app/api/mcp/[name]/route.js +5 -5
  65. package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
  66. package/.next/server/app/api/mcp/oauth/callback/route.js +6 -6
  67. package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
  68. package/.next/server/app/api/mcp/route.js +5 -5
  69. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  70. package/.next/server/app/api/mcp/tools/route.js +5 -5
  71. package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
  72. package/.next/server/app/api/memory/edit/route/app-paths-manifest.json +3 -0
  73. package/.next/server/app/api/memory/edit/route/build-manifest.json +12 -0
  74. package/.next/server/app/api/memory/edit/route/server-reference-manifest.json +4 -0
  75. package/.next/server/app/api/memory/edit/route.js +24 -0
  76. package/.next/server/app/api/memory/edit/route.js.map +5 -0
  77. package/.next/server/app/api/memory/edit/route.js.nft.json +1 -0
  78. package/.next/server/app/api/memory/{tidy → edit}/route_client-reference-manifest.js +1 -1
  79. package/.next/server/app/api/memory/route.js +7 -8
  80. package/.next/server/app/api/memory/route.js.nft.json +1 -1
  81. package/.next/server/app/api/skills/[source]/[name]/route.js +3 -3
  82. package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
  83. package/.next/server/app/api/skills/route.js +3 -3
  84. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  85. package/.next/server/app/api/thursday/call/route.js +9 -7
  86. package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
  87. package/.next/server/app/api/thursday/skills/route.js +9 -7
  88. package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
  89. package/.next/server/app/api/thursday/tool-call/route.js +16 -15
  90. package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
  91. package/.next/server/app/api/workspace/route.js +4 -5
  92. package/.next/server/app/api/workspace/route.js.nft.json +1 -1
  93. package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +1 -1
  94. package/.next/server/app/artifact/[...path]/page.js +5 -6
  95. package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
  96. package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
  97. package/.next/server/app/favicon.ico/route.js +3 -4
  98. package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  99. package/.next/server/app/favicon.ico.body +0 -0
  100. package/.next/server/app/page/server-reference-manifest.json +66 -77
  101. package/.next/server/app/page.js +11 -11
  102. package/.next/server/app/page.js.nft.json +1 -1
  103. package/.next/server/app/page_client-reference-manifest.js +1 -1
  104. package/.next/server/app-paths-manifest.json +5 -1
  105. package/.next/server/chunks/[externals]__0dzuk6_._.js +3 -0
  106. package/.next/server/chunks/[root-of-the-server]__01dkp4a._.js +3 -0
  107. package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +3 -0
  108. package/.next/server/chunks/[root-of-the-server]__02xjoto._.js +3 -0
  109. package/.next/server/chunks/[root-of-the-server]__04q--0f._.js +8 -0
  110. package/.next/server/chunks/[root-of-the-server]__0bl-e63._.js +3 -0
  111. package/.next/server/chunks/[root-of-the-server]__0ce8nf8._.js +5 -0
  112. package/.next/server/chunks/[root-of-the-server]__0ffbg85._.js +3 -0
  113. package/.next/server/chunks/[root-of-the-server]__0j7z0r3._.js +12 -0
  114. package/.next/server/chunks/[root-of-the-server]__0jq4ohy._.js +8 -0
  115. package/.next/server/chunks/[root-of-the-server]__0ls6_8y._.js +8 -0
  116. package/.next/server/chunks/[root-of-the-server]__0ncs9uu._.js +3 -0
  117. package/.next/server/chunks/[root-of-the-server]__0pa2n68._.js +3 -0
  118. package/.next/server/chunks/[root-of-the-server]__0q0vvt2._.js +5 -0
  119. package/.next/server/chunks/[root-of-the-server]__1-ga0kh._.js +5 -0
  120. package/.next/server/chunks/[root-of-the-server]__11n256_._.js +5 -0
  121. package/.next/server/chunks/[root-of-the-server]__12cabg9._.js +3 -0
  122. package/.next/server/chunks/[root-of-the-server]__1339jnv._.js +8 -0
  123. package/.next/server/chunks/[root-of-the-server]__15bjnu5._.js +5 -0
  124. package/.next/server/chunks/[root-of-the-server]__18_teo8._.js +8 -0
  125. package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +5 -0
  126. package/.next/server/chunks/[root-of-the-server]__1anc1p9._.js +3 -0
  127. package/.next/server/chunks/[root-of-the-server]__1ccon1w._.js +10 -0
  128. package/.next/server/chunks/[root-of-the-server]__1fizn31._.js +3 -0
  129. package/.next/server/chunks/[root-of-the-server]__1llj3-b._.js +3 -0
  130. package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +11 -0
  131. package/.next/server/chunks/[root-of-the-server]__1p8m3f4._.js +3 -0
  132. package/.next/server/chunks/[root-of-the-server]__1wa1k7r._.js +8 -0
  133. package/.next/server/chunks/{_1hzrsvg._.js → _0-73of8._.js} +6 -6
  134. package/.next/server/chunks/{_1cbk7ms._.js → _0-fjql4._.js} +10 -10
  135. package/.next/server/chunks/_00xh_q0._.js +27 -0
  136. package/.next/server/chunks/{_0y8is-s._.js → _03a0897._.js} +1 -1
  137. package/.next/server/chunks/{_0pppbb5._.js → _03kp0jp._.js} +166 -35
  138. package/.next/server/chunks/_051qh8u._.js +3 -0
  139. package/.next/server/chunks/{node_modules_next_04q-o58._.js → _05dla15._.js} +2 -2
  140. package/.next/server/chunks/_05h2cii._.js +1 -1
  141. package/.next/server/chunks/_0c9j6rb._.js +49 -0
  142. package/.next/server/chunks/_0fzqt2y._.js +74 -44
  143. package/.next/server/chunks/{_0kl37zl._.js → _0ioz3nd._.js} +1 -1
  144. package/.next/server/chunks/_0iwfby5._.js +3 -0
  145. package/.next/server/chunks/{_0hin38_._.js → _0khihjk._.js} +5 -5
  146. package/.next/server/chunks/_0mecv0f._.js +26 -0
  147. package/.next/server/chunks/_0mh8j4m._.js +3 -0
  148. package/.next/server/chunks/{_1icgbi8._.js → _0n74zsf._.js} +2 -2
  149. package/.next/server/chunks/_0obojvv._.js +3 -0
  150. package/.next/server/chunks/_0recufk._.js +49 -0
  151. package/.next/server/chunks/{_1t8fv7b._.js → _0rnf-6n._.js} +2 -2
  152. package/.next/server/chunks/_0sb7tlz._.js +3 -0
  153. package/.next/server/chunks/{_0jgm3b8._.js → _0u10wmw._.js} +6 -6
  154. package/.next/server/chunks/{_12nr4xc._.js → _0u4aiy2._.js} +2 -2
  155. package/.next/server/chunks/_0wp4le3._.js +1 -1
  156. package/.next/server/chunks/_0y5fg-x._.js +1 -1
  157. package/.next/server/chunks/_1230wbx._.js +10 -0
  158. package/.next/server/chunks/_12nheja._.js +3 -0
  159. package/.next/server/chunks/_13510xh._.js +3 -0
  160. package/.next/server/chunks/_15hq89o._.js +1 -1
  161. package/.next/server/chunks/_17l5ygt._.js +49 -0
  162. package/.next/server/chunks/{_0ks6_sg._.js → _18-1wcc._.js} +6 -6
  163. package/.next/server/chunks/_1_5mnq4._.js +18 -0
  164. package/.next/server/chunks/{_0tzfesa._.js → _1_9mjx-._.js} +1 -1
  165. package/.next/server/chunks/_1d0j961._.js +6 -0
  166. package/.next/server/chunks/_1d5zmy8._.js +1 -1
  167. package/.next/server/chunks/_1drgfx4._.js +18 -0
  168. package/.next/server/chunks/{_1skgy7b._.js → _1e48czp._.js} +5 -5
  169. package/.next/server/chunks/_1f46eie._.js +3 -0
  170. package/.next/server/chunks/_1h5_8sk._.js +3 -0
  171. package/.next/server/chunks/_1hdnxb7._.js +3 -0
  172. package/.next/server/chunks/_1j8k_j5._.js +3 -0
  173. package/.next/server/chunks/{_10qam6o._.js → _1kg70wc._.js} +5 -5
  174. package/.next/server/chunks/_1krd9rf._.js +3 -0
  175. package/.next/server/chunks/_1nc0eui._.js +11 -0
  176. package/.next/server/chunks/_1nula3v._.js +3 -0
  177. package/.next/server/chunks/_1pf4qe-._.js +3 -0
  178. package/.next/server/chunks/_1php4eq._.js +1 -1
  179. package/.next/server/chunks/_1qxheoa._.js +3 -0
  180. package/.next/server/chunks/_1x6kd1r._.js +3 -0
  181. package/.next/server/chunks/_1yuv4vp._.js +1 -1
  182. package/.next/server/chunks/_1zjrdag._.js +3 -0
  183. package/.next/server/chunks/_next-internal_server_app_api_bot_memory_files_route_actions_1_xd_8f.js +3 -0
  184. package/.next/server/chunks/_next-internal_server_app_api_bot_memory_route_actions_1a8xfr7.js +3 -0
  185. package/.next/server/chunks/_next-internal_server_app_api_llm-model_credits_route_actions_0v424pb.js +3 -0
  186. package/.next/server/chunks/_next-internal_server_app_api_llm-model_subscription_route_actions_0-udcm5.js +3 -0
  187. package/.next/server/chunks/_next-internal_server_app_api_memory_edit_route_actions_02sfnmr.js +3 -0
  188. package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
  189. package/.next/server/chunks/features_0rpfxbk._.js +3 -0
  190. package/.next/server/chunks/features_1qf3cei._.js +3 -0
  191. package/.next/server/chunks/features_bot_0zt92oh._.js +3 -0
  192. package/.next/server/chunks/features_bot_bot_query_ts_12mgkl2._.js +1 -1
  193. package/.next/server/chunks/features_memory_1uqvksn._.js +6 -0
  194. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0tf290y._.js → node_modules_consola_dist_chunks_prompt_mjs_0i7cvml._.js} +1 -1
  195. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0228f43._.js → node_modules_consola_dist_chunks_prompt_mjs_0icqaqw._.js} +1 -1
  196. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0ir-vo2._.js → node_modules_consola_dist_chunks_prompt_mjs_0j61-ma._.js} +1 -1
  197. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0otw8ef._.js → node_modules_consola_dist_chunks_prompt_mjs_0r28-sm._.js} +1 -1
  198. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0v_7drq._.js +3 -0
  199. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_11zjo-1._.js +3 -0
  200. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1pycqsq._.js +3 -0
  201. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1xoq2rl._.js +3 -0
  202. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1y49572._.js +3 -0
  203. package/.next/server/chunks/ssr/[externals]__0dizgek._.js +3 -0
  204. package/.next/server/chunks/ssr/[root-of-the-server]__09q9med._.js +1 -1
  205. package/.next/server/chunks/ssr/[root-of-the-server]__0_69wqr._.js +3 -0
  206. package/.next/server/chunks/ssr/[root-of-the-server]__0hg5gib._.js +1 -1
  207. package/.next/server/chunks/ssr/[root-of-the-server]__0i8ie7f._.js +3 -0
  208. package/.next/server/chunks/ssr/{[root-of-the-server]__0jsmmb-._.js → [root-of-the-server]__0mz33a7._.js} +1 -1
  209. package/.next/server/chunks/ssr/[root-of-the-server]__0tbkdlx._.js +3 -0
  210. package/.next/server/chunks/ssr/[root-of-the-server]__0vnmv-s._.js +3 -0
  211. package/.next/server/chunks/ssr/{[root-of-the-server]__0f6s48x._.js → [root-of-the-server]__0xpcv9w._.js} +3 -3
  212. package/.next/server/chunks/ssr/[root-of-the-server]__0xtssj3._.js +1 -1
  213. package/.next/server/chunks/ssr/[root-of-the-server]__0zkv7z_._.js +3 -0
  214. package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +57 -0
  215. package/.next/server/chunks/ssr/[root-of-the-server]__15_uhip._.js +3 -0
  216. package/.next/server/chunks/ssr/[root-of-the-server]__16jc196._.js +1 -1
  217. package/.next/server/chunks/ssr/[root-of-the-server]__1cyjywu._.js +3 -0
  218. package/.next/server/chunks/ssr/[root-of-the-server]__1eh7hid._.js +3 -0
  219. package/.next/server/chunks/ssr/[root-of-the-server]__1gtlw6v._.js +43 -0
  220. package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
  221. package/.next/server/chunks/ssr/[root-of-the-server]__1ox7hbk._.js +4 -0
  222. package/.next/server/chunks/ssr/[root-of-the-server]__1pduf5n._.js +3 -0
  223. package/.next/server/chunks/ssr/{_1mznrxk._.js → _001_ms1._.js} +3 -3
  224. package/.next/server/chunks/ssr/_01_6m32._.js +3 -0
  225. package/.next/server/chunks/ssr/_01n3o0m._.js +3 -0
  226. package/.next/server/chunks/ssr/_07uchnc._.js +3 -0
  227. package/.next/server/chunks/ssr/_0ap2fzn._.js +3 -0
  228. package/.next/server/chunks/ssr/_0c-ql2m._.js +3 -0
  229. package/.next/server/chunks/ssr/_0h42fze._.js +3 -0
  230. package/.next/server/chunks/ssr/_0h7zdni._.js +1 -1
  231. package/.next/server/chunks/ssr/_0i_6q1w._.js +41 -0
  232. package/.next/server/chunks/ssr/_0kbkmar._.js +3 -0
  233. package/.next/server/chunks/ssr/_0lu1n_x._.js +3 -0
  234. package/.next/server/chunks/ssr/{_077-g6s._.js → _0mb8zc8._.js} +3 -3
  235. package/.next/server/chunks/ssr/_0mo2w06._.js +3 -0
  236. package/.next/server/chunks/ssr/{_13punpm._.js → _0q0zan6._.js} +2 -2
  237. package/.next/server/chunks/ssr/{_0gd4vaa._.js → _0u2jv_x._.js} +94 -58
  238. package/.next/server/chunks/ssr/_0y0tiht._.js +4 -0
  239. package/.next/server/chunks/ssr/_0zhoc3r._.js +3 -0
  240. package/.next/server/chunks/ssr/_1-teee5._.js +3 -3
  241. package/.next/server/chunks/ssr/_13fke0x._.js +3 -0
  242. package/.next/server/chunks/ssr/{_0q_2f2x._.js → _13z3f85._.js} +2 -2
  243. package/.next/server/chunks/ssr/_14_lw10._.js +3 -0
  244. package/.next/server/chunks/ssr/_15j2_8f._.js +3 -0
  245. package/.next/server/chunks/ssr/{_0lc_7c8._.js → _1eoqg_g._.js} +2 -2
  246. package/.next/server/chunks/ssr/_1sji22n._.js +3 -0
  247. package/.next/server/chunks/ssr/_1spzm8z._.js +3 -0
  248. package/.next/server/chunks/ssr/{_19_o9d-._.js → _1vi_uo7._.js} +2 -2
  249. package/.next/server/chunks/ssr/_1vyd1ji._.js +3 -0
  250. package/.next/server/chunks/ssr/_1xvgn77._.js +3 -0
  251. package/.next/server/chunks/ssr/_20kd_n0._.js +42 -0
  252. package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +3 -0
  253. package/.next/server/chunks/ssr/features_config_components_config-setting_tsx_0xfwqdg._.js +1 -1
  254. package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
  255. package/.next/server/chunks/ssr/lib_date-like_ts_02is0pw._.js +3 -0
  256. package/.next/server/chunks/ssr/lib_realtime_12wg_dd._.js +27 -0
  257. package/.next/server/chunks/ssr/lib_realtime_15h_v1v._.js +27 -0
  258. package/.next/server/chunks/ssr/{node_modules_1d-is1o._.js → node_modules_063xwpp._.js} +1 -1
  259. package/.next/server/chunks/ssr/{node_modules_1ub40gk._.js → node_modules_0bvraul._.js} +1 -1
  260. package/.next/server/chunks/ssr/{node_modules_1nhw9qg._.js → node_modules_0eu1va6._.js} +1 -1
  261. package/.next/server/chunks/ssr/{node_modules_0xwx4u-._.js → node_modules_0h50b8n._.js} +1 -1
  262. package/.next/server/chunks/ssr/{node_modules_043-236._.js → node_modules_0h5hnr1._.js} +1 -1
  263. package/.next/server/chunks/ssr/{node_modules_1t0y5jt._.js → node_modules_0h7u60n._.js} +1 -1
  264. package/.next/server/chunks/ssr/{node_modules_1k29j1j._.js → node_modules_0lm7_vm._.js} +1 -1
  265. package/.next/server/chunks/ssr/{node_modules_16i4o_3._.js → node_modules_0mwym0g._.js} +1 -1
  266. package/.next/server/chunks/ssr/{node_modules_1y8_3vg._.js → node_modules_0rjg6t1._.js} +1 -1
  267. package/.next/server/chunks/ssr/node_modules_0x3-ply._.js +3 -0
  268. package/.next/server/chunks/ssr/{node_modules_108wd2o._.js → node_modules_0y_cded._.js} +1 -1
  269. package/.next/server/chunks/ssr/{node_modules_1jatz7w._.js → node_modules_0z5tsu8._.js} +1 -1
  270. package/.next/server/chunks/ssr/{node_modules_0ls96je._.js → node_modules_0zp9r92._.js} +1 -1
  271. package/.next/server/chunks/ssr/{node_modules_06kvvuo._.js → node_modules_1-hc6uv._.js} +1 -1
  272. package/.next/server/chunks/ssr/{node_modules_1_588_4._.js → node_modules_113tz0l._.js} +1 -1
  273. package/.next/server/chunks/ssr/{node_modules_0ipn1ho._.js → node_modules_124bue5._.js} +1 -1
  274. package/.next/server/chunks/ssr/node_modules_17bwo43._.js +55 -0
  275. package/.next/server/chunks/ssr/{node_modules_0_j7-g4._.js → node_modules_1_n3ztw._.js} +1 -1
  276. package/.next/server/chunks/ssr/{node_modules_20ynonm._.js → node_modules_1bc7gu8._.js} +1 -1
  277. package/.next/server/chunks/ssr/{node_modules_1hn_sd5._.js → node_modules_1bgb6-f._.js} +1 -1
  278. package/.next/server/chunks/ssr/{node_modules_0bue6gy._.js → node_modules_1h4a4pp._.js} +1 -1
  279. package/.next/server/chunks/ssr/{node_modules_0fbw5-u._.js → node_modules_1i7u1ia._.js} +1 -1
  280. package/.next/server/chunks/ssr/{node_modules_1ee8gav._.js → node_modules_1juq3hs._.js} +1 -1
  281. package/.next/server/chunks/ssr/{node_modules_0_fvxnt._.js → node_modules_1l0qtdu._.js} +1 -1
  282. package/.next/server/chunks/ssr/{node_modules_13f2md6._.js → node_modules_1t9cyee._.js} +1 -1
  283. package/.next/server/chunks/ssr/{node_modules_0y2-av4._.js → node_modules_1uuj9x1._.js} +1 -1
  284. package/.next/server/chunks/ssr/{node_modules_00d6675._.js → node_modules_1vqb6po._.js} +1 -1
  285. package/.next/server/chunks/ssr/{node_modules_1v0077l._.js → node_modules_1xx28h1._.js} +1 -1
  286. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_092s8nx._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0d3skpl._.js} +1 -1
  287. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1nvexgu._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0i44kk5._.js} +1 -1
  288. package/.next/server/chunks/ssr/node_modules_@vercel_oidc_dist_0qe30a_._.js +3 -0
  289. package/.next/server/chunks/ssr/node_modules_consola_dist_chunks_prompt_mjs_05cwqv2._.js +47 -0
  290. package/.next/server/chunks/ssr/{node_modules_next_dist_0w6mzq5._.js → node_modules_next_dist_0drixxt._.js} +4 -4
  291. package/.next/server/chunks/ssr/node_modules_next_dist_1n3w9lb._.js +2 -2
  292. package/.next/server/instrumentation.js +1 -1
  293. package/.next/server/middleware-build-manifest.js +3 -3
  294. package/.next/server/pages/404.html +1 -1
  295. package/.next/server/pages/500.html +1 -1
  296. package/.next/server/server-reference-manifest.js +1 -1
  297. package/.next/server/server-reference-manifest.json +67 -78
  298. package/.next/static/chunks/{31ttnjt6g35a0.js → 0ev4hyghq0mbb.js} +1 -1
  299. package/.next/static/chunks/0r5qcctujhxli.js +1 -0
  300. package/.next/static/chunks/0tmgrnlje14-s.js +3 -0
  301. package/.next/static/chunks/0x79tx04dxbpp.js +1 -0
  302. package/.next/static/chunks/0xzgvc0fkdb6t.js +1 -0
  303. package/.next/static/chunks/10teww7wt-f6h.js +1 -0
  304. package/.next/static/chunks/14hgtsjg-kael.css +1 -0
  305. package/.next/static/chunks/17donp69y4do7.js +40 -0
  306. package/.next/static/chunks/1dkjg87pxk0n9.js +28 -0
  307. package/.next/static/chunks/1ekc7ul556kbl.js +1 -0
  308. package/.next/static/chunks/{1khakdu_iuedc.js → 1grhjo7a5a0_-.js} +1 -1
  309. package/.next/static/chunks/1kq8h8wi_e0bc.js +53 -0
  310. package/.next/static/chunks/1okqiww3pnwka.js +1 -0
  311. package/.next/static/chunks/26-pr2c9ro222.js +1 -0
  312. package/.next/static/chunks/{2ihkf6l2jowo9.js → 280t0_e99i276.js} +3 -3
  313. package/.next/static/chunks/28cizcdaabd4h.js +1 -0
  314. package/.next/static/chunks/2a0k6jlq0_v1u.js +2 -0
  315. package/.next/static/chunks/2fzs9fm8yarvq.js +1 -0
  316. package/.next/static/chunks/2h0sd2vumhb15.js +1 -0
  317. package/.next/static/chunks/2hw2f6zmt7fmt.js +1 -0
  318. package/.next/static/chunks/2t4vhi3m8ahya.js +1 -0
  319. package/.next/static/chunks/2tigdtz3dpcy8.js +1 -0
  320. package/.next/static/chunks/3111pj5wnjgos.js +1 -0
  321. package/.next/static/chunks/3786h5vayt80-.js +28 -0
  322. package/.next/static/chunks/{3aquirz5h71da.js → 3agpgkwaa321p.js} +1 -1
  323. package/.next/static/chunks/3cfi_q6d_wtci.js +1 -0
  324. package/.next/static/chunks/3ok9_x74rip3v.js +1 -0
  325. package/.next/static/chunks/3xk7yqgomx7yq.js +1 -0
  326. package/.next/static/chunks/3xpbkl66ssib5.js +38 -0
  327. package/.next/static/media/favicon.37o1pjldwi2uc.ico +0 -0
  328. package/README.md +6 -4
  329. package/app/api/bot/memory/files/route.ts +14 -0
  330. package/app/api/bot/memory/route.ts +5 -0
  331. package/app/api/events/app-event.client.ts +24 -0
  332. package/app/api/events/app-event.server.ts +45 -0
  333. package/app/api/events/app-event.ts +42 -0
  334. package/app/api/llm-model/catalog/route.ts +12 -0
  335. package/app/api/llm-model/credits/route.ts +11 -0
  336. package/app/api/llm-model/route.ts +26 -0
  337. package/app/api/llm-model/subscription/route.ts +11 -0
  338. package/app/api/memory/edit/route.ts +7 -0
  339. package/app/api/memory/route.ts +21 -0
  340. package/app/api/query-key.ts +159 -0
  341. package/app/api/thursday/tool-call/route.ts +67 -0
  342. package/bin/thursday.mjs +3 -0
  343. package/components/ui/button-group.tsx +45 -0
  344. package/components/ui/custom-icon.tsx +259 -0
  345. package/components/ui/dropdown-menu.tsx +271 -0
  346. package/components/ui/folded-text.tsx +68 -0
  347. package/components/ui/input-group.tsx +157 -0
  348. package/components/ui/json-view.tsx +240 -0
  349. package/components/ui/shiny-text.tsx +55 -0
  350. package/components/ui/text-type.tsx +213 -0
  351. package/components/ui/theme-sync.tsx +9 -0
  352. package/database/migrations/{20260908030742_rainy_marvel_zombies → 20260910173049_numerous_spirit}/migration.sql +30 -33
  353. package/database/migrations/{20260908030742_rainy_marvel_zombies → 20260910173049_numerous_spirit}/snapshot.json +124 -145
  354. package/database/migrations/20260911030320_opposite_jack_power/migration.sql +1 -0
  355. package/database/migrations/20260911030320_opposite_jack_power/snapshot.json +1158 -0
  356. package/docs/how-it-works.md +59 -0
  357. package/docs/images/keeps-going.png +0 -0
  358. package/docs/images/task-thread.png +0 -0
  359. package/docs/images/two-minds.png +0 -0
  360. package/features/ai/chatgpt.ts +617 -0
  361. package/features/ai/components/chatgpt-sign-in.tsx +66 -0
  362. package/features/ai/components/model-picker.tsx +17 -1
  363. package/features/ai/components/provider-icon.tsx +1 -0
  364. package/features/ai/load-tools.ts +105 -39
  365. package/features/ai/model.schema.ts +232 -34
  366. package/features/ai/model.ts +169 -24
  367. package/features/ai/prompts/bot.prompt.ts +245 -59
  368. package/features/ai/prompts/memory-edit.prompt.ts +33 -0
  369. package/features/ai/prompts/prompt-helper.ts +75 -30
  370. package/features/ai/prompts/thursday.prompt.ts +42 -17
  371. package/features/ai/tools/bot.tool.ts +32 -30
  372. package/features/ai/tools/connected.ts +17 -4
  373. package/features/ai/tools/mcp.tool.ts +5 -5
  374. package/features/ai/tools/memory.tool.ts +142 -74
  375. package/features/ai/tools/search.tool.ts +136 -47
  376. package/features/ai/tools/studio.tool.ts +5 -5
  377. package/features/ai/tools/tool-name.ts +2 -3
  378. package/features/ai/tools/workspace.tool.ts +33 -4
  379. package/features/bot/bot.action.ts +24 -7
  380. package/features/bot/bot.memory.ts +89 -0
  381. package/features/bot/bot.query.ts +41 -6
  382. package/features/bot/bot.run.ts +516 -210
  383. package/features/bot/bot.runner.ts +463 -93
  384. package/features/bot/bot.schema.ts +84 -7
  385. package/features/bot/bot.seed.ts +89 -16
  386. package/features/bot/components/bot-mark.tsx +122 -20
  387. package/features/bot/components/bot-room.tsx +519 -391
  388. package/features/bot/components/bot-setting.tsx +832 -341
  389. package/features/bot/components/bot-tool.tsx +2 -6
  390. package/features/bot/components/mark-palette.tsx +54 -0
  391. package/features/bot/components/path-chips.tsx +1 -1
  392. package/features/bot/components/task-badge.tsx +26 -6
  393. package/features/bot/components/task-reply.tsx +22 -33
  394. package/features/bot/components/task-setting.tsx +20 -17
  395. package/features/bot/task.query.ts +233 -33
  396. package/features/bot/task.store.ts +53 -9
  397. package/features/config/components/config-setting.tsx +265 -34
  398. package/features/config/components/models-badge.tsx +42 -0
  399. package/features/config/config.action.ts +12 -0
  400. package/features/config/config.const.ts +38 -2
  401. package/features/connectors/mcp.manager.ts +10 -2
  402. package/features/intro/components/intro.tsx +47 -46
  403. package/features/memory/components/memory-edit.tsx +338 -0
  404. package/features/memory/components/memory-setting.tsx +86 -79
  405. package/features/memory/memory.action.ts +3 -43
  406. package/features/memory/memory.edit.ts +87 -0
  407. package/features/memory/memory.query.ts +33 -44
  408. package/features/memory/memory.schema.ts +50 -97
  409. package/features/settings/components/settings.tsx +2 -0
  410. package/features/settings/settings.alert.ts +3 -1
  411. package/features/skills/components/skills-setting.tsx +9 -1
  412. package/features/thursday/components/ascii-orb.tsx +106 -90
  413. package/features/thursday/components/boot.tsx +7 -0
  414. package/features/thursday/components/call-log.tsx +219 -92
  415. package/features/thursday/components/face.tsx +6 -4
  416. package/features/thursday/components/tab-state.tsx +97 -0
  417. package/features/thursday/components/thursday-mark.tsx +4 -1
  418. package/features/thursday/components/thursday-setting.tsx +17 -47
  419. package/features/thursday/components/thursday.tsx +208 -95
  420. package/features/thursday/thursday.action.ts +12 -17
  421. package/features/thursday/thursday.query.ts +61 -70
  422. package/features/thursday/thursday.schema.ts +20 -7
  423. package/features/thursday/tool-line.ts +85 -11
  424. package/features/thursday/use-thursday.ts +86 -59
  425. package/features/workspace/components/file-view.tsx +4 -2
  426. package/features/workspace/workspace.ts +230 -13
  427. package/hooks/use-draft.ts +37 -0
  428. package/hooks/use-hotkey.ts +105 -0
  429. package/hooks/use-object-state.ts +51 -0
  430. package/hooks/use-on-visible.ts +72 -0
  431. package/hooks/use-theme.ts +106 -0
  432. package/hooks/use-wake-word.ts +262 -0
  433. package/lib/limits.ts +1 -1
  434. package/lib/oauth-page.ts +27 -0
  435. package/lib/realtime/openai.ts +2 -2
  436. package/lib/realtime/realtime.driver.ts +34 -1
  437. package/lib/realtime/realtime.protocol.ts +7 -1
  438. package/lib/realtime/realtime.tap.ts +122 -0
  439. package/lib/sandbox.ts +60 -29
  440. package/lib/tokens.ts +19 -0
  441. package/package.json +1 -1
  442. package/skills/browser/SKILL.md +55 -34
  443. package/.next/server/app/api/memory/tidy/route/app-paths-manifest.json +0 -3
  444. package/.next/server/app/api/memory/tidy/route.js +0 -23
  445. package/.next/server/app/api/memory/tidy/route.js.nft.json +0 -1
  446. package/.next/server/chunks/[root-of-the-server]__019dx9f._.js +0 -5
  447. package/.next/server/chunks/[root-of-the-server]__02_2sm-._.js +0 -5
  448. package/.next/server/chunks/[root-of-the-server]__02kt8yn._.js +0 -10
  449. package/.next/server/chunks/[root-of-the-server]__05luceg._.js +0 -3
  450. package/.next/server/chunks/[root-of-the-server]__06t77t4._.js +0 -11
  451. package/.next/server/chunks/[root-of-the-server]__0bed6hu._.js +0 -8
  452. package/.next/server/chunks/[root-of-the-server]__0dupqt7._.js +0 -5
  453. package/.next/server/chunks/[root-of-the-server]__0h59di-._.js +0 -5
  454. package/.next/server/chunks/[root-of-the-server]__0j_n5l3._.js +0 -3
  455. package/.next/server/chunks/[root-of-the-server]__0le4d-p._.js +0 -3
  456. package/.next/server/chunks/[root-of-the-server]__0m8ywyo._.js +0 -10
  457. package/.next/server/chunks/[root-of-the-server]__0nfuugi._.js +0 -5
  458. package/.next/server/chunks/[root-of-the-server]__0phdgco._.js +0 -8
  459. package/.next/server/chunks/[root-of-the-server]__0qjqtwo._.js +0 -5
  460. package/.next/server/chunks/[root-of-the-server]__0t_dqaj._.js +0 -3
  461. package/.next/server/chunks/[root-of-the-server]__0wvgrsl._.js +0 -3
  462. package/.next/server/chunks/[root-of-the-server]__0yk6s3w._.js +0 -5
  463. package/.next/server/chunks/[root-of-the-server]__0z3gelv._.js +0 -3
  464. package/.next/server/chunks/[root-of-the-server]__10qshki._.js +0 -3
  465. package/.next/server/chunks/[root-of-the-server]__113fqg5._.js +0 -12
  466. package/.next/server/chunks/[root-of-the-server]__11w_7_3._.js +0 -3
  467. package/.next/server/chunks/[root-of-the-server]__16thabu._.js +0 -3
  468. package/.next/server/chunks/[root-of-the-server]__173nhwf._.js +0 -8
  469. package/.next/server/chunks/[root-of-the-server]__1_0q_9w._.js +0 -3
  470. package/.next/server/chunks/[root-of-the-server]__1_aoyr9._.js +0 -3
  471. package/.next/server/chunks/[root-of-the-server]__1bqhuh9._.js +0 -8
  472. package/.next/server/chunks/[root-of-the-server]__1cqizfq._.js +0 -5
  473. package/.next/server/chunks/[root-of-the-server]__1dow0bz._.js +0 -3
  474. package/.next/server/chunks/[root-of-the-server]__1e-ci13._.js +0 -3
  475. package/.next/server/chunks/[root-of-the-server]__1gmn1cs._.js +0 -10
  476. package/.next/server/chunks/[root-of-the-server]__1lr7j9t._.js +0 -5
  477. package/.next/server/chunks/[root-of-the-server]__1mzp_el._.js +0 -3
  478. package/.next/server/chunks/[root-of-the-server]__1txedx6._.js +0 -8
  479. package/.next/server/chunks/[root-of-the-server]__1u_qvc7._.js +0 -3
  480. package/.next/server/chunks/[root-of-the-server]__1zgpz1w._.js +0 -3
  481. package/.next/server/chunks/_012yhfm._.js +0 -39
  482. package/.next/server/chunks/_06mxlgn._.js +0 -3
  483. package/.next/server/chunks/_07rtlxv._.js +0 -3
  484. package/.next/server/chunks/_0a351g7._.js +0 -6
  485. package/.next/server/chunks/_0kjjmag._.js +0 -3
  486. package/.next/server/chunks/_0zmestz._.js +0 -55
  487. package/.next/server/chunks/_0zuzmt_._.js +0 -39
  488. package/.next/server/chunks/_12bbv5i._.js +0 -96
  489. package/.next/server/chunks/_15q1pig._.js +0 -3
  490. package/.next/server/chunks/_1drv2et._.js +0 -36
  491. package/.next/server/chunks/_1ic3bew._.js +0 -5
  492. package/.next/server/chunks/_1mxn_lb._.js +0 -3
  493. package/.next/server/chunks/_1uj4_io._.js +0 -10
  494. package/.next/server/chunks/_1x7p319._.js +0 -6
  495. package/.next/server/chunks/_1yldgo4._.js +0 -55
  496. package/.next/server/chunks/_2050gwn._.js +0 -255
  497. package/.next/server/chunks/_next-internal_server_app_api_memory_tidy_route_actions_0_cfuom.js +0 -3
  498. package/.next/server/chunks/features_0scmr4i._.js +0 -3
  499. package/.next/server/chunks/features_bot_task_query_ts_11xuzl3._.js +0 -3
  500. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0vorg6w._.js +0 -3
  501. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0ykklj0._.js +0 -3
  502. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1ryg3wh._.js +0 -3
  503. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1vmaq9f._.js +0 -3
  504. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1vwbnq_._.js +0 -3
  505. package/.next/server/chunks/ssr/[externals]_node_crypto_1kn79-7._.js +0 -3
  506. package/.next/server/chunks/ssr/[root-of-the-server]__01id-v3._.js +0 -3
  507. package/.next/server/chunks/ssr/[root-of-the-server]__0b-0i32._.js +0 -3
  508. package/.next/server/chunks/ssr/[root-of-the-server]__0dfwvr4._.js +0 -4
  509. package/.next/server/chunks/ssr/[root-of-the-server]__0iuoa-r._.js +0 -3
  510. package/.next/server/chunks/ssr/[root-of-the-server]__1-mnhyd._.js +0 -90
  511. package/.next/server/chunks/ssr/[root-of-the-server]__185grso._.js +0 -3
  512. package/.next/server/chunks/ssr/[root-of-the-server]__1minz8_._.js +0 -3
  513. package/.next/server/chunks/ssr/_0-mc7ro._.js +0 -3
  514. package/.next/server/chunks/ssr/_01p5r6-._.js +0 -3
  515. package/.next/server/chunks/ssr/_09-0k3z._.js +0 -3
  516. package/.next/server/chunks/ssr/_0ay6b01._.js +0 -3
  517. package/.next/server/chunks/ssr/_0cvjbuz._.js +0 -3
  518. package/.next/server/chunks/ssr/_0fafgvl._.js +0 -3
  519. package/.next/server/chunks/ssr/_0j4v8of._.js +0 -3
  520. package/.next/server/chunks/ssr/_0l81bzy._.js +0 -3
  521. package/.next/server/chunks/ssr/_0nso8tp._.js +0 -3
  522. package/.next/server/chunks/ssr/_0sf1isi._.js +0 -3
  523. package/.next/server/chunks/ssr/_0ti51xc._.js +0 -3
  524. package/.next/server/chunks/ssr/_0y84qo6._.js +0 -3
  525. package/.next/server/chunks/ssr/_10uvw3l._.js +0 -3
  526. package/.next/server/chunks/ssr/_1dcxzqe._.js +0 -3
  527. package/.next/server/chunks/ssr/_1e-dgz0._.js +0 -4
  528. package/.next/server/chunks/ssr/_1fq7zgb._.js +0 -3
  529. package/.next/server/chunks/ssr/_1jbv7m1._.js +0 -3
  530. package/.next/server/chunks/ssr/features_bot_components_bot-setting_tsx_01ajft6._.js +0 -4
  531. package/.next/server/chunks/ssr/features_config_components_14jqgy4._.js +0 -3
  532. package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +0 -4
  533. package/.next/server/chunks/ssr/lib_realtime_0aetuyp._.js +0 -24
  534. package/.next/server/chunks/ssr/lib_realtime_18k_aj-._.js +0 -24
  535. package/.next/server/chunks/ssr/node_modules_zod_v4_classic_errors_05xv7vp.js +0 -3
  536. package/.next/server/chunks/ssr/node_modules_zod_v4_classic_external_15fmmz3.js +0 -55
  537. package/.next/static/chunks/0f9sq-7q_yxyl.js +0 -1
  538. package/.next/static/chunks/0tydnn2kybibk.js +0 -1
  539. package/.next/static/chunks/0yysv1gzin17t.js +0 -1
  540. package/.next/static/chunks/1fr5m75pwtyic.js +0 -1
  541. package/.next/static/chunks/1gy3bbv7usnjo.js +0 -1
  542. package/.next/static/chunks/1keib_gt066gc.js +0 -1
  543. package/.next/static/chunks/1ytnip8wdng93.js +0 -1
  544. package/.next/static/chunks/21rk8w7bda-su.js +0 -1
  545. package/.next/static/chunks/247d-r95j8xs0.js +0 -1
  546. package/.next/static/chunks/28g42tw8tsvhd.js +0 -1
  547. package/.next/static/chunks/29gyb3nubj51j.js +0 -53
  548. package/.next/static/chunks/2cwjgkt_hoyhj.js +0 -22
  549. package/.next/static/chunks/2fq_86jvq9ymq.js +0 -2
  550. package/.next/static/chunks/2rbf1fpd8n80-.js +0 -22
  551. package/.next/static/chunks/2ukj8k69y89um.js +0 -1
  552. package/.next/static/chunks/2uxum7qbyeyxd.js +0 -1
  553. package/.next/static/chunks/2wngeetfnzxkp.js +0 -2
  554. package/.next/static/chunks/388-t2v72jh39.css +0 -1
  555. package/.next/static/chunks/3fqvc0cg-atq_.js +0 -1
  556. package/.next/static/chunks/3p4egvfjxpatb.js +0 -1
  557. package/.next/static/chunks/3qe1w1ei-huhl.js +0 -1
  558. package/.next/static/chunks/3xxa2j56-f3nm.js +0 -3
  559. package/.next/static/chunks/3y40riycdip-i.js +0 -1
  560. package/.next/static/chunks/45a6zbtkelph9.js +0 -1
  561. package/.next/static/media/favicon.2vob68tjqpejf.ico +0 -0
  562. package/features/ai/prompts/memory-tidy.prompt.ts +0 -123
  563. package/features/ai/tools/tidy.tool.ts +0 -22
  564. package/features/memory/components/memory-tidy.tsx +0 -395
  565. package/features/memory/memory.tidy.ts +0 -332
  566. package/features/memory/tidy.query.ts +0 -135
  567. package/features/thursday/use-call-title.ts +0 -31
  568. /package/.next/server/app/api/{memory/tidy → bot/memory/files}/route/build-manifest.json +0 -0
  569. /package/.next/server/app/api/{memory/tidy → bot/memory/files}/route/server-reference-manifest.json +0 -0
  570. /package/.next/server/app/api/{memory/tidy → bot/memory/files}/route.js.map +0 -0
  571. /package/.next/static/{X34BUd9bfdH27ripuwwBm → x1cCqY0kWpR_VcYx_lWO5}/_buildManifest.js +0 -0
  572. /package/.next/static/{X34BUd9bfdH27ripuwwBm → x1cCqY0kWpR_VcYx_lWO5}/_clientMiddlewareManifest.js +0 -0
  573. /package/.next/static/{X34BUd9bfdH27ripuwwBm → x1cCqY0kWpR_VcYx_lWO5}/_ssgManifest.js +0 -0
@@ -7,12 +7,14 @@ import {
7
7
  isNotNull,
8
8
  isNull,
9
9
  lt,
10
+ sql,
10
11
  } from "drizzle-orm";
12
+ import { CALL_HISTORY_PAGE } from "@/config";
11
13
  import { database } from "@/database/db";
12
14
  import { callMessageTable, callTable } from "@/database/tables";
15
+ import { listCallJobs } from "@/features/bot/task.query";
13
16
  import { readConfig, writeConfig } from "@/features/config/config.query";
14
17
  import {
15
- CALL_HISTORY_PAGE,
16
18
  type CallRecord,
17
19
  type CallTurn,
18
20
  isSkillsOn,
@@ -139,6 +141,52 @@ export async function listCallTurns(
139
141
  .map((row) => ({ role: row.role as "user" | "assistant", text: row.text }));
140
142
  }
141
143
 
144
+ /**
145
+ * One page of a call, every turn in order, tool turns included; null when the
146
+ * call is gone. Tool turns keep their name and nothing else is read by the
147
+ * caller (ai/tools/memory.tool), but the row carries it all.
148
+ */
149
+ export async function readCallConversation(
150
+ callId: string,
151
+ page: number,
152
+ size: number,
153
+ ): Promise<{
154
+ startedAt: Date;
155
+ total: number;
156
+ turns: {
157
+ role: "user" | "assistant" | "tool";
158
+ tool: string | null;
159
+ text: string;
160
+ }[];
161
+ } | null> {
162
+ const [call] = await database
163
+ .select({ startedAt: callTable.startedAt })
164
+ .from(callTable)
165
+ .where(eq(callTable.id, callId));
166
+ if (!call) return null;
167
+
168
+ const [counted] = await database
169
+ .select({ total: sql<number>`count(*)` })
170
+ .from(callMessageTable)
171
+ .where(eq(callMessageTable.callId, callId));
172
+ const turns = await database
173
+ .select({
174
+ role: callMessageTable.role,
175
+ tool: callMessageTable.tool,
176
+ text: callMessageTable.text,
177
+ })
178
+ .from(callMessageTable)
179
+ .where(eq(callMessageTable.callId, callId))
180
+ .orderBy(asc(callMessageTable.seq))
181
+ .limit(size)
182
+ .offset((page - 1) * size);
183
+ return {
184
+ startedAt: call.startedAt,
185
+ total: Number(counted?.total ?? 0),
186
+ turns,
187
+ };
188
+ }
189
+
142
190
  /**
143
191
  * Whether any call is open, not whether a given job's call is. A tab that
144
192
  * vanished leaves its row open, so boot runs `sweepCalls` first.
@@ -231,81 +279,24 @@ export async function listCallHistory(options: {
231
279
  else turns.set(callId, [turn]);
232
280
  }
233
281
 
282
+ // A job belongs to the call that opened it, and this is how the log still says
283
+ // what became of it once the call is over.
284
+ const jobs = await listCallJobs(calls.map((call) => call.id));
285
+
234
286
  return calls.map((call) => ({
235
287
  ...call,
236
288
  turns: turns.get(call.id) ?? [],
289
+ jobs: jobs
290
+ .filter((job) => job.callId === call.id)
291
+ .map((job) => ({
292
+ id: job.id,
293
+ label: job.label,
294
+ status: job.status,
295
+ outcome: job.outcome,
296
+ })),
237
297
  }));
238
298
  }
239
299
 
240
- // What reading calls back needs (features/memory/memory.tidy): the turns owed,
241
- // and the stamp that says they have been read.
242
-
243
- /** One spoken turn owed to a read-back, with the call it came from. */
244
- export type OwedTurn = {
245
- callId: string;
246
- startedAt: Date;
247
- role: "user" | "assistant";
248
- text: string;
249
- };
250
-
251
- /**
252
- * Every spoken turn of ended calls not read back yet, oldest first. Tool turns
253
- * are left out: they carry arguments, not anything said. A call with no user
254
- * turn still counts nothing towards a read but is stamped with the rest.
255
- */
256
- export async function listOwedTurns(): Promise<OwedTurn[]> {
257
- const rows = await database
258
- .select({
259
- callId: callTable.id,
260
- startedAt: callTable.startedAt,
261
- role: callMessageTable.role,
262
- text: callMessageTable.text,
263
- })
264
- .from(callTable)
265
- .innerJoin(callMessageTable, eq(callMessageTable.callId, callTable.id))
266
- .where(
267
- and(
268
- isNotNull(callTable.endedAt),
269
- isNull(callTable.tidiedAt),
270
- inArray(callMessageTable.role, ["user", "assistant"]),
271
- ),
272
- )
273
- .orderBy(asc(callTable.startedAt), asc(callMessageTable.seq));
274
-
275
- return rows.map((row) => ({
276
- callId: row.callId,
277
- startedAt: row.startedAt,
278
- role: row.role as "user" | "assistant",
279
- text: row.text,
280
- }));
281
- }
282
-
283
- /** Ids of every ended call not read back yet. A read stamps all of them, including the ones it dropped. */
284
- export async function listUnreadCallIds(): Promise<string[]> {
285
- const rows = await database
286
- .select({ id: callTable.id })
287
- .from(callTable)
288
- .where(and(isNotNull(callTable.endedAt), isNull(callTable.tidiedAt)))
289
- .orderBy(asc(callTable.startedAt));
290
- return rows.map((row) => row.id);
291
- }
292
-
293
- export async function markCallsRead(ids: string[]) {
294
- if (!ids.length) return;
295
- await database
296
- .update(callTable)
297
- .set({ tidiedAt: new Date() })
298
- .where(inArray(callTable.id, ids));
299
- }
300
-
301
- /** Stamps every ended call as read, so switching the setting on starts from now. */
302
- export async function markEveryCallRead() {
303
- await database
304
- .update(callTable)
305
- .set({ tidiedAt: new Date() })
306
- .where(and(isNotNull(callTable.endedAt), isNull(callTable.tidiedAt)));
307
- }
308
-
309
300
  /**
310
301
  * Every call that has ended, and its turns (cascade). A call still on the line
311
302
  * stays: its tab is still writing turns against the row (see `deleteCall`).
@@ -1,9 +1,10 @@
1
1
  import z from "zod";
2
+ import { ASCII_FACE } from "@/config";
2
3
  import {
3
4
  type SpeachModelProviderId,
4
5
  speachModelRefSchema,
5
6
  } from "@/features/ai/model.schema";
6
- import { botIconSchema } from "@/features/bot/bot.schema";
7
+ import { botIconSchema, type TaskStatus } from "@/features/bot/bot.schema";
7
8
  import { ASCII_CHARSETS, FACE_KINDS } from "@/features/thursday/face.const";
8
9
  import type { DateLike } from "@/lib/date-like";
9
10
  import { COMMON_VALIDATE } from "@/lib/limits";
@@ -48,10 +49,18 @@ export type CallHandshake = {
48
49
  */
49
50
  export const ThursdayFaceSchema = botIconSchema.extend({
50
51
  kind: z.enum(FACE_KINDS).default("ascii"),
51
- charset: z.enum(ASCII_CHARSETS).default("ascii"),
52
+ charset: z.enum(ASCII_CHARSETS).default(ASCII_FACE.charset),
52
53
  /** Glyph size in px. */
53
- fontSize: z.number().min(4).max(16).default(8),
54
- density: z.number().min(0.6).max(2).default(1.4),
54
+ fontSize: z
55
+ .number()
56
+ .min(ASCII_FACE.fontSize.min)
57
+ .max(ASCII_FACE.fontSize.max)
58
+ .default(ASCII_FACE.fontSize.default),
59
+ density: z
60
+ .number()
61
+ .min(ASCII_FACE.density.min)
62
+ .max(ASCII_FACE.density.max)
63
+ .default(ASCII_FACE.density.default),
55
64
  });
56
65
 
57
66
  export type ThursdayFace = z.infer<typeof ThursdayFaceSchema>;
@@ -177,7 +186,11 @@ export type CallRecord = {
177
186
  /** null when the hang-up was never recorded. */
178
187
  endedAt: DateLike | null;
179
188
  turns: (CallTurn & { at: DateLike })[];
189
+ /** Jobs this call opened, as they stand now; the log draws each under the line that opened it. */
190
+ jobs: {
191
+ id: string;
192
+ label: string;
193
+ status: TaskStatus;
194
+ outcome: string | null;
195
+ }[];
180
196
  };
181
-
182
- /** History page size in calls, not rows; each call carries every turn. */
183
- export const CALL_HISTORY_PAGE = 10;
@@ -13,8 +13,50 @@ const LINES: Record<string, string> = {
13
13
  [TOOL_NAMES.end_call]: "Ending the call",
14
14
  };
15
15
 
16
+ /**
17
+ * How much of a fact the line carries. What is being written is the one thing
18
+ * on this screen the user cannot check afterwards without opening the note, so
19
+ * it is said as it happens — but the row is one line that also carries the
20
+ * path and the tool's name, and a fact cut mid-word reads as a bug rather than
21
+ * a quotation.
22
+ */
23
+ const FACT_MAX = 28;
24
+
25
+ function snippet(text: string): string {
26
+ const said = text.trim().replace(/\s+/g, " ");
27
+ if (said.length <= FACT_MAX) return said;
28
+ const cut = said.slice(0, FACT_MAX);
29
+ const space = cut.lastIndexOf(" ");
30
+ return `${(space > FACT_MAX / 2 ? cut.slice(0, space) : cut).trimEnd()}…`;
31
+ }
32
+
33
+ /** The first fact of a `memory_remember` call, while the arguments are whole enough to read. */
34
+ function firstFact(
35
+ args: Record<string, unknown>,
36
+ ): { text: string; more: number } | null {
37
+ if (!Array.isArray(args.facts)) return null;
38
+ const texts = args.facts
39
+ .map((fact) =>
40
+ fact &&
41
+ typeof fact === "object" &&
42
+ typeof (fact as { text?: unknown }).text === "string"
43
+ ? (fact as { text: string }).text.trim()
44
+ : "",
45
+ )
46
+ .filter(Boolean);
47
+ return texts.length ? { text: texts[0], more: texts.length - 1 } : null;
48
+ }
49
+
16
50
  /** Lines that need the arguments; arguments may still be streaming in. */
17
51
  function fromArgs(name: string, args: Record<string, unknown>): string | null {
52
+ if (name === TOOL_NAMES.memory_remember) {
53
+ const path = typeof args.path === "string" ? args.path.trim() : "";
54
+ const fact = firstFact(args);
55
+ if (!path) return null;
56
+ if (!fact) return `Noting that under ${path}`;
57
+ const more = fact.more > 0 ? ` (+${fact.more})` : "";
58
+ return `Noting under ${path}: ${snippet(fact.text)}${more}`;
59
+ }
18
60
  if (name === TOOL_NAMES.delegate) {
19
61
  const bot = typeof args.bot === "string" ? args.bot.trim() : "";
20
62
  return bot ? `Handing this to ${bot}` : "Handing this over";
@@ -35,20 +77,52 @@ function fromServer(name: string): string | null {
35
77
  return `Reaching ${name.slice(0, at).replace(/[-_]/g, " ")}`;
36
78
  }
37
79
 
80
+ /** Arguments as an object, or null while they are still streaming in. */
81
+ function parseArgs(args?: string): Record<string, unknown> | null {
82
+ if (!args) return null;
83
+ try {
84
+ const value: unknown = JSON.parse(args);
85
+ if (value && typeof value === "object" && !Array.isArray(value)) {
86
+ return value as Record<string, unknown>;
87
+ }
88
+ } catch {
89
+ // Partial or non-JSON arguments: fall back to the name-only line.
90
+ }
91
+ return null;
92
+ }
93
+
38
94
  export function toolLine(name: string, args?: string): string | null {
39
95
  if (name === TOOL_NAMES.tool_search || name === TOOL_NAMES.tool_call) {
40
96
  return "Reaching a connected service";
41
97
  }
42
- let parsed: Record<string, unknown> | null = null;
43
- if (args) {
44
- try {
45
- const value: unknown = JSON.parse(args);
46
- if (value && typeof value === "object" && !Array.isArray(value)) {
47
- parsed = value as Record<string, unknown>;
48
- }
49
- } catch {
50
- // Partial or non-JSON arguments: fall back to the name-only line.
51
- }
52
- }
98
+ const parsed = parseArgs(args);
53
99
  return (parsed && fromArgs(name, parsed)) ?? LINES[name] ?? fromServer(name);
54
100
  }
101
+
102
+ /**
103
+ * The bot a call hands work to, when it names one. The row draws that bot's own
104
+ * face instead of a glyph: who it went to is a face everywhere else in the app.
105
+ */
106
+ export function toolBot(name: string, args?: string): string | null {
107
+ if (name !== TOOL_NAMES.delegate && name !== TOOL_NAMES.ask_bot) return null;
108
+ const bot = parseArgs(args)?.bot;
109
+ return typeof bot === "string" && bot.trim() ? bot.trim() : null;
110
+ }
111
+
112
+ /**
113
+ * The label a `delegate` call was made under, or null for any other turn. It is
114
+ * how a job is found again from the line that opened it — in her prompt and in
115
+ * the call log alike.
116
+ */
117
+ export function delegatedLabel(
118
+ tool: string | null | undefined,
119
+ text: string,
120
+ ): string | null {
121
+ if (tool !== TOOL_NAMES.delegate) return null;
122
+ try {
123
+ const said = JSON.parse(text) as { label?: unknown };
124
+ return typeof said.label === "string" ? said.label : null;
125
+ } catch {
126
+ return null;
127
+ }
128
+ }
@@ -5,10 +5,9 @@ import { useAppEvent } from "@/app/api/events/app-event.client";
5
5
  import { queryKey } from "@/app/api/query-key";
6
6
  import { toast } from "@/components/ui/toast";
7
7
  import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
8
- import { markReportedAction } from "@/features/bot/bot.action";
9
8
  import {
10
9
  type Bot,
11
- isBudgetAsk,
10
+ isAppStop,
12
11
  TASK_CONTINUE,
13
12
  type Task,
14
13
  } from "@/features/bot/bot.schema";
@@ -45,7 +44,7 @@ import type {
45
44
  LiveStatus,
46
45
  } from "./thursday.schema";
47
46
  import { thursdaySettings, useThursdayStore } from "./thursday.store";
48
- import { toolLine } from "./tool-line";
47
+ import { toolBot, toolLine } from "./tool-line";
49
48
 
50
49
  /**
51
50
  * One live call, plus the task inbox the app watches even with no call open.
@@ -103,6 +102,14 @@ const IDLE_GRACE_MS = 15_000;
103
102
  /** The countdown shows on screen inside this window. */
104
103
  const IDLE_WARN_MS = 15_000;
105
104
 
105
+ /**
106
+ * The user finished a turn and nothing came back — no words, no tool — for this
107
+ * long. The line is up and the model is not on it, so there is no goodbye to
108
+ * ask for: the page hangs up. Only armed while an answer is owed, so a quiet
109
+ * line still ends the slow way (IDLE_HANG_UP_MS).
110
+ */
111
+ const AGENT_SILENT_MS = 30_000;
112
+
106
113
  const IDLE_LINE =
107
114
  "The user has said nothing for a minute. Say a one-line goodbye, then call end_call.";
108
115
 
@@ -112,13 +119,9 @@ const IDLE_LINE =
112
119
  */
113
120
  const RELAY_MIC_MS = 15_000;
114
121
 
115
- /**
116
- * A line queued for the model. `mark` is the task id to mark reported once the
117
- * line is actually sent, not when it is queued.
118
- */
122
+ /** A line queued for the model. */
119
123
  type Said = {
120
124
  line: string;
121
- mark?: string;
122
125
  /** Shown on the activity line when the line is sent. */
123
126
  show?: ToolRun;
124
127
  };
@@ -132,8 +135,10 @@ export type ToolRun = {
132
135
  name: string;
133
136
  line: string | null;
134
137
  done: boolean;
135
- /** A relay from a bot (report or question) rather than a tool; `name` is the task label. */
138
+ /** A relay from a bot (answer or question) rather than a tool; `name` is the task label. */
136
139
  kind?: "tool" | "relay";
140
+ /** The bot this names, when it names one: the row draws its face instead of a glyph. */
141
+ bot?: string | null;
137
142
  };
138
143
 
139
144
  export function useThursday() {
@@ -162,12 +167,16 @@ export function useThursday() {
162
167
  spoke: boolean;
163
168
  giveUp: ReturnType<typeof setTimeout> | null;
164
169
  }>({ tool: false, reading: false, spoke: false, giveUp: null });
165
- /** Last activity time, and whether the goodbye was requested. */
170
+ /**
171
+ * Last activity time, whether the goodbye was requested, and when an answer
172
+ * started being owed (null once she answers or works).
173
+ */
166
174
  const idle = useRef<{
167
175
  since: number;
168
176
  asked: boolean;
177
+ owed: number | null;
169
178
  grace: ReturnType<typeof setTimeout> | null;
170
- }>({ since: 0, asked: false, grace: null });
179
+ }>({ since: 0, asked: false, owed: null, grace: null });
171
180
  const linger = useRef<ReturnType<typeof setTimeout> | null>(null);
172
181
  // Every server-run tool in this call starts with this signal, so one abort
173
182
  // reaches running browser commands. Delegated tasks are server-owned and outlive the call
@@ -176,14 +185,15 @@ export function useThursday() {
176
185
  const callId = useRef<string | null>(null);
177
186
  /**
178
187
  * Relays sent this call, keyed by relayKey (id + updatedAt): an answered task
179
- * comes back with reported=false and may ask again, so the id alone would
180
- * silence its second question.
188
+ * can stop to ask again, so the id alone would silence its second question.
181
189
  */
182
190
  const relayed = useRef(new Set<string>());
191
+ /** When this call was placed. An ending from before it is already in her prompt. */
192
+ const placedAt = useRef(0);
183
193
  /**
184
194
  * Lines for the model, including ones raised before the line opens. Held
185
- * until the session exists so nothing is marked reported unheard; this is
186
- * also what lets a call-back queue its line first.
195
+ * until the session exists, which is also what lets a call-back queue its
196
+ * line first.
187
197
  */
188
198
  const outboxRef = useRef<Outbox<Said> | null>(null);
189
199
  const outbox = (outboxRef.current ??= createOutbox<Said>());
@@ -206,6 +216,7 @@ export function useThursday() {
206
216
  setTool({
207
217
  name: call.name,
208
218
  line: toolLine(call.name, call.arguments),
219
+ bot: toolBot(call.name, call.arguments),
209
220
  done: false,
210
221
  });
211
222
  }, []);
@@ -343,11 +354,15 @@ export function useThursday() {
343
354
  },
344
355
  tasks: () => void revalidate(queryKey.tasks),
345
356
  memory: () => void revalidate(queryKey.memory),
346
- "memory-tidy": () => void revalidate(queryKey.memoryTidy),
347
357
  mcp: () => {
348
358
  void revalidate(queryKey.mcp);
349
359
  void revalidate(queryKey.mcpTools);
350
360
  },
361
+ // A sign-in finished in its own window (ai/chatgpt): the key rows and the model picker both read it
362
+ config: () => {
363
+ void revalidate(queryKey.config);
364
+ void revalidate(queryKey.llmModel);
365
+ },
351
366
  });
352
367
 
353
368
  // faces come from the bot list
@@ -356,23 +371,28 @@ export function useThursday() {
356
371
  if (tasks) botTasks.sync(tasks, bots);
357
372
  }, [tasks, bots]);
358
373
 
359
- // Finished or waiting tasks are relayed once. Sending while the line is still
360
- // opening is fine: the outbox holds the line. `status` is in deps because the
361
- // guard is a ref; without it a list that arrived before the line opened
362
- // would wait for the next tasks change
374
+ // A question is relayed on every call, because it still needs an answer. An
375
+ // ending is relayed only on the call it happened during: one from before is
376
+ // already in her prompt, on the `delegate` line that opened it. Telling is not
377
+ // seeing the badge clears when the user opens the job. Sending while the
378
+ // line is still opening is fine: the outbox holds the line. `status` is in
379
+ // deps because the guard is a ref; without it a list that arrived before the
380
+ // line opened would wait for the next tasks change
363
381
  useEffect(() => {
364
382
  if (!tasks || !calling.current) return;
365
383
  for (const task of tasks) {
366
- if (task.status === "running" || task.reported) continue;
384
+ if (task.status === "running") continue;
385
+ // A stop the app picks back up by itself is not news: it runs again in a moment
386
+ if (task.ask?.auto) continue;
387
+ if (
388
+ task.status !== "waiting" &&
389
+ toDate(task.updatedAt).getTime() < placedAt.current
390
+ )
391
+ continue;
367
392
  const key = relayKey(task);
368
393
  if (relayed.current.has(key)) continue;
369
394
  relayed.current.add(key);
370
- // marked reported when the line is actually sent (outbox callback), not here
371
- outbox.send({
372
- line: relayLine(task),
373
- mark: task.id,
374
- show: relayShow(task),
375
- });
395
+ outbox.send({ line: relayLine(task), show: relayShow(task) });
376
396
  }
377
397
  }, [tasks, outbox, status]);
378
398
 
@@ -385,7 +405,7 @@ export function useThursday() {
385
405
  line:
386
406
  act.kind === "answered"
387
407
  ? `The user answered task "${act.label}" on screen: ${act.answer}. The bot is going on with that — do not ask again.`
388
- : `The user stopped task "${act.label}" on screen. It is not running any more — do not wait for it or report on it.`,
408
+ : `The user stopped task "${act.label}" on screen. It is not running any more — do not wait for it or say anything more about it.`,
389
409
  });
390
410
  }),
391
411
  [outbox],
@@ -401,7 +421,7 @@ export function useThursday() {
401
421
  calling.current = false;
402
422
  opening.current = false;
403
423
  relayed.current.clear();
404
- // unsent lines belong to tasks still not reported; the next call resends them
424
+ // unsent lines go: a question is relayed again next call, an ending is in her prompt
405
425
  outbox.close();
406
426
  outbox.clear();
407
427
  // holds the closed session; the next call sets its own
@@ -414,7 +434,7 @@ export function useThursday() {
414
434
  // a pending face timer must not fire after the call
415
435
  restFace();
416
436
  if (idle.current.grace) clearTimeout(idle.current.grace);
417
- idle.current = { since: 0, asked: false, grace: null };
437
+ idle.current = { since: 0, asked: false, owed: null, grace: null };
418
438
  setIdleLeft(null);
419
439
  setSince(null);
420
440
  setStatus("idle");
@@ -459,8 +479,17 @@ export function useThursday() {
459
479
  * agent activity does not, so the goodbye cannot cancel itself.
460
480
  */
461
481
  const stir = useCallback((who: "user" | "agent") => {
462
- idle.current.since = Date.now();
463
- if (who !== "user") return;
482
+ const now = Date.now();
483
+ idle.current.since = now;
484
+ if (who !== "user") {
485
+ // Words or a tool: she is on the line, so nothing is owed.
486
+ idle.current.owed = null;
487
+ return;
488
+ }
489
+ // Rewound by anything the user does, transcript deltas included, so a long
490
+ // turn is never mistaken for a line that stopped answering; it runs from the
491
+ // moment they stopped rather than from the moment they started.
492
+ idle.current.owed = now;
464
493
  if (idle.current.grace) clearTimeout(idle.current.grace);
465
494
  idle.current.grace = null;
466
495
  idle.current.asked = false;
@@ -473,6 +502,17 @@ export function useThursday() {
473
502
  const tick = setInterval(() => {
474
503
  const live = session.current;
475
504
  if (!live) return;
505
+ const owed = idle.current.owed;
506
+ if (owed !== null && Date.now() - owed >= AGENT_SILENT_MS) {
507
+ // Nothing to say goodbye with; the model is what would have said it.
508
+ toast.add({
509
+ type: "error",
510
+ title: "Call ended",
511
+ description: "The model stopped answering.",
512
+ });
513
+ void hangUp();
514
+ return;
515
+ }
476
516
  const left = IDLE_HANG_UP_MS - (Date.now() - idle.current.since);
477
517
  setIdleLeft(
478
518
  left <= IDLE_WARN_MS && !idle.current.asked
@@ -499,6 +539,7 @@ export function useThursday() {
499
539
  // from here on this is a call; the outbox holds lines until the session exists
500
540
  opening.current = true;
501
541
  calling.current = true;
542
+ placedAt.current = Date.now();
502
543
  outbox.clear();
503
544
  try {
504
545
  const handshake = unwrapResult(await openCallAction(thursdaySettings()));
@@ -601,8 +642,6 @@ export function useThursday() {
601
642
  live.say(queued.length === 1 ? queued[0].line : mergedRelay(queued));
602
643
  const last = queued.at(-1)?.show;
603
644
  if (last) showRelay(last);
604
- const marks = queued.flatMap((one) => one.mark ?? []);
605
- if (marks.length) markReported(marks);
606
645
  outbox.close();
607
646
  };
608
647
 
@@ -669,7 +708,8 @@ export function useThursday() {
669
708
  if (!tasks) return;
670
709
  const wants = tasks.filter(
671
710
  (task) =>
672
- !task.reported &&
711
+ !task.seen &&
712
+ !task.ask?.auto &&
673
713
  (asksSomething(task) ||
674
714
  (callBack === "any" && task.status !== "running")),
675
715
  );
@@ -809,25 +849,12 @@ function persistTurn(
809
849
  });
810
850
  }
811
851
 
812
- /** Failure surfaces as a toast: an unmarked report is read again next call. */
813
- function markReported(ids: string[]) {
814
- markReportedAction(ids)
815
- .then(unwrapResult)
816
- .catch((cause) =>
817
- toast.add({
818
- type: "error",
819
- title: "Could not mark the report as delivered",
820
- description: errorToString(cause),
821
- }),
822
- );
823
- }
824
-
825
852
  /**
826
- * Waiting on a real question. A budget ask (out of steps) waits in the inbox
853
+ * Waiting on a real question. A job the app stopped waits in the inbox
827
854
  * instead of ringing.
828
855
  */
829
856
  function asksSomething(task: Task) {
830
- return task.status === "waiting" && !isBudgetAsk(task.ask);
857
+ return task.status === "waiting" && !isAppStop(task.ask);
831
858
  }
832
859
 
833
860
  /**
@@ -835,16 +862,16 @@ function asksSomething(task: Task) {
835
862
  * sender and recipient or the model answers it as user speech.
836
863
  */
837
864
  function relayLine(task: Task) {
838
- // The label travels with the report: what the user says next about this job
865
+ // The label travels with the answer: what the user says next about this job
839
866
  // is a word to it, and the task tool takes it by that name
840
867
  const from = `[${task.bot} → you, about "${task.label}" — not the user speaking; they have not heard this. Anything more on this job goes to the task tool as "${task.label}", never a new job.]`;
841
868
  switch (task.status) {
842
869
  case "waiting": {
843
- // a budget ask is reported, not read as a question
870
+ // a stop is told, not read as a question
844
871
  const options = task.ask?.options ?? [];
845
872
  const said = task.ask?.question ?? task.outcome ?? "";
846
- if (isBudgetAsk(task.ask)) {
847
- return `${from} Out of steps. Where it got to: ${said} Ask whether to keep going; if yes, send "${TASK_CONTINUE}" with the task tool.`;
873
+ if (isAppStop(task.ask)) {
874
+ return `${from} It stopped before finishing. Where it got to: ${said} Ask whether to keep going; if yes, send "${TASK_CONTINUE}" with the task tool.`;
848
875
  }
849
876
  const list = options.length ? ` Options: ${options.join(" / ")}.` : "";
850
877
  return `${from} It asks: ${said}${list} Answer with the task tool if you can; otherwise ask the user and send back what they say.`;
@@ -852,7 +879,7 @@ function relayLine(task: Task) {
852
879
  case "failed":
853
880
  return `${from} It could not finish: ${task.outcome ?? ""}`;
854
881
  default:
855
- return `${from} Done. Its report: ${task.outcome ?? ""}`;
882
+ return `${from} Done. Its answer: ${task.outcome ?? ""}`;
856
883
  }
857
884
  }
858
885
 
@@ -871,13 +898,13 @@ ${queued.map((one) => one.line).join("\n\n")}`;
871
898
  function relayShow(task: Task): ToolRun {
872
899
  const line =
873
900
  task.status === "waiting"
874
- ? isBudgetAsk(task.ask)
875
- ? `${task.bot} is out of steps`
901
+ ? isAppStop(task.ask)
902
+ ? `${task.bot} stopped`
876
903
  : `${task.bot} is asking`
877
904
  : task.status === "failed"
878
905
  ? `${task.bot} could not finish`
879
- : `Report from ${task.bot}`;
880
- return { kind: "relay", name: task.label, line, done: true };
906
+ : `Answer from ${task.bot}`;
907
+ return { kind: "relay", name: task.label, line, done: true, bot: task.bot };
881
908
  }
882
909
 
883
910
  export type { CallMessage, CallStatus };
@@ -158,10 +158,12 @@ export function FileLink({
158
158
  const PAD: Record<FileViewPlace, { prose: string; block: string }> = {
159
159
  dialog: { prose: "px-5 py-4", block: "px-4 py-3" },
160
160
  page: { prose: "px-5 py-6 sm:px-8", block: "px-5 py-5" },
161
+ // Opened under a list row, which already sets the edges
162
+ inline: { prose: "pb-3", block: "pb-3" },
161
163
  };
162
164
 
163
- /** Where the file is read: inside the dialog or on its own page. */
164
- export type FileViewPlace = "dialog" | "page";
165
+ /** Where the file is read: inside the dialog, on its own page, or opened in place under a row. */
166
+ export type FileViewPlace = "dialog" | "page" | "inline";
165
167
 
166
168
  export function FileBody({
167
169
  kind,