thursday-agent 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +5 -1
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +5 -5
- package/.next/routes-manifest.json +27 -3
- 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.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/build-manifest.json +12 -0
- package/.next/server/app/api/bot/memory/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/bot/memory/route.js +14 -0
- package/.next/server/app/api/bot/memory/route.js.map +5 -0
- package/.next/server/app/api/bot/memory/route.js.nft.json +1 -0
- package/.next/server/app/api/bot/memory/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/bot/route.js +7 -7
- package/.next/server/app/api/bot/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/task/[id]/route.js +9 -9
- 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 +6 -6
- 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 +10 -9
- 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 +5 -5
- package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth/callback/route.js +6 -6
- package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js +5 -5
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/tools/route.js +5 -5
- 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 +7 -8
- 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 +16 -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 +66 -77
- package/.next/server/app/page.js +11 -11
- 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 -1
- 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 +3 -0
- 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 +10 -0
- 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/{_1hzrsvg._.js → _0-73of8._.js} +6 -6
- package/.next/server/chunks/{_1cbk7ms._.js → _0-fjql4._.js} +10 -10
- package/.next/server/chunks/_00xh_q0._.js +27 -0
- package/.next/server/chunks/{_0y8is-s._.js → _03a0897._.js} +1 -1
- package/.next/server/chunks/{_0pppbb5._.js → _03kp0jp._.js} +166 -35
- 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 +74 -44
- package/.next/server/chunks/{_0kl37zl._.js → _0ioz3nd._.js} +1 -1
- package/.next/server/chunks/_0iwfby5._.js +3 -0
- package/.next/server/chunks/{_0hin38_._.js → _0khihjk._.js} +5 -5
- package/.next/server/chunks/_0mecv0f._.js +26 -0
- package/.next/server/chunks/_0mh8j4m._.js +3 -0
- package/.next/server/chunks/{_1icgbi8._.js → _0n74zsf._.js} +2 -2
- package/.next/server/chunks/_0obojvv._.js +3 -0
- package/.next/server/chunks/_0recufk._.js +49 -0
- package/.next/server/chunks/{_1t8fv7b._.js → _0rnf-6n._.js} +2 -2
- package/.next/server/chunks/_0sb7tlz._.js +3 -0
- package/.next/server/chunks/{_0jgm3b8._.js → _0u10wmw._.js} +6 -6
- package/.next/server/chunks/{_12nr4xc._.js → _0u4aiy2._.js} +2 -2
- 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/{_0ks6_sg._.js → _18-1wcc._.js} +6 -6
- package/.next/server/chunks/_1_5mnq4._.js +18 -0
- package/.next/server/chunks/{_0tzfesa._.js → _1_9mjx-._.js} +1 -1
- package/.next/server/chunks/_1d0j961._.js +6 -0
- package/.next/server/chunks/_1d5zmy8._.js +1 -1
- package/.next/server/chunks/_1drgfx4._.js +18 -0
- package/.next/server/chunks/{_1skgy7b._.js → _1e48czp._.js} +5 -5
- 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/{_10qam6o._.js → _1kg70wc._.js} +5 -5
- 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 +1 -1
- package/.next/server/chunks/features_memory_1uqvksn._.js +6 -0
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0tf290y._.js → node_modules_consola_dist_chunks_prompt_mjs_0i7cvml._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0228f43._.js → node_modules_consola_dist_chunks_prompt_mjs_0icqaqw._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0ir-vo2._.js → node_modules_consola_dist_chunks_prompt_mjs_0j61-ma._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0otw8ef._.js → node_modules_consola_dist_chunks_prompt_mjs_0r28-sm._.js} +1 -1
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0v_7drq._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_11zjo-1._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1pycqsq._.js +3 -0
- 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_1y49572._.js +3 -0
- package/.next/server/chunks/ssr/[externals]__0dizgek._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__09q9med._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0_69wqr._.js +3 -0
- 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]__1cyjywu._.js +3 -0
- 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/_0lu1n_x._.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/{_0gd4vaa._.js → _0u2jv_x._.js} +94 -58
- 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/{_0q_2f2x._.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/{_0lc_7c8._.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/{_19_o9d-._.js → _1vi_uo7._.js} +2 -2
- package/.next/server/chunks/ssr/_1vyd1ji._.js +3 -0
- package/.next/server/chunks/ssr/_1xvgn77._.js +3 -0
- 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/lib_realtime_12wg_dd._.js +27 -0
- package/.next/server/chunks/ssr/lib_realtime_15h_v1v._.js +27 -0
- package/.next/server/chunks/ssr/{node_modules_1d-is1o._.js → node_modules_063xwpp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1ub40gk._.js → node_modules_0bvraul._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1nhw9qg._.js → node_modules_0eu1va6._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0xwx4u-._.js → node_modules_0h50b8n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_043-236._.js → node_modules_0h5hnr1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1t0y5jt._.js → node_modules_0h7u60n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1k29j1j._.js → node_modules_0lm7_vm._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_16i4o_3._.js → node_modules_0mwym0g._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1y8_3vg._.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_108wd2o._.js → node_modules_0y_cded._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1jatz7w._.js → node_modules_0z5tsu8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0ls96je._.js → node_modules_0zp9r92._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_06kvvuo._.js → node_modules_1-hc6uv._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1_588_4._.js → node_modules_113tz0l._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0ipn1ho._.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_0_j7-g4._.js → node_modules_1_n3ztw._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_20ynonm._.js → node_modules_1bc7gu8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1hn_sd5._.js → node_modules_1bgb6-f._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0bue6gy._.js → node_modules_1h4a4pp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0fbw5-u._.js → node_modules_1i7u1ia._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1ee8gav._.js → node_modules_1juq3hs._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0_fvxnt._.js → node_modules_1l0qtdu._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_13f2md6._.js → node_modules_1t9cyee._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0y2-av4._.js → node_modules_1uuj9x1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_00d6675._.js → node_modules_1vqb6po._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1v0077l._.js → node_modules_1xx28h1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_092s8nx._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0d3skpl._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1nvexgu._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0i44kk5._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_@vercel_oidc_dist_0qe30a_._.js +3 -0
- package/.next/server/chunks/ssr/node_modules_consola_dist_chunks_prompt_mjs_05cwqv2._.js +47 -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 +67 -78
- 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/1dkjg87pxk0n9.js +28 -0
- package/.next/static/chunks/1ekc7ul556kbl.js +1 -0
- package/.next/static/chunks/{1khakdu_iuedc.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/{2ihkf6l2jowo9.js → 280t0_e99i276.js} +3 -3
- 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/3786h5vayt80-.js +28 -0
- package/.next/static/chunks/{3aquirz5h71da.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.client.ts +24 -0
- package/app/api/events/app-event.server.ts +45 -0
- package/app/api/events/app-event.ts +42 -0
- package/app/api/llm-model/catalog/route.ts +12 -0
- package/app/api/llm-model/credits/route.ts +11 -0
- package/app/api/llm-model/route.ts +26 -0
- 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 +159 -0
- package/app/api/thursday/tool-call/route.ts +67 -0
- package/bin/thursday.mjs +3 -0
- package/components/ui/button-group.tsx +45 -0
- package/components/ui/custom-icon.tsx +259 -0
- package/components/ui/dropdown-menu.tsx +271 -0
- package/components/ui/folded-text.tsx +68 -0
- package/components/ui/input-group.tsx +157 -0
- package/components/ui/json-view.tsx +240 -0
- package/components/ui/shiny-text.tsx +55 -0
- package/components/ui/text-type.tsx +213 -0
- package/components/ui/theme-sync.tsx +9 -0
- package/database/migrations/{20260908030742_rainy_marvel_zombies → 20260910173049_numerous_spirit}/migration.sql +30 -33
- package/database/migrations/{20260908030742_rainy_marvel_zombies → 20260910173049_numerous_spirit}/snapshot.json +124 -145
- package/database/migrations/20260911030320_opposite_jack_power/migration.sql +1 -0
- package/database/migrations/20260911030320_opposite_jack_power/snapshot.json +1158 -0
- package/docs/how-it-works.md +59 -0
- package/docs/images/keeps-going.png +0 -0
- package/docs/images/task-thread.png +0 -0
- package/docs/images/two-minds.png +0 -0
- 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 +105 -39
- package/features/ai/model.schema.ts +232 -34
- package/features/ai/model.ts +169 -24
- package/features/ai/prompts/bot.prompt.ts +245 -59
- package/features/ai/prompts/memory-edit.prompt.ts +33 -0
- package/features/ai/prompts/prompt-helper.ts +75 -30
- package/features/ai/prompts/thursday.prompt.ts +42 -17
- package/features/ai/tools/bot.tool.ts +32 -30
- package/features/ai/tools/connected.ts +17 -4
- package/features/ai/tools/mcp.tool.ts +5 -5
- package/features/ai/tools/memory.tool.ts +142 -74
- package/features/ai/tools/search.tool.ts +136 -47
- package/features/ai/tools/studio.tool.ts +5 -5
- package/features/ai/tools/tool-name.ts +2 -3
- package/features/ai/tools/workspace.tool.ts +33 -4
- package/features/bot/bot.action.ts +24 -7
- package/features/bot/bot.memory.ts +89 -0
- package/features/bot/bot.query.ts +41 -6
- package/features/bot/bot.run.ts +516 -210
- package/features/bot/bot.runner.ts +463 -93
- package/features/bot/bot.schema.ts +84 -7
- package/features/bot/bot.seed.ts +89 -16
- package/features/bot/components/bot-mark.tsx +122 -20
- package/features/bot/components/bot-room.tsx +519 -391
- package/features/bot/components/bot-setting.tsx +832 -341
- 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 +233 -33
- 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 +86 -79
- package/features/memory/memory.action.ts +3 -43
- package/features/memory/memory.edit.ts +87 -0
- package/features/memory/memory.query.ts +33 -44
- package/features/memory/memory.schema.ts +50 -97
- package/features/settings/components/settings.tsx +2 -0
- package/features/settings/settings.alert.ts +3 -1
- package/features/skills/components/skills-setting.tsx +9 -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 +230 -13
- package/hooks/use-draft.ts +37 -0
- package/hooks/use-hotkey.ts +105 -0
- package/hooks/use-object-state.ts +51 -0
- package/hooks/use-on-visible.ts +72 -0
- package/hooks/use-theme.ts +106 -0
- package/hooks/use-wake-word.ts +262 -0
- package/lib/limits.ts +1 -1
- package/lib/oauth-page.ts +27 -0
- package/lib/realtime/openai.ts +2 -2
- package/lib/realtime/realtime.driver.ts +34 -1
- package/lib/realtime/realtime.protocol.ts +7 -1
- package/lib/realtime/realtime.tap.ts +122 -0
- package/lib/sandbox.ts +60 -29
- package/lib/tokens.ts +19 -0
- package/package.json +1 -1
- package/skills/browser/SKILL.md +55 -34
- package/.next/server/app/api/memory/tidy/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/memory/tidy/route.js +0 -23
- package/.next/server/app/api/memory/tidy/route.js.nft.json +0 -1
- 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]__02kt8yn._.js +0 -10
- 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]__0dupqt7._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0h59di-._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0j_n5l3._.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]__0phdgco._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0qjqtwo._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0t_dqaj._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0wvgrsl._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0yk6s3w._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0z3gelv._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__10qshki._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__113fqg5._.js +0 -12
- package/.next/server/chunks/[root-of-the-server]__11w_7_3._.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_0q_9w._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1_aoyr9._.js +0 -3
- 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]__1dow0bz._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1e-ci13._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1gmn1cs._.js +0 -10
- package/.next/server/chunks/[root-of-the-server]__1lr7j9t._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1mzp_el._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1txedx6._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1u_qvc7._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1zgpz1w._.js +0 -3
- 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/_0zmestz._.js +0 -55
- package/.next/server/chunks/_0zuzmt_._.js +0 -39
- package/.next/server/chunks/_12bbv5i._.js +0 -96
- package/.next/server/chunks/_15q1pig._.js +0 -3
- package/.next/server/chunks/_1drv2et._.js +0 -36
- package/.next/server/chunks/_1ic3bew._.js +0 -5
- package/.next/server/chunks/_1mxn_lb._.js +0 -3
- package/.next/server/chunks/_1uj4_io._.js +0 -10
- package/.next/server/chunks/_1x7p319._.js +0 -6
- package/.next/server/chunks/_1yldgo4._.js +0 -55
- package/.next/server/chunks/_2050gwn._.js +0 -255
- package/.next/server/chunks/_next-internal_server_app_api_memory_tidy_route_actions_0_cfuom.js +0 -3
- package/.next/server/chunks/features_0scmr4i._.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_0vorg6w._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0ykklj0._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1ryg3wh._.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_1vwbnq_._.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]__01id-v3._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0b-0i32._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0dfwvr4._.js +0 -4
- package/.next/server/chunks/ssr/[root-of-the-server]__0iuoa-r._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1-mnhyd._.js +0 -90
- package/.next/server/chunks/ssr/[root-of-the-server]__185grso._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1minz8_._.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/_09-0k3z._.js +0 -3
- package/.next/server/chunks/ssr/_0ay6b01._.js +0 -3
- package/.next/server/chunks/ssr/_0cvjbuz._.js +0 -3
- package/.next/server/chunks/ssr/_0fafgvl._.js +0 -3
- package/.next/server/chunks/ssr/_0j4v8of._.js +0 -3
- package/.next/server/chunks/ssr/_0l81bzy._.js +0 -3
- package/.next/server/chunks/ssr/_0nso8tp._.js +0 -3
- package/.next/server/chunks/ssr/_0sf1isi._.js +0 -3
- package/.next/server/chunks/ssr/_0ti51xc._.js +0 -3
- package/.next/server/chunks/ssr/_0y84qo6._.js +0 -3
- package/.next/server/chunks/ssr/_10uvw3l._.js +0 -3
- package/.next/server/chunks/ssr/_1dcxzqe._.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/_1jbv7m1._.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/lib_realtime_0aetuyp._.js +0 -24
- package/.next/server/chunks/ssr/lib_realtime_18k_aj-._.js +0 -24
- package/.next/server/chunks/ssr/node_modules_zod_v4_classic_errors_05xv7vp.js +0 -3
- package/.next/server/chunks/ssr/node_modules_zod_v4_classic_external_15fmmz3.js +0 -55
- package/.next/static/chunks/0f9sq-7q_yxyl.js +0 -1
- package/.next/static/chunks/0tydnn2kybibk.js +0 -1
- package/.next/static/chunks/0yysv1gzin17t.js +0 -1
- package/.next/static/chunks/1fr5m75pwtyic.js +0 -1
- package/.next/static/chunks/1gy3bbv7usnjo.js +0 -1
- package/.next/static/chunks/1keib_gt066gc.js +0 -1
- package/.next/static/chunks/1ytnip8wdng93.js +0 -1
- package/.next/static/chunks/21rk8w7bda-su.js +0 -1
- package/.next/static/chunks/247d-r95j8xs0.js +0 -1
- package/.next/static/chunks/28g42tw8tsvhd.js +0 -1
- package/.next/static/chunks/29gyb3nubj51j.js +0 -53
- package/.next/static/chunks/2cwjgkt_hoyhj.js +0 -22
- package/.next/static/chunks/2fq_86jvq9ymq.js +0 -2
- package/.next/static/chunks/2rbf1fpd8n80-.js +0 -22
- package/.next/static/chunks/2ukj8k69y89um.js +0 -1
- package/.next/static/chunks/2uxum7qbyeyxd.js +0 -1
- package/.next/static/chunks/2wngeetfnzxkp.js +0 -2
- package/.next/static/chunks/388-t2v72jh39.css +0 -1
- package/.next/static/chunks/3fqvc0cg-atq_.js +0 -1
- package/.next/static/chunks/3p4egvfjxpatb.js +0 -1
- package/.next/static/chunks/3qe1w1ei-huhl.js +0 -1
- package/.next/static/chunks/3xxa2j56-f3nm.js +0 -3
- package/.next/static/chunks/3y40riycdip-i.js +0 -1
- package/.next/static/chunks/45a6zbtkelph9.js +0 -1
- package/.next/static/media/favicon.2vob68tjqpejf.ico +0 -0
- package/features/ai/prompts/memory-tidy.prompt.ts +0 -123
- package/features/ai/tools/tidy.tool.ts +0 -22
- 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/{memory/tidy → bot/memory/files}/route/build-manifest.json +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory/files}/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory/files}/route.js.map +0 -0
- /package/.next/static/{X34BUd9bfdH27ripuwwBm → x1cCqY0kWpR_VcYx_lWO5}/_buildManifest.js +0 -0
- /package/.next/static/{X34BUd9bfdH27ripuwwBm → x1cCqY0kWpR_VcYx_lWO5}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{X34BUd9bfdH27ripuwwBm → x1cCqY0kWpR_VcYx_lWO5}/_ssgManifest.js +0 -0
|
@@ -1,7 +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
|
-
import
|
|
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";
|
|
5
7
|
import { findPinnedTools } from "@/features/connectors/mcp.query";
|
|
6
8
|
import type { McpToolRef } from "@/features/connectors/mcp.schema";
|
|
7
9
|
import {
|
|
@@ -16,13 +18,18 @@ import {
|
|
|
16
18
|
loadSkills,
|
|
17
19
|
type SkillMetadata,
|
|
18
20
|
} from "@/features/skills/skills.discover";
|
|
19
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
type MachineTools,
|
|
23
|
+
openWorkspace,
|
|
24
|
+
readMachineTools,
|
|
25
|
+
} from "@/features/workspace/workspace";
|
|
20
26
|
import { logger } from "@/lib/logger";
|
|
21
27
|
import { clip } from "@/lib/utils";
|
|
22
28
|
import { listConnectedToolNames } from "../tools/connected";
|
|
23
29
|
import {
|
|
24
30
|
carriedLines,
|
|
25
31
|
type LoadedPrompt,
|
|
32
|
+
logPromptSize,
|
|
26
33
|
mcpToolLines,
|
|
27
34
|
noteLines,
|
|
28
35
|
nowLine,
|
|
@@ -34,50 +41,74 @@ import {
|
|
|
34
41
|
* Each chapter decides for itself whether it is included. Assembled on every run, never cached,
|
|
35
42
|
* so a skill or server added a minute ago is in the next job's prompt.
|
|
36
43
|
* Two seats share this prompt: the bot holding the job, and one borrowed for a part of it
|
|
37
|
-
* (`ask_bot`). Only identity, roster, asking and
|
|
44
|
+
* (`ask_bot`). Only identity, roster, asking and answering differ between them.
|
|
38
45
|
*
|
|
39
46
|
* @param self This run's bot name; used only to drop itself from the roster.
|
|
40
47
|
* @param persona Owner's instruction for this bot from settings.
|
|
41
|
-
* @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.
|
|
42
49
|
*/
|
|
43
50
|
export async function loadBotPrompt(
|
|
44
51
|
self: string,
|
|
45
52
|
persona?: string | null,
|
|
46
|
-
|
|
53
|
+
seat?: { askedBy: string; above: string[]; canBorrow: boolean } | null,
|
|
54
|
+
/** The two folders that are this run's rather than the user's (bot.run). */
|
|
55
|
+
folders?: { scratch: string | null; own: string },
|
|
47
56
|
): Promise<LoadedPrompt> {
|
|
48
57
|
const sandbox = await openWorkspace();
|
|
49
58
|
const name = self.trim();
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
const askedBy = seat?.askedBy ?? null;
|
|
60
|
+
const [
|
|
61
|
+
skills,
|
|
62
|
+
index,
|
|
63
|
+
carried,
|
|
64
|
+
mcpTools,
|
|
65
|
+
pinned,
|
|
66
|
+
allBots,
|
|
67
|
+
kept,
|
|
68
|
+
memoryOn,
|
|
69
|
+
machine,
|
|
70
|
+
] = await Promise.all([
|
|
71
|
+
loadSkills(sandbox),
|
|
72
|
+
listNoteIndex(),
|
|
73
|
+
listAlwaysLoaded(),
|
|
74
|
+
// User-connected servers and the app's studio in one list (tools/connected)
|
|
75
|
+
listConnectedToolNames(),
|
|
76
|
+
// MCP tools this bot already holds; dropped from the listing below
|
|
77
|
+
findPinnedTools(name),
|
|
78
|
+
listJobBots(),
|
|
79
|
+
// What this bot kept on earlier jobs, read off its own folder (bot.memory)
|
|
80
|
+
listBotMemory(name),
|
|
81
|
+
readBotMemoryOn(),
|
|
82
|
+
// One `command -v` sweep; what is here decides the first command (environment)
|
|
83
|
+
readMachineTools(sandbox),
|
|
84
|
+
]);
|
|
85
|
+
|
|
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
|
+
);
|
|
65
94
|
|
|
66
95
|
const text = [
|
|
67
|
-
askedBy ? borrowedIdentity(askedBy) : identity(),
|
|
96
|
+
askedBy ? borrowedIdentity(name, askedBy) : identity(name),
|
|
68
97
|
memory(index, carried),
|
|
98
|
+
memoryOn ? ownMemory(botMemoryFolder(name), kept) : "",
|
|
69
99
|
connectedTools(mcpTools, pinned),
|
|
70
100
|
methods(skills),
|
|
71
|
-
environment(sandbox.cwd),
|
|
101
|
+
environment(sandbox.cwd, machine, folders),
|
|
72
102
|
roster(peers),
|
|
73
103
|
askedBy ? askingBack(askedBy) : ASKING,
|
|
74
|
-
askedBy ? handingUp(askedBy) :
|
|
104
|
+
askedBy ? handingUp(askedBy) : ANSWERING,
|
|
75
105
|
// Last, so it is the closest thing to the work and outranks the rest
|
|
76
106
|
ownerInstruction(persona),
|
|
77
107
|
]
|
|
78
108
|
.filter(Boolean)
|
|
79
109
|
.join("\n\n");
|
|
80
110
|
|
|
111
|
+
logPromptSize("bot", text);
|
|
81
112
|
logger.debug(`bot prompt\n${text}`);
|
|
82
113
|
|
|
83
114
|
return {
|
|
@@ -88,18 +119,19 @@ export async function loadBotPrompt(
|
|
|
88
119
|
}
|
|
89
120
|
|
|
90
121
|
/** Who the bot is, what machine it is on, and that guesses are not results. */
|
|
91
|
-
function identity(): string {
|
|
122
|
+
function identity(name: string): string {
|
|
92
123
|
return [
|
|
93
|
-
|
|
124
|
+
// Named, because the owner's prompt may not name it and its own instructions are addressed to it
|
|
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()}`,
|
|
94
126
|
MACHINE,
|
|
95
127
|
NO_GUESSING,
|
|
96
128
|
].join("\n\n");
|
|
97
129
|
}
|
|
98
130
|
|
|
99
131
|
/** The borrowed seat: above it is the borrowing bot, not Thursday. */
|
|
100
|
-
function borrowedIdentity(askedBy: string): string {
|
|
132
|
+
function borrowedIdentity(name: string, askedBy: string): string {
|
|
101
133
|
return [
|
|
102
|
-
`You are 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()}`,
|
|
103
135
|
MACHINE,
|
|
104
136
|
NO_GUESSING,
|
|
105
137
|
].join("\n\n");
|
|
@@ -107,7 +139,7 @@ function borrowedIdentity(askedBy: string): string {
|
|
|
107
139
|
|
|
108
140
|
const MACHINE = `**You are on a real computer — the user's own.** You have a shell and a filesystem, and the job is done, not described: where there is no tool for something, write one — in \`node\` unless they asked for another language, the runtime this app itself runs on. Reach for \`${TOOL_NAMES.bash}\` before concluding that something cannot be done, but after the roster, not instead of it: a script you write to do another bot's job is the long way round.
|
|
109
141
|
|
|
110
|
-
**What is missing gets installed
|
|
142
|
+
**What is missing gets installed**, onto the machine once they say yes. What is already there is nobody's question — Environment says what this machine has.
|
|
111
143
|
|
|
112
144
|
**Bring back the thing itself** — their own machine, their own accounts, their own copy of whatever they sent you for — not a smaller safer version of it, and not a note on why you did not.`;
|
|
113
145
|
|
|
@@ -127,14 +159,14 @@ Written by the person this bot works for. Where these and anything above disagre
|
|
|
127
159
|
${persona.trim()}`
|
|
128
160
|
: "";
|
|
129
161
|
|
|
130
|
-
/** 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. */
|
|
131
163
|
function memory(
|
|
132
164
|
index: MemoryIndexEntry[],
|
|
133
165
|
carried: MemoryAlwaysLoaded[],
|
|
134
166
|
): string {
|
|
135
|
-
const head = `##
|
|
167
|
+
const head = `## The user's memory
|
|
136
168
|
|
|
137
|
-
What the user
|
|
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.`;
|
|
138
170
|
|
|
139
171
|
const alreadyKnown = carried.length
|
|
140
172
|
? `Already known:
|
|
@@ -151,6 +183,34 @@ A topic not listed is one nobody knows anything about.`;
|
|
|
151
183
|
return [head, alreadyKnown, listing].filter(Boolean).join("\n\n");
|
|
152
184
|
}
|
|
153
185
|
|
|
186
|
+
/**
|
|
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.
|
|
191
|
+
*/
|
|
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}`;
|
|
212
|
+
}
|
|
213
|
+
|
|
154
214
|
/**
|
|
155
215
|
* Names only; schemas stay behind `tool_search`. Without the list the model cannot tell
|
|
156
216
|
* "no such tool" from "not searched yet".
|
|
@@ -184,13 +244,35 @@ Written-down methods. When the job is one of these, read it with \`${TOOL_NAMES.
|
|
|
184
244
|
${skillLines(skills)}`;
|
|
185
245
|
}
|
|
186
246
|
|
|
187
|
-
/**
|
|
188
|
-
|
|
247
|
+
/**
|
|
248
|
+
* The machine, then the workspace. What is installed is read as the prompt is
|
|
249
|
+
* assembled (workspace.ts readMachineTools) rather than left to the job to find
|
|
250
|
+
* out: a bot that has to check first spends a step on it, and one that guesses
|
|
251
|
+
* writes for a runtime that is not here. Naming what is absent does as much
|
|
252
|
+
* work as naming what is present — it is the half a model otherwise assumes.
|
|
253
|
+
* The three folders are named once; `write_file` refuses anything else
|
|
254
|
+
* (workspace.ts writeRefusal).
|
|
255
|
+
*/
|
|
256
|
+
const environment = (
|
|
257
|
+
cwd: string,
|
|
258
|
+
machine: MachineTools,
|
|
259
|
+
folders?: { scratch: string | null; own: string },
|
|
260
|
+
) => `## Environment
|
|
189
261
|
|
|
190
262
|
Current Cwd: ${cwd}
|
|
191
263
|
Platform: ${process.platform}
|
|
264
|
+
${machineLines(machine)}
|
|
192
265
|
|
|
193
|
-
|
|
266
|
+
Read off this machine as the job opened, so it is current: reach for what is here instead of checking for it.
|
|
267
|
+
|
|
268
|
+
Your workspace — \`${TOOL_NAMES.bash}\` runs here. Everything you write goes in one of these, and they are kept apart because what is in them lives for different lengths of time:
|
|
269
|
+
|
|
270
|
+
- \`${PATHS.artifacts}/\` — finished work the user opens, one entry per result. Theirs, and it stays.
|
|
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.
|
|
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.
|
|
274
|
+
|
|
275
|
+
Never the directory above — that is the app you run in; outside the workspace, only where the user pointed you.`;
|
|
194
276
|
|
|
195
277
|
/** Same roster the voice prompt shows, used the other way: which part of a held job is another bot's. */
|
|
196
278
|
function roster(peers: JobBot[]): string {
|
|
@@ -200,63 +282,167 @@ function roster(peers: JobBot[]): string {
|
|
|
200
282
|
|
|
201
283
|
${peers.map((bot) => `- **${bot.name}** — ${bot.description}`).join("\n")}
|
|
202
284
|
|
|
203
|
-
|
|
285
|
+
These lines were written for the user, who reads them on their own screen: where one says "you" it means them, not you.
|
|
286
|
+
|
|
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.`;
|
|
204
288
|
}
|
|
205
289
|
|
|
206
|
-
/** The only place a run can stop.
|
|
290
|
+
/** The only place a run can stop. */
|
|
207
291
|
const ASKING = `## Asking
|
|
208
292
|
|
|
209
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.
|
|
210
294
|
|
|
211
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.
|
|
212
296
|
|
|
213
|
-
|
|
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.`;
|
|
214
298
|
|
|
215
299
|
const askingBack = (askedBy: string) => `## Asking
|
|
216
300
|
|
|
217
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.`;
|
|
218
302
|
|
|
219
|
-
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.`;
|
|
220
|
-
|
|
221
303
|
/**
|
|
222
|
-
*
|
|
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`).
|
|
223
311
|
* Images in `.md` need absolute routes because a document opens from two places and relative paths resolve differently.
|
|
224
312
|
*/
|
|
225
|
-
const
|
|
313
|
+
const ANSWERING = `## Answering
|
|
226
314
|
|
|
227
|
-
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.
|
|
228
316
|
|
|
229
|
-
|
|
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}/…\`).`;
|
|
230
318
|
|
|
231
|
-
const handingUp = (askedBy: string) => `##
|
|
319
|
+
const handingUp = (askedBy: string) => `## Answering
|
|
232
320
|
|
|
233
|
-
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.`;
|
|
234
322
|
|
|
235
323
|
/** How many turns of the call travel with the job: enough for one missed detail, not enough to bury the request. */
|
|
236
324
|
export const OPENING_TURNS = 10;
|
|
237
|
-
|
|
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"];
|
|
238
328
|
|
|
239
329
|
/**
|
|
240
|
-
* The first message
|
|
241
|
-
*
|
|
242
|
-
*
|
|
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".
|
|
243
337
|
*/
|
|
244
338
|
export function buildTaskOpening(input: {
|
|
339
|
+
bot: string;
|
|
245
340
|
request: string;
|
|
246
341
|
conversation: { role: "user" | "assistant"; text: string }[];
|
|
247
|
-
}):
|
|
342
|
+
}): OpeningContent {
|
|
248
343
|
const turns = input.conversation.filter((turn) => turn.text.trim());
|
|
249
|
-
|
|
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.
|
|
250
349
|
|
|
251
|
-
|
|
350
|
+
${turns
|
|
351
|
+
.map(
|
|
252
352
|
(turn) =>
|
|
253
|
-
`${turn.role === "user" ? "user" : "thursday"}: ${clip(turn.text,
|
|
254
|
-
)
|
|
255
|
-
|
|
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
|
+
}
|
|
256
362
|
|
|
257
|
-
|
|
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
|
+
}
|
|
258
390
|
|
|
259
|
-
|
|
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
|
+
}
|
|
260
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.
|
|
261
423
|
${lines.join("\n")}`;
|
|
262
424
|
}
|
|
425
|
+
|
|
426
|
+
/** One line per kind, absences included. Only a bot gets these: the call runs one command as a glance. */
|
|
427
|
+
function machineLines(machine: MachineTools): string {
|
|
428
|
+
const line = (label: string, of: MachineTools["runtimes"]) =>
|
|
429
|
+
`${label}: ${of.found.length ? of.found.join(", ") : "none"}.${
|
|
430
|
+
of.missing.length ? ` Not here: ${of.missing.join(", ")}.` : ""
|
|
431
|
+
}`;
|
|
432
|
+
// Not a preference: openWorkspace writes the pnpm fence, and an `npm install`
|
|
433
|
+
// in a project here resolves against that rather than against the project
|
|
434
|
+
const fenced = machine.managers.found.includes("pnpm")
|
|
435
|
+
? " Use pnpm, not npm — this workspace is fenced for it (`pnpm-workspace.yaml`, `.npmrc`)."
|
|
436
|
+
: "";
|
|
437
|
+
return [
|
|
438
|
+
line("Runtimes", machine.runtimes),
|
|
439
|
+
`${line("Package managers", machine.managers)}${fenced}`,
|
|
440
|
+
machine.browser === null
|
|
441
|
+
? ""
|
|
442
|
+
: machine.browser
|
|
443
|
+
? "Browser: installed."
|
|
444
|
+
: "Browser: not installed — `playwright-cli install-browser chromium` puts one there.",
|
|
445
|
+
]
|
|
446
|
+
.filter(Boolean)
|
|
447
|
+
.join("\n");
|
|
448
|
+
}
|
|
@@ -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,15 +1,16 @@
|
|
|
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
|
-
import {
|
|
12
|
+
import { logger } from "@/lib/logger";
|
|
13
|
+
import { estimateTokens, sectionTokens } from "@/lib/tokens";
|
|
13
14
|
import { clip } from "@/lib/utils";
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -26,12 +27,67 @@ export type LoadedPrompt = {
|
|
|
26
27
|
opening: string | null;
|
|
27
28
|
};
|
|
28
29
|
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
/**
|
|
31
|
+
* What one assembled prompt costs, said where it is assembled. The debug line is
|
|
32
|
+
* the whole breakdown; past PROMPT_BUDGET it is a warning naming the chapter
|
|
33
|
+
* carrying it, and that one is always a listing the user can act on — nothing
|
|
34
|
+
* else in the app would ever say a prompt had grown.
|
|
35
|
+
*/
|
|
36
|
+
export function logPromptSize(kind: string, text: string): void {
|
|
37
|
+
const parts = sectionTokens(text);
|
|
38
|
+
const total = parts.reduce((sum, part) => sum + part.tokens, 0);
|
|
39
|
+
logger.debug(
|
|
40
|
+
`${kind} prompt ${total} tokens — ${parts
|
|
41
|
+
.map((part) => `${part.name} ${part.tokens}`)
|
|
42
|
+
.join(", ")}`,
|
|
43
|
+
);
|
|
44
|
+
const biggest = parts[0];
|
|
45
|
+
if (total > PROMPT_BUDGET && biggest) {
|
|
46
|
+
logger.warn(
|
|
47
|
+
`${kind} prompt is ${total} tokens, over ${PROMPT_BUDGET}: ${biggest.name} carries ${biggest.tokens} of it. Every call and every job pays this.`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** `2026-09-02 (Wed) 15:41 Asia/Seoul` */
|
|
53
|
+
export const clockNow = (now = new Date()) =>
|
|
54
|
+
`${format(now, "yyyy-MM-dd (EEE) HH:mm")} ${
|
|
32
55
|
Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
33
56
|
}`;
|
|
34
57
|
|
|
58
|
+
/** `**Now**: 2026-09-02 (Wed) 15:41 Asia/Seoul` */
|
|
59
|
+
export const nowLine = (now = new Date()) => `**Now**: ${clockNow(now)}`;
|
|
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
|
+
|
|
35
91
|
/** `4mo`, `12d`: short enough to read aloud. */
|
|
36
92
|
function sinceLast(at: MemoryIndexEntry["lastSeenAt"]): string {
|
|
37
93
|
const days = Math.floor((Date.now() - toDate(at).getTime()) / 86_400_000);
|
|
@@ -59,13 +115,15 @@ export const carriedLines = (loaded: MemoryAlwaysLoaded[]): string =>
|
|
|
59
115
|
loaded.map((fact) => `- ${fact.text} · ${fact.path} #${fact.id}`).join("\n");
|
|
60
116
|
|
|
61
117
|
/**
|
|
62
|
-
* Whether it is time to tidy, and why:
|
|
63
|
-
*
|
|
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.
|
|
64
122
|
*/
|
|
65
123
|
export const tidying = (index: MemoryIndexEntry[]) => ({
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
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),
|
|
69
127
|
});
|
|
70
128
|
|
|
71
129
|
/** A bot gets the whole description; `short` gives the voice prompt the first sentence only. */
|
|
@@ -132,9 +190,6 @@ export type RecentCall = {
|
|
|
132
190
|
}[];
|
|
133
191
|
};
|
|
134
192
|
|
|
135
|
-
/** How much of a past job's report is worth carrying; the rest is asked for with `task`. */
|
|
136
|
-
const JOB_OUTCOME = 160;
|
|
137
|
-
|
|
138
193
|
/**
|
|
139
194
|
* One turn as the transcript carries it. A `delegate` line takes what became of
|
|
140
195
|
* the job: the handle to pick it back up, and how it ended — arguments alone say
|
|
@@ -147,25 +202,20 @@ function turnLine(turn: RecentCall["turns"][number], call: RecentCall): string {
|
|
|
147
202
|
const args = `you → ${turn.tool ?? "tool"} ${clip(turn.text, PROMPT_LINE.toolArgs)}`;
|
|
148
203
|
if (turn.tool !== TOOL_NAMES.delegate) return args;
|
|
149
204
|
|
|
150
|
-
const label = (
|
|
151
|
-
try {
|
|
152
|
-
const said = JSON.parse(turn.text) as { label?: unknown };
|
|
153
|
-
return typeof said.label === "string" ? said.label : null;
|
|
154
|
-
} catch {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
})();
|
|
205
|
+
const label = delegatedLabel(turn.tool, turn.text);
|
|
158
206
|
const job = label ? call.jobs?.find((one) => one.label === label) : undefined;
|
|
159
207
|
if (!job) return args;
|
|
160
208
|
|
|
161
|
-
const said = job.outcome
|
|
209
|
+
const said = job.outcome
|
|
210
|
+
? `: ${clip(job.outcome, PROMPT_LINE.jobOutcome)}`
|
|
211
|
+
: "";
|
|
162
212
|
return `you → ${turn.tool} "${job.label}" (${job.id}) — ${job.status}${said}`;
|
|
163
213
|
}
|
|
164
214
|
|
|
165
215
|
/** The last calls as stored, newest last, cut to a token budget. A tool turn carries the call, not the result. */
|
|
166
216
|
export function recentCallLines(calls: RecentCall[], budget: number): string {
|
|
167
217
|
// Newest line backwards until the budget is spent, then put it back in order.
|
|
168
|
-
// 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
|
|
169
219
|
const kept: { call: RecentCall; line: string }[] = [];
|
|
170
220
|
let spent = 0;
|
|
171
221
|
outer: for (let c = calls.length - 1; c >= 0; c--) {
|
|
@@ -185,12 +235,7 @@ export function recentCallLines(calls: RecentCall[], budget: number): string {
|
|
|
185
235
|
for (const { call, line } of kept) {
|
|
186
236
|
if (call !== open) {
|
|
187
237
|
open = call;
|
|
188
|
-
|
|
189
|
-
addSuffix: true,
|
|
190
|
-
});
|
|
191
|
-
lines.push(
|
|
192
|
-
`### ${call.startedAt.toISOString().slice(0, 16).replace("T", " ")} (${when})`,
|
|
193
|
-
);
|
|
238
|
+
lines.push(`### ${callStamp(call.startedAt)}`);
|
|
194
239
|
}
|
|
195
240
|
lines.push(line);
|
|
196
241
|
}
|