thursday-agent 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +3 -2
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.json +8 -1
- package/.next/routes-manifest.json +18 -6
- 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 +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- 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 +13 -13
- package/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
- 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 +10 -6
- package/.next/server/app/api/artifact/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/files/route.js +6 -5
- package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/route.js +8 -8
- package/.next/server/app/api/bot/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/route.js +8 -8
- package/.next/server/app/api/bot/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/thread/[id]/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/bot/thread/[id]/route.js +15 -0
- package/.next/server/app/api/bot/thread/[id]/route.js.nft.json +1 -0
- package/.next/server/app/api/bot/thread/[id]/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/bot/thread/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/bot/thread/route.js +15 -0
- package/.next/server/app/api/bot/thread/route.js.nft.json +1 -0
- package/.next/server/app/api/bot/thread/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/config/route.js +7 -7
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/events/route.js +3 -3
- package/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/server/app/api/file/[...path]/route.js +5 -5
- package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/catalog/route.js +8 -8
- package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/credits/route.js +8 -8
- package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/route.js +8 -8
- package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/subscription/route.js +8 -8
- package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/[name]/route.js +6 -6
- package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth/callback/route.js +4 -4
- package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js +6 -6
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/tools/route.js +6 -6
- package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/edit/route.js +13 -13
- package/.next/server/app/api/memory/edit/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/route.js +7 -6
- package/.next/server/app/api/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[source]/[name]/route.js +6 -6
- package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js +6 -6
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/call/route.js +10 -11
- package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/skills/route.js +10 -11
- package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/tool-call/route.js +15 -15
- package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/missing/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/workspace/missing/route/build-manifest.json +12 -0
- package/.next/server/app/api/workspace/missing/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/workspace/missing/route.js +12 -0
- package/.next/server/app/api/workspace/missing/route.js.map +5 -0
- package/.next/server/app/api/workspace/missing/route.js.nft.json +1 -0
- package/.next/server/app/api/workspace/missing/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/workspace/route.js +5 -4
- 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 +4 -3
- 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.nft.json +1 -1
- package/.next/server/app/page/server-reference-manifest.json +67 -45
- package/.next/server/app/page.js +10 -9
- 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 +3 -2
- package/.next/server/chunks/[root-of-the-server]__02846fb._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__049f521._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__05luceg._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__06--3q3._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__07bnah_._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__08eae20._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0_ue8oe._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0c9fgca._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__0g-ueei._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0h_x6q6._.js +5 -0
- package/.next/server/chunks/{[root-of-the-server]__0pa2n68._.js → [root-of-the-server]__0kxrvxf._.js} +2 -2
- package/.next/server/chunks/{[root-of-the-server]__0q0vvt2._.js → [root-of-the-server]__0ov3iir._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__0qwtlmx._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0sm5xvm._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0ye3da2._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0zp35ul._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__144u9d_._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__18-2tsq._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1e-ci13._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1e2365e._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__1fix932._.js +8 -0
- package/.next/server/chunks/{[root-of-the-server]__0ce8nf8._.js → [root-of-the-server]__1g3t7vn._.js} +3 -3
- package/.next/server/chunks/[root-of-the-server]__1kp-83u._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1kv8p3e._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +2 -3
- package/.next/server/chunks/_02szwk8._.js +5 -0
- package/.next/server/chunks/_05h2cii._.js +1 -1
- package/.next/server/chunks/_06c9kie._.js +216 -0
- package/.next/server/chunks/{_1x6kd1r._.js → _07y2gj-._.js} +1 -1
- package/.next/server/chunks/_0a43a-0._.js +3 -0
- package/.next/server/chunks/_0bujjey._.js +5 -0
- package/.next/server/chunks/_0c9j6rb._.js +1 -1
- package/.next/server/chunks/_0dkd549._.js +3 -0
- package/.next/server/chunks/_0ej1kvv._.js +3 -0
- package/.next/server/chunks/_0f6ts7z._.js +3 -0
- package/.next/server/chunks/_0gm9hyv._.js +55 -0
- package/.next/server/chunks/_0i55en5._.js +25 -0
- package/.next/server/chunks/_0k50n27._.js +18 -0
- package/.next/server/chunks/_0khihjk._.js +3 -3
- package/.next/server/chunks/_0n74zsf._.js +5 -5
- package/.next/server/chunks/_0nvm9ef._.js +3 -0
- package/.next/server/chunks/_0p56fn0._.js +3 -0
- package/.next/server/chunks/_0recufk._.js +1 -1
- package/.next/server/chunks/_0xbkz10._.js +3 -0
- package/.next/server/chunks/_10tkr26._.js +3 -0
- package/.next/server/chunks/{_0ioz3nd._.js → _11u2kp7._.js} +1 -1
- package/.next/server/chunks/_11ujpya._.js +3 -0
- package/.next/server/chunks/_127nx_p._.js +5 -0
- package/.next/server/chunks/_17l5ygt._.js +1 -1
- package/.next/server/chunks/_19uauj6._.js +3 -0
- package/.next/server/chunks/_1_5mnq4._.js +5 -5
- package/.next/server/chunks/_1abl6t9._.js +55 -0
- package/.next/server/chunks/_1d0j961._.js +3 -3
- package/.next/server/chunks/_1dbixxz._.js +3 -0
- package/.next/server/chunks/_1dc_d1q._.js +98 -0
- package/.next/server/chunks/_1drgfx4._.js +5 -5
- package/.next/server/chunks/_1e48czp._.js +3 -3
- package/.next/server/chunks/_1f31u5x._.js +5 -0
- package/.next/server/chunks/_1kg70wc._.js +3 -3
- package/.next/server/chunks/_1klbcft._.js +5 -0
- package/.next/server/chunks/_1krd9rf._.js +4 -1
- package/.next/server/chunks/_1kwmzab._.js +3 -0
- package/.next/server/chunks/{_1pf4qe-._.js → _1oxj9fa._.js} +1 -1
- package/.next/server/chunks/{_1f46eie._.js → _1pcmdbb._.js} +1 -1
- package/.next/server/chunks/_1qgix-j._.js +3 -0
- package/.next/server/chunks/{lib_logger_ts_1exwjut._.js → _1rpchta._.js} +5 -5
- package/.next/server/chunks/_1vsej-s._.js +5 -0
- package/.next/server/chunks/_1yx0p_s._.js +5 -0
- package/.next/server/chunks/{_0rnf-6n._.js → _20fsr_z._.js} +6 -6
- package/.next/server/chunks/_2128hkj._.js +5 -0
- package/.next/server/chunks/_next-internal_server_app_api_bot_thread_[id]_route_actions_1fstjn2.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_bot_thread_route_actions_003ccso.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_workspace_missing_route_actions_1fidi6p.js +3 -0
- package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
- package/.next/server/chunks/features_0-cnt0l._.js +4 -0
- package/.next/server/chunks/features_0hdaci0._.js +4 -0
- package/.next/server/chunks/features_1e39j7-._.js +8 -0
- package/.next/server/chunks/features_bot_bot_query_ts_12mgkl2._.js +1 -1
- package/.next/server/chunks/features_memory_1uqvksn._.js +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0r28-sm._.js → node_modules_consola_dist_chunks_prompt_mjs_0a7-pbw._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0v_7drq._.js → node_modules_consola_dist_chunks_prompt_mjs_0gzvgfv._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0i7cvml._.js → node_modules_consola_dist_chunks_prompt_mjs_107pxfn._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0icqaqw._.js → node_modules_consola_dist_chunks_prompt_mjs_15hbel8._.js} +1 -1
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_18i-23e._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1bewgf3._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1kipdeo._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1nlww1m._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1q77nfx._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1xqdzx_._.js +3 -0
- package/.next/server/chunks/{node_modules_zod_v4_1801ax7._.js → node_modules_zod_v4_0lkux5-._.js} +2 -2
- package/.next/server/chunks/{node_modules_zod_v4_1cha_bw._.js → node_modules_zod_v4_1jmr9cq._.js} +2 -2
- package/.next/server/chunks/{node_modules_zod_v4_0ubdflj._.js → node_modules_zod_v4_1yrxmek._.js} +2 -2
- package/.next/server/chunks/node_modules_zod_v4_classic_errors_0tp0y-q.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]__0bxsfyn._.js +101 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0lyi8i2._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__16jc196._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__172cq4x._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__18dthbp._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__18e68w8._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1fll8dc._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1nygfik._.js +5 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1sdphb0._.js +8 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1waa3rc._.js +100 -0
- package/.next/server/chunks/ssr/_00rehl_._.js +3 -0
- package/.next/server/chunks/ssr/{_1lz_cq2._.js → _02oc_h5._.js} +76 -89
- package/.next/server/chunks/ssr/_03_928f._.js +3 -0
- package/.next/server/chunks/ssr/_05yghx6._.js +3 -0
- package/.next/server/chunks/ssr/_08c4z-9._.js +3 -0
- package/.next/server/chunks/ssr/_0_qfdlw._.js +4 -0
- package/.next/server/chunks/ssr/_0c9e5w6._.js +9 -0
- package/.next/server/chunks/ssr/{_0s99bgb._.js → _0dh2e1j._.js} +9 -3
- package/.next/server/chunks/ssr/_0dr-ddg._.js +3 -0
- package/.next/server/chunks/ssr/_0eaog6_._.js +3 -0
- package/.next/server/chunks/ssr/_0evkpto._.js +3 -0
- package/.next/server/chunks/ssr/_0g_rlog._.js +3 -0
- package/.next/server/chunks/ssr/_0geg212._.js +3 -0
- package/.next/server/chunks/ssr/{_1gd8q8l._.js → _0hxt2ul._.js} +2 -2
- package/.next/server/chunks/ssr/_0i_6q1w._.js +2 -2
- package/.next/server/chunks/ssr/_0lu1n_x._.js +1 -1
- package/.next/server/chunks/ssr/{_15j2_8f._.js → _0wzaht-._.js} +2 -2
- package/.next/server/chunks/ssr/_0z-g0uy._.js +3 -0
- package/.next/server/chunks/ssr/_123ttsf._.js +3 -0
- package/.next/server/chunks/ssr/_123y-ah._.js +3 -0
- package/.next/server/chunks/ssr/_12w42gi._.js +3 -0
- package/.next/server/chunks/ssr/_161kqav._.js +3 -0
- package/.next/server/chunks/ssr/{_0ap2fzn._.js → _16c6_xm._.js} +2 -2
- package/.next/server/chunks/ssr/_18opah7._.js +3 -0
- package/.next/server/chunks/ssr/_18xqmny._.js +3 -0
- package/.next/server/chunks/ssr/_1_krfph._.js +3 -0
- package/.next/server/chunks/ssr/{_1-_etts._.js → _1anqots._.js} +2 -2
- package/.next/server/chunks/ssr/_1ey7qn-._.js +70 -0
- package/.next/server/chunks/ssr/_1g9vs7q._.js +3 -0
- package/.next/server/chunks/ssr/_1jmz33w._.js +3 -0
- package/.next/server/chunks/ssr/{_0n3toaw._.js → _1k0spz7._.js} +2 -2
- package/.next/server/chunks/ssr/_1rgtxhr._.js +5 -0
- package/.next/server/chunks/ssr/_1slp25y._.js +3 -0
- package/.next/server/chunks/ssr/{_1fojd41._.js → _1x9pskj._.js} +3 -3
- package/.next/server/chunks/ssr/_1y6b5mr._.js +101 -0
- package/.next/server/chunks/ssr/_1ztk7p6._.js +7 -0
- package/.next/server/chunks/ssr/components_ui_tabs_tsx_0ej40b4._.js +3 -0
- package/.next/server/chunks/ssr/features_bot_thread_query_ts_023eklt._.js +4 -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/{_1-teee5._.js → lib_logger_ts_0-olsze._.js} +2 -7
- package/.next/server/chunks/ssr/{node_modules_0cxaxk9._.js → node_modules_00_51_v._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_04jf_m8._.js → node_modules_022sipm._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0g7fzk3._.js → node_modules_0332gw4._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1cx_ql6._.js → node_modules_04vxchl._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1vh5ntv._.js → node_modules_0746rzi._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0yugy6m._.js → node_modules_0d5uzof._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_09q35v_._.js → node_modules_0exkwcm._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_08dhkiq._.js → node_modules_0fr-ml8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_14q6g4n._.js → node_modules_0mxvg8h._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0arus10._.js → node_modules_0qapgjr._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1eg7m6c._.js → node_modules_0qbfyjh._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1cz2hle._.js → node_modules_0t-9nup._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_17bwo43._.js → node_modules_0tusx4d._.js} +3 -3
- package/.next/server/chunks/ssr/{node_modules_1efrqxi._.js → node_modules_0vsxbzp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0_-_a--._.js → node_modules_0vv0-fg._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1gdh31p._.js → node_modules_0wsvp00._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1hpopmo._.js → node_modules_1-urho9._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1_pc9kq._.js → node_modules_16pi_dd._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_00etblx._.js → node_modules_1d53yiq._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1aaxuef._.js → node_modules_1g1eihe._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_198nmll._.js → node_modules_1gpednh._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0pvd7q-._.js → node_modules_1gu1pph._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0b__sgl._.js → node_modules_1he1w8_._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1qpjvy5._.js → node_modules_1lnjapm._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0940ns5._.js → node_modules_1lynj9m._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0x3-ply._.js → node_modules_1seuurl._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_14om4ar._.js → node_modules_1u6w1pb._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0had7xd._.js → node_modules_1xn6saw._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1b748ic._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_067_exa._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1z4hm5e._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0nrrdaq._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@vercel_oidc_dist_06mk8id._.js → node_modules_@vercel_oidc_dist_21a5haa._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_trash_mjs_0px2gzr._.js +3 -0
- 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 +68 -46
- package/.next/static/chunks/0dr16v67vj4n7.js +2 -0
- package/.next/static/chunks/0g4b348l0pve7.js +1 -0
- package/.next/static/chunks/0joan-69kbspd.js +1 -0
- package/.next/static/chunks/0vlgzqo9ka90v.js +1 -0
- package/.next/static/chunks/0zrupxgci5gqc.js +1 -0
- package/.next/static/chunks/10k2xvap03z20.css +1 -0
- package/.next/static/chunks/18mkhstgiqcbt.js +1 -0
- package/.next/static/chunks/{15m575979un5f.js → 1i-u2wzub_to1.js} +2 -2
- package/.next/static/chunks/1kp5nfp06nj9h.js +5 -0
- package/.next/static/chunks/1ohslk4568tm3.js +1 -0
- package/.next/static/chunks/1sbmwswc9k2-1.js +1 -0
- package/.next/static/chunks/1t9qms5pwwa3n.js +1 -0
- package/.next/static/chunks/1vj_5bnbxx84e.js +1 -0
- package/.next/static/chunks/1vqezbhjm3goq.js +1 -0
- package/.next/static/chunks/{3akmqm77muj4-.js → 1wlo979mx-y3w.js} +1 -1
- package/.next/static/chunks/26ql4y-43xwhp.js +1 -0
- package/.next/static/chunks/{0fl3gwe4-l6tz.js → 2_pnccjp6j1ca.js} +1 -1
- package/.next/static/chunks/2a51-ywz9b2a3.js +1 -0
- package/.next/static/chunks/2fvdgxih7x7hr.js +1 -0
- package/.next/static/chunks/2jlz8zp4jax_m.js +18 -0
- package/.next/static/chunks/2nvepds1fu2ux.js +1 -0
- package/.next/static/chunks/3addj3i4-izma.js +1 -0
- package/.next/static/chunks/3bfwpww3m3x4u.js +1 -0
- package/.next/static/chunks/3gfh7nxwusbt0.js +1 -0
- package/.next/static/chunks/3gwa44cvz4qoi.js +1 -0
- package/.next/static/chunks/{38gweqdo4jpfj.js → 3izg0a3k87q1-.js} +5 -5
- package/.next/static/chunks/3zk6q3-3f9swq.js +99 -0
- package/.next/static/chunks/3zkg5iup3v4a2.js +12 -0
- package/.next/static/chunks/405m0bqtoihev.js +1 -0
- package/.next/static/chunks/42wcg3wfg_m_p.js +1 -0
- package/README.md +27 -216
- package/app/api/events/app-event.ts +6 -4
- package/app/api/query-key.ts +25 -16
- package/bin/database.mjs +37 -0
- package/bin/thursday.mjs +44 -28
- package/components/ui/custom-icon.tsx +0 -60
- package/components/ui/radio-group.tsx +37 -0
- package/components/ui/shiny-text.tsx +33 -6
- package/database/migrations/{20260910173049_numerous_spirit → 20260916145701_clever_multiple_man}/migration.sql +80 -24
- package/database/migrations/{20260910173049_numerous_spirit → 20260916145701_clever_multiple_man}/snapshot.json +689 -110
- package/database/migrations/20260916160713_thread_cancelled/migration.sql +2 -0
- package/database/migrations/{20260911030320_opposite_jack_power → 20260916160713_thread_cancelled}/snapshot.json +706 -84
- package/docs/how-it-works.md +39 -36
- package/docs/images/keeps-going.png +0 -0
- package/docs/images/two-minds.png +0 -0
- package/docs/live-calls.md +231 -0
- package/docs/thread-rooms.md +71 -0
- package/features/ai/chatgpt.ts +1 -2
- package/features/ai/live.schema.ts +128 -0
- package/features/ai/load-tools.ts +148 -77
- package/features/ai/model.schema.ts +2 -120
- package/features/ai/model.ts +52 -88
- package/features/ai/prompts/bot.prompt.ts +91 -214
- package/features/ai/prompts/live.prompt.ts +265 -0
- package/features/ai/prompts/prompt-helper.ts +91 -32
- package/features/ai/prompts/thursday.prompt.ts +125 -172
- package/features/ai/tools/bot.tool.ts +38 -145
- package/features/ai/tools/call.tool.ts +1 -1
- package/features/ai/tools/connected.ts +5 -3
- package/features/ai/tools/mcp.tool.ts +7 -4
- package/features/ai/tools/memory.tool.ts +35 -31
- package/features/ai/tools/skills.tool.ts +36 -14
- package/features/ai/tools/studio.tool.ts +26 -21
- package/features/ai/tools/tool-name.ts +2 -5
- package/features/ai/tools/workspace.tool.ts +33 -10
- package/features/artifact/artifact.action.ts +2 -2
- package/features/artifact/artifact.query.ts +112 -61
- package/features/artifact/artifact.schema.ts +8 -6
- package/features/artifact/components/artifact-setting.tsx +83 -33
- package/features/bot/bot.action.ts +43 -36
- package/features/bot/bot.memory.ts +137 -20
- package/features/bot/bot.query.ts +28 -11
- package/features/bot/bot.run.ts +299 -636
- package/features/bot/bot.runner.ts +468 -844
- package/features/bot/bot.schema.ts +93 -82
- package/features/bot/bot.seed.ts +141 -64
- package/features/bot/components/bot-mark.tsx +324 -232
- package/features/bot/components/bot-room.tsx +1613 -697
- package/features/bot/components/bot-roster.tsx +8 -13
- package/features/bot/components/bot-setting.tsx +58 -42
- package/features/bot/components/bot-tool.tsx +55 -87
- package/features/bot/components/mark-palette.tsx +35 -32
- package/features/bot/components/path-chips.tsx +33 -3
- package/features/bot/components/thread-badge.tsx +34 -0
- package/features/bot/components/thread-reply.tsx +639 -0
- package/features/bot/components/thread-setting.tsx +674 -0
- package/features/bot/mark.const.ts +79 -31
- package/features/bot/room.query.ts +889 -0
- package/features/bot/room.schema.ts +64 -0
- package/features/bot/seed-bots.ts +2 -1
- package/features/bot/thread.query.ts +971 -0
- package/features/bot/thread.store.ts +587 -0
- package/features/config/components/voice-key.tsx +113 -88
- package/features/config/config.const.ts +5 -9
- package/features/connectors/mcp.schema.ts +0 -2
- package/features/intro/components/intro.tsx +169 -139
- package/features/memory/components/memory-setting.tsx +2 -7
- package/features/memory/memory.schema.ts +14 -23
- package/features/settings/components/setting-ui.tsx +0 -44
- package/features/settings/components/settings.tsx +12 -12
- package/features/settings/settings.alert.ts +3 -3
- package/features/settings/settings.store.ts +1 -1
- package/features/skills/skills.schema.ts +0 -2
- package/features/thursday/components/ascii-field.tsx +24 -44
- package/features/thursday/components/ascii-orb.tsx +359 -358
- package/features/thursday/components/call-log.tsx +46 -44
- package/features/thursday/components/face.tsx +35 -10
- package/features/thursday/components/tab-state.tsx +3 -3
- package/features/thursday/components/thursday-mark.tsx +1 -0
- package/features/thursday/components/thursday-setting.tsx +631 -332
- package/features/thursday/components/thursday.tsx +106 -41
- package/features/thursday/components/voice-picker.tsx +255 -0
- package/features/thursday/thursday.action.ts +94 -68
- package/features/thursday/thursday.query.ts +49 -30
- package/features/thursday/thursday.schema.ts +27 -30
- package/features/thursday/thursday.store.ts +11 -7
- package/features/thursday/tool-call.ts +3 -3
- package/features/thursday/tool-line.ts +5 -3
- package/features/thursday/use-thursday.ts +725 -450
- package/features/workspace/workspace.query.ts +17 -0
- package/features/workspace/workspace.ts +103 -50
- package/lib/live/live.schema.ts +47 -0
- package/lib/live/live.server.ts +155 -0
- package/lib/live/live.session.ts +574 -0
- package/lib/{realtime/realtime.tap.ts → live/live.tap.ts} +41 -12
- package/lib/live/live.transport.ts +152 -0
- package/lib/protocol/use-server-pages.ts +9 -5
- package/lib/utils.ts +21 -20
- package/package.json +2 -2
- package/public/voices/alloy.ogg +0 -0
- package/public/voices/ash.ogg +0 -0
- package/public/voices/ballad.ogg +0 -0
- package/public/voices/beacon.ogg +0 -0
- package/public/voices/bossa.ogg +0 -0
- package/public/voices/cedar.ogg +0 -0
- package/public/voices/cinder.ogg +0 -0
- package/public/voices/coral.ogg +0 -0
- package/public/voices/delta.ogg +0 -0
- package/public/voices/echo.ogg +0 -0
- package/public/voices/gleam.ogg +0 -0
- package/public/voices/marin.ogg +0 -0
- package/public/voices/meridian.ogg +0 -0
- package/public/voices/quartz.ogg +0 -0
- package/public/voices/ripple.ogg +0 -0
- package/public/voices/sage.ogg +0 -0
- package/public/voices/shimmer.ogg +0 -0
- package/public/voices/stone.ogg +0 -0
- package/public/voices/tempo.ogg +0 -0
- package/public/voices/verse.ogg +0 -0
- package/public/voices/vesper.ogg +0 -0
- package/public/voices/willow.ogg +0 -0
- package/scripts/artifact-paths.test.mts +25 -0
- package/scripts/bot-context.test.mts +1408 -0
- package/scripts/live-history.test.mts +115 -0
- package/scripts/live-session.test.mts +948 -0
- package/server.js +1 -1
- package/skills/browser/SKILL.md +17 -6
- package/skills/computer/SKILL.md +1 -1
- package/skills/find-skills/SKILL.md +3 -8
- package/skills/interactive-page/SKILL.md +12 -7
- package/skills/interactive-page/references/diagram.md +89 -0
- package/skills/interactive-page/scripts/archify/LICENSE +22 -0
- package/skills/interactive-page/scripts/archify/README.md +25 -0
- package/skills/interactive-page/scripts/archify/assets/JetBrainsMono-OFL.txt +93 -0
- package/skills/interactive-page/scripts/archify/assets/template.html +14934 -0
- package/skills/interactive-page/scripts/archify/bin/archify.mjs +2126 -0
- package/skills/interactive-page/scripts/archify/bin/open-artifact.mjs +86 -0
- package/skills/interactive-page/scripts/archify/bin/preview.mjs +653 -0
- package/skills/interactive-page/scripts/archify/bin/visual-check.mjs +829 -0
- package/skills/interactive-page/scripts/archify/delta/architecture-delta.mjs +1223 -0
- package/skills/interactive-page/scripts/archify/examples/agent-run.lifecycle.json +60 -0
- package/skills/interactive-page/scripts/archify/examples/agent-tool-call.workflow.json +94 -0
- package/skills/interactive-page/scripts/archify/examples/async-job-roundtrip.sequence.json +61 -0
- package/skills/interactive-page/scripts/archify/examples/cache-miss-request.sequence.json +82 -0
- package/skills/interactive-page/scripts/archify/examples/checkout-platform.base.architecture.json +31 -0
- package/skills/interactive-page/scripts/archify/examples/checkout-platform.head.architecture.json +31 -0
- package/skills/interactive-page/scripts/archify/examples/deployment-release.lifecycle.json +49 -0
- package/skills/interactive-page/scripts/archify/examples/event-stream.dataflow.json +57 -0
- package/skills/interactive-page/scripts/archify/examples/incident-response.workflow.json +64 -0
- package/skills/interactive-page/scripts/archify/examples/product-analytics.dataflow.json +76 -0
- package/skills/interactive-page/scripts/archify/examples/production-deployment.architecture.json +71 -0
- package/skills/interactive-page/scripts/archify/examples/release-delivery.workflow.json +62 -0
- package/skills/interactive-page/scripts/archify/examples/web-app.architecture.json +46 -0
- package/skills/interactive-page/scripts/archify/migrations/workflow-v2.mjs +279 -0
- package/skills/interactive-page/scripts/archify/recipes/scenarios.mjs +284 -0
- package/skills/interactive-page/scripts/archify/references/authoring-contract.md +243 -0
- package/skills/interactive-page/scripts/archify/references/delivery-contract.md +120 -0
- package/skills/interactive-page/scripts/archify/references/viewer-runtime.md +45 -0
- package/skills/interactive-page/scripts/archify/renderers/architecture/grid.mjs +62 -0
- package/skills/interactive-page/scripts/archify/renderers/architecture/render-architecture.mjs +1078 -0
- package/skills/interactive-page/scripts/archify/renderers/dataflow/README.md +104 -0
- package/skills/interactive-page/scripts/archify/renderers/dataflow/render-dataflow.mjs +483 -0
- package/skills/interactive-page/scripts/archify/renderers/lifecycle/README.md +115 -0
- package/skills/interactive-page/scripts/archify/renderers/lifecycle/render-lifecycle.mjs +561 -0
- package/skills/interactive-page/scripts/archify/renderers/sequence/README.md +114 -0
- package/skills/interactive-page/scripts/archify/renderers/sequence/render-sequence.mjs +464 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/brand-marks.mjs +563 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/cli.mjs +218 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/desktop-readability.mjs +26 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/diagnostics.mjs +127 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/engineering-profiles.mjs +157 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/generated-brand-marks.mjs +3 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/generated-validators.mjs +13 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/geometry.mjs +1423 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/i18n.mjs +595 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/layout-report.mjs +40 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/legend.mjs +217 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/output-path.mjs +340 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/repository-evidence.mjs +238 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/repository-location.mjs +58 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/text-fit.mjs +49 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/utils.mjs +232 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/validator.mjs +86 -0
- package/skills/interactive-page/scripts/archify/renderers/workflow/README.md +223 -0
- package/skills/interactive-page/scripts/archify/renderers/workflow/render-workflow.mjs +35 -0
- package/skills/interactive-page/scripts/archify/renderers/workflow/workflow-compiler.mjs +4400 -0
- package/skills/interactive-page/scripts/archify/renderers/workflow/workflow-migration-geometry.mjs +144 -0
- package/skills/interactive-page/scripts/archify/schemas/README.md +211 -0
- package/skills/interactive-page/scripts/archify/schemas/architecture.schema.json +178 -0
- package/skills/interactive-page/scripts/archify/schemas/common.schema.json +115 -0
- package/skills/interactive-page/scripts/archify/schemas/dataflow.schema.json +243 -0
- package/skills/interactive-page/scripts/archify/schemas/lifecycle.schema.json +266 -0
- package/skills/interactive-page/scripts/archify/schemas/sequence.schema.json +223 -0
- package/skills/interactive-page/scripts/archify/schemas/workflow.schema.json +428 -0
- package/skills/interactive-page/scripts/archify/scripts/check-render-output.mjs +916 -0
- package/skills/interactive-page/scripts/archify/scripts/render-examples.mjs +26 -0
- package/skills/interactive-page/scripts/bundle-artifact.sh +9 -8
- package/skills/skill-creator/SKILL.md +4 -5
- package/.next/server/app/api/bot/task/[id]/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/bot/task/[id]/route.js +0 -16
- package/.next/server/app/api/bot/task/[id]/route.js.nft.json +0 -1
- package/.next/server/app/api/bot/task/[id]/route_client-reference-manifest.js +0 -3
- package/.next/server/app/api/bot/task/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/bot/task/route.js +0 -16
- package/.next/server/app/api/bot/task/route.js.nft.json +0 -1
- package/.next/server/app/api/bot/task/route_client-reference-manifest.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__01dkp4a._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__02xjoto._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__04q--0f._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0bl-e63._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0ffbg85._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0jq4ohy._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0ls6_8y._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0ncs9uu._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1-ga0kh._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__11n256_._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__12cabg9._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1339jnv._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__18_teo8._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1anc1p9._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1ccon1w._.js +0 -10
- package/.next/server/chunks/[root-of-the-server]__1fizn31._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1llj3-b._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1p8m3f4._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1wa1k7r._.js +0 -8
- package/.next/server/chunks/_0-73of8._.js +0 -55
- package/.next/server/chunks/_0-fjql4._.js +0 -26
- package/.next/server/chunks/_00xh_q0._.js +0 -25
- package/.next/server/chunks/_03a0897._.js +0 -3
- package/.next/server/chunks/_051qh8u._.js +0 -3
- package/.next/server/chunks/_05sovvj._.js +0 -3
- package/.next/server/chunks/_0fzqt2y._.js +0 -134
- package/.next/server/chunks/_0mecv0f._.js +0 -26
- package/.next/server/chunks/_0mh8j4m._.js +0 -3
- package/.next/server/chunks/_0obojvv._.js +0 -3
- package/.next/server/chunks/_0sb7tlz._.js +0 -3
- package/.next/server/chunks/_0sbynis._.js +0 -3
- package/.next/server/chunks/_0u10wmw._.js +0 -55
- package/.next/server/chunks/_0u4aiy2._.js +0 -3
- package/.next/server/chunks/_0wp4le3._.js +0 -3
- package/.next/server/chunks/_0y5fg-x._.js +0 -3
- package/.next/server/chunks/_1230wbx._.js +0 -10
- package/.next/server/chunks/_12nheja._.js +0 -3
- package/.next/server/chunks/_13510xh._.js +0 -3
- package/.next/server/chunks/_15hq89o._.js +0 -3
- package/.next/server/chunks/_18-1wcc._.js +0 -55
- package/.next/server/chunks/_1_9mjx-._.js +0 -3
- package/.next/server/chunks/_1c78vw5._.js +0 -229
- package/.next/server/chunks/_1h5_8sk._.js +0 -3
- package/.next/server/chunks/_1hdnxb7._.js +0 -3
- package/.next/server/chunks/_1j8k_j5._.js +0 -3
- package/.next/server/chunks/_1nula3v._.js +0 -3
- package/.next/server/chunks/_1php4eq._.js +0 -3
- package/.next/server/chunks/_1yuv4vp._.js +0 -3
- package/.next/server/chunks/_1zjrdag._.js +0 -3
- package/.next/server/chunks/_next-internal_server_app_api_bot_task_[id]_route_actions_1_k_8u3.js +0 -3
- package/.next/server/chunks/_next-internal_server_app_api_bot_task_route_actions_0xln6ra.js +0 -3
- package/.next/server/chunks/features_0rpfxbk._.js +0 -3
- package/.next/server/chunks/features_1qf3cei._.js +0 -3
- package/.next/server/chunks/features_bot_0zt92oh._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1xoq2rl._.js +0 -3
- package/.next/server/chunks/ssr/[externals]__0dizgek._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__092knlj._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0mz33a7._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0s9dq5u._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0s9l2sv._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0vnmv-s._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0xsog8n._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +0 -61
- package/.next/server/chunks/ssr/[root-of-the-server]__1gtlw6v._.js +0 -43
- package/.next/server/chunks/ssr/[root-of-the-server]__1ox7hbk._.js +0 -4
- package/.next/server/chunks/ssr/[root-of-the-server]__202p40z._.js +0 -3
- package/.next/server/chunks/ssr/_001_ms1._.js +0 -28
- package/.next/server/chunks/ssr/_01n3o0m._.js +0 -3
- package/.next/server/chunks/ssr/_0fz4mf_._.js +0 -3
- package/.next/server/chunks/ssr/_0gb4gmf._.js +0 -3
- package/.next/server/chunks/ssr/_0h42fze._.js +0 -3
- package/.next/server/chunks/ssr/_0h7zdni._.js +0 -3
- package/.next/server/chunks/ssr/_0ilna52._.js +0 -42
- package/.next/server/chunks/ssr/_0q0zan6._.js +0 -70
- package/.next/server/chunks/ssr/_0zcjrbg._.js +0 -3
- package/.next/server/chunks/ssr/_0zhoc3r._.js +0 -3
- package/.next/server/chunks/ssr/_13fke0x._.js +0 -3
- package/.next/server/chunks/ssr/_18cymkq._.js +0 -3
- package/.next/server/chunks/ssr/_1b2mjwr._.js +0 -3
- package/.next/server/chunks/ssr/_1f-dg-6._.js +0 -3
- package/.next/server/chunks/ssr/_1h0rw11._.js +0 -3
- package/.next/server/chunks/ssr/_1jhd09t._.js +0 -3
- package/.next/server/chunks/ssr/_1nnsk7z._.js +0 -3
- package/.next/server/chunks/ssr/_1ov37if._.js +0 -3
- package/.next/server/chunks/ssr/_1sji22n._.js +0 -3
- package/.next/server/chunks/ssr/_1vi_uo7._.js +0 -3
- package/.next/server/chunks/ssr/_1vyd1ji._.js +0 -3
- package/.next/server/chunks/ssr/_1xx4zlb._.js +0 -3
- package/.next/server/chunks/ssr/components_ui_1y1l7yj._.js +0 -3
- package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +0 -3
- package/.next/server/chunks/ssr/lib_realtime_12wg_dd._.js +0 -27
- package/.next/server/chunks/ssr/lib_realtime_15h_v1v._.js +0 -27
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0npjf8-._.js +0 -3
- package/.next/static/chunks/00rd4-v8r7axp.js +0 -1
- package/.next/static/chunks/08qe4as2q428z.js +0 -3
- package/.next/static/chunks/0gnqdjn2lvdad.js +0 -2
- package/.next/static/chunks/0hwap1-p0m5sa.js +0 -1
- package/.next/static/chunks/0r5qcctujhxli.js +0 -1
- package/.next/static/chunks/0w52rrrmuj9r9.js +0 -1
- package/.next/static/chunks/0wcprt5ot5she.js +0 -1
- package/.next/static/chunks/10teww7wt-f6h.js +0 -1
- package/.next/static/chunks/17p6tk6k88dq6.js +0 -1
- package/.next/static/chunks/18a96rkhi4_yd.js +0 -1
- package/.next/static/chunks/1dkjg87pxk0n9.js +0 -28
- package/.next/static/chunks/1jd09sxcjddu1.js +0 -1
- package/.next/static/chunks/1w73ece_6bheu.js +0 -18
- package/.next/static/chunks/214ya3n5gxeih.js +0 -1
- package/.next/static/chunks/22_zkas21rpna.js +0 -1
- package/.next/static/chunks/2fh4-3z_q8b_w.js +0 -1
- package/.next/static/chunks/2h0sd2vumhb15.js +0 -1
- package/.next/static/chunks/2t4vhi3m8ahya.js +0 -1
- package/.next/static/chunks/2tigdtz3dpcy8.js +0 -1
- package/.next/static/chunks/2u7xt6mxg44lf.js +0 -1
- package/.next/static/chunks/3786h5vayt80-.js +0 -28
- package/.next/static/chunks/39j0fvpybzabl.js +0 -40
- package/.next/static/chunks/3cq5g494yuke8.css +0 -1
- package/.next/static/chunks/3hibbjnt85-k6.js +0 -1
- package/.next/static/chunks/3woj-xd7ki5_i.js +0 -1
- package/.next/static/chunks/3xk7yqgomx7yq.js +0 -1
- package/.next/static/chunks/3zmcsnuo25zvq.js +0 -1
- package/database/migrations/20260911030320_opposite_jack_power/migration.sql +0 -1
- package/docs/images/task-thread.png +0 -0
- package/features/bot/components/task-badge.tsx +0 -42
- package/features/bot/components/task-reply.tsx +0 -328
- package/features/bot/components/task-setting.tsx +0 -524
- package/features/bot/task.query.ts +0 -976
- package/features/bot/task.store.ts +0 -489
- package/lib/realtime/client-secret.ts +0 -86
- package/lib/realtime/open-session.ts +0 -31
- package/lib/realtime/openai.ts +0 -35
- package/lib/realtime/realtime.audio.ts +0 -196
- package/lib/realtime/realtime.driver.ts +0 -489
- package/lib/realtime/realtime.protocol.ts +0 -393
- package/lib/realtime/realtime.schema.ts +0 -37
- package/lib/realtime/realtime.session.ts +0 -106
- package/lib/realtime/realtime.transport.ts +0 -384
- package/lib/realtime/xai.ts +0 -39
- /package/.next/server/app/api/bot/{task → thread}/[id]/route/build-manifest.json +0 -0
- /package/.next/server/app/api/bot/{task → thread}/[id]/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/bot/{task → thread}/[id]/route.js.map +0 -0
- /package/.next/server/app/api/bot/{task → thread}/route/build-manifest.json +0 -0
- /package/.next/server/app/api/bot/{task → thread}/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/bot/{task → thread}/route.js.map +0 -0
- /package/.next/static/{kaTO0UHqF1bMnWgCDik2f → 0qzGoKn2wTERVZtblX1tp}/_buildManifest.js +0 -0
- /package/.next/static/{kaTO0UHqF1bMnWgCDik2f → 0qzGoKn2wTERVZtblX1tp}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{kaTO0UHqF1bMnWgCDik2f → 0qzGoKn2wTERVZtblX1tp}/_ssgManifest.js +0 -0
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
Trash2,
|
|
16
16
|
Video,
|
|
17
17
|
} from "lucide-react";
|
|
18
|
-
import { useState } from "react";
|
|
18
|
+
import { Fragment, useState } from "react";
|
|
19
19
|
import { queryKey } from "@/app/api/query-key";
|
|
20
20
|
import { Button } from "@/components/ui/button";
|
|
21
21
|
import { notify } from "@/components/ui/notify";
|
|
@@ -28,6 +28,8 @@ import type {
|
|
|
28
28
|
ArtifactSet,
|
|
29
29
|
ArtifactShelf,
|
|
30
30
|
} from "@/features/artifact/artifact.schema";
|
|
31
|
+
import type { Bot } from "@/features/bot/bot.schema";
|
|
32
|
+
import { BotMark } from "@/features/bot/components/bot-mark";
|
|
31
33
|
import {
|
|
32
34
|
SettingError,
|
|
33
35
|
SettingFilter,
|
|
@@ -44,14 +46,14 @@ import { revalidate, useServerRoute } from "@/lib/protocol/use-server-route";
|
|
|
44
46
|
import { cn, formatBytes } from "@/lib/utils";
|
|
45
47
|
|
|
46
48
|
/*
|
|
47
|
-
* What the bots finished, listed the way they
|
|
48
|
-
*
|
|
49
|
-
* a job that makes a set writes
|
|
49
|
+
* What the bots finished, listed the way they file it: each bot writes into
|
|
50
|
+
* `artifacts/<bot>/`, and one entry there is one artifact. A skill writes
|
|
51
|
+
* `<name>.html`, a job that makes a set writes `<name>/`.
|
|
50
52
|
*
|
|
51
53
|
* So this is not Workspace pointed at one folder. There is no tree here: the
|
|
52
|
-
* menu is
|
|
53
|
-
* listing — it opens as a sheet of what it holds, which is the thing a
|
|
54
|
-
* pictures is for. Browsing a tree is Workspace's job.
|
|
54
|
+
* menu is newest-first under each bot's face, and a folder does not open into
|
|
55
|
+
* another listing — it opens as a sheet of what it holds, which is the thing a
|
|
56
|
+
* set of pictures is for. Browsing a tree is Workspace's job.
|
|
55
57
|
*/
|
|
56
58
|
|
|
57
59
|
/** Every kind `viewKindOf` returns, plus the set. One icon table, as in Workspace. */
|
|
@@ -80,6 +82,7 @@ export function ArtifactSetting() {
|
|
|
80
82
|
{ keepPreviousData: true },
|
|
81
83
|
);
|
|
82
84
|
|
|
85
|
+
const { data: bots } = useServerRoute<Bot[]>(queryKey.bot);
|
|
83
86
|
const [reveal] = useServerAction(openFileAction);
|
|
84
87
|
|
|
85
88
|
if (isLoading) return <SettingPanesSkeleton />;
|
|
@@ -89,7 +92,11 @@ export function ArtifactSetting() {
|
|
|
89
92
|
const total = data?.total ?? 0;
|
|
90
93
|
const needle = filter.trim().toLowerCase();
|
|
91
94
|
const shown = needle
|
|
92
|
-
? entries.filter(
|
|
95
|
+
? entries.filter(
|
|
96
|
+
(entry) =>
|
|
97
|
+
entry.name.toLowerCase().includes(needle) ||
|
|
98
|
+
entry.bot?.toLowerCase().includes(needle),
|
|
99
|
+
)
|
|
93
100
|
: entries;
|
|
94
101
|
|
|
95
102
|
// A fresh row when the open one is still listed, so a rewrite shows through
|
|
@@ -130,13 +137,29 @@ export function ArtifactSetting() {
|
|
|
130
137
|
{needle ? "Nothing matches" : "Nothing here yet"}
|
|
131
138
|
</p>
|
|
132
139
|
) : (
|
|
133
|
-
shown.map((
|
|
134
|
-
<
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
+
groupByBot(shown).map(({ bot, rows }) => (
|
|
141
|
+
<Fragment key={bot ?? ""}>
|
|
142
|
+
<span className="flex items-center gap-1.5 px-3 pt-3 pb-1 font-mono text-[10px] text-muted-foreground/60">
|
|
143
|
+
{bot && (
|
|
144
|
+
<BotMark
|
|
145
|
+
size={12}
|
|
146
|
+
seed={bot}
|
|
147
|
+
{...markOf(bot, bots)}
|
|
148
|
+
notify={false}
|
|
149
|
+
className="shrink-0"
|
|
150
|
+
/>
|
|
151
|
+
)}
|
|
152
|
+
<span className="truncate">{bot ?? "Unsorted"}</span>
|
|
153
|
+
</span>
|
|
154
|
+
{rows.map((entry) => (
|
|
155
|
+
<MenuRow
|
|
156
|
+
key={entry.path}
|
|
157
|
+
entry={entry}
|
|
158
|
+
active={entry.path === picked?.path}
|
|
159
|
+
onPick={() => setReading({ row: entry, file: null })}
|
|
160
|
+
/>
|
|
161
|
+
))}
|
|
162
|
+
</Fragment>
|
|
140
163
|
))
|
|
141
164
|
)}
|
|
142
165
|
|
|
@@ -170,6 +193,33 @@ export function ArtifactSetting() {
|
|
|
170
193
|
);
|
|
171
194
|
}
|
|
172
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Rows under the bot that made them, in the order the rows came: newest first,
|
|
198
|
+
* so the bot that handed something over last is on top. Loose rows are one group.
|
|
199
|
+
*/
|
|
200
|
+
function groupByBot(
|
|
201
|
+
entries: Artifact[],
|
|
202
|
+
): { bot: string | null; rows: Artifact[] }[] {
|
|
203
|
+
const groups = new Map<string | null, Artifact[]>();
|
|
204
|
+
for (const entry of entries) {
|
|
205
|
+
const rows = groups.get(entry.bot) ?? [];
|
|
206
|
+
rows.push(entry);
|
|
207
|
+
groups.set(entry.bot, rows);
|
|
208
|
+
}
|
|
209
|
+
return [...groups].map(([bot, rows]) => ({ bot, rows }));
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** Icon from the bot list; the row only carries the name. A bot that is gone draws its seed alone. */
|
|
213
|
+
function markOf(name: string, bots?: Bot[]) {
|
|
214
|
+
const icon = bots?.find((bot) => bot.name === name)?.icon;
|
|
215
|
+
return {
|
|
216
|
+
color: icon?.color,
|
|
217
|
+
shape: icon?.shape,
|
|
218
|
+
outline: icon?.outline,
|
|
219
|
+
paint: icon?.paint,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
173
223
|
/** `4 artifacts · 34 files`, and what is not on screen. Counts rows, so it is free. */
|
|
174
224
|
function countLine(shown: Artifact[], total: number, files: number): string {
|
|
175
225
|
if (total === 0) return "empty";
|
|
@@ -247,7 +297,9 @@ function Reader({
|
|
|
247
297
|
const confirmRemove = async (path: string) => {
|
|
248
298
|
const confirmed = await notify.confirm({
|
|
249
299
|
title: `Delete ${path.split("/").pop()}?`,
|
|
250
|
-
description:
|
|
300
|
+
description: open
|
|
301
|
+
? "It is deleted from disk for good."
|
|
302
|
+
: "The folder and everything in it are deleted from disk for good.",
|
|
251
303
|
okText: "Delete",
|
|
252
304
|
destructive: true,
|
|
253
305
|
});
|
|
@@ -295,25 +347,23 @@ function Reader({
|
|
|
295
347
|
>
|
|
296
348
|
<FolderOpen />
|
|
297
349
|
</Button>
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
</Button>
|
|
309
|
-
)}
|
|
350
|
+
<Button
|
|
351
|
+
size="icon-sm"
|
|
352
|
+
variant="ghost"
|
|
353
|
+
aria-label="Delete"
|
|
354
|
+
loading={removing}
|
|
355
|
+
className="text-muted-foreground"
|
|
356
|
+
onClick={() => confirmRemove(open?.path ?? row.path)}
|
|
357
|
+
>
|
|
358
|
+
<Trash2 />
|
|
359
|
+
</Button>
|
|
310
360
|
</div>
|
|
311
361
|
|
|
312
362
|
<div className="min-h-0 flex-1 overflow-auto">
|
|
313
363
|
{open ? (
|
|
314
364
|
<FilePreview path={open.path} bytes={open.bytes} />
|
|
315
365
|
) : (
|
|
316
|
-
<SetSheet
|
|
366
|
+
<SetSheet path={row.path} onOpen={onOpen} />
|
|
317
367
|
)}
|
|
318
368
|
</div>
|
|
319
369
|
</>
|
|
@@ -325,14 +375,14 @@ function Reader({
|
|
|
325
375
|
* a set nobody opens costs one `readdir` for its count and nothing more.
|
|
326
376
|
*/
|
|
327
377
|
function SetSheet({
|
|
328
|
-
|
|
378
|
+
path,
|
|
329
379
|
onOpen,
|
|
330
380
|
}: {
|
|
331
|
-
|
|
381
|
+
path: string;
|
|
332
382
|
onOpen: (file: ArtifactFile) => void;
|
|
333
383
|
}) {
|
|
334
384
|
const { data, isLoading, error } = useServerRoute<ArtifactSet>(
|
|
335
|
-
queryKey.artifactSet(
|
|
385
|
+
queryKey.artifactSet(path, ARTIFACT_VIEW.setFiles),
|
|
336
386
|
);
|
|
337
387
|
|
|
338
388
|
if (isLoading) {
|
|
@@ -418,7 +468,7 @@ function Nothing({
|
|
|
418
468
|
<p className="max-w-lg text-sm leading-relaxed text-muted-foreground">
|
|
419
469
|
{empty
|
|
420
470
|
? "Nothing finished yet. When a bot ends a job with something to hand over — a page, a report, a set of pictures — it lands here."
|
|
421
|
-
: "Pick something on the left.
|
|
471
|
+
: "Pick something on the left. Each bot's work is under its face; a folder it filled is one row, and opens as a sheet."}
|
|
422
472
|
</p>
|
|
423
473
|
<Button variant="outline" onClick={onReveal}>
|
|
424
474
|
<FolderOpen />
|
|
@@ -7,20 +7,20 @@ import { publicError } from "@/lib/public-error";
|
|
|
7
7
|
import {
|
|
8
8
|
createBot,
|
|
9
9
|
deleteBot,
|
|
10
|
-
|
|
10
|
+
findJobBot,
|
|
11
11
|
updateBot,
|
|
12
12
|
writeBotMemoryOn,
|
|
13
13
|
} from "./bot.query";
|
|
14
14
|
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
answerThread,
|
|
16
|
+
cancelThread,
|
|
17
|
+
removeFinishedThreads,
|
|
18
|
+
removeThread,
|
|
19
|
+
startThread,
|
|
20
20
|
} from "./bot.runner";
|
|
21
21
|
import { BotFormSchema, botIconSchema } from "./bot.schema";
|
|
22
|
-
import { findBotSeed,
|
|
23
|
-
import { markSeen,
|
|
22
|
+
import { findBotSeed, rollSeedIcons } from "./bot.seed";
|
|
23
|
+
import { markSeen, resolveThread } from "./thread.query";
|
|
24
24
|
|
|
25
25
|
export const createBotAction = serverAction(async (input: unknown) => {
|
|
26
26
|
const form = BotFormSchema.parse(input);
|
|
@@ -41,8 +41,8 @@ const SeedPickSchema = z.object({
|
|
|
41
41
|
name: z.string().trim().min(1).max(80),
|
|
42
42
|
provider: textModelProviderSchema.nullish(),
|
|
43
43
|
model: z.string().trim().min(1).max(80).nullish(),
|
|
44
|
-
/** The
|
|
45
|
-
|
|
44
|
+
/** The face the intro already showed for this bot. Rolled here when the caller had no screen. */
|
|
45
|
+
icon: botIconSchema.optional(),
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
/**
|
|
@@ -53,9 +53,9 @@ const SeedPickSchema = z.object({
|
|
|
53
53
|
export const createSeedBotsAction = serverAction(async (picks: unknown) => {
|
|
54
54
|
const wanted = SeedPickSchema.array().max(20).parse(picks);
|
|
55
55
|
|
|
56
|
-
// Seeds carry no
|
|
57
|
-
//
|
|
58
|
-
const rolled =
|
|
56
|
+
// Seeds carry no face of their own (bot.seed); one roll covers the whole batch
|
|
57
|
+
// so bots made together never come out looking alike
|
|
58
|
+
const rolled = rollSeedIcons();
|
|
59
59
|
|
|
60
60
|
const created: string[] = [];
|
|
61
61
|
for (const [at, pick] of wanted.entries()) {
|
|
@@ -65,7 +65,7 @@ export const createSeedBotsAction = serverAction(async (picks: unknown) => {
|
|
|
65
65
|
name: seed.name,
|
|
66
66
|
description: seed.description,
|
|
67
67
|
systemPrompt: seed.systemPrompt,
|
|
68
|
-
icon:
|
|
68
|
+
icon: pick.icon ?? rolled[at % rolled.length],
|
|
69
69
|
provider: pick.provider,
|
|
70
70
|
model: pick.model,
|
|
71
71
|
toolIds: [],
|
|
@@ -84,9 +84,9 @@ export const setBotMemoryOnAction = serverAction(async (on: unknown) => {
|
|
|
84
84
|
await writeBotMemoryOn(on === true);
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
//
|
|
87
|
+
// Threads are opened by the `delegate` tool during a call, or here when the user
|
|
88
88
|
// hands one over from the screen. Each returns at once, the run itself continues
|
|
89
|
-
//
|
|
89
|
+
// as promises held by bot.runner.
|
|
90
90
|
|
|
91
91
|
/** Words a label keeps; the rest of the message is the request, which the bot reads in full. */
|
|
92
92
|
const LABEL_WORDS = 4;
|
|
@@ -103,14 +103,16 @@ function labelFor(request: string): string {
|
|
|
103
103
|
* is the whole request — there is no conversation to draw the rest from, which is
|
|
104
104
|
* why the box asks for a sentence rather than a word.
|
|
105
105
|
*/
|
|
106
|
-
export const
|
|
106
|
+
export const startThreadAction = serverAction(
|
|
107
107
|
async (bot: string, request: string) => {
|
|
108
108
|
const said = request.trim();
|
|
109
109
|
if (!said) publicError("Nothing to hand over.");
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
// Resolved as a delegated job is, so an install with no bots still has its worker
|
|
111
|
+
const worker = await findJobBot(bot);
|
|
112
|
+
if (!worker || worker.disabled)
|
|
113
|
+
publicError(`No enabled bot called "${bot}".`);
|
|
112
114
|
const label = labelFor(said);
|
|
113
|
-
const id = await
|
|
115
|
+
const id = await startThread({
|
|
114
116
|
bot: worker.name,
|
|
115
117
|
request: said,
|
|
116
118
|
label,
|
|
@@ -120,33 +122,38 @@ export const startTaskAction = serverAction(
|
|
|
120
122
|
},
|
|
121
123
|
);
|
|
122
124
|
|
|
123
|
-
export const
|
|
124
|
-
async (ref: string, answer: string) => {
|
|
125
|
-
const
|
|
126
|
-
if (!
|
|
125
|
+
export const answerThreadAction = serverAction(
|
|
126
|
+
async (ref: string, answer: string, recipient?: string, replyTo?: string) => {
|
|
127
|
+
const thread = await resolveThread(ref);
|
|
128
|
+
if (!thread) publicError(`No job called "${ref}".`);
|
|
127
129
|
if (!answer.trim()) publicError("Nothing to tell it.");
|
|
128
|
-
await
|
|
129
|
-
return { id:
|
|
130
|
+
await answerThread(thread.id, answer.trim(), "user", recipient, replyTo);
|
|
131
|
+
return { id: thread.id, label: thread.label, status: "running" as const };
|
|
130
132
|
},
|
|
131
133
|
);
|
|
132
134
|
|
|
133
|
-
export const
|
|
134
|
-
const
|
|
135
|
-
if (!
|
|
136
|
-
await
|
|
137
|
-
return { id:
|
|
135
|
+
export const cancelThreadAction = serverAction(async (ref: string) => {
|
|
136
|
+
const thread = await resolveThread(ref);
|
|
137
|
+
if (!thread) publicError(`No job called "${ref}".`);
|
|
138
|
+
await cancelThread(thread.id);
|
|
139
|
+
return { id: thread.id, label: thread.label, status: "cancelled" as const };
|
|
138
140
|
});
|
|
139
141
|
|
|
140
|
-
/** Marks
|
|
142
|
+
/** Marks threads as read by the user: opened on screen. Their relays are settled with them (thread.query markSeen). */
|
|
141
143
|
export const markSeenAction = serverAction(async (ids: string[]) => {
|
|
142
144
|
await markSeen(ids.filter((id) => typeof id === "string" && id));
|
|
143
145
|
});
|
|
144
146
|
|
|
145
|
-
export const
|
|
146
|
-
if (!(await
|
|
147
|
+
export const deleteThreadAction = serverAction(async (id: string) => {
|
|
148
|
+
if (!(await removeThread(id))) publicError("Thread not found");
|
|
147
149
|
});
|
|
148
150
|
|
|
149
151
|
/** Empties the log of what is over. Running and waiting jobs are not touched. */
|
|
150
|
-
export const
|
|
151
|
-
return { removed: await
|
|
152
|
+
export const clearFinishedThreadsAction = serverAction(async () => {
|
|
153
|
+
return { removed: await removeFinishedThreads() };
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
export const acceptThreadRelaysAction = serverAction(async (ids: unknown) => {
|
|
157
|
+
const { acceptRoomRelays } = await import("./room.query");
|
|
158
|
+
await acceptRoomRelays(z.number().int().positive().array().parse(ids));
|
|
152
159
|
});
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Stats } from "node:fs";
|
|
2
|
+
import {
|
|
3
|
+
open,
|
|
4
|
+
readdir,
|
|
5
|
+
readFile,
|
|
6
|
+
rm,
|
|
7
|
+
stat,
|
|
8
|
+
utimes,
|
|
9
|
+
writeFile,
|
|
10
|
+
} from "node:fs/promises";
|
|
2
11
|
import { join } from "node:path";
|
|
3
|
-
import {
|
|
12
|
+
import { BOT_MEMORY_LIMITS } from "@/config";
|
|
4
13
|
import { botFolder, WORKSPACE } from "@/features/workspace/workspace";
|
|
5
14
|
import type { BotMemory, BotMemoryFile } from "./bot.schema";
|
|
6
15
|
|
|
@@ -19,42 +28,150 @@ const HEAD_BYTES = 1024;
|
|
|
19
28
|
|
|
20
29
|
/**
|
|
21
30
|
* Newest first. `limit` is how many are read for their first line: the prompt lists
|
|
22
|
-
*
|
|
31
|
+
* BOT_MEMORY_LIMITS.files, the bot's page (Settings > Bots) as many as a Workspace folder shows.
|
|
23
32
|
*/
|
|
24
33
|
export async function listBotMemory(
|
|
25
34
|
bot: string,
|
|
26
|
-
limit =
|
|
35
|
+
limit = BOT_MEMORY_LIMITS.files,
|
|
27
36
|
): Promise<BotMemory> {
|
|
28
37
|
const folder = botMemoryFolder(bot);
|
|
29
38
|
const dir = join(WORKSPACE, folder);
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
names
|
|
33
|
-
.filter((name) => !name.startsWith("."))
|
|
34
|
-
.map(async (name) => {
|
|
35
|
-
const info = await stat(join(dir, name)).catch(() => null);
|
|
36
|
-
return info?.isFile()
|
|
37
|
-
? { name, changed: info.mtimeMs, bytes: info.size }
|
|
38
|
-
: null;
|
|
39
|
-
}),
|
|
39
|
+
const files = (await readMemoryFolder(dir)).sort(
|
|
40
|
+
(a, b) => b.info.mtimeMs - a.info.mtimeMs,
|
|
40
41
|
);
|
|
41
|
-
const files = found
|
|
42
|
-
.filter((file) => file !== null)
|
|
43
|
-
.sort((a, b) => b.changed - a.changed);
|
|
44
42
|
const entries = await Promise.all(
|
|
45
43
|
files.slice(0, limit).map(
|
|
46
|
-
async ({ name,
|
|
44
|
+
async ({ name, info }): Promise<BotMemoryFile> => ({
|
|
47
45
|
file: name,
|
|
48
46
|
path: `${folder}/${name}`,
|
|
49
47
|
line: await firstLine(join(dir, name)),
|
|
50
|
-
at: new Date(
|
|
51
|
-
bytes,
|
|
48
|
+
at: new Date(info.mtimeMs),
|
|
49
|
+
bytes: info.size,
|
|
52
50
|
}),
|
|
53
51
|
),
|
|
54
52
|
);
|
|
55
53
|
return { folder, entries, total: files.length };
|
|
56
54
|
}
|
|
57
55
|
|
|
56
|
+
/** What counts as a memory file, for the listing and the limits alike: a plain file, not hidden. */
|
|
57
|
+
async function readMemoryFolder(
|
|
58
|
+
dir: string,
|
|
59
|
+
): Promise<{ name: string; info: Stats }[]> {
|
|
60
|
+
const names = await readdir(dir).catch(() => []);
|
|
61
|
+
const found = await Promise.all(
|
|
62
|
+
names
|
|
63
|
+
.filter((name) => !name.startsWith("."))
|
|
64
|
+
.map(async (name) => {
|
|
65
|
+
const info = await stat(join(dir, name)).catch(() => null);
|
|
66
|
+
return info?.isFile() ? { name, info } : null;
|
|
67
|
+
}),
|
|
68
|
+
);
|
|
69
|
+
return found.filter((file) => file !== null);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* A bot's memory as it stood before a command, so what the command takes past
|
|
74
|
+
* BOT_MEMORY_LIMITS can be put back. A file already past the limit is held without its
|
|
75
|
+
* text: there is nothing within the limit to put back.
|
|
76
|
+
*/
|
|
77
|
+
export type HeldBotMemory = Map<
|
|
78
|
+
string,
|
|
79
|
+
{
|
|
80
|
+
text: string | null;
|
|
81
|
+
size: number;
|
|
82
|
+
mtimeMs: number;
|
|
83
|
+
atime: Date;
|
|
84
|
+
mtime: Date;
|
|
85
|
+
}
|
|
86
|
+
>;
|
|
87
|
+
|
|
88
|
+
export async function holdBotMemory(bot: string): Promise<HeldBotMemory> {
|
|
89
|
+
const dir = join(WORKSPACE, botMemoryFolder(bot));
|
|
90
|
+
const held: HeldBotMemory = new Map();
|
|
91
|
+
await Promise.all(
|
|
92
|
+
(await readMemoryFolder(dir)).map(async ({ name, info }) => {
|
|
93
|
+
// More than four bytes a character is past the limit without reading it
|
|
94
|
+
const text =
|
|
95
|
+
info.size > BOT_MEMORY_LIMITS.chars * 4
|
|
96
|
+
? null
|
|
97
|
+
: await readFile(join(dir, name), "utf8").catch(() => null);
|
|
98
|
+
held.set(name, {
|
|
99
|
+
text:
|
|
100
|
+
text !== null && charCount(text) <= BOT_MEMORY_LIMITS.chars
|
|
101
|
+
? text
|
|
102
|
+
: null,
|
|
103
|
+
size: info.size,
|
|
104
|
+
mtimeMs: info.mtimeMs,
|
|
105
|
+
atime: info.atime,
|
|
106
|
+
mtime: info.mtime,
|
|
107
|
+
});
|
|
108
|
+
}),
|
|
109
|
+
);
|
|
110
|
+
return held;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Puts back what was done to a bot's memory past BOT_MEMORY_LIMITS since `held`, and says
|
|
115
|
+
* so in lines the bot can act on; null when nothing went past. A file written past `chars`
|
|
116
|
+
* goes back to what it was, or is removed when it is new; new files that take the folder
|
|
117
|
+
* past `files` are removed. A file that was already past the limit stays and is named.
|
|
118
|
+
*/
|
|
119
|
+
export async function keepBotMemory(
|
|
120
|
+
bot: string,
|
|
121
|
+
held: HeldBotMemory,
|
|
122
|
+
): Promise<string | null> {
|
|
123
|
+
const folder = botMemoryFolder(bot);
|
|
124
|
+
const dir = join(WORKSPACE, folder);
|
|
125
|
+
const { files: most, chars } = BOT_MEMORY_LIMITS;
|
|
126
|
+
const lines: string[] = [];
|
|
127
|
+
const fresh: string[] = [];
|
|
128
|
+
let count = 0;
|
|
129
|
+
|
|
130
|
+
for (const { name, info } of await readMemoryFolder(dir)) {
|
|
131
|
+
count += 1;
|
|
132
|
+
const was = held.get(name);
|
|
133
|
+
if (was && was.size === info.size && was.mtimeMs === info.mtimeMs) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const path = join(dir, name);
|
|
137
|
+
const length = charCount(await readFile(path, "utf8").catch(() => ""));
|
|
138
|
+
if (length <= chars) {
|
|
139
|
+
if (!was) fresh.push(name);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const size = `${length.toLocaleString("en-US")} characters, past the ${chars.toLocaleString("en-US")} a memory file holds`;
|
|
143
|
+
if (!was) {
|
|
144
|
+
await rm(path, { force: true });
|
|
145
|
+
count -= 1;
|
|
146
|
+
lines.push(
|
|
147
|
+
`Not kept: \`${folder}/${name}\` came to ${size}, so it was removed. Write it again shorter.`,
|
|
148
|
+
);
|
|
149
|
+
} else if (was.text !== null) {
|
|
150
|
+
await writeFile(path, was.text);
|
|
151
|
+
await utimes(path, was.atime, was.mtime);
|
|
152
|
+
lines.push(
|
|
153
|
+
`Not kept: \`${folder}/${name}\` came to ${size}, so it is back as it was. Write it again shorter.`,
|
|
154
|
+
);
|
|
155
|
+
} else {
|
|
156
|
+
lines.push(`\`${folder}/${name}\` is ${size}. Shorten it.`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (count > most && fresh.length) {
|
|
161
|
+
await Promise.all(
|
|
162
|
+
fresh.map((name) => rm(join(dir, name), { force: true })),
|
|
163
|
+
);
|
|
164
|
+
const named = fresh.map((name) => `\`${folder}/${name}\``).join(", ");
|
|
165
|
+
lines.push(
|
|
166
|
+
`Not kept: your memory holds ${most} files at most and this made ${count}, so ${named} ${fresh.length === 1 ? "was" : "were"} removed. Delete or merge files no longer worth keeping, then write it again.`,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
return lines.length ? lines.join("\n") : null;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** A file's length as BOT_MEMORY_LIMITS counts it. */
|
|
173
|
+
const charCount = (text: string): number => [...text.trim()].length;
|
|
174
|
+
|
|
58
175
|
/**
|
|
59
176
|
* The line a file is listed by: its first, without a heading's `#`. A file that opens with
|
|
60
177
|
* frontmatter anyway — a shape models are trained on — is listed by its `description`, or by
|
|
@@ -4,10 +4,11 @@ import {
|
|
|
4
4
|
botMcpToolTable,
|
|
5
5
|
botTable,
|
|
6
6
|
mcpToolTable,
|
|
7
|
-
|
|
7
|
+
threadTable,
|
|
8
8
|
} from "@/database/tables";
|
|
9
9
|
import type { TextModelProviderId } from "@/features/ai/model.schema";
|
|
10
10
|
import { readConfig, writeConfig } from "@/features/config/config.query";
|
|
11
|
+
import { botFolderName } from "@/features/workspace/workspace";
|
|
11
12
|
import {
|
|
12
13
|
BOT_MEMORY_KEY,
|
|
13
14
|
type BotForm,
|
|
@@ -98,17 +99,17 @@ export async function findAllBots() {
|
|
|
98
99
|
})
|
|
99
100
|
.from(botMcpToolTable)
|
|
100
101
|
.innerJoin(mcpToolTable, eq(botMcpToolTable.toolId, mcpToolTable.id)),
|
|
101
|
-
// Grouped by name;
|
|
102
|
+
// Grouped by name; threads point at bots by name (tables.ts thread.bot)
|
|
102
103
|
database
|
|
103
104
|
.select({
|
|
104
|
-
bot:
|
|
105
|
-
input: sql<number>`coalesce(sum(${
|
|
106
|
-
output: sql<number>`coalesce(sum(${
|
|
105
|
+
bot: threadTable.bot,
|
|
106
|
+
input: sql<number>`coalesce(sum(${threadTable.inputTokens}), 0)`,
|
|
107
|
+
output: sql<number>`coalesce(sum(${threadTable.outputTokens}), 0)`,
|
|
107
108
|
// Raw max over a timestamp column arrives as integer seconds
|
|
108
|
-
lastJobAt: sql<number | null>`max(${
|
|
109
|
+
lastJobAt: sql<number | null>`max(${threadTable.updatedAt})`,
|
|
109
110
|
})
|
|
110
|
-
.from(
|
|
111
|
-
.groupBy(
|
|
111
|
+
.from(threadTable)
|
|
112
|
+
.groupBy(threadTable.bot),
|
|
112
113
|
]);
|
|
113
114
|
|
|
114
115
|
const byBot = new Map<string, PinnedTool[]>();
|
|
@@ -155,9 +156,25 @@ export async function findBot(name: string) {
|
|
|
155
156
|
return bot ?? null;
|
|
156
157
|
}
|
|
157
158
|
|
|
158
|
-
/**
|
|
159
|
+
/**
|
|
160
|
+
* Every name that has folders in the workspace: the rows, switched off or not,
|
|
161
|
+
* and DEFAULT_BOT, which works without one.
|
|
162
|
+
*/
|
|
163
|
+
export async function listBotNames(): Promise<string[]> {
|
|
164
|
+
const rows = await database.select({ name: botTable.name }).from(botTable);
|
|
165
|
+
return [...new Set([...rows.map((row) => row.name), DEFAULT_BOT.name])];
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Returns null when the name is taken: two bots with one name would be a coin
|
|
170
|
+
* toss at delegate time, and two whose names give one folder would share their
|
|
171
|
+
* memory and artifacts (workspace.ts botFolderName).
|
|
172
|
+
*/
|
|
159
173
|
export async function createBot(form: BotForm) {
|
|
160
|
-
|
|
174
|
+
const folder = botFolderName(form.name).toLowerCase();
|
|
175
|
+
const rows = await database.select({ name: botTable.name }).from(botTable);
|
|
176
|
+
if (rows.some((row) => botFolderName(row.name).toLowerCase() === folder))
|
|
177
|
+
return null;
|
|
161
178
|
|
|
162
179
|
const { toolIds, ...values } = pickedModel(form);
|
|
163
180
|
const [bot] = await database.insert(botTable).values(values).returning();
|
|
@@ -170,7 +187,7 @@ export async function updateBot(name: string, patch: Partial<BotForm>) {
|
|
|
170
187
|
// (pickedModel reads a missing field as null and would clear the other)
|
|
171
188
|
const { toolIds, ...values } =
|
|
172
189
|
"provider" in patch || "model" in patch ? pickedModel(patch) : patch;
|
|
173
|
-
// Renaming would orphan pinned tools and every
|
|
190
|
+
// Renaming would orphan pinned tools and every thread sent to the old name, so name is never patched
|
|
174
191
|
delete (values as { name?: string }).name;
|
|
175
192
|
|
|
176
193
|
const [bot] = Object.keys(values).length
|