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,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";
|
|
@@ -29,6 +29,7 @@ import { listConnectedToolNames } from "../tools/connected";
|
|
|
29
29
|
import {
|
|
30
30
|
carriedLines,
|
|
31
31
|
type LoadedPrompt,
|
|
32
|
+
logPromptSize,
|
|
32
33
|
mcpServerLines,
|
|
33
34
|
noteLines,
|
|
34
35
|
nowLine,
|
|
@@ -85,6 +86,7 @@ export async function loadThursdayPrompt(
|
|
|
85
86
|
.filter(Boolean)
|
|
86
87
|
.join("\n\n");
|
|
87
88
|
|
|
89
|
+
logPromptSize("thursday", text);
|
|
88
90
|
logger.debug(`thursday prompt\n${text}`);
|
|
89
91
|
|
|
90
92
|
return {
|
|
@@ -157,27 +159,46 @@ ${carriedLines(carried)}`
|
|
|
157
159
|
|
|
158
160
|
${noteLines(index, crowded)}
|
|
159
161
|
|
|
160
|
-
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.
|
|
161
163
|
|
|
162
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.
|
|
163
165
|
|
|
164
166
|
${MEMORY_PATHS.map((entry) => `- ${entry.path} — ${entry.of}`).join("\n")}`;
|
|
165
167
|
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
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)
|
|
169
175
|
.map((note) => `${note.path} (${note.factCount})`)
|
|
170
|
-
.join(", ")}
|
|
171
|
-
|
|
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
|
|
172
184
|
.slice(-4)
|
|
173
185
|
.map((note) => note.path)
|
|
174
|
-
.join(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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");
|
|
181
202
|
}
|
|
182
203
|
|
|
183
204
|
/** Last calls verbatim, marked as past so the model does not answer as if just asked. Absent on the first call. */
|
|
@@ -242,7 +263,7 @@ Who you hand work to — the names \`${TOOL_NAMES.delegate}\` takes.
|
|
|
242
263
|
|
|
243
264
|
${input.roster.map((bot) => `- **${bot.name}** — ${bot.description}`).join("\n")}`;
|
|
244
265
|
|
|
245
|
-
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.`;
|
|
246
267
|
|
|
247
268
|
const hands = [
|
|
248
269
|
input.skills.length
|
|
@@ -263,9 +284,13 @@ ${hands.join("\n\n")}`
|
|
|
263
284
|
|
|
264
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.
|
|
265
286
|
|
|
266
|
-
|
|
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.`;
|
|
267
288
|
|
|
268
|
-
|
|
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.`;
|
|
269
294
|
|
|
270
295
|
return [list, machine, catalogue, handingOver, comingBack]
|
|
271
296
|
.filter(Boolean)
|
|
@@ -8,7 +8,7 @@ import { insideWorkspace } from "@/features/workspace/workspace";
|
|
|
8
8
|
/**
|
|
9
9
|
* Specs for the tools that move work between the voice session and bots. Only what the model
|
|
10
10
|
* sees lives here; execution belongs to whoever runs the tool (load-tools, bot.run), and the
|
|
11
|
-
* screen draws a call off its spec (task.query). `
|
|
11
|
+
* screen draws a call off its spec (task.query). `answer` has its own execute because what it
|
|
12
12
|
* checks is a file on disk.
|
|
13
13
|
*/
|
|
14
14
|
|
|
@@ -45,12 +45,12 @@ export const askBotSpec = {
|
|
|
45
45
|
request: z
|
|
46
46
|
.string()
|
|
47
47
|
.describe(
|
|
48
|
-
"The part they take
|
|
48
|
+
"The part they take: the outcome you want, the shape to hand it back in (a path, a number, a list), and every name, path, number and limit that bears on it. It reaches them under the job and the call it came from, which are attached for you — write the part, not the job again.",
|
|
49
49
|
),
|
|
50
50
|
context: z
|
|
51
51
|
.string()
|
|
52
52
|
.describe(
|
|
53
|
-
"
|
|
53
|
+
"What you have done on the job so far and why this part is theirs — exact values, and the paths of files you wrote for them to read. They see this, the part, the job and the call; not your thread or your tool output, so a value you leave out is one they fetch again.",
|
|
54
54
|
),
|
|
55
55
|
}),
|
|
56
56
|
};
|
|
@@ -94,7 +94,7 @@ export const askThursdaySpec = {
|
|
|
94
94
|
// joined string, and a schema rejection only loops. The reader takes arrays only (task.query optionsOf)
|
|
95
95
|
options: z
|
|
96
96
|
.union([z.string().array(), z.string()])
|
|
97
|
-
.
|
|
97
|
+
.nullish()
|
|
98
98
|
.describe(
|
|
99
99
|
'Only when there really are choices — two or three, each short, as an array: ["Signed in", "Not yet"]. Null for an open question.',
|
|
100
100
|
),
|
|
@@ -103,22 +103,18 @@ export const askThursdaySpec = {
|
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
105
|
* The one way a run ends on its own terms; the loop is stopped by it (`hasToolCall`, bot.run).
|
|
106
|
-
*
|
|
106
|
+
* Whether the job is over is the runtime's to say, never an argument: an answer ends it, and a
|
|
107
|
+
* run the app stopped first (bot.run `stopped`) waits to be continued.
|
|
107
108
|
*/
|
|
108
|
-
export const
|
|
109
|
-
name: TOOL_NAMES.
|
|
109
|
+
export const answerSpec = {
|
|
110
|
+
name: TOOL_NAMES.answer,
|
|
110
111
|
description:
|
|
111
|
-
"
|
|
112
|
+
"Answer the job you were given. Calling this ends the job — nothing after it runs.",
|
|
112
113
|
parameters: z.object({
|
|
113
114
|
result: z
|
|
114
115
|
.string()
|
|
115
116
|
.describe(
|
|
116
|
-
"The
|
|
117
|
-
),
|
|
118
|
-
complete: z
|
|
119
|
-
.boolean()
|
|
120
|
-
.describe(
|
|
121
|
-
"True when the whole request is done. False when work is left over — the user is then asked whether to keep going, and `result` is what they decide on.",
|
|
117
|
+
"The answer itself — what you found or did, not a replay of how. As long as the answer needs and no longer: one number is one line. In the user's language; the thread is on their screen. If you could not do it, say what stopped you.",
|
|
122
118
|
),
|
|
123
119
|
}),
|
|
124
120
|
};
|
|
@@ -132,13 +128,13 @@ export const taskSpec = {
|
|
|
132
128
|
action: z.enum(["status", "answer", "cancel"]),
|
|
133
129
|
task: z
|
|
134
130
|
.string()
|
|
135
|
-
.
|
|
131
|
+
.nullish()
|
|
136
132
|
.describe(
|
|
137
|
-
|
|
133
|
+
'The job, by its label or by the handle a past call\'s transcript carries. Leave it out with `answer` and it goes to the job that moved last — what "that one" means a moment after it answered. With `status`: null for every job in one line each — that is the list — or name one to get its answer in full.',
|
|
138
134
|
),
|
|
139
135
|
answer: z
|
|
140
136
|
.string()
|
|
141
|
-
.
|
|
137
|
+
.nullish()
|
|
142
138
|
.describe(
|
|
143
139
|
"With `answer`: what to tell the bot — the answer to its question, a course correction for a job still running, or what to do next on one that finished.",
|
|
144
140
|
),
|
|
@@ -152,33 +148,39 @@ export const askThursdayTool = tool({
|
|
|
152
148
|
});
|
|
153
149
|
|
|
154
150
|
/**
|
|
155
|
-
* `
|
|
151
|
+
* `answer` does have an execute, and it only acknowledges. The loop is stopped
|
|
156
152
|
* by `hasToolCall` after the step, not by the absence of an execute — that way
|
|
157
153
|
* the call and its result are both written to the thread, and a resumed run
|
|
158
154
|
* reads a finished exchange rather than a call left hanging.
|
|
159
155
|
*/
|
|
160
|
-
export const
|
|
161
|
-
description:
|
|
162
|
-
inputSchema:
|
|
163
|
-
execute: async ({ result
|
|
156
|
+
export const answerTool = tool({
|
|
157
|
+
description: answerSpec.description,
|
|
158
|
+
inputSchema: answerSpec.parameters,
|
|
159
|
+
execute: async ({ result }) => {
|
|
164
160
|
const missing = await missingFiles(result);
|
|
165
161
|
if (missing.length) {
|
|
166
|
-
return `${
|
|
162
|
+
return `${NOT_ANSWERED} these files do not exist — ${missing.join(", ")}. Write them first, or take the paths out of the answer.`;
|
|
167
163
|
}
|
|
168
|
-
return
|
|
169
|
-
? "Handed back. The job is closed; nothing further runs."
|
|
170
|
-
: "Handed back as unfinished. The user decides whether to continue.";
|
|
164
|
+
return "Answered. The job is closed; nothing further runs.";
|
|
171
165
|
},
|
|
172
166
|
});
|
|
173
167
|
|
|
174
168
|
/**
|
|
175
|
-
*
|
|
169
|
+
* An answer naming a workspace file that does not exist is refused: the path becomes a link
|
|
176
170
|
* and opens by itself (bot.runner artifactIn). Paths outside the workspace are not checked.
|
|
177
171
|
*/
|
|
178
|
-
const
|
|
172
|
+
const NOT_ANSWERED = "Not answered:";
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* `answer` was called `report` before it was renamed. A stored thread keeps the name the
|
|
176
|
+
* call was made under, and the room draws that call as the job's prose — so the three
|
|
177
|
+
* places that read messages back match either name. Nothing writes the old one.
|
|
178
|
+
*/
|
|
179
|
+
export const isAnswerCall = (toolName: string): boolean =>
|
|
180
|
+
toolName === TOOL_NAMES.answer || toolName === "report";
|
|
179
181
|
|
|
180
|
-
export const
|
|
181
|
-
typeof output !== "string" || !output.startsWith(
|
|
182
|
+
export const answerAccepted = (output: unknown): boolean =>
|
|
183
|
+
typeof output !== "string" || !output.startsWith(NOT_ANSWERED);
|
|
182
184
|
|
|
183
185
|
async function missingFiles(result: string): Promise<string[]> {
|
|
184
186
|
const missing: string[] = [];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import z from "zod";
|
|
2
|
-
import { STUDIO_SERVER } from "@/config";
|
|
2
|
+
import { CONNECTED_TOOL_TIMEOUT_MS, STUDIO_SERVER } from "@/config";
|
|
3
3
|
import {
|
|
4
4
|
McpAuthRequiredError,
|
|
5
5
|
mcpManager,
|
|
@@ -80,6 +80,8 @@ export async function findConnectedSchemas(
|
|
|
80
80
|
/**
|
|
81
81
|
* Run one, wherever it lives. Long answers are folded (lib/sandbox fold). Failures are reported,
|
|
82
82
|
* not thrown; a server that wants the user to sign in first comes back as its own status with the url.
|
|
83
|
+
* One deadline covers both sources (config CONNECTED_TOOL_TIMEOUT_MS): nothing behind this door
|
|
84
|
+
* bounds itself, and a tool that never answers would hold the job's step for good.
|
|
83
85
|
*/
|
|
84
86
|
export async function callConnectedTool(
|
|
85
87
|
sandbox: Sandbox,
|
|
@@ -88,11 +90,15 @@ export async function callConnectedTool(
|
|
|
88
90
|
args: Record<string, unknown> | undefined,
|
|
89
91
|
abortSignal?: AbortSignal,
|
|
90
92
|
): Promise<McpCallOutcome> {
|
|
93
|
+
const deadline = AbortSignal.timeout(CONNECTED_TOOL_TIMEOUT_MS);
|
|
94
|
+
const signal = abortSignal
|
|
95
|
+
? AbortSignal.any([abortSignal, deadline])
|
|
96
|
+
: deadline;
|
|
91
97
|
try {
|
|
92
98
|
const text =
|
|
93
99
|
server === STUDIO_SERVER
|
|
94
|
-
? await callStudioTool(sandbox, name, args,
|
|
95
|
-
: await callMcpTool(server, name, args);
|
|
100
|
+
? await callStudioTool(sandbox, name, args, signal)
|
|
101
|
+
: await callMcpTool(server, name, args, signal);
|
|
96
102
|
if (typeof text !== "string") return text;
|
|
97
103
|
return {
|
|
98
104
|
status: "ok",
|
|
@@ -106,6 +112,12 @@ export async function callConnectedTool(
|
|
|
106
112
|
authorizationUrl: error.authorizationUrl,
|
|
107
113
|
};
|
|
108
114
|
}
|
|
115
|
+
if (deadline.aborted && !abortSignal?.aborted) {
|
|
116
|
+
return {
|
|
117
|
+
status: "error",
|
|
118
|
+
text: `${name} on ${server} gave no answer in ${CONNECTED_TOOL_TIMEOUT_MS / 60_000} minutes and was given up on.`,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
109
121
|
return { status: "error", text: errorToString(error) };
|
|
110
122
|
}
|
|
111
123
|
}
|
|
@@ -131,9 +143,10 @@ async function callMcpTool(
|
|
|
131
143
|
server: string,
|
|
132
144
|
name: string,
|
|
133
145
|
args: Record<string, unknown> | undefined,
|
|
146
|
+
signal: AbortSignal,
|
|
134
147
|
): Promise<string | McpCallOutcome> {
|
|
135
148
|
const outcome = flattenToolResult(
|
|
136
|
-
await mcpManager.callTool(server, name, args),
|
|
149
|
+
await mcpManager.callTool(server, name, args, signal),
|
|
137
150
|
);
|
|
138
151
|
return outcome.status === "ok" ? outcome.text : outcome;
|
|
139
152
|
}
|
|
@@ -22,9 +22,9 @@ const MAX_SCHEMAS = 8;
|
|
|
22
22
|
export const mcpToolSpec = {
|
|
23
23
|
[TOOL_NAMES.tool_search]: {
|
|
24
24
|
name: TOOL_NAMES.tool_search,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
// What it is, not when to reach for it: the Connected tools chapter says
|
|
26
|
+
// that the listing carries names alone and that this is how a schema is got
|
|
27
|
+
description: `Return the description and exact inputSchema of tools on a connected server, so they can be called with \`${TOOL_NAMES.tool_call}\`.`,
|
|
28
28
|
parameters: z.object({
|
|
29
29
|
server: z
|
|
30
30
|
.string()
|
|
@@ -48,13 +48,13 @@ The Connected tools section names every server and every tool on it, and that is
|
|
|
48
48
|
tool: z.string().describe("Its name, as search returned it."),
|
|
49
49
|
args: z
|
|
50
50
|
.record(z.string(), z.unknown())
|
|
51
|
-
.
|
|
51
|
+
.nullish()
|
|
52
52
|
.describe(
|
|
53
53
|
"Arguments matching the inputSchema search returned — do not guess. Null when it takes none.",
|
|
54
54
|
),
|
|
55
55
|
description: z
|
|
56
56
|
.string()
|
|
57
|
-
.
|
|
57
|
+
.nullish()
|
|
58
58
|
.describe(
|
|
59
59
|
"One short line for the user: what this call is for. Shown on their screen while it runs.",
|
|
60
60
|
),
|
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
import { tool } from "ai";
|
|
2
2
|
import * as z from "zod";
|
|
3
3
|
import { appEvents } from "@/app/api/events/app-event.server";
|
|
4
|
+
import { MEMORY_CONVERSATION_PAGE, MEMORY_LIMITS } from "@/config";
|
|
5
|
+
import {
|
|
6
|
+
callStamp,
|
|
7
|
+
conversationLines,
|
|
8
|
+
saidStamp,
|
|
9
|
+
} from "@/features/ai/prompts/prompt-helper";
|
|
4
10
|
import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
|
|
5
11
|
import {
|
|
12
|
+
findFactCall,
|
|
6
13
|
forgetFactById,
|
|
7
14
|
readNotes,
|
|
8
15
|
resolveNotePath,
|
|
9
16
|
writeNotes,
|
|
10
17
|
} from "@/features/memory/memory.query";
|
|
11
18
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
19
|
+
APP_NAMED_NOTES,
|
|
20
|
+
appNoteLine,
|
|
21
|
+
isAppNamed,
|
|
14
22
|
isMemoryPath,
|
|
15
|
-
MANY_FACTS,
|
|
16
|
-
MEMORY_ALWAYS_LISTED,
|
|
17
23
|
MEMORY_INBOX,
|
|
24
|
+
type MemoryNoteView,
|
|
25
|
+
type MemorySource,
|
|
18
26
|
} from "@/features/memory/memory.schema";
|
|
27
|
+
import { readCallConversation } from "@/features/thursday/thursday.query";
|
|
19
28
|
|
|
20
29
|
const GONE =
|
|
21
30
|
"Deleted for good. The listing in your instructions is from when this session opened and still shows it that way until the next one.";
|
|
@@ -23,11 +32,56 @@ const GONE =
|
|
|
23
32
|
const WROTE =
|
|
24
33
|
"Saved. The listing in your instructions is from when this session opened and will not show this until the next one — the note below is current.";
|
|
25
34
|
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
/**
|
|
36
|
+
* A note as a model reads it: how many facts it holds now, and `said` on each
|
|
37
|
+
* fact a call wrote — the local time of that call, the same stamp its
|
|
38
|
+
* conversation opens with, so a fact from a call already in the prompt reads
|
|
39
|
+
* as that call. Never the Date itself: it would serialise as UTC.
|
|
40
|
+
*/
|
|
41
|
+
const withCount = (note: MemoryNoteView) => ({
|
|
42
|
+
...note,
|
|
43
|
+
facts: note.facts.map(({ saidAt, ...fact }) =>
|
|
44
|
+
saidAt ? { ...fact, said: saidStamp(saidAt) } : fact,
|
|
45
|
+
),
|
|
46
|
+
factCount: note.facts.length,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
/** Why a fact has no conversation to open, by the hand that wrote it. */
|
|
50
|
+
const noConversation = (source: MemorySource | null) =>
|
|
51
|
+
source === "user"
|
|
52
|
+
? "Typed on the screen — there is no conversation behind it."
|
|
53
|
+
: source === "bot"
|
|
54
|
+
? "Saved by a bot during a job — there is no conversation behind it."
|
|
55
|
+
: "The conversation it was saved in is not kept.";
|
|
29
56
|
|
|
30
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Said when a note has outgrown the recommended size, and only then — the write
|
|
59
|
+
* itself always goes through. It names no tool: this one answers the call and a
|
|
60
|
+
* bot, and only one of them has a screen to put a note on. How to do it is the
|
|
61
|
+
* call prompt's (prompts/thursday.prompt); the ask is the same either way,
|
|
62
|
+
* because a bot that turned up a fact can hand the same request back with it.
|
|
63
|
+
*/
|
|
64
|
+
const overSize = (count: number) =>
|
|
65
|
+
count > MEMORY_LIMITS.factsPerNote
|
|
66
|
+
? ` This note now holds ${count} facts, past the ${MEMORY_LIMITS.factsPerNote} one note holds well. Ask the user which of it is no longer true and delete what they name.`
|
|
67
|
+
: "";
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @param source Which hand these writes are recorded under. The runtime knows
|
|
71
|
+
* it without being told, so no model ever chooses it (load-tools,
|
|
72
|
+
* memory.schema MemorySource).
|
|
73
|
+
* @param callId The call these tools serve, when there is one: recorded on
|
|
74
|
+
* what `memory_remember` writes, and the conversation `memory_conversation`
|
|
75
|
+
* does not hand back because the model is already in it.
|
|
76
|
+
* @param options.countReads Whether opening a note counts as reading it. The
|
|
77
|
+
* counts rank notes cold in the call prompt, so only a runtime that recalls on
|
|
78
|
+
* the user's behalf counts; an edit opening a note to change it does not.
|
|
79
|
+
*/
|
|
80
|
+
export const createMemoryTools = (
|
|
81
|
+
source: MemorySource,
|
|
82
|
+
callId: string | null = null,
|
|
83
|
+
{ countReads = true }: { countReads?: boolean } = {},
|
|
84
|
+
) => ({
|
|
31
85
|
[TOOL_NAMES.memory_recall]: tool({
|
|
32
86
|
description: "Open one note from the listing, whole.",
|
|
33
87
|
inputSchema: z.object({
|
|
@@ -38,14 +92,13 @@ export const createMemoryTools = () => ({
|
|
|
38
92
|
),
|
|
39
93
|
}),
|
|
40
94
|
execute: async ({ path }) => {
|
|
41
|
-
const { notes } = await readNotes([path]);
|
|
95
|
+
const { notes } = await readNotes([path], { touch: countReads });
|
|
42
96
|
const note = notes[0];
|
|
43
97
|
// A missing note is an answer to relay, not a reason to retry spellings
|
|
44
98
|
if (!note)
|
|
45
99
|
return { note: `Nothing on the listing called ${path.trim()}.` };
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
: note;
|
|
100
|
+
const over = overSize(note.facts.length);
|
|
101
|
+
return over ? { ...withCount(note), note: over.trim() } : withCount(note);
|
|
49
102
|
},
|
|
50
103
|
}),
|
|
51
104
|
|
|
@@ -65,32 +118,32 @@ export const createMemoryTools = () => ({
|
|
|
65
118
|
replaces: z
|
|
66
119
|
.number()
|
|
67
120
|
.int()
|
|
68
|
-
.
|
|
121
|
+
.nullish()
|
|
69
122
|
.describe(
|
|
70
123
|
"The id of the fact this replaces — from this note as handed back here or by `memory_recall`. Null if this is new. A fact that stopped being true is replaced rather than deleted, and so is a note saying the same thing twice: replacing keeps what changed on the record, deleting does not.",
|
|
71
124
|
),
|
|
72
125
|
alwaysLoad: z
|
|
73
126
|
.boolean()
|
|
74
|
-
.
|
|
127
|
+
.nullish()
|
|
75
128
|
.describe(
|
|
76
|
-
`True carries this line into every call's instructions without opening its note — for what to call them, their language and register, a standing rule. At most ${
|
|
129
|
+
`True carries this line into every call's instructions without opening its note — for what to call them, their language and register, a standing rule. At most ${MEMORY_LIMITS.carried}. Null leaves it; false makes a carried line an ordinary fact.`,
|
|
77
130
|
),
|
|
78
131
|
})
|
|
79
132
|
.array()
|
|
80
|
-
.
|
|
133
|
+
.nullish()
|
|
81
134
|
.describe(
|
|
82
135
|
"What to write under this note. Send everything that came up at once: one call is one pause in the conversation, three calls are three. Null when only naming it.",
|
|
83
136
|
),
|
|
84
137
|
description: z
|
|
85
138
|
.string()
|
|
86
|
-
.
|
|
139
|
+
.nullish()
|
|
87
140
|
.describe(
|
|
88
|
-
`One line saying what this note is about, not what it currently says. Give it for a new note, or when the line no longer fits. Null leaves it; ${
|
|
141
|
+
`One line saying what this note is about, not what it currently says. Give it for a new note, or when the line no longer fits. Null leaves it; ${APP_NAMED_NOTES.join(", ")} keep their own line.`,
|
|
89
142
|
),
|
|
90
143
|
aliases: z
|
|
91
144
|
.string()
|
|
92
145
|
.array()
|
|
93
|
-
.
|
|
146
|
+
.nullish()
|
|
94
147
|
.describe(
|
|
95
148
|
'What the user calls this note out loud, in the language they say it — the words they would use to ask for it, not the facts inside. A note at people/yuri might be "Yuri" and "my wife". Replaces the set it has, so send the whole set. Null leaves it.',
|
|
96
149
|
),
|
|
@@ -100,11 +153,15 @@ export const createMemoryTools = () => ({
|
|
|
100
153
|
const said = input.path.trim();
|
|
101
154
|
const known = await resolveNotePath(said);
|
|
102
155
|
const aliases = input.aliases ?? null;
|
|
103
|
-
// The listing line of the
|
|
104
|
-
// the model's description is ignored there
|
|
105
|
-
// the
|
|
106
|
-
|
|
107
|
-
|
|
156
|
+
// The listing line of the app-named notes is the app's (memory.schema
|
|
157
|
+
// isAppNamed); the model's description is ignored there and its own line
|
|
158
|
+
// written instead, so the inbox cannot end up described by whatever fell
|
|
159
|
+
// into it. `alwaysLoad` is not forced on them: the first-call opener
|
|
160
|
+
// (thursday.prompt) asks the model to set it.
|
|
161
|
+
const target = known ?? said;
|
|
162
|
+
const description = isAppNamed(target)
|
|
163
|
+
? appNoteLine(target)
|
|
164
|
+
: input.description?.trim() || null;
|
|
108
165
|
const facts = input.facts ?? [];
|
|
109
166
|
if (!facts.length && !description && !aliases) {
|
|
110
167
|
return {
|
|
@@ -120,14 +177,14 @@ export const createMemoryTools = () => ({
|
|
|
120
177
|
// A new path outside the convention goes to inbox, which keeps its own line and takes no aliases
|
|
121
178
|
const filed =
|
|
122
179
|
known || isMemoryPath(said)
|
|
123
|
-
? { path:
|
|
180
|
+
? { path: target, description, aliases, facts }
|
|
124
181
|
: {
|
|
125
182
|
path: MEMORY_INBOX,
|
|
126
|
-
description:
|
|
183
|
+
description: appNoteLine(MEMORY_INBOX),
|
|
127
184
|
facts,
|
|
128
185
|
};
|
|
129
186
|
|
|
130
|
-
const write = await writeNotes([filed]);
|
|
187
|
+
const write = await writeNotes([filed], source, callId);
|
|
131
188
|
|
|
132
189
|
// The write already succeeded; what follows are requests, not failures.
|
|
133
190
|
// A path filed elsewhere must be said, or the model reports it saved where it asked.
|
|
@@ -139,17 +196,71 @@ export const createMemoryTools = () => ({
|
|
|
139
196
|
const unnamed = write.unnamed.length
|
|
140
197
|
? ` ${write.unnamed[0]} is new and has no line yet — the listing shows its first fact instead. Call again with \`description\` (one line about what it is) and \`aliases\` (the names they say for it).`
|
|
141
198
|
: "";
|
|
142
|
-
// Carried lines are full: saved as an ordinary fact, and the user picks what to drop (
|
|
199
|
+
// Carried lines are full: saved as an ordinary fact, and the user picks what to drop (config MEMORY_LIMITS.carried)
|
|
143
200
|
const notLoaded = write.notLoaded.length
|
|
144
|
-
? ` All ${
|
|
201
|
+
? ` All ${MEMORY_LIMITS.carried} carried lines are taken, so ${write.notLoaded
|
|
145
202
|
.map((text) => `"${text}"`)
|
|
146
203
|
.join(
|
|
147
204
|
", ",
|
|
148
205
|
)} saved as an ordinary fact. Say which carried line you would drop for it and let them choose.`
|
|
149
206
|
: "";
|
|
207
|
+
const written = withCount(write.notes[0]);
|
|
208
|
+
return {
|
|
209
|
+
...written,
|
|
210
|
+
note: `${WROTE}${elsewhere}${unnamed}${notLoaded}${overSize(written.factCount)}`,
|
|
211
|
+
};
|
|
212
|
+
},
|
|
213
|
+
}),
|
|
214
|
+
|
|
215
|
+
[TOOL_NAMES.memory_conversation]: tool({
|
|
216
|
+
description:
|
|
217
|
+
"Open the conversation a fact was saved in, whole: what each side said, and which tools were used.",
|
|
218
|
+
inputSchema: z.object({
|
|
219
|
+
factId: z
|
|
220
|
+
.number()
|
|
221
|
+
.int()
|
|
222
|
+
.describe("The id that came with the fact when its note was opened."),
|
|
223
|
+
page: z
|
|
224
|
+
.number()
|
|
225
|
+
.int()
|
|
226
|
+
.min(1)
|
|
227
|
+
.nullish()
|
|
228
|
+
.describe(
|
|
229
|
+
`${MEMORY_CONVERSATION_PAGE} turns a page, oldest first. Null for the first.`,
|
|
230
|
+
),
|
|
231
|
+
}),
|
|
232
|
+
execute: async ({ factId, page }) => {
|
|
233
|
+
const fact = await findFactCall(factId);
|
|
234
|
+
if (!fact) return { note: `No fact with id ${factId}.` };
|
|
235
|
+
if (!fact.callId) return { note: noConversation(fact.source) };
|
|
236
|
+
// Already in the model's context: handing it back only spends it twice
|
|
237
|
+
if (fact.callId === callId) {
|
|
238
|
+
return {
|
|
239
|
+
note: "Said in this call — it is the conversation you are in.",
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
const at = page ?? 1;
|
|
244
|
+
const read = await readCallConversation(
|
|
245
|
+
fact.callId,
|
|
246
|
+
at,
|
|
247
|
+
MEMORY_CONVERSATION_PAGE,
|
|
248
|
+
);
|
|
249
|
+
if (!read) return { note: noConversation(fact.source) };
|
|
250
|
+
const pages = Math.max(
|
|
251
|
+
1,
|
|
252
|
+
Math.ceil(read.total / MEMORY_CONVERSATION_PAGE),
|
|
253
|
+
);
|
|
254
|
+
if (at > pages) {
|
|
255
|
+
return {
|
|
256
|
+
note: `That conversation has ${pages} page${pages > 1 ? "s" : ""}.`,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
150
259
|
return {
|
|
151
|
-
|
|
152
|
-
|
|
260
|
+
when: callStamp(read.startedAt),
|
|
261
|
+
page: at,
|
|
262
|
+
pages,
|
|
263
|
+
conversation: conversationLines(read.turns),
|
|
153
264
|
};
|
|
154
265
|
},
|
|
155
266
|
}),
|
|
@@ -210,46 +321,3 @@ what to drop and you drop it.`,
|
|
|
210
321
|
},
|
|
211
322
|
}),
|
|
212
323
|
});
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* The bot's write. Same act under the same name, without what only the call can
|
|
216
|
-
* do: no `replaces`, no carried lines, no naming a note — a bot has neither the
|
|
217
|
-
* user in front of it nor the listing's history. Rare by nature; what the job
|
|
218
|
-
* turned up belongs in the report, and only what outlives the job comes here.
|
|
219
|
-
*/
|
|
220
|
-
export const botRememberTool = tool({
|
|
221
|
-
description:
|
|
222
|
-
"Save a lasting fact about the user. Only for what outlives this job; what the job itself turned up goes in the report.",
|
|
223
|
-
inputSchema: z.object({
|
|
224
|
-
path: z
|
|
225
|
-
.string()
|
|
226
|
-
.describe(
|
|
227
|
-
"Exactly as the listing writes it, or a new path following the same convention.",
|
|
228
|
-
),
|
|
229
|
-
facts: z
|
|
230
|
-
.string()
|
|
231
|
-
.array()
|
|
232
|
-
.describe("One statement each, standing on its own later."),
|
|
233
|
-
}),
|
|
234
|
-
execute: async ({ path, facts }) => {
|
|
235
|
-
const said = path.trim();
|
|
236
|
-
const written = facts.map((text) => text.trim()).filter(Boolean);
|
|
237
|
-
if (!written.length) return { note: "Nothing to write: send a fact." };
|
|
238
|
-
|
|
239
|
-
const known = await resolveNotePath(said);
|
|
240
|
-
// A path outside the convention goes to inbox, as it does for the call
|
|
241
|
-
const filed = known || isMemoryPath(said) ? (known ?? said) : MEMORY_INBOX;
|
|
242
|
-
|
|
243
|
-
await writeNotes([
|
|
244
|
-
{ path: filed, facts: written.map((text) => ({ text })) },
|
|
245
|
-
]);
|
|
246
|
-
|
|
247
|
-
// A write filed elsewhere must be said, or the report claims the wrong place
|
|
248
|
-
return {
|
|
249
|
-
note:
|
|
250
|
-
filed === said
|
|
251
|
-
? `Saved to ${filed}.`
|
|
252
|
-
: `Saved to ${filed}: "${said}" is not a path this listing can carry.`,
|
|
253
|
-
};
|
|
254
|
-
},
|
|
255
|
-
});
|