thursday-agent 0.5.0 → 0.6.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 (662) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +3 -2
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +3 -3
  5. package/.next/required-server-files.json +8 -1
  6. package/.next/routes-manifest.json +18 -6
  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 +1 -1
  10. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  14. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/server/app/_not-found.html +1 -1
  16. package/.next/server/app/_not-found.rsc +13 -13
  17. package/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
  18. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
  19. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  20. package/.next/server/app/api/artifact/route.js +10 -6
  21. package/.next/server/app/api/artifact/route.js.nft.json +1 -1
  22. package/.next/server/app/api/bot/memory/files/route.js +5 -4
  23. package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -1
  24. package/.next/server/app/api/bot/memory/route.js +8 -8
  25. package/.next/server/app/api/bot/memory/route.js.nft.json +1 -1
  26. package/.next/server/app/api/bot/route.js +8 -8
  27. package/.next/server/app/api/bot/route.js.nft.json +1 -1
  28. package/.next/server/app/api/bot/thread/[id]/route/app-paths-manifest.json +3 -0
  29. package/.next/server/app/api/bot/thread/[id]/route.js +15 -0
  30. package/.next/server/app/api/bot/thread/[id]/route.js.nft.json +1 -0
  31. package/.next/server/app/api/bot/thread/[id]/route_client-reference-manifest.js +3 -0
  32. package/.next/server/app/api/bot/thread/route/app-paths-manifest.json +3 -0
  33. package/.next/server/app/api/bot/thread/route.js +15 -0
  34. package/.next/server/app/api/bot/thread/route.js.nft.json +1 -0
  35. package/.next/server/app/api/bot/thread/route_client-reference-manifest.js +3 -0
  36. package/.next/server/app/api/config/route.js +7 -7
  37. package/.next/server/app/api/config/route.js.nft.json +1 -1
  38. package/.next/server/app/api/events/route.js +3 -3
  39. package/.next/server/app/api/events/route.js.nft.json +1 -1
  40. package/.next/server/app/api/file/[...path]/route.js +4 -4
  41. package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
  42. package/.next/server/app/api/llm-model/catalog/route.js +8 -8
  43. package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
  44. package/.next/server/app/api/llm-model/credits/route.js +8 -8
  45. package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -1
  46. package/.next/server/app/api/llm-model/route.js +8 -8
  47. package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
  48. package/.next/server/app/api/llm-model/subscription/route.js +8 -8
  49. package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -1
  50. package/.next/server/app/api/mcp/[name]/route.js +6 -6
  51. package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
  52. package/.next/server/app/api/mcp/oauth/callback/route.js +4 -4
  53. package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
  54. package/.next/server/app/api/mcp/route.js +6 -6
  55. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  56. package/.next/server/app/api/mcp/tools/route.js +6 -6
  57. package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
  58. package/.next/server/app/api/memory/edit/route.js +15 -15
  59. package/.next/server/app/api/memory/edit/route.js.nft.json +1 -1
  60. package/.next/server/app/api/memory/route.js +7 -6
  61. package/.next/server/app/api/memory/route.js.nft.json +1 -1
  62. package/.next/server/app/api/skills/[source]/[name]/route.js +6 -6
  63. package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
  64. package/.next/server/app/api/skills/route.js +6 -6
  65. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  66. package/.next/server/app/api/thursday/call/route.js +10 -11
  67. package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
  68. package/.next/server/app/api/thursday/skills/route.js +9 -10
  69. package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
  70. package/.next/server/app/api/thursday/tool-call/route.js +15 -15
  71. package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
  72. package/.next/server/app/api/workspace/missing/route/app-paths-manifest.json +3 -0
  73. package/.next/server/app/api/workspace/missing/route/build-manifest.json +12 -0
  74. package/.next/server/app/api/workspace/missing/route/server-reference-manifest.json +4 -0
  75. package/.next/server/app/api/workspace/missing/route.js +12 -0
  76. package/.next/server/app/api/workspace/missing/route.js.map +5 -0
  77. package/.next/server/app/api/workspace/missing/route.js.nft.json +1 -0
  78. package/.next/server/app/api/workspace/missing/route_client-reference-manifest.js +3 -0
  79. package/.next/server/app/api/workspace/route.js +5 -5
  80. package/.next/server/app/api/workspace/route.js.nft.json +1 -1
  81. package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +1 -1
  82. package/.next/server/app/artifact/[...path]/page.js +4 -3
  83. package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
  84. package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
  85. package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
  86. package/.next/server/app/page/server-reference-manifest.json +67 -45
  87. package/.next/server/app/page.js +10 -9
  88. package/.next/server/app/page.js.nft.json +1 -1
  89. package/.next/server/app/page_client-reference-manifest.js +1 -1
  90. package/.next/server/app-paths-manifest.json +3 -2
  91. package/.next/server/chunks/[root-of-the-server]__02846fb._.js +8 -0
  92. package/.next/server/chunks/[root-of-the-server]__049f521._.js +3 -0
  93. package/.next/server/chunks/[root-of-the-server]__05luceg._.js +3 -0
  94. package/.next/server/chunks/[root-of-the-server]__06--3q3._.js +8 -0
  95. package/.next/server/chunks/[root-of-the-server]__07bnah_._.js +3 -0
  96. package/.next/server/chunks/[root-of-the-server]__08eae20._.js +8 -0
  97. package/.next/server/chunks/[root-of-the-server]__0_ue8oe._.js +3 -0
  98. package/.next/server/chunks/[root-of-the-server]__0c9fgca._.js +5 -0
  99. package/.next/server/chunks/[root-of-the-server]__0g-ueei._.js +8 -0
  100. package/.next/server/chunks/[root-of-the-server]__0h_x6q6._.js +5 -0
  101. package/.next/server/chunks/{[root-of-the-server]__0pa2n68._.js → [root-of-the-server]__0kxrvxf._.js} +2 -2
  102. package/.next/server/chunks/{[root-of-the-server]__0q0vvt2._.js → [root-of-the-server]__0ov3iir._.js} +2 -2
  103. package/.next/server/chunks/[root-of-the-server]__0qwtlmx._.js +8 -0
  104. package/.next/server/chunks/[root-of-the-server]__0sm5xvm._.js +3 -0
  105. package/.next/server/chunks/[root-of-the-server]__0ye3da2._.js +3 -0
  106. package/.next/server/chunks/[root-of-the-server]__0zp35ul._.js +5 -0
  107. package/.next/server/chunks/[root-of-the-server]__144u9d_._.js +3 -0
  108. package/.next/server/chunks/[root-of-the-server]__18-2tsq._.js +5 -0
  109. package/.next/server/chunks/[root-of-the-server]__1e-ci13._.js +3 -0
  110. package/.next/server/chunks/[root-of-the-server]__1e2365e._.js +8 -0
  111. package/.next/server/chunks/[root-of-the-server]__1fix932._.js +8 -0
  112. package/.next/server/chunks/{[root-of-the-server]__0ce8nf8._.js → [root-of-the-server]__1g3t7vn._.js} +3 -3
  113. package/.next/server/chunks/[root-of-the-server]__1kp-83u._.js +5 -0
  114. package/.next/server/chunks/[root-of-the-server]__1kv8p3e._.js +5 -0
  115. package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +2 -3
  116. package/.next/server/chunks/_02szwk8._.js +5 -0
  117. package/.next/server/chunks/_05h2cii._.js +1 -1
  118. package/.next/server/chunks/_06c9kie._.js +216 -0
  119. package/.next/server/chunks/{_1x6kd1r._.js → _07y2gj-._.js} +1 -1
  120. package/.next/server/chunks/_0a43a-0._.js +3 -0
  121. package/.next/server/chunks/_0bujjey._.js +5 -0
  122. package/.next/server/chunks/_0c9j6rb._.js +1 -1
  123. package/.next/server/chunks/_0dkd549._.js +3 -0
  124. package/.next/server/chunks/_0ej1kvv._.js +3 -0
  125. package/.next/server/chunks/_0f6ts7z._.js +3 -0
  126. package/.next/server/chunks/_0gm9hyv._.js +55 -0
  127. package/.next/server/chunks/_0i55en5._.js +25 -0
  128. package/.next/server/chunks/_0k50n27._.js +18 -0
  129. package/.next/server/chunks/_0khihjk._.js +3 -3
  130. package/.next/server/chunks/_0n74zsf._.js +5 -5
  131. package/.next/server/chunks/_0nvm9ef._.js +3 -0
  132. package/.next/server/chunks/_0p56fn0._.js +3 -0
  133. package/.next/server/chunks/_0recufk._.js +1 -1
  134. package/.next/server/chunks/_0xbkz10._.js +3 -0
  135. package/.next/server/chunks/_10tkr26._.js +3 -0
  136. package/.next/server/chunks/{_0ioz3nd._.js → _11u2kp7._.js} +1 -1
  137. package/.next/server/chunks/_11ujpya._.js +3 -0
  138. package/.next/server/chunks/_127nx_p._.js +5 -0
  139. package/.next/server/chunks/_17l5ygt._.js +1 -1
  140. package/.next/server/chunks/_19uauj6._.js +3 -0
  141. package/.next/server/chunks/_1_5mnq4._.js +5 -5
  142. package/.next/server/chunks/_1abl6t9._.js +55 -0
  143. package/.next/server/chunks/_1d0j961._.js +3 -3
  144. package/.next/server/chunks/_1dbixxz._.js +3 -0
  145. package/.next/server/chunks/_1dc_d1q._.js +98 -0
  146. package/.next/server/chunks/_1drgfx4._.js +5 -5
  147. package/.next/server/chunks/_1e48czp._.js +3 -3
  148. package/.next/server/chunks/_1f31u5x._.js +5 -0
  149. package/.next/server/chunks/_1kg70wc._.js +3 -3
  150. package/.next/server/chunks/_1klbcft._.js +5 -0
  151. package/.next/server/chunks/_1krd9rf._.js +4 -1
  152. package/.next/server/chunks/_1kwmzab._.js +3 -0
  153. package/.next/server/chunks/{_1pf4qe-._.js → _1oxj9fa._.js} +1 -1
  154. package/.next/server/chunks/{_1f46eie._.js → _1pcmdbb._.js} +1 -1
  155. package/.next/server/chunks/_1qgix-j._.js +3 -0
  156. package/.next/server/chunks/{lib_logger_ts_1exwjut._.js → _1rpchta._.js} +5 -5
  157. package/.next/server/chunks/_1vsej-s._.js +5 -0
  158. package/.next/server/chunks/_1yx0p_s._.js +5 -0
  159. package/.next/server/chunks/{_0rnf-6n._.js → _20fsr_z._.js} +6 -6
  160. package/.next/server/chunks/_2128hkj._.js +5 -0
  161. package/.next/server/chunks/_next-internal_server_app_api_bot_thread_[id]_route_actions_1fstjn2.js +3 -0
  162. package/.next/server/chunks/_next-internal_server_app_api_bot_thread_route_actions_003ccso.js +3 -0
  163. package/.next/server/chunks/_next-internal_server_app_api_workspace_missing_route_actions_1fidi6p.js +3 -0
  164. package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
  165. package/.next/server/chunks/features_0-cnt0l._.js +4 -0
  166. package/.next/server/chunks/features_0hdaci0._.js +4 -0
  167. package/.next/server/chunks/features_1e39j7-._.js +8 -0
  168. package/.next/server/chunks/features_bot_bot_query_ts_12mgkl2._.js +1 -1
  169. package/.next/server/chunks/features_memory_1uqvksn._.js +1 -1
  170. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0v_7drq._.js → node_modules_consola_dist_chunks_prompt_mjs_0a7-pbw._.js} +1 -1
  171. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_17k8irj._.js → node_modules_consola_dist_chunks_prompt_mjs_0gzvgfv._.js} +1 -1
  172. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0i7cvml._.js → node_modules_consola_dist_chunks_prompt_mjs_107pxfn._.js} +1 -1
  173. package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0icqaqw._.js → node_modules_consola_dist_chunks_prompt_mjs_15hbel8._.js} +1 -1
  174. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_18i-23e._.js +3 -0
  175. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1bewgf3._.js +3 -0
  176. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1kipdeo._.js +3 -0
  177. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1nlww1m._.js +3 -0
  178. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1q77nfx._.js +3 -0
  179. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1xqdzx_._.js +3 -0
  180. package/.next/server/chunks/{node_modules_zod_v4_1801ax7._.js → node_modules_zod_v4_0lkux5-._.js} +2 -2
  181. package/.next/server/chunks/{node_modules_zod_v4_1cha_bw._.js → node_modules_zod_v4_1jmr9cq._.js} +2 -2
  182. package/.next/server/chunks/{node_modules_zod_v4_0ubdflj._.js → node_modules_zod_v4_1yrxmek._.js} +2 -2
  183. package/.next/server/chunks/node_modules_zod_v4_classic_errors_0tp0y-q.js +3 -0
  184. package/.next/server/chunks/ssr/[root-of-the-server]__09q9med._.js +1 -1
  185. package/.next/server/chunks/ssr/[root-of-the-server]__0bxsfyn._.js +101 -0
  186. package/.next/server/chunks/ssr/[root-of-the-server]__0lyi8i2._.js +1 -1
  187. package/.next/server/chunks/ssr/[root-of-the-server]__16jc196._.js +1 -1
  188. package/.next/server/chunks/ssr/[root-of-the-server]__172cq4x._.js +3 -0
  189. package/.next/server/chunks/ssr/[root-of-the-server]__18dthbp._.js +3 -0
  190. package/.next/server/chunks/ssr/[root-of-the-server]__18e68w8._.js +3 -0
  191. package/.next/server/chunks/ssr/[root-of-the-server]__1fll8dc._.js +3 -0
  192. package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
  193. package/.next/server/chunks/ssr/[root-of-the-server]__1nygfik._.js +5 -0
  194. package/.next/server/chunks/ssr/[root-of-the-server]__1sdphb0._.js +8 -0
  195. package/.next/server/chunks/ssr/[root-of-the-server]__1waa3rc._.js +100 -0
  196. package/.next/server/chunks/ssr/_00rehl_._.js +3 -0
  197. package/.next/server/chunks/ssr/{_1lz_cq2._.js → _02oc_h5._.js} +76 -97
  198. package/.next/server/chunks/ssr/_03_928f._.js +3 -0
  199. package/.next/server/chunks/ssr/_05yghx6._.js +3 -0
  200. package/.next/server/chunks/ssr/_08c4z-9._.js +3 -0
  201. package/.next/server/chunks/ssr/_0_qfdlw._.js +4 -0
  202. package/.next/server/chunks/ssr/_0c9e5w6._.js +9 -0
  203. package/.next/server/chunks/ssr/{_0s99bgb._.js → _0dh2e1j._.js} +9 -3
  204. package/.next/server/chunks/ssr/_0dr-ddg._.js +3 -0
  205. package/.next/server/chunks/ssr/_0eaog6_._.js +3 -0
  206. package/.next/server/chunks/ssr/_0evkpto._.js +3 -0
  207. package/.next/server/chunks/ssr/_0g_rlog._.js +3 -0
  208. package/.next/server/chunks/ssr/_0geg212._.js +3 -0
  209. package/.next/server/chunks/ssr/{_1jdgjv9._.js → _0hxt2ul._.js} +2 -2
  210. package/.next/server/chunks/ssr/_0i_6q1w._.js +2 -2
  211. package/.next/server/chunks/ssr/_0lu1n_x._.js +1 -1
  212. package/.next/server/chunks/ssr/{_15j2_8f._.js → _0wzaht-._.js} +2 -2
  213. package/.next/server/chunks/ssr/_0z-g0uy._.js +3 -0
  214. package/.next/server/chunks/ssr/_123ttsf._.js +3 -0
  215. package/.next/server/chunks/ssr/_123y-ah._.js +3 -0
  216. package/.next/server/chunks/ssr/_12w42gi._.js +3 -0
  217. package/.next/server/chunks/ssr/_161kqav._.js +3 -0
  218. package/.next/server/chunks/ssr/{_0ap2fzn._.js → _16c6_xm._.js} +2 -2
  219. package/.next/server/chunks/ssr/_18opah7._.js +3 -0
  220. package/.next/server/chunks/ssr/_18xqmny._.js +3 -0
  221. package/.next/server/chunks/ssr/_1_krfph._.js +3 -0
  222. package/.next/server/chunks/ssr/_1anqots._.js +3 -0
  223. package/.next/server/chunks/ssr/_1ey7qn-._.js +70 -0
  224. package/.next/server/chunks/ssr/_1g9vs7q._.js +3 -0
  225. package/.next/server/chunks/ssr/_1jmz33w._.js +3 -0
  226. package/.next/server/chunks/ssr/_1k0spz7._.js +3 -0
  227. package/.next/server/chunks/ssr/_1rgtxhr._.js +5 -0
  228. package/.next/server/chunks/ssr/_1slp25y._.js +3 -0
  229. package/.next/server/chunks/ssr/{_0rzucul._.js → _1x9pskj._.js} +3 -3
  230. package/.next/server/chunks/ssr/_1y6b5mr._.js +101 -0
  231. package/.next/server/chunks/ssr/_1ztk7p6._.js +7 -0
  232. package/.next/server/chunks/ssr/components_ui_tabs_tsx_0ej40b4._.js +3 -0
  233. package/.next/server/chunks/ssr/features_bot_thread_query_ts_023eklt._.js +4 -0
  234. package/.next/server/chunks/ssr/features_config_components_config-setting_tsx_0xfwqdg._.js +1 -1
  235. package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
  236. package/.next/server/chunks/ssr/{_1-teee5._.js → lib_logger_ts_0-olsze._.js} +2 -7
  237. package/.next/server/chunks/ssr/{node_modules_1y79i83._.js → node_modules_00_51_v._.js} +1 -1
  238. package/.next/server/chunks/ssr/{node_modules_0m383r2._.js → node_modules_022sipm._.js} +1 -1
  239. package/.next/server/chunks/ssr/{node_modules_05-n6dz._.js → node_modules_0332gw4._.js} +1 -1
  240. package/.next/server/chunks/ssr/{node_modules_0zeg3x_._.js → node_modules_04vxchl._.js} +1 -1
  241. package/.next/server/chunks/ssr/{node_modules_07dsgkx._.js → node_modules_0746rzi._.js} +1 -1
  242. package/.next/server/chunks/ssr/{node_modules_0fkeku3._.js → node_modules_0d5uzof._.js} +1 -1
  243. package/.next/server/chunks/ssr/{node_modules_1k6n600._.js → node_modules_0exkwcm._.js} +1 -1
  244. package/.next/server/chunks/ssr/{node_modules_16mkxuo._.js → node_modules_0fr-ml8._.js} +1 -1
  245. package/.next/server/chunks/ssr/{node_modules_0iur59s._.js → node_modules_0mxvg8h._.js} +1 -1
  246. package/.next/server/chunks/ssr/{node_modules_1j8j4pt._.js → node_modules_0qapgjr._.js} +1 -1
  247. package/.next/server/chunks/ssr/{node_modules_20c28js._.js → node_modules_0qbfyjh._.js} +1 -1
  248. package/.next/server/chunks/ssr/{node_modules_1k7z2j6._.js → node_modules_0t-9nup._.js} +1 -1
  249. package/.next/server/chunks/ssr/{node_modules_17bwo43._.js → node_modules_0tusx4d._.js} +3 -3
  250. package/.next/server/chunks/ssr/{node_modules_1chvq5f._.js → node_modules_0vsxbzp._.js} +1 -1
  251. package/.next/server/chunks/ssr/{node_modules_04sksn9._.js → node_modules_0vv0-fg._.js} +1 -1
  252. package/.next/server/chunks/ssr/{node_modules_1k8j8n0._.js → node_modules_0wsvp00._.js} +1 -1
  253. package/.next/server/chunks/ssr/{node_modules_1lz0oxc._.js → node_modules_1-urho9._.js} +1 -1
  254. package/.next/server/chunks/ssr/{node_modules_1-y7nni._.js → node_modules_16pi_dd._.js} +1 -1
  255. package/.next/server/chunks/ssr/{node_modules_1uyk91w._.js → node_modules_1d53yiq._.js} +1 -1
  256. package/.next/server/chunks/ssr/{node_modules_0bvopy2._.js → node_modules_1g1eihe._.js} +1 -1
  257. package/.next/server/chunks/ssr/{node_modules_1a0kmjl._.js → node_modules_1gpednh._.js} +1 -1
  258. package/.next/server/chunks/ssr/{node_modules_0u9da1h._.js → node_modules_1gu1pph._.js} +1 -1
  259. package/.next/server/chunks/ssr/{node_modules_056qgf-._.js → node_modules_1he1w8_._.js} +1 -1
  260. package/.next/server/chunks/ssr/{node_modules_0-dr_o7._.js → node_modules_1lnjapm._.js} +1 -1
  261. package/.next/server/chunks/ssr/{node_modules_1t77e4n._.js → node_modules_1lynj9m._.js} +1 -1
  262. package/.next/server/chunks/ssr/{node_modules_0x3-ply._.js → node_modules_1seuurl._.js} +2 -2
  263. package/.next/server/chunks/ssr/{node_modules_0ifp389._.js → node_modules_1u6w1pb._.js} +1 -1
  264. package/.next/server/chunks/ssr/{node_modules_1x0ztf4._.js → node_modules_1xn6saw._.js} +1 -1
  265. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0bkwd0u._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_067_exa._.js} +1 -1
  266. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0p9a9su._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0nrrdaq._.js} +1 -1
  267. package/.next/server/chunks/ssr/{node_modules_@vercel_oidc_dist_1o553h-._.js → node_modules_@vercel_oidc_dist_21a5haa._.js} +1 -1
  268. package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_trash_mjs_0px2gzr._.js +3 -0
  269. package/.next/server/middleware-build-manifest.js +3 -3
  270. package/.next/server/pages/404.html +1 -1
  271. package/.next/server/pages/500.html +1 -1
  272. package/.next/server/server-reference-manifest.js +1 -1
  273. package/.next/server/server-reference-manifest.json +68 -46
  274. package/.next/static/chunks/0dr16v67vj4n7.js +2 -0
  275. package/.next/static/chunks/0g4b348l0pve7.js +1 -0
  276. package/.next/static/chunks/0joan-69kbspd.js +1 -0
  277. package/.next/static/chunks/0vlgzqo9ka90v.js +1 -0
  278. package/.next/static/chunks/0zrupxgci5gqc.js +1 -0
  279. package/.next/static/chunks/10k2xvap03z20.css +1 -0
  280. package/.next/static/chunks/18mkhstgiqcbt.js +1 -0
  281. package/.next/static/chunks/{435atsnhs7ksu.js → 1i-u2wzub_to1.js} +7 -7
  282. package/.next/static/chunks/1kp5nfp06nj9h.js +5 -0
  283. package/.next/static/chunks/1ohslk4568tm3.js +1 -0
  284. package/.next/static/chunks/1sbmwswc9k2-1.js +1 -0
  285. package/.next/static/chunks/1t9qms5pwwa3n.js +1 -0
  286. package/.next/static/chunks/1vj_5bnbxx84e.js +1 -0
  287. package/.next/static/chunks/1vqezbhjm3goq.js +1 -0
  288. package/.next/static/chunks/{408ueu4hfvcg7.js → 1wlo979mx-y3w.js} +1 -1
  289. package/.next/static/chunks/26ql4y-43xwhp.js +1 -0
  290. package/.next/static/chunks/{11r2yp_yh9_qn.js → 2_pnccjp6j1ca.js} +1 -1
  291. package/.next/static/chunks/2a51-ywz9b2a3.js +1 -0
  292. package/.next/static/chunks/2fvdgxih7x7hr.js +1 -0
  293. package/.next/static/chunks/2jlz8zp4jax_m.js +18 -0
  294. package/.next/static/chunks/2nvepds1fu2ux.js +1 -0
  295. package/.next/static/chunks/3addj3i4-izma.js +1 -0
  296. package/.next/static/chunks/3bfwpww3m3x4u.js +1 -0
  297. package/.next/static/chunks/3gfh7nxwusbt0.js +1 -0
  298. package/.next/static/chunks/3gwa44cvz4qoi.js +1 -0
  299. package/.next/static/chunks/{38gweqdo4jpfj.js → 3izg0a3k87q1-.js} +5 -5
  300. package/.next/static/chunks/3zk6q3-3f9swq.js +99 -0
  301. package/.next/static/chunks/3zkg5iup3v4a2.js +12 -0
  302. package/.next/static/chunks/405m0bqtoihev.js +1 -0
  303. package/.next/static/chunks/42wcg3wfg_m_p.js +1 -0
  304. package/README.md +27 -216
  305. package/app/api/events/app-event.ts +6 -4
  306. package/app/api/query-key.ts +25 -16
  307. package/bin/database.mjs +37 -0
  308. package/bin/thursday.mjs +44 -28
  309. package/components/ui/custom-icon.tsx +0 -60
  310. package/components/ui/radio-group.tsx +37 -0
  311. package/components/ui/shiny-text.tsx +33 -6
  312. package/database/migrations/{20260910173049_numerous_spirit → 20260916145701_clever_multiple_man}/migration.sql +80 -24
  313. package/database/migrations/{20260910173049_numerous_spirit → 20260916145701_clever_multiple_man}/snapshot.json +689 -110
  314. package/database/migrations/20260916160713_thread_cancelled/migration.sql +2 -0
  315. package/database/migrations/{20260911030320_opposite_jack_power → 20260916160713_thread_cancelled}/snapshot.json +706 -84
  316. package/docs/how-it-works.md +39 -36
  317. package/docs/images/keeps-going.png +0 -0
  318. package/docs/images/two-minds.png +0 -0
  319. package/docs/live-calls.md +231 -0
  320. package/docs/thread-rooms.md +71 -0
  321. package/features/ai/chatgpt.ts +1 -2
  322. package/features/ai/live.schema.ts +128 -0
  323. package/features/ai/load-tools.ts +148 -77
  324. package/features/ai/model.schema.ts +2 -120
  325. package/features/ai/model.ts +52 -88
  326. package/features/ai/prompts/bot.prompt.ts +91 -214
  327. package/features/ai/prompts/live.prompt.ts +265 -0
  328. package/features/ai/prompts/prompt-helper.ts +91 -32
  329. package/features/ai/prompts/thursday.prompt.ts +125 -172
  330. package/features/ai/tools/bot.tool.ts +38 -145
  331. package/features/ai/tools/call.tool.ts +1 -1
  332. package/features/ai/tools/connected.ts +5 -3
  333. package/features/ai/tools/mcp.tool.ts +7 -4
  334. package/features/ai/tools/memory.tool.ts +35 -31
  335. package/features/ai/tools/skills.tool.ts +11 -6
  336. package/features/ai/tools/studio.tool.ts +26 -21
  337. package/features/ai/tools/tool-name.ts +2 -5
  338. package/features/ai/tools/workspace.tool.ts +33 -10
  339. package/features/artifact/artifact.action.ts +2 -2
  340. package/features/artifact/artifact.query.ts +112 -61
  341. package/features/artifact/artifact.schema.ts +8 -6
  342. package/features/artifact/components/artifact-setting.tsx +83 -33
  343. package/features/bot/bot.action.ts +43 -36
  344. package/features/bot/bot.memory.ts +137 -20
  345. package/features/bot/bot.query.ts +28 -11
  346. package/features/bot/bot.run.ts +296 -744
  347. package/features/bot/bot.runner.ts +461 -862
  348. package/features/bot/bot.schema.ts +93 -82
  349. package/features/bot/bot.seed.ts +141 -64
  350. package/features/bot/components/bot-mark.tsx +324 -232
  351. package/features/bot/components/bot-room.tsx +1613 -697
  352. package/features/bot/components/bot-roster.tsx +8 -13
  353. package/features/bot/components/bot-setting.tsx +58 -42
  354. package/features/bot/components/bot-tool.tsx +55 -87
  355. package/features/bot/components/mark-palette.tsx +35 -32
  356. package/features/bot/components/path-chips.tsx +33 -3
  357. package/features/bot/components/thread-badge.tsx +34 -0
  358. package/features/bot/components/thread-reply.tsx +639 -0
  359. package/features/bot/components/thread-setting.tsx +674 -0
  360. package/features/bot/mark.const.ts +79 -31
  361. package/features/bot/room.query.ts +889 -0
  362. package/features/bot/room.schema.ts +64 -0
  363. package/features/bot/seed-bots.ts +2 -1
  364. package/features/bot/thread.query.ts +971 -0
  365. package/features/bot/thread.store.ts +587 -0
  366. package/features/config/components/voice-key.tsx +113 -88
  367. package/features/config/config.const.ts +5 -9
  368. package/features/connectors/mcp.schema.ts +0 -2
  369. package/features/intro/components/intro.tsx +169 -139
  370. package/features/memory/components/memory-setting.tsx +2 -7
  371. package/features/memory/memory.schema.ts +14 -23
  372. package/features/settings/components/setting-ui.tsx +0 -44
  373. package/features/settings/components/settings.tsx +12 -12
  374. package/features/settings/settings.alert.ts +3 -3
  375. package/features/settings/settings.store.ts +1 -1
  376. package/features/skills/skills.schema.ts +0 -2
  377. package/features/thursday/components/ascii-field.tsx +24 -44
  378. package/features/thursday/components/ascii-orb.tsx +359 -358
  379. package/features/thursday/components/call-log.tsx +46 -44
  380. package/features/thursday/components/face.tsx +35 -10
  381. package/features/thursday/components/tab-state.tsx +3 -3
  382. package/features/thursday/components/thursday-mark.tsx +1 -0
  383. package/features/thursday/components/thursday-setting.tsx +631 -332
  384. package/features/thursday/components/thursday.tsx +106 -41
  385. package/features/thursday/components/voice-picker.tsx +255 -0
  386. package/features/thursday/thursday.action.ts +94 -68
  387. package/features/thursday/thursday.query.ts +49 -30
  388. package/features/thursday/thursday.schema.ts +27 -30
  389. package/features/thursday/thursday.store.ts +11 -7
  390. package/features/thursday/tool-call.ts +3 -3
  391. package/features/thursday/tool-line.ts +5 -3
  392. package/features/thursday/use-thursday.ts +725 -450
  393. package/features/workspace/workspace.query.ts +17 -0
  394. package/features/workspace/workspace.ts +82 -36
  395. package/lib/live/live.schema.ts +47 -0
  396. package/lib/live/live.server.ts +155 -0
  397. package/lib/live/live.session.ts +574 -0
  398. package/lib/{realtime/realtime.tap.ts → live/live.tap.ts} +41 -12
  399. package/lib/live/live.transport.ts +152 -0
  400. package/lib/protocol/use-server-pages.ts +9 -5
  401. package/lib/utils.ts +21 -20
  402. package/package.json +2 -2
  403. package/public/voices/alloy.ogg +0 -0
  404. package/public/voices/ash.ogg +0 -0
  405. package/public/voices/ballad.ogg +0 -0
  406. package/public/voices/beacon.ogg +0 -0
  407. package/public/voices/bossa.ogg +0 -0
  408. package/public/voices/cedar.ogg +0 -0
  409. package/public/voices/cinder.ogg +0 -0
  410. package/public/voices/coral.ogg +0 -0
  411. package/public/voices/delta.ogg +0 -0
  412. package/public/voices/echo.ogg +0 -0
  413. package/public/voices/gleam.ogg +0 -0
  414. package/public/voices/marin.ogg +0 -0
  415. package/public/voices/meridian.ogg +0 -0
  416. package/public/voices/quartz.ogg +0 -0
  417. package/public/voices/ripple.ogg +0 -0
  418. package/public/voices/sage.ogg +0 -0
  419. package/public/voices/shimmer.ogg +0 -0
  420. package/public/voices/stone.ogg +0 -0
  421. package/public/voices/tempo.ogg +0 -0
  422. package/public/voices/verse.ogg +0 -0
  423. package/public/voices/vesper.ogg +0 -0
  424. package/public/voices/willow.ogg +0 -0
  425. package/scripts/artifact-paths.test.mts +25 -0
  426. package/scripts/bot-context.test.mts +1408 -0
  427. package/scripts/live-history.test.mts +115 -0
  428. package/scripts/live-session.test.mts +948 -0
  429. package/server.js +1 -1
  430. package/skills/browser/SKILL.md +11 -1
  431. package/skills/computer/SKILL.md +1 -1
  432. package/skills/find-skills/SKILL.md +3 -8
  433. package/skills/interactive-page/SKILL.md +12 -7
  434. package/skills/interactive-page/references/diagram.md +89 -0
  435. package/skills/interactive-page/scripts/archify/LICENSE +22 -0
  436. package/skills/interactive-page/scripts/archify/README.md +25 -0
  437. package/skills/interactive-page/scripts/archify/assets/JetBrainsMono-OFL.txt +93 -0
  438. package/skills/interactive-page/scripts/archify/assets/template.html +14934 -0
  439. package/skills/interactive-page/scripts/archify/bin/archify.mjs +2126 -0
  440. package/skills/interactive-page/scripts/archify/bin/open-artifact.mjs +86 -0
  441. package/skills/interactive-page/scripts/archify/bin/preview.mjs +653 -0
  442. package/skills/interactive-page/scripts/archify/bin/visual-check.mjs +829 -0
  443. package/skills/interactive-page/scripts/archify/delta/architecture-delta.mjs +1223 -0
  444. package/skills/interactive-page/scripts/archify/examples/agent-run.lifecycle.json +60 -0
  445. package/skills/interactive-page/scripts/archify/examples/agent-tool-call.workflow.json +94 -0
  446. package/skills/interactive-page/scripts/archify/examples/async-job-roundtrip.sequence.json +61 -0
  447. package/skills/interactive-page/scripts/archify/examples/cache-miss-request.sequence.json +82 -0
  448. package/skills/interactive-page/scripts/archify/examples/checkout-platform.base.architecture.json +31 -0
  449. package/skills/interactive-page/scripts/archify/examples/checkout-platform.head.architecture.json +31 -0
  450. package/skills/interactive-page/scripts/archify/examples/deployment-release.lifecycle.json +49 -0
  451. package/skills/interactive-page/scripts/archify/examples/event-stream.dataflow.json +57 -0
  452. package/skills/interactive-page/scripts/archify/examples/incident-response.workflow.json +64 -0
  453. package/skills/interactive-page/scripts/archify/examples/product-analytics.dataflow.json +76 -0
  454. package/skills/interactive-page/scripts/archify/examples/production-deployment.architecture.json +71 -0
  455. package/skills/interactive-page/scripts/archify/examples/release-delivery.workflow.json +62 -0
  456. package/skills/interactive-page/scripts/archify/examples/web-app.architecture.json +46 -0
  457. package/skills/interactive-page/scripts/archify/migrations/workflow-v2.mjs +279 -0
  458. package/skills/interactive-page/scripts/archify/recipes/scenarios.mjs +284 -0
  459. package/skills/interactive-page/scripts/archify/references/authoring-contract.md +243 -0
  460. package/skills/interactive-page/scripts/archify/references/delivery-contract.md +120 -0
  461. package/skills/interactive-page/scripts/archify/references/viewer-runtime.md +45 -0
  462. package/skills/interactive-page/scripts/archify/renderers/architecture/grid.mjs +62 -0
  463. package/skills/interactive-page/scripts/archify/renderers/architecture/render-architecture.mjs +1078 -0
  464. package/skills/interactive-page/scripts/archify/renderers/dataflow/README.md +104 -0
  465. package/skills/interactive-page/scripts/archify/renderers/dataflow/render-dataflow.mjs +483 -0
  466. package/skills/interactive-page/scripts/archify/renderers/lifecycle/README.md +115 -0
  467. package/skills/interactive-page/scripts/archify/renderers/lifecycle/render-lifecycle.mjs +561 -0
  468. package/skills/interactive-page/scripts/archify/renderers/sequence/README.md +114 -0
  469. package/skills/interactive-page/scripts/archify/renderers/sequence/render-sequence.mjs +464 -0
  470. package/skills/interactive-page/scripts/archify/renderers/shared/brand-marks.mjs +563 -0
  471. package/skills/interactive-page/scripts/archify/renderers/shared/cli.mjs +218 -0
  472. package/skills/interactive-page/scripts/archify/renderers/shared/desktop-readability.mjs +26 -0
  473. package/skills/interactive-page/scripts/archify/renderers/shared/diagnostics.mjs +127 -0
  474. package/skills/interactive-page/scripts/archify/renderers/shared/engineering-profiles.mjs +157 -0
  475. package/skills/interactive-page/scripts/archify/renderers/shared/generated-brand-marks.mjs +3 -0
  476. package/skills/interactive-page/scripts/archify/renderers/shared/generated-validators.mjs +13 -0
  477. package/skills/interactive-page/scripts/archify/renderers/shared/geometry.mjs +1423 -0
  478. package/skills/interactive-page/scripts/archify/renderers/shared/i18n.mjs +595 -0
  479. package/skills/interactive-page/scripts/archify/renderers/shared/layout-report.mjs +40 -0
  480. package/skills/interactive-page/scripts/archify/renderers/shared/legend.mjs +217 -0
  481. package/skills/interactive-page/scripts/archify/renderers/shared/output-path.mjs +340 -0
  482. package/skills/interactive-page/scripts/archify/renderers/shared/repository-evidence.mjs +238 -0
  483. package/skills/interactive-page/scripts/archify/renderers/shared/repository-location.mjs +58 -0
  484. package/skills/interactive-page/scripts/archify/renderers/shared/text-fit.mjs +49 -0
  485. package/skills/interactive-page/scripts/archify/renderers/shared/utils.mjs +232 -0
  486. package/skills/interactive-page/scripts/archify/renderers/shared/validator.mjs +86 -0
  487. package/skills/interactive-page/scripts/archify/renderers/workflow/README.md +223 -0
  488. package/skills/interactive-page/scripts/archify/renderers/workflow/render-workflow.mjs +35 -0
  489. package/skills/interactive-page/scripts/archify/renderers/workflow/workflow-compiler.mjs +4400 -0
  490. package/skills/interactive-page/scripts/archify/renderers/workflow/workflow-migration-geometry.mjs +144 -0
  491. package/skills/interactive-page/scripts/archify/schemas/README.md +211 -0
  492. package/skills/interactive-page/scripts/archify/schemas/architecture.schema.json +178 -0
  493. package/skills/interactive-page/scripts/archify/schemas/common.schema.json +115 -0
  494. package/skills/interactive-page/scripts/archify/schemas/dataflow.schema.json +243 -0
  495. package/skills/interactive-page/scripts/archify/schemas/lifecycle.schema.json +266 -0
  496. package/skills/interactive-page/scripts/archify/schemas/sequence.schema.json +223 -0
  497. package/skills/interactive-page/scripts/archify/schemas/workflow.schema.json +428 -0
  498. package/skills/interactive-page/scripts/archify/scripts/check-render-output.mjs +916 -0
  499. package/skills/interactive-page/scripts/archify/scripts/render-examples.mjs +26 -0
  500. package/skills/interactive-page/scripts/bundle-artifact.sh +9 -8
  501. package/skills/skill-creator/SKILL.md +4 -5
  502. package/.next/server/app/api/bot/task/[id]/route/app-paths-manifest.json +0 -3
  503. package/.next/server/app/api/bot/task/[id]/route.js +0 -16
  504. package/.next/server/app/api/bot/task/[id]/route.js.nft.json +0 -1
  505. package/.next/server/app/api/bot/task/[id]/route_client-reference-manifest.js +0 -3
  506. package/.next/server/app/api/bot/task/route/app-paths-manifest.json +0 -3
  507. package/.next/server/app/api/bot/task/route.js +0 -16
  508. package/.next/server/app/api/bot/task/route.js.nft.json +0 -1
  509. package/.next/server/app/api/bot/task/route_client-reference-manifest.js +0 -3
  510. package/.next/server/chunks/[root-of-the-server]__026u77e._.js +0 -5
  511. package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +0 -3
  512. package/.next/server/chunks/[root-of-the-server]__050zri4._.js +0 -3
  513. package/.next/server/chunks/[root-of-the-server]__0bg9710._.js +0 -3
  514. package/.next/server/chunks/[root-of-the-server]__0ffbg85._.js +0 -3
  515. package/.next/server/chunks/[root-of-the-server]__0in-d5s._.js +0 -3
  516. package/.next/server/chunks/[root-of-the-server]__0ncs9uu._.js +0 -3
  517. package/.next/server/chunks/[root-of-the-server]__0pa9k-f._.js +0 -8
  518. package/.next/server/chunks/[root-of-the-server]__0qi_m0e._.js +0 -8
  519. package/.next/server/chunks/[root-of-the-server]__0tq0m_k._.js +0 -3
  520. package/.next/server/chunks/[root-of-the-server]__0xep6j_._.js +0 -3
  521. package/.next/server/chunks/[root-of-the-server]__1-ga0kh._.js +0 -5
  522. package/.next/server/chunks/[root-of-the-server]__11n256_._.js +0 -5
  523. package/.next/server/chunks/[root-of-the-server]__144l7qt._.js +0 -8
  524. package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +0 -5
  525. package/.next/server/chunks/[root-of-the-server]__1anc1p9._.js +0 -3
  526. package/.next/server/chunks/[root-of-the-server]__1fizn31._.js +0 -3
  527. package/.next/server/chunks/[root-of-the-server]__1jg8t86._.js +0 -8
  528. package/.next/server/chunks/[root-of-the-server]__1lldzy9._.js +0 -3
  529. package/.next/server/chunks/[root-of-the-server]__1llj3-b._.js +0 -3
  530. package/.next/server/chunks/[root-of-the-server]__1p8m3f4._.js +0 -3
  531. package/.next/server/chunks/[root-of-the-server]__1peqvsi._.js +0 -3
  532. package/.next/server/chunks/[root-of-the-server]__1w8gm5h._.js +0 -10
  533. package/.next/server/chunks/[root-of-the-server]__1xt39nn._.js +0 -8
  534. package/.next/server/chunks/[root-of-the-server]__1zb8mfo._.js +0 -8
  535. package/.next/server/chunks/_0-73of8._.js +0 -55
  536. package/.next/server/chunks/_0-fjql4._.js +0 -31
  537. package/.next/server/chunks/_00xh_q0._.js +0 -25
  538. package/.next/server/chunks/_051qh8u._.js +0 -3
  539. package/.next/server/chunks/_05sovvj._.js +0 -3
  540. package/.next/server/chunks/_091bi8d._.js +0 -3
  541. package/.next/server/chunks/_0fzqt2y._.js +0 -142
  542. package/.next/server/chunks/_0lr92vd._.js +0 -3
  543. package/.next/server/chunks/_0mecv0f._.js +0 -31
  544. package/.next/server/chunks/_0mh8j4m._.js +0 -3
  545. package/.next/server/chunks/_0sb7tlz._.js +0 -3
  546. package/.next/server/chunks/_0si7xzn._.js +0 -3
  547. package/.next/server/chunks/_0u10wmw._.js +0 -55
  548. package/.next/server/chunks/_0wp4le3._.js +0 -3
  549. package/.next/server/chunks/_0y5fg-x._.js +0 -3
  550. package/.next/server/chunks/_1230wbx._.js +0 -10
  551. package/.next/server/chunks/_12nheja._.js +0 -3
  552. package/.next/server/chunks/_13510xh._.js +0 -3
  553. package/.next/server/chunks/_15hq89o._.js +0 -3
  554. package/.next/server/chunks/_18-1wcc._.js +0 -55
  555. package/.next/server/chunks/_18d7-5p._.js +0 -3
  556. package/.next/server/chunks/_1c78vw5._.js +0 -237
  557. package/.next/server/chunks/_1h5_8sk._.js +0 -3
  558. package/.next/server/chunks/_1hdnxb7._.js +0 -3
  559. package/.next/server/chunks/_1j8k_j5._.js +0 -3
  560. package/.next/server/chunks/_1nula3v._.js +0 -3
  561. package/.next/server/chunks/_1php4eq._.js +0 -3
  562. package/.next/server/chunks/_1yuv4vp._.js +0 -3
  563. package/.next/server/chunks/_1zkfbaa._.js +0 -3
  564. package/.next/server/chunks/_next-internal_server_app_api_bot_task_[id]_route_actions_1_k_8u3.js +0 -3
  565. package/.next/server/chunks/_next-internal_server_app_api_bot_task_route_actions_0xln6ra.js +0 -3
  566. package/.next/server/chunks/features_0rpfxbk._.js +0 -3
  567. package/.next/server/chunks/features_1qf3cei._.js +0 -8
  568. package/.next/server/chunks/features_bot_0zt92oh._.js +0 -3
  569. package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1jidylq._.js +0 -3
  570. package/.next/server/chunks/ssr/[externals]__0dizgek._.js +0 -3
  571. package/.next/server/chunks/ssr/[root-of-the-server]__0-nob52._.js +0 -4
  572. package/.next/server/chunks/ssr/[root-of-the-server]__092knlj._.js +0 -3
  573. package/.next/server/chunks/ssr/[root-of-the-server]__0mz33a7._.js +0 -3
  574. package/.next/server/chunks/ssr/[root-of-the-server]__0s4wb56._.js +0 -3
  575. package/.next/server/chunks/ssr/[root-of-the-server]__0s9dq5u._.js +0 -3
  576. package/.next/server/chunks/ssr/[root-of-the-server]__0sd3izg._.js +0 -3
  577. package/.next/server/chunks/ssr/[root-of-the-server]__0vnmv-s._.js +0 -3
  578. package/.next/server/chunks/ssr/[root-of-the-server]__1-13tcn._.js +0 -43
  579. package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +0 -61
  580. package/.next/server/chunks/ssr/[root-of-the-server]__1zidpfl._.js +0 -3
  581. package/.next/server/chunks/ssr/_001_ms1._.js +0 -33
  582. package/.next/server/chunks/ssr/_01n3o0m._.js +0 -3
  583. package/.next/server/chunks/ssr/_04z2c7b._.js +0 -3
  584. package/.next/server/chunks/ssr/_06tssji._.js +0 -3
  585. package/.next/server/chunks/ssr/_0fk4c7d._.js +0 -3
  586. package/.next/server/chunks/ssr/_0h42fze._.js +0 -3
  587. package/.next/server/chunks/ssr/_0h7zdni._.js +0 -3
  588. package/.next/server/chunks/ssr/_0m2lsd1._.js +0 -3
  589. package/.next/server/chunks/ssr/_0mggveb._.js +0 -3
  590. package/.next/server/chunks/ssr/_0nbpc_8._.js +0 -3
  591. package/.next/server/chunks/ssr/_0q0zan6._.js +0 -70
  592. package/.next/server/chunks/ssr/_0zcjrbg._.js +0 -3
  593. package/.next/server/chunks/ssr/_0zhoc3r._.js +0 -3
  594. package/.next/server/chunks/ssr/_11j92tu._.js +0 -3
  595. package/.next/server/chunks/ssr/_13fke0x._.js +0 -3
  596. package/.next/server/chunks/ssr/_18cymkq._.js +0 -3
  597. package/.next/server/chunks/ssr/_1ebxla1._.js +0 -3
  598. package/.next/server/chunks/ssr/_1nj4niv._.js +0 -42
  599. package/.next/server/chunks/ssr/_1ov37if._.js +0 -3
  600. package/.next/server/chunks/ssr/_1ovmc9s._.js +0 -3
  601. package/.next/server/chunks/ssr/_1sji22n._.js +0 -3
  602. package/.next/server/chunks/ssr/_1vi_uo7._.js +0 -3
  603. package/.next/server/chunks/ssr/_1vyd1ji._.js +0 -3
  604. package/.next/server/chunks/ssr/_1xx4zlb._.js +0 -3
  605. package/.next/server/chunks/ssr/components_ui_1y1l7yj._.js +0 -3
  606. package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +0 -3
  607. package/.next/server/chunks/ssr/lib_realtime_12wg_dd._.js +0 -27
  608. package/.next/server/chunks/ssr/lib_realtime_15h_v1v._.js +0 -27
  609. package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0npjf8-._.js +0 -3
  610. package/.next/static/chunks/0n3jle9kbqfr2.js +0 -40
  611. package/.next/static/chunks/0r5qcctujhxli.js +0 -1
  612. package/.next/static/chunks/10teww7wt-f6h.js +0 -1
  613. package/.next/static/chunks/126fj4pga_72k.js +0 -1
  614. package/.next/static/chunks/159udiexf6dom.js +0 -2
  615. package/.next/static/chunks/18a96rkhi4_yd.js +0 -1
  616. package/.next/static/chunks/18gi7o2ibrgh8.js +0 -3
  617. package/.next/static/chunks/1dkjg87pxk0n9.js +0 -28
  618. package/.next/static/chunks/1q9z1tohil7xn.js +0 -1
  619. package/.next/static/chunks/1sjgfets224re.js +0 -1
  620. package/.next/static/chunks/1wszsr83t01gh.js +0 -1
  621. package/.next/static/chunks/22_zkas21rpna.js +0 -1
  622. package/.next/static/chunks/2fh4-3z_q8b_w.js +0 -1
  623. package/.next/static/chunks/2h0sd2vumhb15.js +0 -1
  624. package/.next/static/chunks/2szintyibu0s5.js +0 -1
  625. package/.next/static/chunks/2t4vhi3m8ahya.js +0 -1
  626. package/.next/static/chunks/2tigdtz3dpcy8.js +0 -1
  627. package/.next/static/chunks/3-b6b7entqazs.js +0 -1
  628. package/.next/static/chunks/3786h5vayt80-.js +0 -28
  629. package/.next/static/chunks/3cq5g494yuke8.css +0 -1
  630. package/.next/static/chunks/3dmbhsv2u_8kj.js +0 -1
  631. package/.next/static/chunks/3hibbjnt85-k6.js +0 -1
  632. package/.next/static/chunks/3i0a5px-oufgc.js +0 -1
  633. package/.next/static/chunks/3wexk9qo8zuj3.js +0 -18
  634. package/.next/static/chunks/3xk7yqgomx7yq.js +0 -1
  635. package/.next/static/chunks/3xre8bu_pk1p_.js +0 -1
  636. package/.next/static/chunks/3zv6t3i77xhr_.js +0 -1
  637. package/database/migrations/20260911030320_opposite_jack_power/migration.sql +0 -1
  638. package/docs/images/task-thread.png +0 -0
  639. package/features/bot/components/task-badge.tsx +0 -42
  640. package/features/bot/components/task-reply.tsx +0 -328
  641. package/features/bot/components/task-setting.tsx +0 -524
  642. package/features/bot/task.query.ts +0 -1079
  643. package/features/bot/task.store.ts +0 -487
  644. package/lib/realtime/client-secret.ts +0 -86
  645. package/lib/realtime/open-session.ts +0 -31
  646. package/lib/realtime/openai.ts +0 -35
  647. package/lib/realtime/realtime.audio.ts +0 -196
  648. package/lib/realtime/realtime.driver.ts +0 -489
  649. package/lib/realtime/realtime.protocol.ts +0 -393
  650. package/lib/realtime/realtime.schema.ts +0 -37
  651. package/lib/realtime/realtime.session.ts +0 -106
  652. package/lib/realtime/realtime.transport.ts +0 -384
  653. package/lib/realtime/xai.ts +0 -39
  654. /package/.next/server/app/api/bot/{task → thread}/[id]/route/build-manifest.json +0 -0
  655. /package/.next/server/app/api/bot/{task → thread}/[id]/route/server-reference-manifest.json +0 -0
  656. /package/.next/server/app/api/bot/{task → thread}/[id]/route.js.map +0 -0
  657. /package/.next/server/app/api/bot/{task → thread}/route/build-manifest.json +0 -0
  658. /package/.next/server/app/api/bot/{task → thread}/route/server-reference-manifest.json +0 -0
  659. /package/.next/server/app/api/bot/{task → thread}/route.js.map +0 -0
  660. /package/.next/static/{G6-gNoyGDEcgAsq-L4PE1 → 0qzGoKn2wTERVZtblX1tp}/_buildManifest.js +0 -0
  661. /package/.next/static/{G6-gNoyGDEcgAsq-L4PE1 → 0qzGoKn2wTERVZtblX1tp}/_clientMiddlewareManifest.js +0 -0
  662. /package/.next/static/{G6-gNoyGDEcgAsq-L4PE1 → 0qzGoKn2wTERVZtblX1tp}/_ssgManifest.js +0 -0
@@ -1,21 +1,14 @@
1
- import { stat } from "node:fs/promises";
2
- import { tool } from "ai";
3
1
  import * as z from "zod";
2
+ import { THREAD_STATUS_LIMIT } from "@/config";
4
3
  import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
5
- import { pathsIn } from "@/features/workspace/file-kind";
6
- import { insideWorkspace } from "@/features/workspace/workspace";
7
-
8
- /**
9
- * Specs for the tools that move work between the voice session and bots. Only what the model
10
- * sees lives here; execution belongs to whoever runs the tool (load-tools, bot.run), and the
11
- * screen draws a call off its spec (task.query). `answer` has its own execute because what it
12
- * checks is a file on disk.
13
- */
4
+ import { THREAD_CONTINUE } from "@/features/bot/bot.schema";
5
+ import { RoomMessageSchema } from "@/features/bot/room.schema";
14
6
 
7
+ /** Tools for starting a thread, sending messages, and following work from the call. */
15
8
  export const delegateSpec = {
16
9
  name: TOOL_NAMES.delegate,
17
10
  description:
18
- "Hand a job to a bot. Returns immediately; the job runs in the background and its result is put in front of you later.",
11
+ "Hand a job to a bot. Returns a receipt at once; the job runs in the background and its updates reach the conversation on their own.",
19
12
  parameters: z.object({
20
13
  bot: z.string().describe("A name from the bot list."),
21
14
  request: z
@@ -32,166 +25,66 @@ export const delegateSpec = {
32
25
  }),
33
26
  };
34
27
 
35
- /**
36
- * `context` carries what the asking bot found, since its thread is not handed over (bot.run).
37
- * A returning participant keeps its own thread; `context` adds only what this caller knows.
38
- */
39
- export const askBotSpec = {
40
- name: TOOL_NAMES.ask_bot,
28
+ export const sendMessageSpec = {
41
29
  description:
42
- "Send a request to another bot on this job and wait for their reply. The same bot continues its own work and conversation whenever you ask it again. The job stays yours.",
43
- parameters: z.object({
44
- bot: z.string().describe("A name from the bot list."),
45
- request: z
30
+ "Send a message to a participant or Thursday and receive a delivery receipt immediately. Mark a question for Thursday to request user input; ordinary messages to Thursday are notifications and need no answer.",
31
+ parameters: RoomMessageSchema.extend({
32
+ kind: RoomMessageSchema.shape.kind.describe(
33
+ "Use question only when Thursday must obtain an answer from the user: it ends your turn, and you continue when the answer arrives. Use message for bot collaboration, progress updates and reports.",
34
+ ),
35
+ options: RoomMessageSchema.shape.options.describe(
36
+ "With a question, offer concise answer choices when useful. Omit for an open-ended question; the user can always type their own answer.",
37
+ ),
38
+ to: z
46
39
  .string()
47
- .describe(
48
- "The part they take: the outcome you want, the shape to hand it back in (a path, a number, a list), and every name, path, number and limit that bears on it. It reaches them under the job and the call it came from, which are attached for you — write the part, not the job again.",
49
- ),
50
- context: z
40
+ .trim()
41
+ .min(1)
42
+ .describe("Choose a bot from the roster, or Thursday to reach the user."),
43
+ text: z
51
44
  .string()
45
+ .trim()
46
+ .min(1)
52
47
  .describe(
53
- "Pass on what you know that they do not: exact values and paths they need. They keep their own previous work and your exchanges, but cannot read your private thread or tool output.",
48
+ "Write the message and include the context the recipient needs.",
54
49
  ),
55
- }),
56
- };
57
-
58
- /**
59
- * The borrowed bot's one way up. The borrowing bot answers in one model call over its own
60
- * context, without tools (bot.run answerBack); nothing stops. No options, since nobody reads
61
- * these aloud; the count is structural (bot.run MAX_ASK_BACK).
62
- */
63
- export const askBackSpec = {
64
- name: TOOL_NAMES.ask_back,
65
- description:
66
- "Ask the bot that handed you this part. They answer from what they have — the original request, the call it came from, what they found before asking you.",
67
- parameters: z.object({
68
- question: z
50
+ replyTo: z
69
51
  .string()
52
+ .nullish()
70
53
  .describe(
71
- "One whole question — what you need and why. They cannot take it to the user for you, so ask what they would know.",
54
+ "Use an incoming message ID to send an explicit reply; omit to start a new exchange. Your ordinary final text already replies to your current correspondent.",
72
55
  ),
73
56
  }),
74
57
  };
75
58
 
76
- /**
77
- * A bot stopping in front of something it cannot get on its own. No `execute` on purpose:
78
- * the loop halts on a tool without one (ai-sdk), the run is stored as `waiting`, and the
79
- * answer returns as this call's result on resume (bot.runner). Only the bot holding the job
80
- * may ask. Options are the one structure that works both on screen and read aloud; there is
81
- * no input type.
82
- */
83
- export const askThursdaySpec = {
84
- name: TOOL_NAMES.ask_thursday,
85
- description:
86
- "Ask Thursday, who handed you this job. The job stops until an answer comes back.",
59
+ /** The voice session's handle on a job already handed over. Run by the server, like `delegate` (load-tools). */
60
+ export const threadSpec = {
61
+ name: TOOL_NAMES.thread,
62
+ description: `List up to ${THREAD_STATUS_LIMIT} jobs, prioritizing running and waiting work before recent endings; inspect one job, answer it, cancel it, open it on the user's screen, or mark it seen — the same as the user opening it, which takes it off the work waiting on them.`,
87
63
  parameters: z.object({
88
- question: z
64
+ action: z.enum(["status", "answer", "cancel", "open", "seen"]),
65
+ recipient: z
89
66
  .string()
90
- .describe(
91
- "One whole question — what you need and why. One or two sentences, in the user's language: she may read it to them out loud, options and all.",
92
- ),
93
- // A string is accepted as well as an array: a provider may serialize the array as one
94
- // joined string, and a schema rejection only loops. The reader takes arrays only (task.query optionsOf)
95
- options: z
96
- .union([z.string().array(), z.string()])
97
67
  .nullish()
98
68
  .describe(
99
- 'Only when there really are choices — two or three, each short, as an array: ["Signed in", "Not yet"]. Null for an open question.',
69
+ "With answer, name the participant to receive it. Words to a participant waiting on its question answer that question; omit to reach the only open question, or the coordinator when none is open.",
100
70
  ),
101
- }),
102
- };
103
-
104
- /**
105
- * The one way a run ends on its own terms; the loop is stopped by it (`hasToolCall`, bot.run).
106
- * Whether the job is over is the runtime's to say, never an argument: an answer ends it, and a
107
- * run the app stopped first (bot.run `stopped`) waits to be continued.
108
- */
109
- export const answerSpec = {
110
- name: TOOL_NAMES.answer,
111
- description:
112
- "Answer the job you were given. Calling this ends the job — nothing after it runs.",
113
- parameters: z.object({
114
- result: z
71
+ replyTo: z
115
72
  .string()
73
+ .nullish()
116
74
  .describe(
117
- "The answer itself — what you found or did, not a replay of how. As long as the answer needs and no longer: one number is one line. In the user's language; the thread is on their screen. If you could not do it, say what stopped you.",
75
+ "With answer, use the message ID of the question being answered when several questions are open.",
118
76
  ),
119
- }),
120
- };
121
-
122
- /** The voice session's handle on a job already handed over. Run by the server, like `delegate` (load-tools). */
123
- export const taskSpec = {
124
- name: TOOL_NAMES.task,
125
- description:
126
- "Check a job you handed over, answer what it is asking, or cancel it.",
127
- parameters: z.object({
128
- action: z.enum(["status", "answer", "cancel"]),
129
- task: z
77
+ thread: z
130
78
  .string()
131
79
  .nullish()
132
80
  .describe(
133
- 'The job, by its label or by the handle a past call\'s transcript carries. Leave it out with `answer` and it goes to the job that moved last — what "that one" means a moment after it answered. With `status`: null for every job in one line each — that is the list — or name one to get its answer in full.',
81
+ `Identify the job by label or ID. With status, omit or use null to list up to ${THREAD_STATUS_LIMIT} jobs, prioritizing open work and filling remaining places with recent endings; name one to read its full result and pending questions. With open, omit to show the job that moved last. With answer, omit only to answer the one question waiting.`,
134
82
  ),
135
83
  answer: z
136
84
  .string()
137
85
  .nullish()
138
86
  .describe(
139
- "With `answer`: what to tell the bot — the answer to its question, a course correction for a job still running, or what to do next on one that finished.",
87
+ `With \`answer\`: what to tell the bot — the answer to its question, a course correction for a job still running, or what to do next on one that finished. \`${THREAD_CONTINUE}\` carries on a job that stopped before finishing, from where it was.`,
140
88
  ),
141
89
  }),
142
90
  };
143
-
144
- /** Deliberately no `execute` — the loop halts here. See askThursdaySpec. */
145
- export const askThursdayTool = tool({
146
- description: askThursdaySpec.description,
147
- inputSchema: askThursdaySpec.parameters,
148
- });
149
-
150
- /**
151
- * `answer` does have an execute, and it only acknowledges. The loop is stopped
152
- * by `hasToolCall` after the step, not by the absence of an execute — that way
153
- * the call and its result are both written to the thread, and a resumed run
154
- * reads a finished exchange rather than a call left hanging.
155
- */
156
- export const answerTool = tool({
157
- description: answerSpec.description,
158
- inputSchema: answerSpec.parameters,
159
- execute: async ({ result }) => {
160
- const missing = await missingFiles(result);
161
- if (missing.length) {
162
- return `${NOT_ANSWERED} these files do not exist — ${missing.join(", ")}. Write them first, or take the paths out of the answer.`;
163
- }
164
- return "Answered. The job is closed; nothing further runs.";
165
- },
166
- });
167
-
168
- /**
169
- * An answer naming a workspace file that does not exist is refused: the path becomes a link
170
- * and opens by itself (bot.runner artifactIn). Paths outside the workspace are not checked.
171
- */
172
- const NOT_ANSWERED = "Not answered:";
173
-
174
- /**
175
- * `answer` was called `report` before it was renamed. A stored thread keeps the name the
176
- * call was made under, and the room draws that call as the job's prose — so the three
177
- * places that read messages back match either name. Nothing writes the old one.
178
- */
179
- export const isAnswerCall = (toolName: string): boolean =>
180
- toolName === TOOL_NAMES.answer || toolName === "report";
181
-
182
- export const answerAccepted = (output: unknown): boolean =>
183
- typeof output !== "string" || !output.startsWith(NOT_ANSWERED);
184
-
185
- async function missingFiles(result: string): Promise<string[]> {
186
- const missing: string[] = [];
187
- for (const rel of pathsIn(result)) {
188
- const full = await insideWorkspace(rel);
189
- if (!full) continue;
190
- const exists = await stat(full).then(
191
- (info) => info.isFile(),
192
- () => false,
193
- );
194
- if (!exists) missing.push(rel);
195
- }
196
- return missing;
197
- }
@@ -11,7 +11,7 @@ export const endCallSpec = {
11
11
  name: TOOL_NAMES.end_call,
12
12
  description: `End the call.
13
13
 
14
- Say goodbye first — nothing said after this reaches the user.`,
14
+ The line stays open until this runs, and drops once the goodbye being said is over.`,
15
15
  parameters: z.object({}),
16
16
  };
17
17
 
@@ -88,7 +88,8 @@ export async function callConnectedTool(
88
88
  server: string,
89
89
  name: string,
90
90
  args: Record<string, unknown> | undefined,
91
- abortSignal?: AbortSignal,
91
+ /** `artifacts`: the calling bot's folder, where the studio saves what it makes (workspace.ts botArtifacts). */
92
+ { artifacts, abortSignal }: { artifacts: string; abortSignal?: AbortSignal },
92
93
  ): Promise<McpCallOutcome> {
93
94
  const deadline = AbortSignal.timeout(CONNECTED_TOOL_TIMEOUT_MS);
94
95
  const signal = abortSignal
@@ -97,7 +98,7 @@ export async function callConnectedTool(
97
98
  try {
98
99
  const text =
99
100
  server === STUDIO_SERVER
100
- ? await callStudioTool(sandbox, name, args, signal)
101
+ ? await callStudioTool(sandbox, name, args, artifacts, signal)
101
102
  : await callMcpTool(server, name, args, signal);
102
103
  if (typeof text !== "string") return text;
103
104
  return {
@@ -126,6 +127,7 @@ async function callStudioTool(
126
127
  sandbox: Sandbox,
127
128
  name: string,
128
129
  args: Record<string, unknown> | undefined,
130
+ artifacts: string,
129
131
  abortSignal?: AbortSignal,
130
132
  ): Promise<string> {
131
133
  const tool = (await loadStudio()).find((one) => one.name === name);
@@ -135,7 +137,7 @@ async function callStudioTool(
135
137
  `"${name}" is not in the ${STUDIO_SERVER} right now — the key that runs it is gone.`,
136
138
  );
137
139
  }
138
- return tool.execute(args ?? {}, { sandbox, abortSignal });
140
+ return tool.execute(args ?? {}, { sandbox, artifacts, abortSignal });
139
141
  }
140
142
 
141
143
  /** Definitions come from what the last connect stored (mcp.query); a session is opened only for a tool that runs (mcp.manager). */
@@ -2,6 +2,7 @@ import { jsonSchema, type ToolSet, tool } from "ai";
2
2
  import * as z from "zod";
3
3
  import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
4
4
  import { findPinnedTools } from "@/features/connectors/mcp.query";
5
+ import { botArtifacts } from "@/features/workspace/workspace";
5
6
  import type { Sandbox } from "@/lib/sandbox";
6
7
  import {
7
8
  callConnectedTool,
@@ -89,6 +90,7 @@ export async function createMcpTools(
89
90
  findPinnedTools(botName),
90
91
  ]);
91
92
  const tools: ToolSet = {};
93
+ const artifacts = botArtifacts(botName);
92
94
 
93
95
  for (const entry of pinned) {
94
96
  const key = toolNameFor(entry.server, entry.name);
@@ -110,13 +112,14 @@ export async function createMcpTools(
110
112
  entry.server,
111
113
  entry.name,
112
114
  (args ?? undefined) as Record<string, unknown> | undefined,
113
- abortSignal,
115
+ { artifacts, abortSignal },
114
116
  ),
115
117
  });
116
118
  }
117
119
 
118
120
  // The search pair only when something is left to find; otherwise `tool_search` could only refuse
119
- if (all.length > pinned.length) Object.assign(tools, searchPair(sandbox));
121
+ if (all.length > pinned.length)
122
+ Object.assign(tools, searchPair(sandbox, artifacts));
120
123
  return tools;
121
124
  }
122
125
 
@@ -132,7 +135,7 @@ async function whatExists(server: string): Promise<string> {
132
135
  : "Nothing is connected.";
133
136
  }
134
137
 
135
- const searchPair = (sandbox: Sandbox): ToolSet => ({
138
+ const searchPair = (sandbox: Sandbox, artifacts: string): ToolSet => ({
136
139
  [TOOL_NAMES.tool_search]: tool({
137
140
  description: mcpToolSpec[TOOL_NAMES.tool_search].description,
138
141
  inputSchema: mcpToolSpec[TOOL_NAMES.tool_search].parameters,
@@ -179,7 +182,7 @@ const searchPair = (sandbox: Sandbox): ToolSet => ({
179
182
  server.trim(),
180
183
  name.trim(),
181
184
  args ?? undefined,
182
- abortSignal,
185
+ { artifacts, abortSignal },
183
186
  );
184
187
  },
185
188
  }),
@@ -15,16 +15,21 @@ import {
15
15
  writeNotes,
16
16
  } from "@/features/memory/memory.query";
17
17
  import {
18
- APP_NAMED_NOTES,
19
18
  appNoteLine,
20
- isAppNamed,
19
+ isAlwaysListed,
21
20
  isMemoryPath,
22
- MEMORY_INBOX,
21
+ MEMORY_ALWAYS_LISTED,
22
+ MEMORY_PATHS,
23
23
  type MemoryNoteView,
24
24
  type MemorySource,
25
25
  } from "@/features/memory/memory.schema";
26
26
  import { readCallConversation } from "@/features/thursday/thursday.query";
27
27
 
28
+ /** `profile, preferences, people/<name>, …` — the shapes a new note's path may take. */
29
+ const PATH_SHAPES = MEMORY_PATHS.map((entry) =>
30
+ entry.path.endsWith("/") ? `${entry.path}<name>` : entry.path,
31
+ ).join(", ");
32
+
28
33
  const GONE =
29
34
  "Deleted for good. The listing in your instructions is from when this session opened and still shows it that way until the next one.";
30
35
 
@@ -107,7 +112,7 @@ export const createMemoryTools = (
107
112
  path: z
108
113
  .string()
109
114
  .describe(
110
- "Exactly as the listing writes it, or a new path following the same convention.",
115
+ "The group this note is found by — the person, project or topic its facts are about. Exactly as the listing writes it, or a new path following the same convention. A fact goes under the one note it is about; other notes name it rather than repeat it.",
111
116
  ),
112
117
  facts: z
113
118
  .object({
@@ -121,7 +126,7 @@ export const createMemoryTools = (
121
126
  .int()
122
127
  .nullish()
123
128
  .describe(
124
- "The id of the fact this replaces — from this note as handed back here or by `memory_recall`. Null if this is new. A fact that stopped being true is replaced rather than deleted, and so is a note saying the same thing twice: replacing keeps what changed on the record, deleting does not.",
129
+ `The id of the fact this replaces — from this note as handed back here or by \`${TOOL_NAMES.memory_recall}\`. Null if this is new. A fact that stopped being true is replaced rather than deleted, and so is a note saying the same thing twice: replacing keeps what changed on the record, deleting does not.`,
125
130
  ),
126
131
  alwaysLoad: z
127
132
  .boolean()
@@ -139,28 +144,27 @@ export const createMemoryTools = (
139
144
  .string()
140
145
  .nullish()
141
146
  .describe(
142
- `One line saying what this note is about, not what it currently says. Give it for a new note, or when the line no longer fits. Null leaves it; ${APP_NAMED_NOTES.join(", ")} keep their own line.`,
147
+ `One line saying what this note holds, so the listing alone tells which facts are inside. Give it for a new note, and again with new facts: rewritten from the current line and the new facts together, so it covers the whole note rather than only what was added. Null leaves it; ${MEMORY_ALWAYS_LISTED.join(", ")} keep their own line.`,
143
148
  ),
144
149
  aliases: z
145
150
  .string()
146
151
  .array()
147
152
  .nullish()
148
153
  .describe(
149
- 'What the user calls this note out loud, in the language they say it — the words they would use to ask for it, not the facts inside. A note at people/yuri might be "Yuri" and "my wife". Replaces the set it has, so send the whole set. Null leaves it.',
154
+ 'What the user calls this note out loud, in the language they say it — the words they would use to ask for it, not the facts inside. A note at people/partner might be "my partner" and their first name. Replaces the set it has, so send the whole set. Null leaves it.',
150
155
  ),
151
156
  }),
152
157
  execute: async (input) => {
153
- // Resolve the name the way recall does (memory.query resolveNotePath), so a note opened by alias is written to itself, not inbox
158
+ // Resolve the name the way recall does (memory.query resolveNotePath), so a note opened by alias is written to itself
154
159
  const said = input.path.trim();
155
160
  const known = await resolveNotePath(said);
156
161
  const aliases = input.aliases ?? null;
157
- // The listing line of the app-named notes is the app's (memory.schema
158
- // isAppNamed); the model's description is ignored there and its own line
159
- // written instead, so the inbox cannot end up described by whatever fell
160
- // into it. `alwaysLoad` is not forced on them: the first-call opener
161
- // (thursday.prompt) asks the model to set it.
162
+ // The listing line of the always-listed notes is the app's (memory.schema
163
+ // MEMORY_ALWAYS_LISTED); the model's description is ignored there and
164
+ // its own line written instead. `alwaysLoad` is not forced on them: its
165
+ // own schema says what it is for (what to call them, their language).
162
166
  const target = known ?? said;
163
- const description = isAppNamed(target)
167
+ const description = isAlwaysListed(target)
164
168
  ? appNoteLine(target)
165
169
  : input.description?.trim() || null;
166
170
  const facts = input.facts ?? [];
@@ -169,31 +173,26 @@ export const createMemoryTools = (
169
173
  note: "Nothing to write: send facts, a line, names, or any of them.",
170
174
  };
171
175
  }
176
+ // Refused rather than filed elsewhere: a note is found by its path, line and names, and a catch-all keeps none of them
177
+ if (!known && !isMemoryPath(said)) {
178
+ return {
179
+ note: `Nothing was saved: "${said}" is not a path this listing can carry. Write it again under one of ${PATH_SHAPES}.`,
180
+ };
181
+ }
172
182
  // Naming amends, never creates: a note without facts is not listed (memory.query listNoteIndex)
173
183
  if (!known && !facts.length) {
174
184
  return {
175
185
  note: `Nothing on the listing called ${said}. A note comes into being with a fact — send at least one.`,
176
186
  };
177
187
  }
178
- // A new path outside the convention goes to inbox, which keeps its own line and takes no aliases
179
- const toInbox = !known && !isMemoryPath(said);
180
- const filed = toInbox
181
- ? {
182
- path: MEMORY_INBOX,
183
- description: appNoteLine(MEMORY_INBOX),
184
- facts,
185
- }
186
- : { path: target, description, aliases, facts };
187
188
 
188
- const write = await writeNotes([filed], source, callId);
189
+ const write = await writeNotes(
190
+ [{ path: target, description, aliases, facts }],
191
+ source,
192
+ callId,
193
+ );
189
194
 
190
195
  // The write already succeeded; what follows are requests, not failures.
191
- // Only a path that landed in inbox is said: one reached by a name the
192
- // listing carries is where it was asked for, however it was spelled.
193
- const elsewhere = toInbox
194
- ? ` Filed under ${filed.path}: "${said}" is not a path this listing can carry. If that is not where it belongs, write it again under one that is.`
195
- : "";
196
-
197
196
  const unnamed = write.unnamed.length
198
197
  ? ` ${write.unnamed[0]} is new and has no line yet — the listing shows its first fact instead. Call again with \`description\` (one line about what it is) and \`aliases\` (the names they say for it).`
199
198
  : "";
@@ -206,9 +205,14 @@ export const createMemoryTools = (
206
205
  )} saved as an ordinary fact. Say which carried line you would drop for it and let them choose.`
207
206
  : "";
208
207
  const written = withCount(write.notes[0]);
208
+ // New facts under a line that was not resent: the listing is what a later call opens a note by
209
+ const stale =
210
+ known && facts.length && !description
211
+ ? ` Its line still reads "${written.description}"; if that no longer says what the note holds, send \`description\`.`
212
+ : "";
209
213
  return {
210
214
  ...written,
211
- note: `${WROTE}${elsewhere}${unnamed}${notLoaded}${overSize(written.factCount)}`,
215
+ note: `${WROTE}${unnamed}${notLoaded}${stale}${overSize(written.factCount)}`,
212
216
  };
213
217
  },
214
218
  }),
@@ -1,7 +1,10 @@
1
1
  import { tool } from "ai";
2
2
  import z from "zod";
3
3
  import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
4
- import type { SkillMetadata } from "@/features/skills/skills.discover";
4
+ import {
5
+ loadSkills,
6
+ type SkillMetadata,
7
+ } from "@/features/skills/skills.discover";
5
8
  import { splitFrontmatter } from "@/features/skills/skills.query";
6
9
  import type { Sandbox } from "@/lib/sandbox";
7
10
 
@@ -24,17 +27,19 @@ export const createSkillTools = ({
24
27
  name: z
25
28
  .string()
26
29
  .describe(
27
- "Exact name from the Skills list. Do not guess names that are not on it.",
30
+ "Exact name from the Skills list, or of a skill installed during this job. Do not guess names.",
28
31
  ),
29
32
  }),
30
33
  execute: async ({ name }, { messages }) => {
31
- const skill = skills.find(
32
- (s) => s.name.toLowerCase() === name.toLowerCase(),
33
- );
34
+ const named = (list: SkillMetadata[]) =>
35
+ list.find((s) => s.name.toLowerCase() === name.toLowerCase());
36
+ // The list is read when the run starts; a skill installed since is only on disk
37
+ const listed = named(skills) ? skills : await loadSkills(sandbox);
38
+ const skill = named(listed);
34
39
  if (!skill) {
35
40
  return {
36
41
  error: `No skill named '${name}'.`,
37
- available: skills.map((s) => s.name),
42
+ available: listed.map((s) => s.name),
38
43
  };
39
44
  }
40
45
 
@@ -8,7 +8,6 @@ import {
8
8
  } from "ai";
9
9
  import { format } from "date-fns";
10
10
  import z from "zod";
11
- import { PATHS } from "@/config";
12
11
  import {
13
12
  buildImageModel,
14
13
  buildSpeechModel,
@@ -25,9 +24,20 @@ import { errorToString } from "@/lib/utils";
25
24
  * Media tools (image, speech, transcription, video), exposed behind `tool_search`/`tool_call`
26
25
  * under one server name (config STUDIO_SERVER) like an MCP server's tools. They are code rather
27
26
  * than skills or shell commands because each needs a key, and keys never reach a bot's shell.
28
- * Bytes go to a file under `artifacts/`; only the path travels, since tool results are replayed on every resume.
27
+ * Bytes go to a file in the calling bot's artifacts folder; only the path travels, since tool results are replayed on every resume.
29
28
  */
30
29
 
30
+ /**
31
+ * What a run hands a studio tool: the shell's sandbox, and `artifacts`, the
32
+ * calling bot's folder, which is where what it makes is finished work the user
33
+ * opens (workspace.ts botArtifacts).
34
+ */
35
+ type StudioContext = {
36
+ sandbox: Sandbox;
37
+ artifacts: string;
38
+ abortSignal?: AbortSignal;
39
+ };
40
+
31
41
  /** One studio tool as `tool_search` describes it and `tool_call` runs it. The zod schema becomes JSON Schema for the model (connected.ts). */
32
42
  export type StudioTool = {
33
43
  name: string;
@@ -35,7 +45,7 @@ export type StudioTool = {
35
45
  inputSchema: z.ZodObject<z.ZodRawShape>;
36
46
  execute: (
37
47
  args: Record<string, unknown>,
38
- ctx: { sandbox: Sandbox; abortSignal?: AbortSignal },
48
+ ctx: StudioContext,
39
49
  ) => Promise<string>;
40
50
  };
41
51
 
@@ -46,7 +56,7 @@ function define<Shape extends z.ZodRawShape>(spec: {
46
56
  inputSchema: z.ZodObject<Shape>;
47
57
  execute: (
48
58
  args: z.infer<z.ZodObject<Shape>>,
49
- ctx: { sandbox: Sandbox; abortSignal?: AbortSignal },
59
+ ctx: StudioContext,
50
60
  ) => Promise<string>;
51
61
  }): StudioTool {
52
62
  return {
@@ -59,14 +69,6 @@ function define<Shape extends z.ZodRawShape>(spec: {
59
69
  };
60
70
  }
61
71
 
62
- /** Under artifacts: what is made here is finished work the user opens. */
63
- const DIR = {
64
- images: `${PATHS.artifacts}/images`,
65
- audio: `${PATHS.artifacts}/audio`,
66
- transcripts: `${PATHS.artifacts}/transcripts`,
67
- videos: `${PATHS.artifacts}/videos`,
68
- };
69
-
70
72
  /** A filename someone can recognise a week later, out of what was asked for. */
71
73
  function fileName(stem: string, ext: string): string {
72
74
  const slug = stem
@@ -92,7 +94,7 @@ async function save(
92
94
 
93
95
  /** The path first, on its own line: whoever draws this row reads line one as the file to open. */
94
96
  const saved = (path: string) =>
95
- `${path}\nSaved. Give the user this path — the file opens from the task row. Do not describe it back to them; they can open it.`;
97
+ `${path}\nSaved. Give the user this path — the file opens from the thread row. Do not describe it back to them; they can open it.`;
96
98
 
97
99
  /** `video/mp4` → `mp4`, with a fallback for a provider that says nothing. */
98
100
  const extOf = (mediaType: string | undefined, fallback: string) =>
@@ -121,7 +123,10 @@ const imageTool = async (): Promise<StudioTool | null> => {
121
123
  .nullish()
122
124
  .describe("Aspect ratio. Null for square."),
123
125
  }),
124
- execute: async ({ prompt, aspectRatio }, { sandbox, abortSignal }) => {
126
+ execute: async (
127
+ { prompt, aspectRatio },
128
+ { sandbox, artifacts, abortSignal },
129
+ ) => {
125
130
  const { image } = await generateImage({
126
131
  model,
127
132
  prompt,
@@ -130,7 +135,7 @@ const imageTool = async (): Promise<StudioTool | null> => {
130
135
  });
131
136
  const path = await save(
132
137
  sandbox,
133
- DIR.images,
138
+ artifacts,
134
139
  fileName(prompt, extOf(image.mediaType, "png")),
135
140
  image.uint8Array,
136
141
  );
@@ -172,7 +177,7 @@ const speechTool = async (): Promise<StudioTool | null> => {
172
177
  }),
173
178
  execute: async (
174
179
  { text, voice, instructions },
175
- { sandbox, abortSignal },
180
+ { sandbox, artifacts, abortSignal },
176
181
  ) => {
177
182
  const { audio } = await generateSpeech({
178
183
  model,
@@ -184,7 +189,7 @@ const speechTool = async (): Promise<StudioTool | null> => {
184
189
  });
185
190
  const path = await save(
186
191
  sandbox,
187
- DIR.audio,
192
+ artifacts,
188
193
  fileName(text.slice(0, 60), audio.format || "mp3"),
189
194
  audio.uint8Array,
190
195
  );
@@ -216,7 +221,7 @@ const transcribeTool = async (): Promise<StudioTool | null> => {
216
221
  "The audio file: a path relative to the workspace, or an absolute one anywhere on this machine.",
217
222
  ),
218
223
  }),
219
- execute: async ({ path }, { sandbox, abortSignal }) => {
224
+ execute: async ({ path }, { sandbox, artifacts, abortSignal }) => {
220
225
  const audio = await readFile(sandbox.resolve(path));
221
226
  const result = await transcribe({ model, audio, abortSignal });
222
227
 
@@ -231,7 +236,7 @@ const transcribeTool = async (): Promise<StudioTool | null> => {
231
236
  const stem = basename(path, extname(path));
232
237
  const out = await save(
233
238
  sandbox,
234
- DIR.transcripts,
239
+ artifacts,
235
240
  fileName(stem, "md"),
236
241
  Buffer.from(`# ${stem}\n\n${result.text.trim()}${timeline}\n`),
237
242
  );
@@ -273,7 +278,7 @@ const videoTool = async (): Promise<StudioTool | null> => {
273
278
  }),
274
279
  execute: async (
275
280
  { prompt, aspectRatio, seconds },
276
- { sandbox, abortSignal },
281
+ { sandbox, artifacts, abortSignal },
277
282
  ) => {
278
283
  const { video } = await generateVideo({
279
284
  model,
@@ -284,7 +289,7 @@ const videoTool = async (): Promise<StudioTool | null> => {
284
289
  });
285
290
  const path = await save(
286
291
  sandbox,
287
- DIR.videos,
292
+ artifacts,
288
293
  fileName(prompt, extOf(video.mediaType, "mp4")),
289
294
  video.uint8Array,
290
295
  );
@@ -20,11 +20,8 @@ export const TOOL_NAMES = {
20
20
  web_search: "web_search",
21
21
 
22
22
  delegate: "delegate",
23
- task: "task",
24
- ask_bot: "ask_bot",
25
- ask_thursday: "ask_thursday",
26
- ask_back: "ask_back",
27
- answer: "answer",
23
+ thread: "thread",
24
+ send_message: "send_message",
28
25
 
29
26
  end_call: "end_call",
30
27
  } as const;