thursday-agent 0.2.0 → 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.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +5 -2
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +5 -5
- package/.next/routes-manifest.json +24 -6
- package/.next/server/app/_global-error/page.js +2 -2
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +2 -2
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +2 -2
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +14 -14
- package/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/artifact/route.js +3 -3
- package/.next/server/app/api/artifact/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/files/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/bot/memory/files/route.js +10 -0
- package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -0
- package/.next/server/app/api/bot/memory/files/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/bot/memory/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/bot/memory/route.js +14 -0
- package/.next/server/app/api/bot/{notes → memory}/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/bot/route.js +6 -6
- package/.next/server/app/api/bot/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/task/[id]/route.js +8 -8
- package/.next/server/app/api/bot/task/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/task/route.js +8 -8
- package/.next/server/app/api/bot/task/route.js.nft.json +1 -1
- package/.next/server/app/api/config/route.js +5 -5
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/events/route.js +4 -5
- package/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/server/app/api/file/[...path]/route.js +3 -3
- package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/catalog/route.js +9 -8
- package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/credits/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/llm-model/credits/route/build-manifest.json +12 -0
- package/.next/server/app/api/llm-model/credits/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/llm-model/credits/route.js +16 -0
- package/.next/server/app/api/llm-model/credits/route.js.map +5 -0
- package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -0
- package/.next/server/app/api/llm-model/credits/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/llm-model/route.js +10 -8
- package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/subscription/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/llm-model/subscription/route/build-manifest.json +12 -0
- package/.next/server/app/api/llm-model/subscription/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/llm-model/subscription/route.js +15 -0
- package/.next/server/app/api/llm-model/subscription/route.js.map +5 -0
- package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -0
- package/.next/server/app/api/llm-model/subscription/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/mcp/[name]/route.js +4 -4
- package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth/callback/route.js +5 -5
- package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js +4 -4
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/tools/route.js +4 -4
- package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/edit/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/memory/edit/route/build-manifest.json +12 -0
- package/.next/server/app/api/memory/edit/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/memory/edit/route.js +24 -0
- package/.next/server/app/api/memory/edit/route.js.map +5 -0
- package/.next/server/app/api/memory/edit/route.js.nft.json +1 -0
- package/.next/server/app/api/memory/{tidy → edit}/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/memory/route.js +6 -7
- package/.next/server/app/api/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[source]/[name]/route.js +3 -3
- package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js +3 -3
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/call/route.js +9 -7
- package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/skills/route.js +9 -7
- package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/tool-call/route.js +17 -15
- package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/route.js +4 -5
- package/.next/server/app/api/workspace/route.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +1 -1
- package/.next/server/app/artifact/[...path]/page.js +5 -6
- package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/favicon.ico/route.js +3 -4
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/server/app/favicon.ico.body +0 -0
- package/.next/server/app/page/server-reference-manifest.json +57 -90
- package/.next/server/app/page.js +10 -10
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +5 -2
- package/.next/server/chunks/[externals]__0dzuk6_._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__01dkp4a._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__02xjoto._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__04q--0f._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0bl-e63._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0ce8nf8._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__0ffbg85._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0j7z0r3._.js +12 -0
- package/.next/server/chunks/[root-of-the-server]__0jq4ohy._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0ls6_8y._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0ncs9uu._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0pa2n68._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0q0vvt2._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1-ga0kh._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__11n256_._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__12cabg9._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1339jnv._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__15bjnu5._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__18_teo8._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1anc1p9._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1ccon1w._.js +5 -5
- package/.next/server/chunks/[root-of-the-server]__1fizn31._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1llj3-b._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +11 -0
- package/.next/server/chunks/[root-of-the-server]__1p8m3f4._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1wa1k7r._.js +8 -0
- package/.next/server/chunks/_0-73of8._.js +5 -5
- package/.next/server/chunks/_0-fjql4._.js +26 -0
- package/.next/server/chunks/_00xh_q0._.js +27 -0
- package/.next/server/chunks/{_0pppbb5._.js → _03kp0jp._.js} +163 -36
- package/.next/server/chunks/_051qh8u._.js +3 -0
- package/.next/server/chunks/{node_modules_next_04q-o58._.js → _05dla15._.js} +2 -2
- package/.next/server/chunks/_05h2cii._.js +1 -1
- package/.next/server/chunks/_0c9j6rb._.js +49 -0
- package/.next/server/chunks/_0fzqt2y._.js +130 -0
- package/.next/server/chunks/{_0vnutv9._.js → _0ioz3nd._.js} +1 -1
- package/.next/server/chunks/_0iwfby5._.js +3 -0
- package/.next/server/chunks/_0mecv0f._.js +26 -0
- package/.next/server/chunks/_0mh8j4m._.js +3 -0
- package/.next/server/chunks/_0n74zsf._.js +4 -4
- package/.next/server/chunks/_0obojvv._.js +3 -0
- package/.next/server/chunks/_0recufk._.js +49 -0
- package/.next/server/chunks/_0rnf-6n._.js +4 -4
- package/.next/server/chunks/_0sb7tlz._.js +3 -0
- package/.next/server/chunks/_0u10wmw._.js +5 -5
- package/.next/server/chunks/_0u4aiy2._.js +3 -0
- package/.next/server/chunks/_0wp4le3._.js +1 -1
- package/.next/server/chunks/_0y5fg-x._.js +1 -1
- package/.next/server/chunks/_1230wbx._.js +10 -0
- package/.next/server/chunks/_12nheja._.js +3 -0
- package/.next/server/chunks/_13510xh._.js +3 -0
- package/.next/server/chunks/_15hq89o._.js +1 -1
- package/.next/server/chunks/_17l5ygt._.js +49 -0
- package/.next/server/chunks/_18-1wcc._.js +5 -5
- package/.next/server/chunks/_1_5mnq4._.js +4 -4
- package/.next/server/chunks/_1_9mjx-._.js +3 -0
- package/.next/server/chunks/_1d0j961._.js +6 -0
- package/.next/server/chunks/_1d5zmy8._.js +1 -1
- package/.next/server/chunks/_1drgfx4._.js +4 -4
- package/.next/server/chunks/_1f46eie._.js +3 -0
- package/.next/server/chunks/_1h5_8sk._.js +3 -0
- package/.next/server/chunks/_1hdnxb7._.js +3 -0
- package/.next/server/chunks/_1j8k_j5._.js +3 -0
- package/.next/server/chunks/_1krd9rf._.js +3 -0
- package/.next/server/chunks/_1nc0eui._.js +11 -0
- package/.next/server/chunks/_1nula3v._.js +3 -0
- package/.next/server/chunks/_1pf4qe-._.js +3 -0
- package/.next/server/chunks/_1php4eq._.js +1 -1
- package/.next/server/chunks/_1qxheoa._.js +3 -0
- package/.next/server/chunks/_1x6kd1r._.js +3 -0
- package/.next/server/chunks/_1yuv4vp._.js +1 -1
- package/.next/server/chunks/_1zjrdag._.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_bot_memory_files_route_actions_1_xd_8f.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_bot_memory_route_actions_1a8xfr7.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_llm-model_credits_route_actions_0v424pb.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_llm-model_subscription_route_actions_0-udcm5.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_memory_edit_route_actions_02sfnmr.js +3 -0
- package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
- package/.next/server/chunks/features_0rpfxbk._.js +3 -0
- package/.next/server/chunks/features_1qf3cei._.js +3 -0
- package/.next/server/chunks/features_bot_0zt92oh._.js +3 -0
- package/.next/server/chunks/features_bot_bot_query_ts_12mgkl2._.js +3 -0
- package/.next/server/chunks/features_memory_1uqvksn._.js +6 -0
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0a1rd09._.js → node_modules_consola_dist_chunks_prompt_mjs_0i7cvml._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_06067w6._.js → node_modules_consola_dist_chunks_prompt_mjs_0icqaqw._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_096ais_._.js → node_modules_consola_dist_chunks_prompt_mjs_0r28-sm._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_02s3hjt._.js → node_modules_consola_dist_chunks_prompt_mjs_0v_7drq._.js} +1 -1
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1xoq2rl._.js +3 -0
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0tvkfgh._.js → node_modules_consola_dist_chunks_prompt_mjs_1y49572._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__09q9med._.js +1 -1
- package/.next/server/chunks/ssr/{[root-of-the-server]__1qfqvmg._.js → [root-of-the-server]__0_69wqr._.js} +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__0hg5gib._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0i8ie7f._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__0jsmmb-._.js → [root-of-the-server]__0mz33a7._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0tbkdlx._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0vnmv-s._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__0f6s48x._.js → [root-of-the-server]__0xpcv9w._.js} +3 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0xtssj3._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0zkv7z_._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +57 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__15_uhip._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__16jc196._.js +1 -1
- package/.next/server/chunks/ssr/{[root-of-the-server]__0m1b5ky._.js → [root-of-the-server]__1cyjywu._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1eh7hid._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1gtlw6v._.js +43 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1ox7hbk._.js +4 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1pduf5n._.js +3 -0
- package/.next/server/chunks/ssr/{_1mznrxk._.js → _001_ms1._.js} +3 -3
- package/.next/server/chunks/ssr/_01_6m32._.js +3 -0
- package/.next/server/chunks/ssr/_01n3o0m._.js +3 -0
- package/.next/server/chunks/ssr/_07uchnc._.js +3 -0
- package/.next/server/chunks/ssr/_0ap2fzn._.js +3 -0
- package/.next/server/chunks/ssr/_0c-ql2m._.js +3 -0
- package/.next/server/chunks/ssr/_0h42fze._.js +3 -0
- package/.next/server/chunks/ssr/_0h7zdni._.js +1 -1
- package/.next/server/chunks/ssr/_0i_6q1w._.js +41 -0
- package/.next/server/chunks/ssr/_0kbkmar._.js +3 -0
- package/.next/server/chunks/ssr/{_077-g6s._.js → _0mb8zc8._.js} +3 -3
- package/.next/server/chunks/ssr/_0mo2w06._.js +3 -0
- package/.next/server/chunks/ssr/{_13punpm._.js → _0q0zan6._.js} +2 -2
- package/.next/server/chunks/ssr/{_040sk32._.js → _0u2jv_x._.js} +76 -82
- package/.next/server/chunks/ssr/_0y0tiht._.js +4 -0
- package/.next/server/chunks/ssr/_0zhoc3r._.js +3 -0
- package/.next/server/chunks/ssr/_1-teee5._.js +3 -3
- package/.next/server/chunks/ssr/_13fke0x._.js +3 -0
- package/.next/server/chunks/ssr/{_1lip4th._.js → _13z3f85._.js} +2 -2
- package/.next/server/chunks/ssr/_14_lw10._.js +3 -0
- package/.next/server/chunks/ssr/_15j2_8f._.js +3 -0
- package/.next/server/chunks/ssr/{_09ja_w1._.js → _1eoqg_g._.js} +2 -2
- package/.next/server/chunks/ssr/_1sji22n._.js +3 -0
- package/.next/server/chunks/ssr/_1spzm8z._.js +3 -0
- package/.next/server/chunks/ssr/{_0x_nu5e._.js → _1vi_uo7._.js} +2 -2
- package/.next/server/chunks/ssr/_1vyd1ji._.js +1 -1
- package/.next/server/chunks/ssr/{_1m3bsfr._.js → _1xvgn77._.js} +2 -2
- package/.next/server/chunks/ssr/_20kd_n0._.js +42 -0
- package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +3 -0
- package/.next/server/chunks/ssr/features_config_components_config-setting_tsx_0xfwqdg._.js +1 -1
- package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
- package/.next/server/chunks/ssr/lib_date-like_ts_02is0pw._.js +3 -0
- package/.next/server/chunks/ssr/{node_modules_18_dk7_._.js → node_modules_063xwpp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_01qnv-a._.js → node_modules_0bvraul._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0n1kj4p._.js → node_modules_0eu1va6._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0kl7-tn._.js → node_modules_0h50b8n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0_n241r._.js → node_modules_0h5hnr1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0lrjk5t._.js → node_modules_0h7u60n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0ndvxub._.js → node_modules_0lm7_vm._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_13r44jq._.js → node_modules_0mwym0g._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_17lrt3y._.js → node_modules_0rjg6t1._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_0x3-ply._.js +3 -0
- package/.next/server/chunks/ssr/{node_modules_004qlr4._.js → node_modules_0y_cded._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0kxz4gt._.js → node_modules_0z5tsu8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0iz1rzd._.js → node_modules_0zp9r92._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_19dp7ko._.js → node_modules_1-hc6uv._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1q0p85z._.js → node_modules_113tz0l._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1toafc-._.js → node_modules_124bue5._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_17bwo43._.js +55 -0
- package/.next/server/chunks/ssr/{node_modules_08d8bke._.js → node_modules_1_n3ztw._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1dwguw_._.js → node_modules_1bc7gu8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_20yebtj._.js → node_modules_1bgb6-f._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1n5ygqe._.js → node_modules_1h4a4pp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_04n7mjs._.js → node_modules_1i7u1ia._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1hn8z1f._.js → node_modules_1juq3hs._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1xyd7ov._.js → node_modules_1l0qtdu._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0m93zeg._.js → node_modules_1t9cyee._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_09xhur7._.js → node_modules_1uuj9x1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1hd-5tv._.js → node_modules_1vqb6po._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1zu988w._.js → node_modules_1xx28h1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0m9a4y0._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0d3skpl._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_13w_wy9._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0i44kk5._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_@vercel_oidc_dist_0qe30a_._.js +3 -0
- package/.next/server/chunks/ssr/{node_modules_next_dist_0w6mzq5._.js → node_modules_next_dist_0drixxt._.js} +4 -4
- package/.next/server/chunks/ssr/node_modules_next_dist_1n3w9lb._.js +2 -2
- package/.next/server/instrumentation.js +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +58 -91
- package/.next/static/chunks/{31ttnjt6g35a0.js → 0ev4hyghq0mbb.js} +1 -1
- package/.next/static/chunks/0r5qcctujhxli.js +1 -0
- package/.next/static/chunks/0tmgrnlje14-s.js +3 -0
- package/.next/static/chunks/0x79tx04dxbpp.js +1 -0
- package/.next/static/chunks/0xzgvc0fkdb6t.js +1 -0
- package/.next/static/chunks/10teww7wt-f6h.js +1 -0
- package/.next/static/chunks/14hgtsjg-kael.css +1 -0
- package/.next/static/chunks/17donp69y4do7.js +40 -0
- package/.next/static/chunks/{3_h9txt3tq8t8.js → 1dkjg87pxk0n9.js} +1 -1
- package/.next/static/chunks/1ekc7ul556kbl.js +1 -0
- package/.next/static/chunks/{3ard_noqapnw1.js → 1grhjo7a5a0_-.js} +1 -1
- package/.next/static/chunks/1kq8h8wi_e0bc.js +53 -0
- package/.next/static/chunks/1okqiww3pnwka.js +1 -0
- package/.next/static/chunks/26-pr2c9ro222.js +1 -0
- package/.next/static/chunks/{18vhba44l1fc9.js → 280t0_e99i276.js} +1 -1
- package/.next/static/chunks/28cizcdaabd4h.js +1 -0
- package/.next/static/chunks/2a0k6jlq0_v1u.js +2 -0
- package/.next/static/chunks/2fzs9fm8yarvq.js +1 -0
- package/.next/static/chunks/2h0sd2vumhb15.js +1 -0
- package/.next/static/chunks/2hw2f6zmt7fmt.js +1 -0
- package/.next/static/chunks/2t4vhi3m8ahya.js +1 -0
- package/.next/static/chunks/2tigdtz3dpcy8.js +1 -0
- package/.next/static/chunks/3111pj5wnjgos.js +1 -0
- package/.next/static/chunks/{07kl352c-lvcz.js → 3agpgkwaa321p.js} +1 -1
- package/.next/static/chunks/3cfi_q6d_wtci.js +1 -0
- package/.next/static/chunks/3ok9_x74rip3v.js +1 -0
- package/.next/static/chunks/3xk7yqgomx7yq.js +1 -0
- package/.next/static/chunks/3xpbkl66ssib5.js +38 -0
- package/.next/static/media/favicon.37o1pjldwi2uc.ico +0 -0
- package/README.md +6 -4
- package/app/api/bot/memory/files/route.ts +14 -0
- package/app/api/bot/memory/route.ts +5 -0
- package/app/api/events/app-event.ts +3 -5
- package/app/api/llm-model/credits/route.ts +11 -0
- package/app/api/llm-model/route.ts +6 -1
- package/app/api/llm-model/subscription/route.ts +11 -0
- package/app/api/memory/edit/route.ts +7 -0
- package/app/api/memory/route.ts +21 -0
- package/app/api/query-key.ts +19 -4
- package/bin/thursday.mjs +3 -0
- package/components/ui/shiny-text.tsx +48 -134
- package/database/migrations/{20260909060813_optimal_sabretooth → 20260910173049_numerous_spirit}/migration.sql +24 -34
- package/database/migrations/{20260909060813_optimal_sabretooth → 20260910173049_numerous_spirit}/snapshot.json +71 -145
- package/database/migrations/20260911030320_opposite_jack_power/migration.sql +1 -0
- package/database/migrations/{20260909063821_bitter_tenebrous → 20260911030320_opposite_jack_power}/snapshot.json +57 -184
- package/features/ai/chatgpt.ts +617 -0
- package/features/ai/components/chatgpt-sign-in.tsx +66 -0
- package/features/ai/components/model-picker.tsx +17 -1
- package/features/ai/components/provider-icon.tsx +1 -0
- package/features/ai/load-tools.ts +58 -42
- package/features/ai/model.schema.ts +232 -34
- package/features/ai/model.ts +169 -24
- package/features/ai/prompts/bot.prompt.ts +156 -65
- package/features/ai/prompts/memory-edit.prompt.ts +33 -0
- package/features/ai/prompts/prompt-helper.ts +45 -26
- package/features/ai/prompts/thursday.prompt.ts +40 -17
- package/features/ai/tools/bot.tool.ts +35 -52
- package/features/ai/tools/connected.ts +17 -4
- package/features/ai/tools/memory.tool.ts +133 -72
- package/features/ai/tools/search.tool.ts +136 -47
- package/features/ai/tools/tool-name.ts +2 -5
- package/features/ai/tools/workspace.tool.ts +2 -1
- package/features/bot/bot.action.ts +8 -18
- package/features/bot/bot.memory.ts +89 -0
- package/features/bot/bot.query.ts +37 -57
- package/features/bot/bot.run.ts +507 -241
- package/features/bot/bot.runner.ts +410 -114
- package/features/bot/bot.schema.ts +79 -19
- package/features/bot/bot.seed.ts +89 -16
- package/features/bot/components/bot-mark.tsx +122 -20
- package/features/bot/components/bot-room.tsx +159 -130
- package/features/bot/components/bot-setting.tsx +790 -402
- package/features/bot/components/bot-tool.tsx +2 -6
- package/features/bot/components/mark-palette.tsx +54 -0
- package/features/bot/components/path-chips.tsx +1 -1
- package/features/bot/components/task-badge.tsx +26 -6
- package/features/bot/components/task-reply.tsx +22 -33
- package/features/bot/components/task-setting.tsx +20 -17
- package/features/bot/task.query.ts +215 -28
- package/features/bot/task.store.ts +53 -9
- package/features/config/components/config-setting.tsx +265 -34
- package/features/config/components/models-badge.tsx +42 -0
- package/features/config/config.action.ts +12 -0
- package/features/config/config.const.ts +38 -2
- package/features/connectors/mcp.manager.ts +10 -2
- package/features/intro/components/intro.tsx +47 -46
- package/features/memory/components/memory-edit.tsx +338 -0
- package/features/memory/components/memory-setting.tsx +75 -77
- package/features/memory/memory.action.ts +3 -43
- package/features/memory/memory.edit.ts +87 -0
- package/features/memory/memory.query.ts +24 -42
- package/features/memory/memory.schema.ts +29 -106
- package/features/settings/components/settings.tsx +2 -0
- package/features/settings/settings.alert.ts +3 -1
- package/features/thursday/components/ascii-orb.tsx +106 -90
- package/features/thursday/components/boot.tsx +7 -0
- package/features/thursday/components/call-log.tsx +219 -92
- package/features/thursday/components/face.tsx +6 -4
- package/features/thursday/components/tab-state.tsx +97 -0
- package/features/thursday/components/thursday-mark.tsx +4 -1
- package/features/thursday/components/thursday-setting.tsx +17 -47
- package/features/thursday/components/thursday.tsx +208 -95
- package/features/thursday/thursday.action.ts +12 -17
- package/features/thursday/thursday.query.ts +61 -70
- package/features/thursday/thursday.schema.ts +20 -7
- package/features/thursday/tool-line.ts +85 -11
- package/features/thursday/use-thursday.ts +86 -59
- package/features/workspace/components/file-view.tsx +4 -2
- package/features/workspace/workspace.ts +110 -26
- package/lib/limits.ts +1 -1
- package/lib/oauth-page.ts +27 -0
- package/lib/realtime/openai.ts +2 -2
- package/lib/realtime/realtime.protocol.ts +1 -1
- package/lib/realtime/realtime.tap.ts +122 -0
- package/lib/sandbox.ts +59 -36
- package/package.json +1 -1
- package/skills/browser/SKILL.md +55 -34
- package/.next/server/app/api/bot/notes/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/bot/notes/route.js +0 -14
- package/.next/server/app/api/bot/notes/route_client-reference-manifest.js +0 -3
- package/.next/server/app/api/memory/tidy/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/memory/tidy/route.js +0 -22
- package/.next/server/app/api/memory/tidy/route.js.nft.json +0 -1
- package/.next/server/chunks/0d-b_next_dist_server_app-render_after-task-async-storage_external_0-exn7p.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0-npkh_._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__005var5._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__019dx9f._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__02_2sm-._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__04_8spk._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__05luceg._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__06t77t4._.js +0 -11
- package/.next/server/chunks/[root-of-the-server]__0bed6hu._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0cro2dz._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0dupqt7._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0emr6go._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0le4d-p._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0m8ywyo._.js +0 -10
- package/.next/server/chunks/[root-of-the-server]__0nfuugi._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0p32jfz._.js +0 -12
- package/.next/server/chunks/[root-of-the-server]__0phdgco._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0wvgrsl._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__10qshki._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__11j52t0._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1692zrv._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__16thabu._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__173nhwf._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1_aoyr9._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1bn73ih._.js +0 -10
- package/.next/server/chunks/[root-of-the-server]__1bqhuh9._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1cqizfq._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1e-ci13._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1fboj2j._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1lr7j9t._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1oli73c._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1txedx6._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1untqv8._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1zgpz1w._.js +0 -3
- package/.next/server/chunks/_00_584r._.js +0 -293
- package/.next/server/chunks/_012yhfm._.js +0 -39
- package/.next/server/chunks/_06mxlgn._.js +0 -3
- package/.next/server/chunks/_07rtlxv._.js +0 -3
- package/.next/server/chunks/_0a351g7._.js +0 -6
- package/.next/server/chunks/_0kjjmag._.js +0 -3
- package/.next/server/chunks/_0nn99o2._.js +0 -3
- package/.next/server/chunks/_0zuzmt_._.js +0 -39
- package/.next/server/chunks/_106co2o._.js +0 -3
- package/.next/server/chunks/_12bbv5i._.js +0 -100
- package/.next/server/chunks/_15q1pig._.js +0 -3
- package/.next/server/chunks/_19wg5yn._.js +0 -138
- package/.next/server/chunks/_1bt95p9._.js +0 -55
- package/.next/server/chunks/_1cbk7ms._.js +0 -26
- package/.next/server/chunks/_1drv2et._.js +0 -40
- package/.next/server/chunks/_1ic3bew._.js +0 -5
- package/.next/server/chunks/_1mxn_lb._.js +0 -3
- package/.next/server/chunks/_1rysr-r._.js +0 -10
- package/.next/server/chunks/_1u3rwbr._.js +0 -3
- package/.next/server/chunks/_1x7p319._.js +0 -6
- package/.next/server/chunks/_next-internal_server_app_api_bot_notes_route_actions_0qcsyu7.js +0 -3
- package/.next/server/chunks/_next-internal_server_app_api_memory_tidy_route_actions_0_cfuom.js +0 -3
- package/.next/server/chunks/features_bot_task_query_ts_11xuzl3._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0gzvgfv._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0vorg6w._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1tpvamf._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1vmaq9f._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1y9-wcr._.js +0 -3
- package/.next/server/chunks/ssr/[externals]_node_crypto_1kn79-7._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0iuoa-r._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0un-erv._.js +0 -4
- package/.next/server/chunks/ssr/[root-of-the-server]__1-mnhyd._.js +0 -92
- package/.next/server/chunks/ssr/[root-of-the-server]__1bww500._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1vcdast._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1xwnu-h._.js +0 -3
- package/.next/server/chunks/ssr/_0-mc7ro._.js +0 -3
- package/.next/server/chunks/ssr/_01p5r6-._.js +0 -3
- package/.next/server/chunks/ssr/_03webdr._.js +0 -3
- package/.next/server/chunks/ssr/_09-0k3z._.js +0 -3
- package/.next/server/chunks/ssr/_0f_b_9s._.js +0 -3
- package/.next/server/chunks/ssr/_0fafgvl._.js +0 -3
- package/.next/server/chunks/ssr/_0sf1isi._.js +0 -3
- package/.next/server/chunks/ssr/_0su6_08._.js +0 -3
- package/.next/server/chunks/ssr/_0ti51xc._.js +0 -3
- package/.next/server/chunks/ssr/_0w5bgak._.js +0 -3
- package/.next/server/chunks/ssr/_0y84qo6._.js +0 -3
- package/.next/server/chunks/ssr/_1ciyoo3._.js +0 -3
- package/.next/server/chunks/ssr/_1e-dgz0._.js +0 -4
- package/.next/server/chunks/ssr/_1fq7zgb._.js +0 -3
- package/.next/server/chunks/ssr/_1g6l4uj._.js +0 -3
- package/.next/server/chunks/ssr/_1ruzehw._.js +0 -3
- package/.next/server/chunks/ssr/features_bot_components_bot-setting_tsx_01ajft6._.js +0 -4
- package/.next/server/chunks/ssr/features_config_components_14jqgy4._.js +0 -3
- package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +0 -4
- package/.next/server/chunks/ssr/node_modules_zod_v4_classic_external_15fmmz3.js +0 -55
- package/.next/static/chunks/05b6nx_o3_f_n.js +0 -1
- package/.next/static/chunks/0dmns-gi0raa4.js +0 -1
- package/.next/static/chunks/0f9sq-7q_yxyl.js +0 -1
- package/.next/static/chunks/0oc4_xoia77dg.css +0 -1
- package/.next/static/chunks/0pheo8m3a-rzi.js +0 -1
- package/.next/static/chunks/19i8h2t-5evjx.js +0 -1
- package/.next/static/chunks/1c5fcj473025q.js +0 -1
- package/.next/static/chunks/1pi_hbmjw-f-z.js +0 -1
- package/.next/static/chunks/1twt6k09vg4np.js +0 -1
- package/.next/static/chunks/1ytnip8wdng93.js +0 -1
- package/.next/static/chunks/28gotuisldmom.js +0 -1
- package/.next/static/chunks/2998p0y7k1c8z.js +0 -3
- package/.next/static/chunks/29gyb3nubj51j.js +0 -53
- package/.next/static/chunks/2l233xfycjpd8.js +0 -1
- package/.next/static/chunks/2p5n7pa3c40t-.js +0 -2
- package/.next/static/chunks/2ru1q132af7h7.js +0 -1
- package/.next/static/chunks/2t8wqycwg3y04.js +0 -2
- package/.next/static/chunks/2uxum7qbyeyxd.js +0 -1
- package/.next/static/chunks/32z_ypgtchw48.js +0 -1
- package/.next/static/chunks/33pyjb3xd1iez.js +0 -1
- package/.next/static/chunks/3omud5xunrk1f.js +0 -1
- package/.next/static/chunks/42dnrkbph9e-1.js +0 -1
- package/.next/static/media/favicon.2vob68tjqpejf.ico +0 -0
- package/database/migrations/20260909063821_bitter_tenebrous/migration.sql +0 -1
- package/features/ai/prompts/memory-tidy.prompt.ts +0 -129
- package/features/ai/tools/tidy.tool.ts +0 -22
- package/features/bot/bot.notes.ts +0 -120
- package/features/memory/components/memory-tidy.tsx +0 -395
- package/features/memory/memory.tidy.ts +0 -332
- package/features/memory/tidy.query.ts +0 -135
- package/features/thursday/use-call-title.ts +0 -31
- /package/.next/server/app/api/bot/{notes → memory/files}/route/build-manifest.json +0 -0
- /package/.next/server/app/api/bot/{notes → memory/files}/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/bot/{notes → memory/files}/route.js.map +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory}/route/build-manifest.json +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory}/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory}/route.js.map +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → x1cCqY0kWpR_VcYx_lWO5}/_buildManifest.js +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → x1cCqY0kWpR_VcYx_lWO5}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → x1cCqY0kWpR_VcYx_lWO5}/_ssgManifest.js +0 -0
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ModelMessage } from "ai";
|
|
2
|
+
import { PATHS, PROMPT_LINE, WORKSPACE_KEEP } from "@/config";
|
|
2
3
|
import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
readBotNotesOn,
|
|
7
|
-
} from "@/features/bot/bot.query";
|
|
8
|
-
import type { JobBot } from "@/features/bot/bot.schema";
|
|
4
|
+
import { botMemoryFolder, listBotMemory } from "@/features/bot/bot.memory";
|
|
5
|
+
import { listJobBots, readBotMemoryOn } from "@/features/bot/bot.query";
|
|
6
|
+
import type { BotMemory, JobBot } from "@/features/bot/bot.schema";
|
|
9
7
|
import { findPinnedTools } from "@/features/connectors/mcp.query";
|
|
10
8
|
import type { McpToolRef } from "@/features/connectors/mcp.schema";
|
|
11
9
|
import {
|
|
@@ -43,21 +41,22 @@ import {
|
|
|
43
41
|
* Each chapter decides for itself whether it is included. Assembled on every run, never cached,
|
|
44
42
|
* so a skill or server added a minute ago is in the next job's prompt.
|
|
45
43
|
* Two seats share this prompt: the bot holding the job, and one borrowed for a part of it
|
|
46
|
-
* (`ask_bot`). Only identity, roster, asking and
|
|
44
|
+
* (`ask_bot`). Only identity, roster, asking and answering differ between them.
|
|
47
45
|
*
|
|
48
46
|
* @param self This run's bot name; used only to drop itself from the roster.
|
|
49
47
|
* @param persona Owner's instruction for this bot from settings.
|
|
50
|
-
* @param
|
|
48
|
+
* @param seat The borrowed seat — who handed it this part, every bot above it on the job, whether it may borrow in turn; null for the bot holding the job.
|
|
51
49
|
*/
|
|
52
50
|
export async function loadBotPrompt(
|
|
53
51
|
self: string,
|
|
54
52
|
persona?: string | null,
|
|
55
|
-
|
|
53
|
+
seat?: { askedBy: string; above: string[]; canBorrow: boolean } | null,
|
|
56
54
|
/** The two folders that are this run's rather than the user's (bot.run). */
|
|
57
55
|
folders?: { scratch: string | null; own: string },
|
|
58
56
|
): Promise<LoadedPrompt> {
|
|
59
57
|
const sandbox = await openWorkspace();
|
|
60
58
|
const name = self.trim();
|
|
59
|
+
const askedBy = seat?.askedBy ?? null;
|
|
61
60
|
const [
|
|
62
61
|
skills,
|
|
63
62
|
index,
|
|
@@ -65,8 +64,8 @@ export async function loadBotPrompt(
|
|
|
65
64
|
mcpTools,
|
|
66
65
|
pinned,
|
|
67
66
|
allBots,
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
kept,
|
|
68
|
+
memoryOn,
|
|
70
69
|
machine,
|
|
71
70
|
] = await Promise.all([
|
|
72
71
|
loadSkills(sandbox),
|
|
@@ -77,26 +76,32 @@ export async function loadBotPrompt(
|
|
|
77
76
|
// MCP tools this bot already holds; dropped from the listing below
|
|
78
77
|
findPinnedTools(name),
|
|
79
78
|
listJobBots(),
|
|
80
|
-
// What this bot
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
// What this bot kept on earlier jobs, read off its own folder (bot.memory)
|
|
80
|
+
listBotMemory(name),
|
|
81
|
+
readBotMemoryOn(),
|
|
83
82
|
// One `command -v` sweep; what is here decides the first command (environment)
|
|
84
83
|
readMachineTools(sandbox),
|
|
85
84
|
]);
|
|
86
85
|
|
|
87
|
-
// Drop
|
|
88
|
-
|
|
86
|
+
// Drop itself and every bot above it on this job, which are blocked waiting on
|
|
87
|
+
// it; the last seat the depth allows has no roster at all (config BOT_RUN.depth)
|
|
88
|
+
const peers =
|
|
89
|
+
seat && !seat.canBorrow
|
|
90
|
+
? []
|
|
91
|
+
: allBots.filter(
|
|
92
|
+
(bot) => bot.name !== name && !seat?.above.includes(bot.name),
|
|
93
|
+
);
|
|
89
94
|
|
|
90
95
|
const text = [
|
|
91
96
|
askedBy ? borrowedIdentity(name, askedBy) : identity(name),
|
|
92
97
|
memory(index, carried),
|
|
93
|
-
|
|
98
|
+
memoryOn ? ownMemory(botMemoryFolder(name), kept) : "",
|
|
94
99
|
connectedTools(mcpTools, pinned),
|
|
95
100
|
methods(skills),
|
|
96
101
|
environment(sandbox.cwd, machine, folders),
|
|
97
102
|
roster(peers),
|
|
98
103
|
askedBy ? askingBack(askedBy) : ASKING,
|
|
99
|
-
askedBy ? handingUp(askedBy) :
|
|
104
|
+
askedBy ? handingUp(askedBy) : ANSWERING,
|
|
100
105
|
// Last, so it is the closest thing to the work and outranks the rest
|
|
101
106
|
ownerInstruction(persona),
|
|
102
107
|
]
|
|
@@ -117,7 +122,7 @@ export async function loadBotPrompt(
|
|
|
117
122
|
function identity(name: string): string {
|
|
118
123
|
return [
|
|
119
124
|
// Named, because the owner's prompt may not name it and its own instructions are addressed to it
|
|
120
|
-
`You are ${name}, a worker. Thursday handed you a job while she keeps talking to the user — they speak to her and to nobody else, and what she
|
|
125
|
+
`You are ${name}, a worker. Thursday handed you a job while she keeps talking to the user — they speak to her and to nobody else, and what she says out of your answer is the only part of this that reaches them. You are not in that conversation and never address the user. This thread is drawn on their screen while you work, though: not written to them, but not private either. ${nowLine()}`,
|
|
121
126
|
MACHINE,
|
|
122
127
|
NO_GUESSING,
|
|
123
128
|
].join("\n\n");
|
|
@@ -126,7 +131,7 @@ function identity(name: string): string {
|
|
|
126
131
|
/** The borrowed seat: above it is the borrowing bot, not Thursday. */
|
|
127
132
|
function borrowedIdentity(name: string, askedBy: string): string {
|
|
128
133
|
return [
|
|
129
|
-
`You are ${name}, a worker. ${askedBy}
|
|
134
|
+
`You are ${name}, a worker. ${askedBy} has handed you one part of a job Thursday handed over; your first message says who holds it and how it reached you. The user speaks to Thursday and to nobody else; you never address them, and what you hand back goes into ${askedBy}'s answer as-is. This thread is drawn on their screen while you work: not written to them, but not private either. ${nowLine()}`,
|
|
130
135
|
MACHINE,
|
|
131
136
|
NO_GUESSING,
|
|
132
137
|
].join("\n\n");
|
|
@@ -154,16 +159,14 @@ Written by the person this bot works for. Where these and anything above disagre
|
|
|
154
159
|
${persona.trim()}`
|
|
155
160
|
: "";
|
|
156
161
|
|
|
157
|
-
/** A bot reads memory and
|
|
162
|
+
/** A bot only reads memory; every write, revising and the names the user says are the call's (load-tools), so the chapter is that small. */
|
|
158
163
|
function memory(
|
|
159
164
|
index: MemoryIndexEntry[],
|
|
160
165
|
carried: MemoryAlwaysLoaded[],
|
|
161
166
|
): string {
|
|
162
|
-
const head = `##
|
|
163
|
-
|
|
164
|
-
What the user's assistant knows about them. Thursday keeps it as she talks with them, and everyone reads it.
|
|
167
|
+
const head = `## The user's memory
|
|
165
168
|
|
|
166
|
-
|
|
169
|
+
What Thursday knows about the user, kept as she talks with them. Every bot reads it; none writes to it. Open a note with \`${TOOL_NAMES.memory_recall}\` when the job needs something about them — the address they sign in with, the name to book under — and put what you find out about them in your answer; she decides what to keep. It describes them, not you: how they are named and spoken to is hers to use. What you learn about the work goes in your own memory, below.`;
|
|
167
170
|
|
|
168
171
|
const alreadyKnown = carried.length
|
|
169
172
|
? `Already known:
|
|
@@ -181,21 +184,31 @@ A topic not listed is one nobody knows anything about.`;
|
|
|
181
184
|
}
|
|
182
185
|
|
|
183
186
|
/**
|
|
184
|
-
* The bot's own
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* to write something turns every job into a note, and there is nothing to nudge once a bot
|
|
189
|
-
* has one. The count is here for the same reason: the room left is a fact, not a target.
|
|
187
|
+
* The bot's own memory (features/bot/bot.memory), listed by each file's first line so what a
|
|
188
|
+
* file holds costs one line until a job opens it. Always drawn, so a first job knows it has one.
|
|
189
|
+
* Nothing says what usually goes in first: a line like that is what a first job writes, whether
|
|
190
|
+
* or not the job taught it anything.
|
|
190
191
|
*/
|
|
191
|
-
function
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
${
|
|
197
|
-
|
|
198
|
-
|
|
192
|
+
function ownMemory(folder: string, kept: BotMemory): string {
|
|
193
|
+
const listing = kept.entries.length
|
|
194
|
+
? kept.entries
|
|
195
|
+
.map(({ file, line }) =>
|
|
196
|
+
line
|
|
197
|
+
? `- ${file} — ${clip(line, PROMPT_LINE.botMemory)}`
|
|
198
|
+
: `- ${file}`,
|
|
199
|
+
)
|
|
200
|
+
.join("\n")
|
|
201
|
+
: "Empty.";
|
|
202
|
+
const rest =
|
|
203
|
+
kept.total > kept.entries.length
|
|
204
|
+
? `\n\nThe newest ${kept.entries.length} of ${kept.total}; \`ls ${folder}\` for the rest.`
|
|
205
|
+
: "";
|
|
206
|
+
|
|
207
|
+
return `## Your memory
|
|
208
|
+
|
|
209
|
+
What you kept from your own earlier jobs, in \`${folder}/\`: one topic per file, its first line saying what it holds, read by no other bot. Keep what a later job would otherwise have to find out again — how a site signs in, the way through its screens, a command that turned out right — and fix or delete a file that proved wrong. No passwords, keys or codes.
|
|
210
|
+
|
|
211
|
+
${listing}${rest}`;
|
|
199
212
|
}
|
|
200
213
|
|
|
201
214
|
/**
|
|
@@ -256,8 +269,8 @@ Your workspace — \`${TOOL_NAMES.bash}\` runs here. Everything you write goes i
|
|
|
256
269
|
|
|
257
270
|
- \`${PATHS.artifacts}/\` — finished work the user opens, one entry per result. Theirs, and it stays.
|
|
258
271
|
- \`${PATHS.projects}/\` — code you build, one folder each. It outlives this job, and a project's dependencies install inside it, never at the workspace root.
|
|
259
|
-
- \`${folders?.scratch ?? PATHS.scratch}/\` — this job's working material. It
|
|
260
|
-
- \`${folders?.own ?? PATHS.bots}/\` — yours, across every job you run here
|
|
272
|
+
- \`${folders?.scratch ?? PATHS.scratch}/\` — this job's working material, one folder for every bot on the job: what another bot on it wrote is here too. It is cleared ${Math.round(WORKSPACE_KEEP.forMs / 86_400_000)} days after the job ends, so nothing here is worth keeping.
|
|
273
|
+
- \`${folders?.own ?? PATHS.bots}/\` — yours, across every job you run here: your memory, a script you wrote once and will want again, a table you built.
|
|
261
274
|
|
|
262
275
|
Never the directory above — that is the app you run in; outside the workspace, only where the user pointed you.`;
|
|
263
276
|
|
|
@@ -271,64 +284,142 @@ ${peers.map((bot) => `- **${bot.name}** — ${bot.description}`).join("\n")}
|
|
|
271
284
|
|
|
272
285
|
These lines were written for the user, who reads them on their own screen: where one says "you" it means them, not you.
|
|
273
286
|
|
|
274
|
-
A part of your job another bot is for goes to \`${TOOL_NAMES.ask_bot}\`, because their tools and their practice are the reason they exist. What you build is made of what they bring back, so send for it before you build. A part you could finish in a couple of commands is yours; one that would take a run of its own is theirs.
|
|
287
|
+
A part of your job another bot is for goes to \`${TOOL_NAMES.ask_bot}\`, because their tools and their practice are the reason they exist. What you build is made of what they bring back, so send for it before you build. A part you could finish in a couple of commands is yours; one that would take a run of its own is theirs. What you were handed stays yours and you answer for it. They get the job, the call it came from and what you write them — not this thread.`;
|
|
275
288
|
}
|
|
276
289
|
|
|
277
|
-
/** The only place a run can stop.
|
|
290
|
+
/** The only place a run can stop. */
|
|
278
291
|
const ASKING = `## Asking
|
|
279
292
|
|
|
280
293
|
What you cannot get for yourself — a decision between real options, a detail only the conversation has, a go-ahead before deleting or sending — goes to \`${TOOL_NAMES.ask_thursday}\`, once, with everything in it. Ask before you start, not after an hour; never ask what one command would tell you.
|
|
281
294
|
|
|
282
295
|
A job that arrives without its shape — several ways to do it, no telling what it is for, a scale nobody named — is planned before it is built: put the plan up in two or three lines with what you need decided. A job asked for as one thing is built, not proposed.
|
|
283
296
|
|
|
284
|
-
|
|
297
|
+
Only what is theirs alone stops the job: a password, a one-time code, a passkey, a permission on their machine. Set it up one action away, ask, and carry on when the answer comes back.`;
|
|
285
298
|
|
|
286
299
|
const askingBack = (askedBy: string) => `## Asking
|
|
287
300
|
|
|
288
301
|
What you cannot get for yourself goes to \`${TOOL_NAMES.ask_back}\`: ${askedBy} handed you this part and answers from what they have. They cannot take a question to the user, so for what is the user's alone take the safer reading and say so in what you hand back. Ask before you start, once, whole.`;
|
|
289
302
|
|
|
290
|
-
const STEP_CAP = `Your steps are capped at ${BOT_RUN.steps}; running long, report what you have with \`complete: false\` while the summary is still yours to write.`;
|
|
291
|
-
|
|
292
303
|
/**
|
|
293
|
-
*
|
|
304
|
+
* An answer is sized by the request, not by the shape of a document: this is where
|
|
305
|
+
* the only upper bound on a run is stated, and the one place that says the spoken
|
|
306
|
+
* line is hers to compose. Nothing here asks for a script — a bot that writes to be
|
|
307
|
+
* heard writes for a length rather than for a question, and the padding it adds to
|
|
308
|
+
* reach that length is steps, not words.
|
|
309
|
+
* The step cap is stated nowhere a bot reads: told the number, runs work to it. It is
|
|
310
|
+
* enforced where it cannot be argued with (bot.run `stepCountIs`, and `lastStep`).
|
|
294
311
|
* Images in `.md` need absolute routes because a document opens from two places and relative paths resolve differently.
|
|
295
312
|
*/
|
|
296
|
-
const
|
|
313
|
+
const ANSWERING = `## Answering
|
|
297
314
|
|
|
298
|
-
Every job ends with \`${TOOL_NAMES.
|
|
315
|
+
Every job ends with \`${TOOL_NAMES.answer}\`. **Answer what was asked, at the size it was asked**: a question ends in its answer — one number is one line — and a thing to make comes back made, an action done, photos in a page, a comparison in a table. Once you have what they asked for the job is done; the next thing you would go and check is theirs to ask for.
|
|
299
316
|
|
|
300
|
-
|
|
317
|
+
You are answering Thursday, not the user: she is on the call and picks what to say out of this. Write it plainly, in the user's language — the thread is on their screen as you write it. Anything past a few lines is a file under \`${PATHS.artifacts}/\`, and the answer names its path — it becomes a link on their screen. In a \`.md\`, images only by absolute route (\`/api/file/${PATHS.artifacts}/…\`).`;
|
|
301
318
|
|
|
302
|
-
const handingUp = (askedBy: string) => `##
|
|
319
|
+
const handingUp = (askedBy: string) => `## Answering
|
|
303
320
|
|
|
304
|
-
Every part ends with \`${TOOL_NAMES.
|
|
321
|
+
Every part ends with \`${TOOL_NAMES.answer}\`; what you hand back goes into ${askedBy}'s own answer. Hand back what the brief asked for, in the shape it asked for, with everything you learned that bears on it — exact values, the paths of files you wrote, what did not work. They cannot see your thread, so long is right here.`;
|
|
305
322
|
|
|
306
323
|
/** How many turns of the call travel with the job: enough for one missed detail, not enough to bury the request. */
|
|
307
324
|
export const OPENING_TURNS = 10;
|
|
308
|
-
|
|
325
|
+
|
|
326
|
+
/** A user message's content; every seat's first message is two text parts (buildTaskOpening). */
|
|
327
|
+
export type OpeningContent = Extract<ModelMessage, { role: "user" }>["content"];
|
|
309
328
|
|
|
310
329
|
/**
|
|
311
|
-
* The first message
|
|
312
|
-
*
|
|
313
|
-
*
|
|
330
|
+
* The first message of the bot holding a job, stored as the thread's first row
|
|
331
|
+
* (seq 0, bot.runner startTask) and read whole on every resume and after every
|
|
332
|
+
* compaction. Two text parts: who is who on this job, then the chain — the job
|
|
333
|
+
* as Thursday handed it and the call it came from, verbatim, because the request
|
|
334
|
+
* is one sentence the realtime model produced and a detail the user said may
|
|
335
|
+
* only be in the call. The chain is what a borrowed bot inherits (buildHandoff),
|
|
336
|
+
* so its headings name people and never say "you".
|
|
314
337
|
*/
|
|
315
338
|
export function buildTaskOpening(input: {
|
|
339
|
+
bot: string;
|
|
316
340
|
request: string;
|
|
317
341
|
conversation: { role: "user" | "assistant"; text: string }[];
|
|
318
|
-
}):
|
|
342
|
+
}): OpeningContent {
|
|
319
343
|
const turns = input.conversation.filter((turn) => turn.text.trim());
|
|
320
|
-
|
|
344
|
+
const job = `## Thursday → ${input.bot}: the job\n\n${input.request.trim()}`;
|
|
345
|
+
const call = turns.length
|
|
346
|
+
? `## The call the job came from — its last ${turns.length} turns, verbatim
|
|
347
|
+
|
|
348
|
+
A detail missing from the job may be here — a name, a number, which of two. Where the two disagree the job wins, unless they asked out loud for something to be done and the job only asks about it: then the doing is the job.
|
|
321
349
|
|
|
322
|
-
|
|
350
|
+
${turns
|
|
351
|
+
.map(
|
|
323
352
|
(turn) =>
|
|
324
|
-
`${turn.role === "user" ? "user" : "thursday"}: ${clip(turn.text,
|
|
325
|
-
)
|
|
326
|
-
|
|
353
|
+
`${turn.role === "user" ? "user" : "thursday"}: ${clip(turn.text, PROMPT_LINE.callTurn)}`,
|
|
354
|
+
)
|
|
355
|
+
.join("\n")}`
|
|
356
|
+
: "";
|
|
357
|
+
return [
|
|
358
|
+
{ type: "text", text: whoIsWho([input.bot]) },
|
|
359
|
+
{ type: "text", text: [job, call].filter(Boolean).join("\n\n") },
|
|
360
|
+
];
|
|
361
|
+
}
|
|
327
362
|
|
|
328
|
-
|
|
363
|
+
/**
|
|
364
|
+
* The first message of a borrowed bot, built by the bot that borrows it (bot.run
|
|
365
|
+
* `ask_bot`) and never stored: the chain it inherits, copied as it is, then what
|
|
366
|
+
* the borrowing bot has done and the part it hands over. `bots` runs from the
|
|
367
|
+
* bot holding the job down to this one, so each hand-off adds one name and two
|
|
368
|
+
* sections and every seat reads the same shape.
|
|
369
|
+
*/
|
|
370
|
+
export function buildHandoff(input: {
|
|
371
|
+
chain: string;
|
|
372
|
+
bots: string[];
|
|
373
|
+
did: string | null;
|
|
374
|
+
part: string;
|
|
375
|
+
}): OpeningContent {
|
|
376
|
+
const to = input.bots.at(-1) ?? "";
|
|
377
|
+
const from = input.bots.at(-2) ?? "";
|
|
378
|
+
const did = input.did?.trim()
|
|
379
|
+
? `## ${from} → ${to}: what ${from} has done, and why this part is ${to}'s\n\n${input.did.trim()}`
|
|
380
|
+
: "";
|
|
381
|
+
const part = `## ${from} → ${to}: the part\n\n${input.part.trim()}`;
|
|
382
|
+
return [
|
|
383
|
+
{ type: "text", text: whoIsWho(input.bots) },
|
|
384
|
+
{
|
|
385
|
+
type: "text",
|
|
386
|
+
text: [input.chain, did, part].filter(Boolean).join("\n\n"),
|
|
387
|
+
},
|
|
388
|
+
];
|
|
389
|
+
}
|
|
329
390
|
|
|
330
|
-
|
|
391
|
+
/**
|
|
392
|
+
* The chain out of a seat's first message, for the next hand-off. A thread
|
|
393
|
+
* opened before the two-part shape has its opening as one string, which is the
|
|
394
|
+
* whole chain there was.
|
|
395
|
+
*/
|
|
396
|
+
export function chainOf(first: ModelMessage | undefined): string {
|
|
397
|
+
if (first?.role !== "user") return "";
|
|
398
|
+
if (typeof first.content === "string") return first.content;
|
|
399
|
+
const texts = first.content.flatMap((part) =>
|
|
400
|
+
part.type === "text" ? [part.text] : [],
|
|
401
|
+
);
|
|
402
|
+
return texts.at(-1) ?? "";
|
|
403
|
+
}
|
|
331
404
|
|
|
405
|
+
/** Who is who on this job; the last of `bots` is the one reading it. */
|
|
406
|
+
function whoIsWho(bots: string[]): string {
|
|
407
|
+
const you = bots.length - 1;
|
|
408
|
+
const lines = bots.map((bot, index) => {
|
|
409
|
+
if (index === 0) {
|
|
410
|
+
return index === you
|
|
411
|
+
? `- **${bot} (you)** — Thursday handed you this job. You answer to Thursday, and your answer is the only part of it that reaches the user.`
|
|
412
|
+
: `- **${bot}** — holds the job Thursday handed over, and answers for it.`;
|
|
413
|
+
}
|
|
414
|
+
const from = bots[index - 1];
|
|
415
|
+
return index === you
|
|
416
|
+
? `- **${bot} (you)** — ${from} handed you one part of it: the last section below. You answer to ${from}; nobody else hears from you.`
|
|
417
|
+
: `- **${bot}** — ${from} handed them one part of it.`;
|
|
418
|
+
});
|
|
419
|
+
return `## Who is who on this job
|
|
420
|
+
|
|
421
|
+
- **The user** — talks only to Thursday, on a voice call. No bot addresses them.
|
|
422
|
+
- **Thursday** — the user's assistant on that call. Hands jobs to bots and tells the user what comes back.
|
|
332
423
|
${lines.join("\n")}`;
|
|
333
424
|
}
|
|
334
425
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
|
|
2
|
+
import { listNoteIndex } from "@/features/memory/memory.query";
|
|
3
|
+
import { MEMORY_PATHS } from "@/features/memory/memory.schema";
|
|
4
|
+
import { logPromptSize, noteLines, nowLine } from "./prompt-helper";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Everything an edit from the memory screen hears (features/memory/memory.edit):
|
|
8
|
+
* who it is working for, and memory as a listing — one line a note, with how
|
|
9
|
+
* many facts it holds — the way the call sees it. Facts and their ids come from
|
|
10
|
+
* opening a note, so the prompt grows with the number of notes, not of facts.
|
|
11
|
+
* Assembled once per request.
|
|
12
|
+
*/
|
|
13
|
+
export async function loadMemoryEditPrompt(): Promise<string> {
|
|
14
|
+
const text = [identity(), memory(await listNoteIndex())].join("\n\n");
|
|
15
|
+
logPromptSize("memory-edit", text);
|
|
16
|
+
return text;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function identity(): string {
|
|
20
|
+
return `You are the user's personal assistant, and this is their memory. Change it the way their message asks: add what is new, replace what stopped being true, remove what they want gone. Make every change with \`${TOOL_NAMES.memory_remember}\` and \`${TOOL_NAMES.memory_forget}\`; when nothing is left to change, stop. ${nowLine()}`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function memory(index: Awaited<ReturnType<typeof listNoteIndex>>): string {
|
|
24
|
+
return `## Memory
|
|
25
|
+
|
|
26
|
+
path — what is under it (facts) "what the user calls it"
|
|
27
|
+
|
|
28
|
+
${noteLines(index)}
|
|
29
|
+
|
|
30
|
+
A note is listed, not shown: open it with \`${TOOL_NAMES.memory_recall}\` for its facts and their ids before replacing or removing any of them. Adding to a note needs no opening.
|
|
31
|
+
|
|
32
|
+
${MEMORY_PATHS.map((entry) => `- ${entry.path} — ${entry.of}`).join("\n")}`;
|
|
33
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { format, formatDistanceToNowStrict } from "date-fns";
|
|
2
|
-
import {
|
|
2
|
+
import { MEMORY_LIMITS, PROMPT_BUDGET, PROMPT_LINE } from "@/config";
|
|
3
3
|
import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
|
|
4
4
|
import type { McpToolRef } from "@/features/connectors/mcp.schema";
|
|
5
5
|
import type {
|
|
6
6
|
MemoryAlwaysLoaded,
|
|
7
7
|
MemoryIndexEntry,
|
|
8
8
|
} from "@/features/memory/memory.schema";
|
|
9
|
-
import { MANY_FACTS } from "@/features/memory/memory.schema";
|
|
10
9
|
import type { SkillMetadata } from "@/features/skills/skills.discover";
|
|
10
|
+
import { delegatedLabel } from "@/features/thursday/tool-line";
|
|
11
11
|
import { toDate } from "@/lib/date-like";
|
|
12
12
|
import { logger } from "@/lib/logger";
|
|
13
13
|
import { estimateTokens, sectionTokens } from "@/lib/tokens";
|
|
@@ -58,6 +58,36 @@ export const clockNow = (now = new Date()) =>
|
|
|
58
58
|
/** `**Now**: 2026-09-02 (Wed) 15:41 Asia/Seoul` */
|
|
59
59
|
export const nowLine = (now = new Date()) => `**Now**: ${clockNow(now)}`;
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* When a call happened, the one way every prompt and tool says it: local, the
|
|
63
|
+
* same shape as `Now` (clockNow), with how long ago. A UTC stamp beside a local
|
|
64
|
+
* `Now` put two clocks nine hours apart in one prompt, and a call from last
|
|
65
|
+
* night read as one from this afternoon.
|
|
66
|
+
*/
|
|
67
|
+
export const callStamp = (at: Date): string =>
|
|
68
|
+
`${format(at, "yyyy-MM-dd (EEE) HH:mm")} (${formatDistanceToNowStrict(at, { addSuffix: true })})`;
|
|
69
|
+
|
|
70
|
+
/** When a fact was said, for the fact itself: the date and time without the distance. */
|
|
71
|
+
export const saidStamp = (at: Date): string =>
|
|
72
|
+
format(at, "yyyy-MM-dd (EEE) HH:mm");
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A call as a conversation: who said what, and which tool was used — never its
|
|
76
|
+
* arguments or its result. What was asked for and what was said back is the
|
|
77
|
+
* conversation; the arguments are already in memory and the results are not
|
|
78
|
+
* what anyone said.
|
|
79
|
+
*/
|
|
80
|
+
export const conversationLines = (
|
|
81
|
+
turns: { role: string; tool: string | null; text: string }[],
|
|
82
|
+
): string =>
|
|
83
|
+
turns
|
|
84
|
+
.map((turn) =>
|
|
85
|
+
turn.role === "tool"
|
|
86
|
+
? `you → ${turn.tool ?? "tool"}`
|
|
87
|
+
: `${turn.role === "user" ? "user" : "you"}: ${turn.text}`,
|
|
88
|
+
)
|
|
89
|
+
.join("\n");
|
|
90
|
+
|
|
61
91
|
/** `4mo`, `12d`: short enough to read aloud. */
|
|
62
92
|
function sinceLast(at: MemoryIndexEntry["lastSeenAt"]): string {
|
|
63
93
|
const days = Math.floor((Date.now() - toDate(at).getTime()) / 86_400_000);
|
|
@@ -85,13 +115,15 @@ export const carriedLines = (loaded: MemoryAlwaysLoaded[]): string =>
|
|
|
85
115
|
loaded.map((fact) => `- ${fact.text} · ${fact.path} #${fact.id}`).join("\n");
|
|
86
116
|
|
|
87
117
|
/**
|
|
88
|
-
* Whether it is time to tidy, and why:
|
|
89
|
-
*
|
|
118
|
+
* Whether it is time to tidy, and why: too much held in all (the coldest notes
|
|
119
|
+
* are what to drop), or one note too long to hold in one piece (it names itself).
|
|
120
|
+
* Both counted in facts, the unit the user sees on their own screen and the one
|
|
121
|
+
* every write hands back — a token estimate is nobody's unit and cannot be acted on.
|
|
90
122
|
*/
|
|
91
123
|
export const tidying = (index: MemoryIndexEntry[]) => ({
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
heavy: index.filter((note) => note.factCount >
|
|
124
|
+
crowded:
|
|
125
|
+
index.reduce((sum, note) => sum + note.factCount, 0) > MEMORY_LIMITS.facts,
|
|
126
|
+
heavy: index.filter((note) => note.factCount > MEMORY_LIMITS.factsPerNote),
|
|
95
127
|
});
|
|
96
128
|
|
|
97
129
|
/** A bot gets the whole description; `short` gives the voice prompt the first sentence only. */
|
|
@@ -158,9 +190,6 @@ export type RecentCall = {
|
|
|
158
190
|
}[];
|
|
159
191
|
};
|
|
160
192
|
|
|
161
|
-
/** How much of a past job's report is worth carrying; the rest is asked for with `task`. */
|
|
162
|
-
const JOB_OUTCOME = 160;
|
|
163
|
-
|
|
164
193
|
/**
|
|
165
194
|
* One turn as the transcript carries it. A `delegate` line takes what became of
|
|
166
195
|
* the job: the handle to pick it back up, and how it ended — arguments alone say
|
|
@@ -173,25 +202,20 @@ function turnLine(turn: RecentCall["turns"][number], call: RecentCall): string {
|
|
|
173
202
|
const args = `you → ${turn.tool ?? "tool"} ${clip(turn.text, PROMPT_LINE.toolArgs)}`;
|
|
174
203
|
if (turn.tool !== TOOL_NAMES.delegate) return args;
|
|
175
204
|
|
|
176
|
-
const label = (
|
|
177
|
-
try {
|
|
178
|
-
const said = JSON.parse(turn.text) as { label?: unknown };
|
|
179
|
-
return typeof said.label === "string" ? said.label : null;
|
|
180
|
-
} catch {
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
})();
|
|
205
|
+
const label = delegatedLabel(turn.tool, turn.text);
|
|
184
206
|
const job = label ? call.jobs?.find((one) => one.label === label) : undefined;
|
|
185
207
|
if (!job) return args;
|
|
186
208
|
|
|
187
|
-
const said = job.outcome
|
|
209
|
+
const said = job.outcome
|
|
210
|
+
? `: ${clip(job.outcome, PROMPT_LINE.jobOutcome)}`
|
|
211
|
+
: "";
|
|
188
212
|
return `you → ${turn.tool} "${job.label}" (${job.id}) — ${job.status}${said}`;
|
|
189
213
|
}
|
|
190
214
|
|
|
191
215
|
/** The last calls as stored, newest last, cut to a token budget. A tool turn carries the call, not the result. */
|
|
192
216
|
export function recentCallLines(calls: RecentCall[], budget: number): string {
|
|
193
217
|
// Newest line backwards until the budget is spent, then put it back in order.
|
|
194
|
-
// Measured on the rendered line: a job's
|
|
218
|
+
// Measured on the rendered line: a job's answer is on it and its arguments are not
|
|
195
219
|
const kept: { call: RecentCall; line: string }[] = [];
|
|
196
220
|
let spent = 0;
|
|
197
221
|
outer: for (let c = calls.length - 1; c >= 0; c--) {
|
|
@@ -211,12 +235,7 @@ export function recentCallLines(calls: RecentCall[], budget: number): string {
|
|
|
211
235
|
for (const { call, line } of kept) {
|
|
212
236
|
if (call !== open) {
|
|
213
237
|
open = call;
|
|
214
|
-
|
|
215
|
-
addSuffix: true,
|
|
216
|
-
});
|
|
217
|
-
lines.push(
|
|
218
|
-
`### ${call.startedAt.toISOString().slice(0, 16).replace("T", " ")} (${when})`,
|
|
219
|
-
);
|
|
238
|
+
lines.push(`### ${callStamp(call.startedAt)}`);
|
|
220
239
|
}
|
|
221
240
|
lines.push(line);
|
|
222
241
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RECENT_CALL } from "@/config";
|
|
1
|
+
import { MEMORY_LIMITS, RECENT_CALL } from "@/config";
|
|
2
2
|
import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
|
|
3
3
|
import { listJobBots } from "@/features/bot/bot.query";
|
|
4
4
|
import type { JobBot } from "@/features/bot/bot.schema";
|
|
@@ -159,27 +159,46 @@ ${carriedLines(carried)}`
|
|
|
159
159
|
|
|
160
160
|
${noteLines(index, crowded)}
|
|
161
161
|
|
|
162
|
-
Open a note before answering out of it; a topic not listed is one you know nothing about.
|
|
162
|
+
Open a note before answering out of it; a topic not listed is one you know nothing about. A fact marked \`said\` came from a call; open that call with \`${TOOL_NAMES.memory_conversation}\` only when the line itself cannot answer — exactly what they said, or why it was saved.
|
|
163
163
|
|
|
164
164
|
Anything worth knowing next time goes in the moment it comes up, without asking — one fact per line, dates as dates. A rule they lay down for you — their language, how long an answer runs, when to hang up — is \`alwaysLoad\`; unsaved, it dies with the call. What stopped being true is corrected with \`replaces\`, not left standing beside it. Never claim to remember what you did not save.
|
|
165
165
|
|
|
166
166
|
${MEMORY_PATHS.map((entry) => `- ${entry.path} — ${entry.of}`).join("\n")}`;
|
|
167
167
|
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
|
|
168
|
+
// Only when there is something to tidy, and it names a few notes rather than
|
|
169
|
+
// every one it caught: a warning that lists everything is a second listing,
|
|
170
|
+
// and what it is warning about is that the first one is already too long.
|
|
171
|
+
const full = heavy.length
|
|
172
|
+
? `${[...heavy]
|
|
173
|
+
.sort((a, b) => b.factCount - a.factCount)
|
|
174
|
+
.slice(0, 3)
|
|
171
175
|
.map((note) => `${note.path} (${note.factCount})`)
|
|
172
|
-
.join(", ")}
|
|
173
|
-
|
|
176
|
+
.join(", ")} ${heavy.length > 1 ? "have" : "has"} grown past ${
|
|
177
|
+
MEMORY_LIMITS.factsPerNote
|
|
178
|
+
} facts, more than one note holds well. Put ${
|
|
179
|
+
heavy.length > 1 ? "each" : "it"
|
|
180
|
+
} on their screen with \`${TOOL_NAMES.memory_show}\`, read back what is stale and forget only what they name.`
|
|
181
|
+
: "";
|
|
182
|
+
const many = crowded
|
|
183
|
+
? `Memory is past ${MEMORY_LIMITS.facts} facts in all. The coldest notes are ${index
|
|
174
184
|
.slice(-4)
|
|
175
185
|
.map((note) => note.path)
|
|
176
|
-
.join(
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
186
|
+
.join(
|
|
187
|
+
", ",
|
|
188
|
+
)} — ask whether any of them is still worth keeping, and delete the note if not.`
|
|
189
|
+
: "";
|
|
190
|
+
// Ahead of anything else she would raise, never ahead of what they came with
|
|
191
|
+
const tidy = [full, many].filter(Boolean).join(" ");
|
|
192
|
+
|
|
193
|
+
return [
|
|
194
|
+
head,
|
|
195
|
+
alreadyKnown,
|
|
196
|
+
listing,
|
|
197
|
+
tidy &&
|
|
198
|
+
`${tidy} Get this settled before anything else you would bring up yourself — not before what they came to you with.`,
|
|
199
|
+
]
|
|
200
|
+
.filter(Boolean)
|
|
201
|
+
.join("\n\n");
|
|
183
202
|
}
|
|
184
203
|
|
|
185
204
|
/** Last calls verbatim, marked as past so the model does not answer as if just asked. Absent on the first call. */
|
|
@@ -244,7 +263,7 @@ Who you hand work to — the names \`${TOOL_NAMES.delegate}\` takes.
|
|
|
244
263
|
|
|
245
264
|
${input.roster.map((bot) => `- **${bot.name}** — ${bot.description}`).join("\n")}`;
|
|
246
265
|
|
|
247
|
-
const machine = `**A bot has the whole machine** — this computer, a real browser, the web, files, a shell to build whatever is missing — and far more time than you. It signs in where it has to, with the window in front of them, and carries a job to the end: the
|
|
266
|
+
const machine = `**A bot has the whole machine** — this computer, a real browser, the web, files, a shell to build whatever is missing — and far more time than you. It signs in where it has to, with the window in front of them, and carries a job to the end: the account made, the page built. How, and whether, is its call; yours is what they want — so a thing you have no idea how to do is a job, not a no. Bots borrow each other, so a job that spans several things is still one job for one bot.`;
|
|
248
267
|
|
|
249
268
|
const hands = [
|
|
250
269
|
input.skills.length
|
|
@@ -265,9 +284,13 @@ ${hands.join("\n\n")}`
|
|
|
265
284
|
|
|
266
285
|
const handingOver = `**Anything that takes more than a few seconds is a bot's** — one note or one file is yours. \`${TOOL_NAMES.delegate}\` answers at once: say who has it and keep talking. Put the request in their own words, with what it stands on and nothing they did not say; if something only they can say is missing — how much, which one, by when — ask that first.
|
|
267
286
|
|
|
268
|
-
|
|
287
|
+
**The conversation belongs to the job, not to the bot** — hand the same bot a second job and it starts from nothing, knowing neither what was asked nor what it found. So more about a job you already handed over goes to \`${TOOL_NAMES.task}\` by its name, and the bot wakes with that job's own thread; with no name given it takes the one that moved last.`;
|
|
269
288
|
|
|
270
|
-
|
|
289
|
+
// An answer is written to her, and the whole of it is already drawn on the
|
|
290
|
+
// user's screen (bot-room). Saying so is what keeps its length from deciding
|
|
291
|
+
// hers: a bot that answers a one-line question in one line and a bot that
|
|
292
|
+
// hands back a table both end in one spoken sentence.
|
|
293
|
+
const comingBack = `A job comes back as a system note, not the user speaking. **It was written to you, not to them** — its length is not how much to say, and the whole of it is already on their screen. Give them the part that answers what they asked, in one sentence, in your own words. A file it names opens there by itself — say what it holds, not the path. A question arrives the same way: answer it yourself if you can, else read them the options and send back what they say.`;
|
|
271
294
|
|
|
272
295
|
return [list, machine, catalogue, handingOver, comingBack]
|
|
273
296
|
.filter(Boolean)
|