thursday-agent 0.15.0 → 0.16.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/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +4 -4
- 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 +11 -11
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/artifact/route.js +8 -8
- package/.next/server/app/api/artifact/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/route.js +3 -3
- package/.next/server/app/api/bot/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/route.js +3 -3
- package/.next/server/app/api/bot/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/thread/[id]/route.js +7 -7
- package/.next/server/app/api/bot/thread/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/thread/route.js +6 -6
- package/.next/server/app/api/bot/thread/route.js.nft.json +1 -1
- package/.next/server/app/api/config/route.js +5 -5
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/events/route.js +1 -1
- package/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/server/app/api/favicon/[host]/route.js +1 -1
- package/.next/server/app/api/favicon/[host]/route.js.nft.json +1 -1
- package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/catalog/route.js +7 -7
- package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/credits/route.js +7 -7
- package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/route.js +4 -4
- package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/subscription/route.js +4 -4
- package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth/callback/route.js +2 -2
- package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/edit/route.js +14 -15
- package/.next/server/app/api/memory/edit/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/reach/route.js +18 -19
- package/.next/server/app/api/reach/route.js.nft.json +1 -1
- package/.next/server/app/api/routine/route.js +3 -3
- package/.next/server/app/api/routine/route.js.nft.json +1 -1
- package/.next/server/app/api/signins/route.js +1 -1
- package/.next/server/app/api/signins/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[source]/[name]/route.js +8 -5
- package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js +8 -5
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/call/route.js +7 -7
- package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/settings/route.js +7 -7
- package/.next/server/app/api/thursday/settings/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/text/route.js +15 -16
- package/.next/server/app/api/thursday/text/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/tool-call/route.js +12 -13
- package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/files/route.js +7 -7
- package/.next/server/app/api/workspace/files/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/route.js +7 -7
- package/.next/server/app/api/workspace/route.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +3 -3
- package/.next/server/app/artifact/[...path]/page.js +4 -4
- 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/manifest.webmanifest/route.js.nft.json +1 -1
- package/.next/server/app/page/server-reference-manifest.json +60 -60
- package/.next/server/app/page.js +9 -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/chunks/[root-of-the-server]__00qyw01._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__03b09q0._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__03vunn6._.js +1 -1
- package/.next/server/chunks/{[root-of-the-server]__0adz-25._.js → [root-of-the-server]__05dp5tr._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__05n-hql._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__06nspyt._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0aijj66._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0g38-aj._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__0h656y-._.js +11 -0
- package/.next/server/chunks/{[root-of-the-server]__0g67-oo._.js → [root-of-the-server]__0j_nz36._.js} +1 -1
- package/.next/server/chunks/[root-of-the-server]__0ljizgj._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mrk2it._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0sm5xvm._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0tsded0._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__0tvoct-._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1-tdj60._.js +3 -0
- package/.next/server/chunks/{[root-of-the-server]__0132c27._.js → [root-of-the-server]__10_7vqz._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__10xnb7e._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__118qjk_._.js +3 -3
- package/.next/server/chunks/[root-of-the-server]__11g20j-._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__13hng6h._.js +1 -1
- package/.next/server/chunks/{[root-of-the-server]__0o-w4t4._.js → [root-of-the-server]__16yw3mb._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__18e65_-._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__18k8s-z._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1b8tp42._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1c2kwku._.js +12 -0
- package/.next/server/chunks/[root-of-the-server]__1ceammd._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1ep-pao._.js +7 -0
- package/.next/server/chunks/[root-of-the-server]__1gamvcz._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1gzcbda._.js +1 -1
- package/.next/server/chunks/{[root-of-the-server]__20tvhdf._.js → [root-of-the-server]__1mbd2w_._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__1ndi14y._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1p47fbb._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1qcn1ti._.js +3 -3
- package/.next/server/chunks/[root-of-the-server]__1t0jj1j._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1v7x5ym._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1vlxv19._.js +1 -1
- package/.next/server/chunks/{[root-of-the-server]__0ei2xnb._.js → [root-of-the-server]__1voqqyc._.js} +1 -1
- package/.next/server/chunks/[root-of-the-server]__1ygplx1._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1zn039k._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1zrwxis._.js +3 -0
- package/.next/server/chunks/_01t8da9._.js +1 -1
- package/.next/server/chunks/_02fn1o3._.js +3 -0
- package/.next/server/chunks/_05sa7xl._.js +1 -1
- package/.next/server/chunks/_06u9yo-._.js +1 -1
- package/.next/server/chunks/_07nxi75._.js +250 -0
- package/.next/server/chunks/_08354bn._.js +107 -0
- package/.next/server/chunks/_0caua_s._.js +1 -1
- package/.next/server/chunks/_0j0-gq6._.js +5 -0
- package/.next/server/chunks/_0nn99o2._.js +1 -1
- package/.next/server/chunks/_0p-h6xe._.js +5 -0
- package/.next/server/chunks/_0p6v1fr._.js +5 -0
- package/.next/server/chunks/_0qoush_._.js +3 -0
- package/.next/server/chunks/_0srlnvd._.js +1 -1
- package/.next/server/chunks/_0t_7gji._.js +1 -1
- package/.next/server/chunks/_0uir6hb._.js +9 -9
- package/.next/server/chunks/_0uzj57i._.js +1 -1
- package/.next/server/chunks/_0xm040x._.js +1 -1
- package/.next/server/chunks/_0xx3ryc._.js +2 -2
- package/.next/server/chunks/_0xygcxs._.js +250 -0
- package/.next/server/chunks/{_0ol42w-._.js → _1-sk_q4._.js} +2 -2
- package/.next/server/chunks/_146mcip._.js +1 -1
- package/.next/server/chunks/_19kea1l._.js +8 -8
- package/.next/server/chunks/_1d5zmy8._.js +1 -1
- package/.next/server/chunks/_1dxq827._.js +5 -0
- package/.next/server/chunks/{_0ejoy4d._.js → _1e54wxa._.js} +2 -2
- package/.next/server/chunks/_1gn2r2q._.js +12 -12
- package/.next/server/chunks/_1gxankq._.js +2 -2
- package/.next/server/chunks/_1hyvcgk._.js +5 -0
- package/.next/server/chunks/_1m88lkh._.js +9 -9
- package/.next/server/chunks/_1mfu9a3._.js +5 -0
- package/.next/server/chunks/_1mx9sfo._.js +1 -1
- package/.next/server/chunks/_1ozcb6o._.js +27 -0
- package/.next/server/chunks/_1q6e56i._.js +12 -12
- package/.next/server/chunks/_1qgix-j._.js +1 -1
- package/.next/server/chunks/_1w6uf9k._.js +3 -0
- package/.next/server/chunks/_1wl2g8_._.js +2 -2
- package/.next/server/chunks/_1wwl_7o._.js +1 -1
- package/.next/server/chunks/_1xcnogc._.js +6 -0
- package/.next/server/chunks/_1zfxb7j._.js +1 -1
- package/.next/server/chunks/_20oecmn._.js +6 -0
- package/.next/server/chunks/_211dn2c._.js +1 -1
- package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
- package/.next/server/chunks/features_0wm-ujw._.js +6 -0
- package/.next/server/chunks/features_workspace_workspace_ts_13h82gv._.js +4 -4
- package/.next/server/chunks/features_workspace_workspace_ts_1iyjroj._.js +3 -3
- package/.next/server/chunks/{node_modules_1osf6vs._.js → node_modules_0dctjy-._.js} +1 -1
- package/.next/server/chunks/{node_modules_1821h5r._.js → node_modules_0mquap1._.js} +1 -1
- package/.next/server/chunks/{node_modules_1bfhxob._.js → node_modules_1er1u8w._.js} +1 -1
- package/.next/server/chunks/{node_modules_1i11kg5._.js → node_modules_1rosz79._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_035jiu9._.js → node_modules_consola_dist_chunks_prompt_mjs_0_nz09c._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0736s17._.js → node_modules_consola_dist_chunks_prompt_mjs_0rx6rvb._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_07szfwb._.js → node_modules_consola_dist_chunks_prompt_mjs_128pb4i._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0rzuf5j._.js → node_modules_consola_dist_chunks_prompt_mjs_1x3bsmx._.js} +1 -1
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_20s275p._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__0670az2._.js → [root-of-the-server]__02jdtqa._.js} +3 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__0rnjkw2._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__10eb-1x._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__17h1ggo._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1867koj._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1d7usu0._.js +2 -2
- package/.next/server/chunks/ssr/{[root-of-the-server]__00ro8qe._.js → [root-of-the-server]__1jyeu61._.js} +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__1y5_1cv._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1y8_-v1._.js +3 -0
- package/.next/server/chunks/ssr/{_1zdizo8._.js → _0-ou1b0._.js} +2 -2
- package/.next/server/chunks/ssr/{_02u485c._.js → _0afrpci._.js} +2 -2
- package/.next/server/chunks/ssr/_0cd6g3l._.js +5 -5
- package/.next/server/chunks/ssr/{_0trt3zp._.js → _0fo4552._.js} +17 -19
- package/.next/server/chunks/ssr/{_168tvri._.js → _0l1-xc6._.js} +2 -2
- package/.next/server/chunks/ssr/{_1rxpx-u._.js → _0ncuqct._.js} +2 -2
- package/.next/server/chunks/ssr/_0qsmpcu._.js +1 -1
- package/.next/server/chunks/ssr/{_0c1h0l9._.js → _0r0g9ki._.js} +3 -3
- package/.next/server/chunks/ssr/_0rvbegp._.js +7 -0
- package/.next/server/chunks/ssr/{_1_n8qpv._.js → _0w8r7o7._.js} +2 -2
- package/.next/server/chunks/ssr/{_074hv3s._.js → _0wupyvd._.js} +2 -2
- package/.next/server/chunks/ssr/_0x8ophf._.js +1 -1
- package/.next/server/chunks/ssr/{_0z0scn4._.js → _0y28gl3._.js} +3 -3
- package/.next/server/chunks/ssr/{node_modules_0vi73_6._.js → _10-_awu._.js} +2 -2
- package/.next/server/chunks/ssr/{_06m66w8._.js → _10fwcz_._.js} +2 -2
- package/.next/server/chunks/ssr/{_0ze-0vs._.js → _11pnnvd._.js} +4 -4
- package/.next/server/chunks/ssr/_17ble8k._.js +162 -0
- package/.next/server/chunks/ssr/_17qtuv7._.js +3 -0
- package/.next/server/chunks/ssr/{_1xq-4on._.js → _1dqaksc._.js} +2 -2
- package/.next/server/chunks/ssr/{_20lwjif._.js → _1f6s34p._.js} +2 -2
- package/.next/server/chunks/ssr/_1g48r6t._.js +3 -0
- package/.next/server/chunks/ssr/_1k0efi3._.js +3 -0
- package/.next/server/chunks/ssr/_1neoj22._.js +1 -1
- package/.next/server/chunks/ssr/_1u5vsy-._.js +3 -0
- package/.next/server/chunks/ssr/_1uij_rj._.js +3 -0
- package/.next/server/chunks/ssr/{_1r0tx3q._.js → _1umbr78._.js} +3 -3
- package/.next/server/chunks/ssr/_1w9w1ok._.js +3 -0
- package/.next/server/chunks/ssr/_1z586yw._.js +3 -0
- package/.next/server/chunks/ssr/features_0796o8r._.js +3 -0
- package/.next/server/chunks/ssr/features_133mpna._.js +6 -0
- package/.next/server/chunks/ssr/features_bot_1k25jdg._.js +3 -0
- package/.next/server/chunks/ssr/{features_config_13cg2cx._.js → features_config_11dpa7r._.js} +3 -3
- package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +3 -3
- package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +1 -1
- package/.next/server/chunks/ssr/features_routine_components_routine-setting_tsx_055fknz._.js +1 -1
- package/.next/server/chunks/ssr/features_workspace_workspace_ts_1wc7_u_._.js +4 -3
- package/.next/server/chunks/ssr/{node_modules_1lmv1ux._.js → node_modules_0-8r9yw._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1-20i0r._.js → node_modules_0-ew8f8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1us2bdc._.js → node_modules_02uwbwp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1vx7yq2._.js → node_modules_097cl9f._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_16oefzh._.js → node_modules_0bas34k._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0v6s4c8._.js → node_modules_0bbwe-u._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1ngj__4._.js → node_modules_0etz1i0._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0den7sw._.js → node_modules_0ka8te1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_10t4pbm._.js → node_modules_0ld7p-1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_09eqoqr._.js → node_modules_0mark4f._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_01uutx9._.js → node_modules_0n1js5k._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0t93862._.js → node_modules_0sdjzae._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1x2-bh1._.js → node_modules_0u24mg0._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_15ksxpk._.js → node_modules_0uibk9z._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0r6leyg._.js → node_modules_0x_2io2._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1_gizvz._.js → node_modules_0y5uubt._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1j59xrt._.js → node_modules_138kcrz._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_20d3gsv._.js → node_modules_156m1qh._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_19d6gup._.js → node_modules_18yn_bs._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_218nu70._.js → node_modules_1dzye0n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1gdff1c._.js → node_modules_1o9n7_n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0yslr-j._.js → node_modules_1ozyial._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_16op-wf._.js → node_modules_1r5o-bo._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1uil5qp._.js → node_modules_1tj7_9z._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0h3dnyw._.js → node_modules_1xua-g1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_03hfcze._.js → node_modules_1zkzksd._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0wbgrv5._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_133hjui._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_15680yt._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1b3vwd3._.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 +61 -61
- package/.next/static/chunks/00d54fcfm-lko.js +1 -0
- package/.next/static/chunks/05scfrgo_a_5_.js +58 -0
- package/.next/static/chunks/{1rjn_x_ty28qc.js → 0609ejkwuy4sf.js} +2 -2
- package/.next/static/chunks/{3w3v100tg-tun.js → 07vcuxousbmy1.js} +1 -1
- package/.next/static/chunks/{3r1p-za3kwq6b.js → 0cl_fgkphk1oz.js} +1 -1
- package/.next/static/chunks/0gjlsu6vrfzod.js +1 -0
- package/.next/static/chunks/0npvak0wpgagb.js +1 -0
- package/.next/static/chunks/{1wkrzv0y4qx48.js → 0o7o0eb7ihxi6.js} +1 -1
- package/.next/static/chunks/0q4ws7qd21chx.js +35 -0
- package/.next/static/chunks/{2q33y6q5_4yxf.js → 0unonxbajyknw.js} +1 -1
- package/.next/static/chunks/17yqt1p_svv13.js +1 -0
- package/.next/static/chunks/19l81deo_pyoc.js +1 -0
- package/.next/static/chunks/1ub9obhgfm4jl.js +1 -0
- package/.next/static/chunks/203pbwecfs3tm.js +1 -0
- package/.next/static/chunks/{30_2pay06oou4.js → 23tx-2paw9qa6.js} +3 -3
- package/.next/static/chunks/{22djpz2dakws5.js → 245_cp14iz637.js} +1 -1
- package/.next/static/chunks/2jbjyazqfqyoh.js +1 -0
- package/.next/static/chunks/2oa4gpkzjtpni.js +1 -0
- package/.next/static/chunks/2uraofiaoy32s.js +1 -0
- package/.next/static/chunks/{1ln0zczby868j.js → 2xjr5b-yk_h3o.js} +2 -2
- package/.next/static/chunks/314szf8yer-3n.js +2 -0
- package/.next/static/chunks/{38srd01ofppmn.css → 31kn4_h2rvf6k.css} +1 -1
- package/.next/static/chunks/39miwvg4k-b2d.js +1 -0
- package/.next/static/chunks/3ghvoe_mlljzs.js +15 -0
- package/.next/static/chunks/{2-9ybn1k9el1e.js → 3gn7dubb4-pwy.js} +1 -1
- package/.next/static/chunks/3j-l8un0d77v7.js +18 -0
- package/.next/static/chunks/{1iezy4u4v9kl7.js → 3ro66d9dc70bc.js} +1 -1
- package/.next/static/chunks/3vwjs5kq11417.js +1 -0
- package/.next/static/chunks/42m371fn687r5.js +1 -0
- package/README.md +3 -1
- package/guide/bots.md +3 -2
- package/guide/calls.md +16 -15
- package/guide/index.md +1 -1
- package/guide/setup.md +19 -10
- package/guide/trouble.md +12 -2
- package/package.json +2 -2
- package/public/sounds/NOTICE +213 -0
- package/public/sounds/end_voice.ogg +0 -0
- package/public/sounds/ring.ogg +0 -0
- package/public/sounds/start_voice.ogg +0 -0
- package/seed-skills/concierge/travel/SKILL.md +4 -4
- package/seed-skills/marketer/marketing/references/copywriting-copy-frameworks.md +3 -10
- package/seed-skills/marketer/marketing/references/copywriting.md +2 -2
- package/seed-skills/marketer/marketing/references/social-platforms.md +5 -5
- package/skills/artifact/SKILL.md +2 -1
- package/skills/artifact/references/book.md +2 -3
- package/skills/artifact/references/deck.md +4 -0
- package/skills/artifact/runtime/app/kit/vite.config.ts +6 -3
- package/skills/artifact/runtime/app/page/index.html +1 -1
- package/skills/artifact/runtime/book/book.html +1 -1
- package/skills/artifact/runtime/canvas/canvas.html +1 -1
- package/skills/artifact/runtime/deck/deck.html +1 -1
- package/skills/artifact/runtime/document/quick.html +1 -1
- package/skills/artifact/scripts/chart.mjs +122 -14
- package/skills/artifact/scripts/document.mjs +3 -2
- package/skills/daily-brief/scripts/story.mjs +13 -1
- package/skills/media-digest/SKILL.md +4 -2
- package/skills/media-digest/references/no-captions.md +2 -1
- package/skills/media-digest/scripts/audio.mjs +7 -2
- package/.next/server/chunks/[root-of-the-server]__0876r42._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0brcw76._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0c_j_qe._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0grmfwp._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0kv916d._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0tkqhnc._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0vffrja._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0vn91fr._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0vxvcj4._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0zbo906._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__10ep3hy._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__10iry08._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__11d0tvc._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__19sv9or._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1_1zysn._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1e0f7he._.js +0 -7
- package/.next/server/chunks/[root-of-the-server]__1fdpwcm._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1hgdkzg._.js +0 -11
- package/.next/server/chunks/[root-of-the-server]__1ksm9m-._.js +0 -12
- package/.next/server/chunks/[root-of-the-server]__1l_nubj._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1pmsv_6._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1tdudkf._.js +0 -5
- package/.next/server/chunks/_02lipqs._.js +0 -5
- package/.next/server/chunks/_034lk-r._.js +0 -3
- package/.next/server/chunks/_04ynt0z._.js +0 -252
- package/.next/server/chunks/_171rt-v._.js +0 -109
- package/.next/server/chunks/_17esum5._.js +0 -5
- package/.next/server/chunks/_1p8rzg_._.js +0 -252
- package/.next/server/chunks/_1v5g4kx._.js +0 -3
- package/.next/server/chunks/_1vxrw1q._.js +0 -5
- package/.next/server/chunks/features_0-cnt0l._.js +0 -4
- package/.next/server/chunks/features_0hdaci0._.js +0 -4
- package/.next/server/chunks/features_0p85gv6._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0ta6hsy._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0tok7g7._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_187uwe9._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1cu9mam._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1g1et-d._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__099tvf0._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0dxszdt._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0ihvne0._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__11hcjwx._.js +0 -3
- package/.next/server/chunks/ssr/_018vrx-._.js +0 -3
- package/.next/server/chunks/ssr/_0afqubz._.js +0 -162
- package/.next/server/chunks/ssr/_0ayihi5._.js +0 -3
- package/.next/server/chunks/ssr/_0gv5wzb._.js +0 -3
- package/.next/server/chunks/ssr/_0kkdx7t._.js +0 -3
- package/.next/server/chunks/ssr/_0yjztzi._.js +0 -3
- package/.next/server/chunks/ssr/_14fdswx._.js +0 -3
- package/.next/server/chunks/ssr/_1ajl6hf._.js +0 -5
- package/.next/server/chunks/ssr/_1o_i8-d._.js +0 -7
- package/.next/server/chunks/ssr/_1ri-y7z._.js +0 -4
- package/.next/server/chunks/ssr/features_0ctqq63._.js +0 -4
- package/.next/server/chunks/ssr/features_bot_0v6r-lh._.js +0 -3
- package/.next/static/chunks/0j8_qql4enu93.js +0 -1
- package/.next/static/chunks/0mr03ivl4_fxd.js +0 -1
- package/.next/static/chunks/13qwyo9-jd5kw.js +0 -1
- package/.next/static/chunks/17_b97pj_av_t.js +0 -1
- package/.next/static/chunks/18id2dgl_39_1.js +0 -18
- package/.next/static/chunks/1lp02y2nmddxg.js +0 -1
- package/.next/static/chunks/249i2g6ele3t2.js +0 -1
- package/.next/static/chunks/249wisxmxrwa9.js +0 -1
- package/.next/static/chunks/27dovttmtqjhi.js +0 -15
- package/.next/static/chunks/2k1rwhz_x2lej.js +0 -1
- package/.next/static/chunks/2p2pqpub-48me.js +0 -58
- package/.next/static/chunks/34-6gj9kheq74.js +0 -2
- package/.next/static/chunks/3a29oqdmvp25o.js +0 -35
- package/.next/static/chunks/3c_bgfr_z4peu.js +0 -1
- package/.next/static/chunks/3gyqds2iodotb.js +0 -1
- package/.next/static/chunks/3hxors_gsfsut.js +0 -1
- package/.next/static/chunks/3q-3lu8gpr4-h.js +0 -1
- package/.next/static/chunks/3qkm3p4g4ajku.js +0 -3
- package/.next/static/chunks/3w3mgbz8nuug2.js +0 -1
- package/app/api/bot/memory/files/route.ts +0 -14
- package/app/api/bot/memory/route.ts +0 -5
- package/app/api/events/app-event.client.ts +0 -30
- package/app/api/events/app-event.server.ts +0 -47
- package/app/api/events/app-event.ts +0 -78
- package/app/api/llm-model/catalog/route.ts +0 -12
- package/app/api/llm-model/credits/route.ts +0 -11
- package/app/api/llm-model/route.ts +0 -26
- package/app/api/llm-model/subscription/route.ts +0 -11
- package/app/api/memory/edit/route.ts +0 -7
- package/app/api/memory/route.ts +0 -8
- package/app/api/query-key.ts +0 -192
- package/app/api/thursday/tool-call/route.ts +0 -76
- package/biome.json +0 -72
- package/components/ui/button-group.tsx +0 -45
- package/components/ui/custom-icon.tsx +0 -199
- package/components/ui/dropdown-menu.tsx +0 -271
- package/components/ui/folded-text.tsx +0 -68
- package/components/ui/input-group.tsx +0 -157
- package/components/ui/json-view.tsx +0 -240
- package/components/ui/radio-group.tsx +0 -37
- package/components/ui/shiny-text.tsx +0 -68
- package/components/ui/site-icon.tsx +0 -45
- package/components/ui/source-chips.tsx +0 -54
- package/components/ui/theme-sync.tsx +0 -9
- package/components.json +0 -25
- package/docs/how-it-works.md +0 -76
- package/docs/images/errands-dark.png +0 -0
- package/docs/images/errands-light.png +0 -0
- package/docs/images/hero-dark.png +0 -0
- package/docs/images/hero-light.png +0 -0
- package/docs/images/keeps-going.png +0 -0
- package/docs/images/more-dark.png +0 -0
- package/docs/images/more-light.png +0 -0
- package/docs/images/results-dark.png +0 -0
- package/docs/images/results-light.png +0 -0
- package/docs/images/talk-dark.png +0 -0
- package/docs/images/talk-light.png +0 -0
- package/docs/images/team-dark.png +0 -0
- package/docs/images/team-light.png +0 -0
- package/docs/images/two-minds.png +0 -0
- package/features/ai/chatgpt.ts +0 -638
- package/features/ai/components/chatgpt-sign-in.tsx +0 -66
- package/features/ai/components/effort-switch.tsx +0 -112
- package/features/ai/components/gateway-mark.tsx +0 -188
- package/features/ai/components/model-browser.tsx +0 -324
- package/features/ai/components/model-picker.tsx +0 -336
- package/features/ai/components/provider-icon.tsx +0 -162
- package/features/ai/guide.ts +0 -44
- package/features/ai/live.schema.ts +0 -150
- package/features/ai/load-tools.ts +0 -495
- package/features/ai/model.schema.ts +0 -985
- package/features/ai/model.ts +0 -662
- package/features/ai/prompts/bot.prompt.ts +0 -418
- package/features/ai/prompts/call-standing.ts +0 -43
- package/features/ai/prompts/live.prompt.ts +0 -197
- package/features/ai/prompts/memory-edit.prompt.ts +0 -33
- package/features/ai/prompts/persona.ts +0 -114
- package/features/ai/prompts/prompt-helper.ts +0 -287
- package/features/ai/prompts/thursday.prompt.ts +0 -281
- package/features/ai/tools/bot.tool.ts +0 -183
- package/features/ai/tools/call.tool.ts +0 -50
- package/features/ai/tools/connected.ts +0 -199
- package/features/ai/tools/deck.tool.ts +0 -518
- package/features/ai/tools/look.tool.ts +0 -65
- package/features/ai/tools/mcp.tool.ts +0 -187
- package/features/ai/tools/memory.tool.ts +0 -296
- package/features/ai/tools/routine.tool.ts +0 -214
- package/features/ai/tools/search.tool.ts +0 -248
- package/features/ai/tools/self.tool.ts +0 -58
- package/features/ai/tools/signin.tool.ts +0 -138
- package/features/ai/tools/skills.tool.ts +0 -109
- package/features/ai/tools/studio.tool.ts +0 -360
- package/features/ai/tools/tool-name.ts +0 -56
- package/features/ai/tools/workspace.tool.ts +0 -126
- package/features/ai/words.ts +0 -60
- package/features/artifact/artifact.action.ts +0 -12
- package/features/artifact/artifact.query.ts +0 -218
- package/features/artifact/artifact.schema.ts +0 -58
- package/features/artifact/components/artifact-setting.tsx +0 -513
- package/features/bot/bot.action.ts +0 -195
- package/features/bot/bot.memory.ts +0 -206
- package/features/bot/bot.query.ts +0 -293
- package/features/bot/bot.run.ts +0 -909
- package/features/bot/bot.runner.ts +0 -595
- package/features/bot/bot.schema.ts +0 -501
- package/features/bot/bot.seed.ts +0 -160
- package/features/bot/components/attachments.tsx +0 -225
- package/features/bot/components/bot-badge.tsx +0 -21
- package/features/bot/components/bot-mark.tsx +0 -1678
- package/features/bot/components/bot-room.tsx +0 -439
- package/features/bot/components/bot-roster.tsx +0 -43
- package/features/bot/components/bot-setting.tsx +0 -1698
- package/features/bot/components/bot-tip.tsx +0 -48
- package/features/bot/components/bot-tool.tsx +0 -644
- package/features/bot/components/crew-motion.ts +0 -168
- package/features/bot/components/mark-palette.tsx +0 -57
- package/features/bot/components/room-conversation.tsx +0 -1208
- package/features/bot/components/room-list.tsx +0 -539
- package/features/bot/components/room-pill.tsx +0 -1045
- package/features/bot/components/thread-badge.tsx +0 -37
- package/features/bot/components/thread-reply.tsx +0 -780
- package/features/bot/components/thread-setting.tsx +0 -718
- package/features/bot/components/write-orb.tsx +0 -298
- package/features/bot/mark.const.ts +0 -164
- package/features/bot/room.query.ts +0 -922
- package/features/bot/room.schema.ts +0 -78
- package/features/bot/seed-bots.ts +0 -44
- package/features/bot/thread.query.ts +0 -1175
- package/features/bot/thread.store.ts +0 -726
- package/features/config/components/config-badge.tsx +0 -28
- package/features/config/components/config-setting.tsx +0 -881
- package/features/config/components/models-badge.tsx +0 -42
- package/features/config/components/voice-key.tsx +0 -321
- package/features/config/config.action.ts +0 -67
- package/features/config/config.const.ts +0 -356
- package/features/config/config.query.ts +0 -43
- package/features/connectors/components/mcp-badge.tsx +0 -17
- package/features/connectors/components/mcp-mark.tsx +0 -4
- package/features/connectors/components/mcp-setting.tsx +0 -1028
- package/features/connectors/mcp.action.ts +0 -93
- package/features/connectors/mcp.const.ts +0 -336
- package/features/connectors/mcp.manager.ts +0 -497
- package/features/connectors/mcp.query.ts +0 -256
- package/features/connectors/mcp.schema.ts +0 -122
- package/features/intro/components/echoes.tsx +0 -563
- package/features/intro/components/intro.tsx +0 -964
- package/features/intro/intro-voice.ts +0 -174
- package/features/memory/components/memory-edit.tsx +0 -333
- package/features/memory/components/memory-mark.tsx +0 -4
- package/features/memory/components/memory-setting.tsx +0 -662
- package/features/memory/memory.action.ts +0 -75
- package/features/memory/memory.edit.ts +0 -79
- package/features/memory/memory.query.ts +0 -513
- package/features/memory/memory.schema.ts +0 -196
- package/features/reach/channel.ts +0 -127
- package/features/reach/chat-text.ts +0 -364
- package/features/reach/components/reach-ask.tsx +0 -94
- package/features/reach/components/reach-badge.tsx +0 -22
- package/features/reach/components/reach-guide.tsx +0 -777
- package/features/reach/discord.ts +0 -308
- package/features/reach/pictures.ts +0 -88
- package/features/reach/reach.action.ts +0 -30
- package/features/reach/reach.schema.ts +0 -80
- package/features/reach/reach.ts +0 -946
- package/features/reach/slack.ts +0 -319
- package/features/reach/socket.ts +0 -63
- package/features/reach/telegram.ts +0 -323
- package/features/routine/components/routine-mark.tsx +0 -7
- package/features/routine/components/routine-setting.tsx +0 -1078
- package/features/routine/routine.action.ts +0 -31
- package/features/routine/routine.clock.ts +0 -102
- package/features/routine/routine.query.ts +0 -207
- package/features/routine/routine.schema.ts +0 -157
- package/features/settings/components/install-app.tsx +0 -153
- package/features/settings/components/setting-ui.tsx +0 -482
- package/features/settings/components/settings.tsx +0 -464
- package/features/settings/settings.alert.ts +0 -42
- package/features/settings/settings.store.ts +0 -44
- package/features/signins/components/signin-ask.tsx +0 -51
- package/features/signins/components/signins-setting.tsx +0 -261
- package/features/signins/signins.action.ts +0 -22
- package/features/signins/signins.query.ts +0 -261
- package/features/signins/signins.schema.ts +0 -26
- package/features/skills/components/skills-mark.tsx +0 -4
- package/features/skills/components/skills-setting.tsx +0 -736
- package/features/skills/skills.action.ts +0 -118
- package/features/skills/skills.discover.ts +0 -146
- package/features/skills/skills.query.ts +0 -363
- package/features/skills/skills.schema.ts +0 -105
- package/features/thursday/ascii.const.ts +0 -218
- package/features/thursday/call-signal.ts +0 -41
- package/features/thursday/components/ascii-orb.tsx +0 -1523
- package/features/thursday/components/boot.tsx +0 -24
- package/features/thursday/components/call-log.tsx +0 -503
- package/features/thursday/components/caption-words.tsx +0 -117
- package/features/thursday/components/connect-wave.tsx +0 -266
- package/features/thursday/components/face.tsx +0 -137
- package/features/thursday/components/side-captions.tsx +0 -347
- package/features/thursday/components/tab-state.tsx +0 -108
- package/features/thursday/components/thursday-mark.tsx +0 -168
- package/features/thursday/components/thursday-setting.tsx +0 -1084
- package/features/thursday/components/thursday.tsx +0 -1823
- package/features/thursday/components/voice-picker.tsx +0 -254
- package/features/thursday/components/write-line.tsx +0 -714
- package/features/thursday/expressions.ts +0 -1278
- package/features/thursday/eyes.ts +0 -274
- package/features/thursday/face-words.ts +0 -44
- package/features/thursday/face.const.ts +0 -6
- package/features/thursday/face.store.ts +0 -62
- package/features/thursday/field.ts +0 -93
- package/features/thursday/open-work.ts +0 -180
- package/features/thursday/screen-act.ts +0 -15
- package/features/thursday/silent-voice.ts +0 -14
- package/features/thursday/smoke.ts +0 -510
- package/features/thursday/thursday.action.ts +0 -266
- package/features/thursday/thursday.query.ts +0 -382
- package/features/thursday/thursday.schema.ts +0 -251
- package/features/thursday/thursday.store.ts +0 -129
- package/features/thursday/thursday.text.ts +0 -567
- package/features/thursday/tool-call.ts +0 -42
- package/features/thursday/tool-line.ts +0 -333
- package/features/thursday/use-call-ring.ts +0 -194
- package/features/thursday/use-live-settings.ts +0 -66
- package/features/thursday/use-text-call.ts +0 -551
- package/features/thursday/use-thursday.ts +0 -1231
- package/features/thursday/wash.ts +0 -116
- package/features/thursday/work-chip.tsx +0 -64
- package/features/workspace/components/artifact-view.tsx +0 -510
- package/features/workspace/components/file-thumb.tsx +0 -253
- package/features/workspace/components/file-view.tsx +0 -875
- package/features/workspace/components/given-files.tsx +0 -195
- package/features/workspace/components/workspace-mark.tsx +0 -4
- package/features/workspace/components/workspace-setting.tsx +0 -454
- package/features/workspace/file-kind.ts +0 -190
- package/features/workspace/workspace.action.ts +0 -88
- package/features/workspace/workspace.query.ts +0 -220
- package/features/workspace/workspace.schema.ts +0 -58
- package/features/workspace/workspace.ts +0 -553
- package/hooks/use-draft.ts +0 -38
- package/hooks/use-hotkey.ts +0 -171
- package/hooks/use-object-state.ts +0 -22
- package/hooks/use-on-visible.ts +0 -72
- package/hooks/use-theme.ts +0 -120
- package/hooks/use-wake-word.ts +0 -262
- package/knip.json +0 -7
- package/lib/date-like.ts +0 -37
- package/lib/desktop-notify.ts +0 -81
- package/lib/favicon.ts +0 -88
- package/lib/json-schema.ts +0 -42
- package/lib/live/live.schema.ts +0 -36
- package/lib/live/live.server.ts +0 -188
- package/lib/live/live.session.ts +0 -712
- package/lib/live/live.tap.ts +0 -288
- package/lib/live/live.transport.ts +0 -152
- package/lib/live/ring.ts +0 -62
- package/lib/logger.ts +0 -14
- package/lib/oauth-page.ts +0 -27
- package/lib/protocol/events.client.ts +0 -89
- package/lib/protocol/events.server.ts +0 -158
- package/lib/protocol/events.ts +0 -53
- package/lib/protocol/presence.ts +0 -65
- package/lib/protocol/result.ts +0 -63
- package/lib/protocol/server-action.ts +0 -13
- package/lib/protocol/server-route.ts +0 -20
- package/lib/protocol/to-result.ts +0 -46
- package/lib/protocol/use-server-action.ts +0 -105
- package/lib/protocol/use-server-pages.ts +0 -117
- package/lib/protocol/use-server-route.ts +0 -165
- package/lib/public-error.ts +0 -19
- package/lib/queue.ts +0 -79
- package/lib/reveal-path.ts +0 -46
- package/lib/sandbox.ts +0 -269
- package/lib/theme.ts +0 -9
- package/lib/tokens.ts +0 -35
- package/lib/utils.ts +0 -163
- package/release-please-config.json +0 -21
- package/scripts/artifact-paths.test.mts +0 -56
- package/scripts/bot-context.test.mts +0 -2122
- package/scripts/intro-voice.mts +0 -65
- package/scripts/live-history.test.mts +0 -115
- package/scripts/live-session.test.mts +0 -1286
- package/scripts/memory-tools.test.mts +0 -177
- package/scripts/page-edits.test.mts +0 -319
- package/scripts/reach-channels.test.mts +0 -524
- package/scripts/skill-files.test.mts +0 -225
- package/scripts/text-call.test.mts +0 -540
- package/skills-lock.json +0 -23
- package/tsconfig.json +0 -44
- /package/.next/static/{0yrnAMu4F_o69_DY3W-ho → RtLRT9EEaGn-OqwpMFdYg}/_buildManifest.js +0 -0
- /package/.next/static/{0yrnAMu4F_o69_DY3W-ho → RtLRT9EEaGn-OqwpMFdYg}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{0yrnAMu4F_o69_DY3W-ho → RtLRT9EEaGn-OqwpMFdYg}/_ssgManifest.js +0 -0
package/features/bot/bot.run.ts
DELETED
|
@@ -1,909 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type FinishReason,
|
|
3
|
-
generateText,
|
|
4
|
-
type LanguageModel,
|
|
5
|
-
type LanguageModelUsage,
|
|
6
|
-
type ModelMessage,
|
|
7
|
-
type PrepareStepResult,
|
|
8
|
-
type ProviderMetadata,
|
|
9
|
-
stepCountIs,
|
|
10
|
-
ToolLoopAgent,
|
|
11
|
-
type ToolSet,
|
|
12
|
-
tool,
|
|
13
|
-
} from "ai";
|
|
14
|
-
import { BOT_RUN } from "@/config";
|
|
15
|
-
import { loadTools } from "@/features/ai/load-tools";
|
|
16
|
-
import {
|
|
17
|
-
compactBudget,
|
|
18
|
-
getTextModel,
|
|
19
|
-
isContextOverflow,
|
|
20
|
-
isProviderRefusal,
|
|
21
|
-
modelErrorToString,
|
|
22
|
-
resolveDefaultModel,
|
|
23
|
-
runEffort,
|
|
24
|
-
} from "@/features/ai/model";
|
|
25
|
-
import { loadBotPrompt } from "@/features/ai/prompts/bot.prompt";
|
|
26
|
-
import { sendMessageSpec } from "@/features/ai/tools/bot.tool";
|
|
27
|
-
import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
|
|
28
|
-
import { asWords } from "@/features/ai/words";
|
|
29
|
-
import {
|
|
30
|
-
COMPACT_AT_MIN,
|
|
31
|
-
type JobBot,
|
|
32
|
-
type TokenUsage,
|
|
33
|
-
} from "@/features/bot/bot.schema";
|
|
34
|
-
import { renewSignIns } from "@/features/signins/signins.query";
|
|
35
|
-
import {
|
|
36
|
-
botBrowserSession,
|
|
37
|
-
filesOnDisk,
|
|
38
|
-
openBotFolders,
|
|
39
|
-
openJobScratch,
|
|
40
|
-
} from "@/features/workspace/workspace";
|
|
41
|
-
import { logger } from "@/lib/logger";
|
|
42
|
-
import { estimateTokens } from "@/lib/tokens";
|
|
43
|
-
import { findJobBot } from "./bot.query";
|
|
44
|
-
import {
|
|
45
|
-
argumentLine,
|
|
46
|
-
findThread,
|
|
47
|
-
listWrittenPaths,
|
|
48
|
-
writtenPathsIn,
|
|
49
|
-
} from "./thread.query";
|
|
50
|
-
|
|
51
|
-
/** Events from one participant turn; the runner persists them in that participant's transcript. */
|
|
52
|
-
type BotEvent =
|
|
53
|
-
/** A finished chunk of prose. */
|
|
54
|
-
| { type: "text"; text: string }
|
|
55
|
-
/** A tool call. `id` is where the result lands. */
|
|
56
|
-
| {
|
|
57
|
-
type: "tool";
|
|
58
|
-
id: string;
|
|
59
|
-
name: string;
|
|
60
|
-
input: unknown;
|
|
61
|
-
providerExecuted?: boolean;
|
|
62
|
-
providerOptions?: ProviderMetadata;
|
|
63
|
-
}
|
|
64
|
-
| {
|
|
65
|
-
type: "tool-result";
|
|
66
|
-
id: string;
|
|
67
|
-
name: string;
|
|
68
|
-
output: unknown;
|
|
69
|
-
/** The tool threw; `output` is what it said. */
|
|
70
|
-
error?: boolean;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* A step finished; `messages` is what the model sees next time.
|
|
74
|
-
* `budget` is where this run compacts (config BOT_RUN).
|
|
75
|
-
*/
|
|
76
|
-
| {
|
|
77
|
-
type: "step";
|
|
78
|
-
messages: ModelMessage[];
|
|
79
|
-
usage: TokenUsage;
|
|
80
|
-
budget: number;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* The context passed its budget and the model summarized it (compact). The
|
|
84
|
-
* runner stores `text` as the compact row a resume restarts from. `usage`
|
|
85
|
-
* is the summary's cost; `messages`/`tokens` what it replaced.
|
|
86
|
-
*/
|
|
87
|
-
| {
|
|
88
|
-
type: "compact";
|
|
89
|
-
text: string;
|
|
90
|
-
usage: TokenUsage;
|
|
91
|
-
messages: number;
|
|
92
|
-
tokens: number;
|
|
93
|
-
}
|
|
94
|
-
/** Normal turn end; interruption is a runtime fact, separate from room completion. */
|
|
95
|
-
| { type: "turn-end"; text: string; stopped: boolean }
|
|
96
|
-
/**
|
|
97
|
-
* The run broke, in words a person can act on; `budget` is where to compact next
|
|
98
|
-
* time, when the model refused the context as too long; `retry` whether another try
|
|
99
|
-
* may pass (config BOT_RUN.retryMs), false when only a person can change the outcome.
|
|
100
|
-
*/
|
|
101
|
-
| { type: "error"; message: string; budget?: number; retry: boolean };
|
|
102
|
-
|
|
103
|
-
/** The event as the thread sees it: which participant and continuation. */
|
|
104
|
-
export type ThreadEvent = BotEvent & { bot: string; parent: string | null };
|
|
105
|
-
|
|
106
|
-
type RunOptions = {
|
|
107
|
-
signal?: AbortSignal;
|
|
108
|
-
parent?: string | null;
|
|
109
|
-
threadId?: string | null;
|
|
110
|
-
session?: string | null;
|
|
111
|
-
caller: string;
|
|
112
|
-
owner: string;
|
|
113
|
-
contextBudget?: number;
|
|
114
|
-
/**
|
|
115
|
-
* The user asked for this desk to summarize itself now (bot.runner askCompact). Asked
|
|
116
|
-
* before each step and true once: the step after it compacts whatever its size.
|
|
117
|
-
*/
|
|
118
|
-
compactNow?: () => boolean;
|
|
119
|
-
notes?: () => Promise<string[]>;
|
|
120
|
-
send: (input: {
|
|
121
|
-
id: string;
|
|
122
|
-
to: string;
|
|
123
|
-
text: string;
|
|
124
|
-
why: string;
|
|
125
|
-
kind?: "message" | "question";
|
|
126
|
-
options?: string[] | null;
|
|
127
|
-
}) => Promise<unknown>;
|
|
128
|
-
emit: (event: ThreadEvent) => Promise<void>;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
const MAX_STEPS = BOT_RUN.steps;
|
|
132
|
-
type RunInput = { bot: string; messages: ModelMessage[] };
|
|
133
|
-
|
|
134
|
-
export async function runBot(
|
|
135
|
-
input: RunInput,
|
|
136
|
-
options: RunOptions,
|
|
137
|
-
): Promise<void> {
|
|
138
|
-
const parent = options.parent ?? null;
|
|
139
|
-
const bot = await findJobBot(input.bot.trim());
|
|
140
|
-
const name = bot?.name ?? input.bot.trim();
|
|
141
|
-
const emit = (event: BotEvent) =>
|
|
142
|
-
options.emit({ ...event, bot: name, parent });
|
|
143
|
-
|
|
144
|
-
if (!bot) {
|
|
145
|
-
await emit({
|
|
146
|
-
type: "error",
|
|
147
|
-
message: `No bot named "${input.bot}". Use a name from the list.`,
|
|
148
|
-
retry: false,
|
|
149
|
-
});
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
const history = input.messages;
|
|
153
|
-
|
|
154
|
-
// Tools are built on the model: web search runs on this bot's model (load-tools).
|
|
155
|
-
const model = await resolveModel(bot);
|
|
156
|
-
const row = options.threadId ? await findThread(options.threadId) : null;
|
|
157
|
-
// Participants share thread files while retaining their own context and browser.
|
|
158
|
-
const [scratch, { own, artifacts }] = await Promise.all([
|
|
159
|
-
options.threadId
|
|
160
|
-
? openJobScratch(options.threadId, row?.label ?? "job")
|
|
161
|
-
: null,
|
|
162
|
-
openBotFolders(name),
|
|
163
|
-
]);
|
|
164
|
-
const session =
|
|
165
|
-
options.session ??
|
|
166
|
-
(options.threadId ? botBrowserSession(options.threadId, name) : null);
|
|
167
|
-
const [prompt, tools] = await Promise.all([
|
|
168
|
-
loadBotPrompt(
|
|
169
|
-
name,
|
|
170
|
-
bot.systemPrompt,
|
|
171
|
-
{
|
|
172
|
-
thread: options.threadId ?? null,
|
|
173
|
-
owner: options.owner,
|
|
174
|
-
caller: options.caller,
|
|
175
|
-
},
|
|
176
|
-
{ scratch, own, artifacts },
|
|
177
|
-
),
|
|
178
|
-
loadTools({
|
|
179
|
-
target: "bot",
|
|
180
|
-
bot: name,
|
|
181
|
-
thread: options.threadId ?? null,
|
|
182
|
-
session,
|
|
183
|
-
model,
|
|
184
|
-
}),
|
|
185
|
-
]);
|
|
186
|
-
// What the owner set, else the model's own window, else the constant (model.ts
|
|
187
|
-
// compactBudget), and never above where this participant last fit: a context the
|
|
188
|
-
// model refused as too long lowers its own number (room.query
|
|
189
|
-
// lowerRoomContextBudget). The thread row's budget only draws the meter.
|
|
190
|
-
const budget = Math.min(
|
|
191
|
-
await compactBudget(model.ref, bot.compactAt),
|
|
192
|
-
options.contextBudget || Number.POSITIVE_INFINITY,
|
|
193
|
-
);
|
|
194
|
-
// What the owner set, else the app default, and nothing at all where the model's ladder is
|
|
195
|
-
// unknown (model.ts runEffort). The sdk translates the step into whatever this provider takes.
|
|
196
|
-
const reasoning = await runEffort(model.ref, bot.effort);
|
|
197
|
-
|
|
198
|
-
// A committed question to the user ends the turn; the answer brings the bot back (room.query tellRoom).
|
|
199
|
-
let asked = false;
|
|
200
|
-
const agentTools: ToolSet = {
|
|
201
|
-
...tools,
|
|
202
|
-
[TOOL_NAMES.send_message]: tool({
|
|
203
|
-
description: sendMessageSpec.description,
|
|
204
|
-
inputSchema: sendMessageSpec.parameters,
|
|
205
|
-
execute: async (input, call) => {
|
|
206
|
-
const receipt = await options.send({ ...input, id: call.toolCallId });
|
|
207
|
-
if (input.kind === "question") asked = true;
|
|
208
|
-
return receipt;
|
|
209
|
-
},
|
|
210
|
-
}),
|
|
211
|
-
};
|
|
212
|
-
// Persist local calls before their side effects, and results before another model step.
|
|
213
|
-
// The stream can repeat these events; the writer deduplicates them by call ID.
|
|
214
|
-
const inFlight = new Set<Promise<unknown>>();
|
|
215
|
-
const quiet = silenceWatch(BOT_RUN.silenceMs);
|
|
216
|
-
for (const [toolName, held] of Object.entries(agentTools)) {
|
|
217
|
-
const execute = held.execute;
|
|
218
|
-
if (!execute) continue;
|
|
219
|
-
held.execute = (args, call) => {
|
|
220
|
-
const execution = (async () => {
|
|
221
|
-
options.signal?.throwIfAborted();
|
|
222
|
-
await emit({
|
|
223
|
-
type: "tool",
|
|
224
|
-
id: call.toolCallId,
|
|
225
|
-
name: toolName,
|
|
226
|
-
input: args,
|
|
227
|
-
});
|
|
228
|
-
quiet.hold();
|
|
229
|
-
try {
|
|
230
|
-
options.signal?.throwIfAborted();
|
|
231
|
-
let output = await execute(args, call);
|
|
232
|
-
if (
|
|
233
|
-
output &&
|
|
234
|
-
typeof output === "object" &&
|
|
235
|
-
Symbol.asyncIterator in output
|
|
236
|
-
) {
|
|
237
|
-
let last: unknown;
|
|
238
|
-
for await (const value of output as AsyncIterable<unknown>)
|
|
239
|
-
last = value;
|
|
240
|
-
output = last;
|
|
241
|
-
}
|
|
242
|
-
await emit({
|
|
243
|
-
type: "tool-result",
|
|
244
|
-
id: call.toolCallId,
|
|
245
|
-
name: toolName,
|
|
246
|
-
output,
|
|
247
|
-
});
|
|
248
|
-
return output;
|
|
249
|
-
} catch (cause) {
|
|
250
|
-
await emit({
|
|
251
|
-
type: "tool-result",
|
|
252
|
-
id: call.toolCallId,
|
|
253
|
-
name: toolName,
|
|
254
|
-
output: modelErrorToString(cause),
|
|
255
|
-
error: true,
|
|
256
|
-
});
|
|
257
|
-
throw cause;
|
|
258
|
-
} finally {
|
|
259
|
-
quiet.release();
|
|
260
|
-
}
|
|
261
|
-
})();
|
|
262
|
-
inFlight.add(execution);
|
|
263
|
-
void execution.finally(() => inFlight.delete(execution)).catch(() => {});
|
|
264
|
-
return execution;
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// The SDK can prepare the next step before the consumer has stored this one.
|
|
269
|
-
let writtenStep: Promise<void> = Promise.resolve();
|
|
270
|
-
let acknowledgeStep = () => {};
|
|
271
|
-
/** Context size the latest step went out at; an overflow shrinks the budget from it. */
|
|
272
|
-
let sent = 0;
|
|
273
|
-
|
|
274
|
-
const agent = new ToolLoopAgent({
|
|
275
|
-
model: model.model,
|
|
276
|
-
instructions: prompt.text,
|
|
277
|
-
tools: agentTools,
|
|
278
|
-
reasoning,
|
|
279
|
-
stopWhen: [stepCountIs(MAX_STEPS), () => asked],
|
|
280
|
-
prepareStep: async ({ stepNumber, steps, messages }) => {
|
|
281
|
-
await writtenStep;
|
|
282
|
-
options.signal?.throwIfAborted();
|
|
283
|
-
const step: NonNullable<PrepareStepResult<ToolSet>> = {};
|
|
284
|
-
// What the provider counted, and the estimate only for one that counts nothing —
|
|
285
|
-
// never the larger of the two. `sizeOf` reads a message as its JSON, so a picture
|
|
286
|
-
// in the conversation is counted as the length of its base64: a 1 MB screenshot
|
|
287
|
-
// measures about 350k tokens against a 400k budget where the provider charges one
|
|
288
|
-
// or two thousand, and a job compacted itself after two of them with its window
|
|
289
|
-
// almost empty. The provider's count also covers the instructions and tool schemas
|
|
290
|
-
// the estimate cannot see, so it is the better number wherever it exists. It is the
|
|
291
|
-
// step before this one, missing that step's tool result; `compactHeadroom` is the
|
|
292
|
-
// room that leaves.
|
|
293
|
-
const measured = steps.at(-1)?.usage.inputTokens ?? 0;
|
|
294
|
-
const size = measured || sizeOf(messages);
|
|
295
|
-
sent = size;
|
|
296
|
-
let next = messages;
|
|
297
|
-
// The opening survives every compaction, so past it and one summary there is nothing to compact
|
|
298
|
-
const compactAsked = options.compactNow?.() ?? false;
|
|
299
|
-
if ((size > budget || compactAsked) && messages.length > 2) {
|
|
300
|
-
// One long call that sends nothing until it is done, and bounds itself
|
|
301
|
-
quiet.hold();
|
|
302
|
-
const summary = await compact(model.model, agentTools, messages, {
|
|
303
|
-
signal: options.signal,
|
|
304
|
-
budget,
|
|
305
|
-
instructions: prompt.text,
|
|
306
|
-
}).finally(quiet.release);
|
|
307
|
-
logger.debug(
|
|
308
|
-
`compacted ${messages.length} messages at ${size} tokens (budget ${budget})`,
|
|
309
|
-
);
|
|
310
|
-
// Which files the job has is read off its rows and the disk, never asked of the model
|
|
311
|
-
const text = `${summary.text}${await filesUnder(row?.id ?? null, messages, scratch)}`;
|
|
312
|
-
await emit({
|
|
313
|
-
type: "compact",
|
|
314
|
-
text,
|
|
315
|
-
usage: summary.usage,
|
|
316
|
-
messages: messages.length,
|
|
317
|
-
tokens: size,
|
|
318
|
-
});
|
|
319
|
-
next = [messages[0], { role: "user", content: text }];
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Notes said during the last step go in as user turns after everything
|
|
323
|
-
// the model has (and after the summary). Not on the first step.
|
|
324
|
-
const notes = stepNumber > 0 ? ((await options.notes?.()) ?? []) : [];
|
|
325
|
-
if (notes.length) {
|
|
326
|
-
next = [
|
|
327
|
-
...next,
|
|
328
|
-
...notes.map((text) => ({ role: "user" as const, content: text })),
|
|
329
|
-
];
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
if (next === messages) return step;
|
|
333
|
-
// Carried forward by the sdk: from here the steps stack on these
|
|
334
|
-
return { ...step, messages: next };
|
|
335
|
-
},
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
// Step messages arrive by callback and the stream by loop, with no ordering
|
|
339
|
-
// between them: the callback queues, the loop takes at `finish-step`.
|
|
340
|
-
const steps = stepQueue();
|
|
341
|
-
// The job stopping and the model going quiet end the stream the same way;
|
|
342
|
-
// which of the two it was is read at `abort`
|
|
343
|
-
const stop = options.signal
|
|
344
|
-
? AbortSignal.any([options.signal, quiet.signal])
|
|
345
|
-
: quiet.signal;
|
|
346
|
-
quiet.touch();
|
|
347
|
-
const execution = new AbortController();
|
|
348
|
-
const signal = AbortSignal.any([stop, execution.signal]);
|
|
349
|
-
let result;
|
|
350
|
-
try {
|
|
351
|
-
result = await agent.stream({
|
|
352
|
-
messages: history,
|
|
353
|
-
abortSignal: signal,
|
|
354
|
-
onStepEnd: (step) => {
|
|
355
|
-
writtenStep = new Promise<void>((resolve) => {
|
|
356
|
-
acknowledgeStep = resolve;
|
|
357
|
-
});
|
|
358
|
-
steps.push({
|
|
359
|
-
messages: storedMessages(step),
|
|
360
|
-
usage: usageOf(step.usage),
|
|
361
|
-
});
|
|
362
|
-
},
|
|
363
|
-
});
|
|
364
|
-
} catch (cause) {
|
|
365
|
-
quiet.end();
|
|
366
|
-
execution.abort();
|
|
367
|
-
await Promise.allSettled([...inFlight]);
|
|
368
|
-
throw cause;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
let writing = "";
|
|
372
|
-
/** Only prose from the final step is returned to the correspondent. */
|
|
373
|
-
let last = "";
|
|
374
|
-
/** Why the latest step ended; prose cut off at the output limit is not an answer. */
|
|
375
|
-
let finish: FinishReason | null = null;
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Every way the stream breaks, as the runner takes it: the words for the row, and
|
|
379
|
-
* where to compact next time when the context was refused as too long. The row
|
|
380
|
-
* keeps only the words, so the whole cause is logged here.
|
|
381
|
-
*/
|
|
382
|
-
const failed = (cause: unknown): Extract<BotEvent, { type: "error" }> => {
|
|
383
|
-
logger.error(`${name}: the model run broke`, cause);
|
|
384
|
-
const message = modelErrorToString(cause);
|
|
385
|
-
const retry = !isProviderRefusal(cause);
|
|
386
|
-
if (!isContextOverflow(cause)) return { type: "error", message, retry };
|
|
387
|
-
const shrunk = Math.floor(
|
|
388
|
-
Math.min(budget, sent || budget) * BOT_RUN.overflowShrink,
|
|
389
|
-
);
|
|
390
|
-
return {
|
|
391
|
-
type: "error",
|
|
392
|
-
message,
|
|
393
|
-
budget: Math.max(COMPACT_AT_MIN, shrunk),
|
|
394
|
-
retry,
|
|
395
|
-
};
|
|
396
|
-
};
|
|
397
|
-
|
|
398
|
-
// An abort ends the stream without a finish; release any waiting take.
|
|
399
|
-
stop.addEventListener(
|
|
400
|
-
"abort",
|
|
401
|
-
() => {
|
|
402
|
-
steps.end();
|
|
403
|
-
acknowledgeStep();
|
|
404
|
-
},
|
|
405
|
-
{ once: true },
|
|
406
|
-
);
|
|
407
|
-
try {
|
|
408
|
-
for await (const part of result.stream) {
|
|
409
|
-
// Anything at all is the model still there
|
|
410
|
-
quiet.touch();
|
|
411
|
-
switch (part.type) {
|
|
412
|
-
case "start-step":
|
|
413
|
-
last = "";
|
|
414
|
-
writing = "";
|
|
415
|
-
break;
|
|
416
|
-
|
|
417
|
-
case "text-delta":
|
|
418
|
-
writing += part.text;
|
|
419
|
-
break;
|
|
420
|
-
|
|
421
|
-
case "text-end": {
|
|
422
|
-
const text = writing.trim();
|
|
423
|
-
writing = "";
|
|
424
|
-
if (!text) break;
|
|
425
|
-
last = [last, text].filter(Boolean).join("\n\n");
|
|
426
|
-
await emit({ type: "text", text });
|
|
427
|
-
break;
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
case "tool-call": {
|
|
431
|
-
await emit({
|
|
432
|
-
type: "tool",
|
|
433
|
-
id: part.toolCallId,
|
|
434
|
-
name: part.toolName,
|
|
435
|
-
input: part.input,
|
|
436
|
-
providerExecuted: part.providerExecuted,
|
|
437
|
-
providerOptions: part.providerMetadata,
|
|
438
|
-
});
|
|
439
|
-
break;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
case "tool-result":
|
|
443
|
-
// A provider-executed tool (web search) lands here too; the step's own
|
|
444
|
-
// messages decide where it belongs (bot.runner).
|
|
445
|
-
await emit({
|
|
446
|
-
type: "tool-result",
|
|
447
|
-
id: part.toolCallId,
|
|
448
|
-
name: part.toolName,
|
|
449
|
-
output: part.output,
|
|
450
|
-
});
|
|
451
|
-
break;
|
|
452
|
-
|
|
453
|
-
case "tool-error":
|
|
454
|
-
// The model reads it and carries on; the row shows it now rather than
|
|
455
|
-
// when the step ends
|
|
456
|
-
await emit({
|
|
457
|
-
type: "tool-result",
|
|
458
|
-
id: part.toolCallId,
|
|
459
|
-
name: part.toolName,
|
|
460
|
-
output: modelErrorToString(part.error),
|
|
461
|
-
error: true,
|
|
462
|
-
});
|
|
463
|
-
break;
|
|
464
|
-
|
|
465
|
-
case "finish-step": {
|
|
466
|
-
finish = part.finishReason;
|
|
467
|
-
const step = await steps.take();
|
|
468
|
-
if (step) await emit({ type: "step", ...step, budget });
|
|
469
|
-
acknowledgeStep();
|
|
470
|
-
break;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
case "abort":
|
|
474
|
-
// The job was stopped: whoever stopped it writes the row (bot.runner)
|
|
475
|
-
if (options.signal?.aborted) return;
|
|
476
|
-
// Otherwise the model went quiet (silenceWatch). The sdk types `reason` as
|
|
477
|
-
// a string but hands over the signal's reason, the watch's DOMException.
|
|
478
|
-
await emit(failed(part.reason ?? "The model stopped sending."));
|
|
479
|
-
return;
|
|
480
|
-
|
|
481
|
-
case "error":
|
|
482
|
-
await emit(failed(part.error));
|
|
483
|
-
return;
|
|
484
|
-
|
|
485
|
-
default:
|
|
486
|
-
break;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
} finally {
|
|
490
|
-
execution.abort();
|
|
491
|
-
steps.end();
|
|
492
|
-
quiet.end();
|
|
493
|
-
acknowledgeStep();
|
|
494
|
-
await Promise.allSettled([...inFlight]);
|
|
495
|
-
if (session)
|
|
496
|
-
void renewSignIns(session).catch((cause) =>
|
|
497
|
-
logger.warn(`${name}: kept sign-ins were not renewed`, cause),
|
|
498
|
-
);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
try {
|
|
502
|
-
await result.finalStep;
|
|
503
|
-
} catch (cause) {
|
|
504
|
-
// Stopped between steps: whoever stopped it writes the row
|
|
505
|
-
if (options.signal?.aborted) return;
|
|
506
|
-
await emit(failed(cause));
|
|
507
|
-
return;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
// The provider's filter stopped the answer: there is nothing to continue past
|
|
511
|
-
if (finish === "content-filter") {
|
|
512
|
-
await emit({
|
|
513
|
-
type: "error",
|
|
514
|
-
message: "The provider's content filter stopped the response.",
|
|
515
|
-
retry: false,
|
|
516
|
-
});
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
await emit({
|
|
521
|
-
type: "turn-end",
|
|
522
|
-
text: last,
|
|
523
|
-
// A turn that asked the user ends on its tool call by design, not cut off
|
|
524
|
-
stopped:
|
|
525
|
-
!asked &&
|
|
526
|
-
(finish === "length" || finish === "error" || finish === "tool-calls"),
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
/** Rough token weight of a message list. The provider's own count wins when it reports one (prepareStep). */
|
|
531
|
-
function sizeOf(messages: ModelMessage[]): number {
|
|
532
|
-
return messages.reduce(
|
|
533
|
-
(sum, message) =>
|
|
534
|
-
sum +
|
|
535
|
-
estimateTokens(
|
|
536
|
-
typeof message.content === "string"
|
|
537
|
-
? message.content
|
|
538
|
-
: JSON.stringify(message.content),
|
|
539
|
-
) +
|
|
540
|
-
4,
|
|
541
|
-
0,
|
|
542
|
-
);
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
/** Instructions for compacting. The summary replaces everything above it, opening included, so it must restate the job. */
|
|
546
|
-
const compactInstructions = (
|
|
547
|
-
words: number,
|
|
548
|
-
) => `Compact your context. The first message above — who handed you the job, and the job — stays exactly as it is. Everything after it is replaced by what you write now, and you carry on from that first message and this alone; nothing else above can be read again. Write it for a fresh copy of you that has your tools, your instructions and that first message, but has seen none of the rest.
|
|
549
|
-
|
|
550
|
-
Cover all of it, and prefer a fact over a description of a fact:
|
|
551
|
-
|
|
552
|
-
- **Where the job stands against that first message.** Do not restate the job; say what has changed since — a choice made, a detail settled, an answer that came back, a correction, anything you are still waiting on.
|
|
553
|
-
- **What is already true.** Every value you have — numbers, names, dates, ids, urls, prices, times — written out, not referred to. A value you leave out is one the next steps go and fetch again.
|
|
554
|
-
- **Where you are.** Which page the browser is on by url, whether you are signed in and to what, what is running, what you were in the middle of. Element refs do not survive this: name what to look for, never a ref.
|
|
555
|
-
- **Files.** Every path you wrote or read, and one line on what each holds.
|
|
556
|
-
- **What did not work**, and why: the url that 404s, the endpoint that needs POST not GET, the selector that is not there, the site that refuses a headless browser, the argument a tool rejected. This is the part that stops the next steps repeating an hour of yours.
|
|
557
|
-
- **What is left**, in the order you would do it.
|
|
558
|
-
|
|
559
|
-
Plain text, under ${words} words. No preamble, no headings about the summary itself, no account of how you have been going.`;
|
|
560
|
-
|
|
561
|
-
/** Word cap for a summary, scaled to the budget it stands in for (config BOT_RUN.summaryWords). */
|
|
562
|
-
const summaryWords = (budget: number) => {
|
|
563
|
-
const { min, max, perTokens } = BOT_RUN.summaryWords;
|
|
564
|
-
return Math.min(max, Math.max(min, Math.round(budget / perTokens)));
|
|
565
|
-
};
|
|
566
|
-
|
|
567
|
-
/** Prefix of the summary that follows the first message after a compaction (and on a resume). */
|
|
568
|
-
const COMPACT_PREAMBLE =
|
|
569
|
-
"Everything between the first message and here was compacted. Below is your own summary of it; carry on from the first message and this.";
|
|
570
|
-
|
|
571
|
-
/** Heads the file list under a compaction summary (filesUnder). */
|
|
572
|
-
const FILES_HEAD =
|
|
573
|
-
"Files this job has on disk now — open one rather than fetching again what is in it:";
|
|
574
|
-
|
|
575
|
-
/**
|
|
576
|
-
* The files a job has on disk, as lines under its compaction summary. Read off the
|
|
577
|
-
* job's rows — every participant's `write_file` — and off its folder,
|
|
578
|
-
* never asked of the model: a path a summary leaves out is work the next steps redo.
|
|
579
|
-
* Without a thread, the run reads only the messages it is compacting.
|
|
580
|
-
* A listing that fails costs the list, never the compaction.
|
|
581
|
-
*/
|
|
582
|
-
async function filesUnder(
|
|
583
|
-
threadId: string | null,
|
|
584
|
-
messages: ModelMessage[],
|
|
585
|
-
folder: string | null,
|
|
586
|
-
): Promise<string> {
|
|
587
|
-
try {
|
|
588
|
-
const written = threadId
|
|
589
|
-
? await listWrittenPaths(threadId)
|
|
590
|
-
: writtenPathsIn(messages.map((message) => message.content));
|
|
591
|
-
const files = await filesOnDisk(written, folder);
|
|
592
|
-
if (!files.length) return "";
|
|
593
|
-
const shown = files.slice(-BOT_RUN.compactFiles);
|
|
594
|
-
const older = files.length - shown.length;
|
|
595
|
-
const lines = shown.map((path) => `- ${path}`);
|
|
596
|
-
if (older) lines.unshift(`- …and ${older} older ones`);
|
|
597
|
-
return `\n\n${FILES_HEAD}\n${lines.join("\n")}`;
|
|
598
|
-
} catch (cause) {
|
|
599
|
-
logger.warn("files under the summary could not be listed", cause);
|
|
600
|
-
return "";
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* The model summarizes its own context and continues from the summary. Tools
|
|
606
|
-
* are passed with calling off: providers refuse a history of tool calls
|
|
607
|
-
* without the tools that made them. The run's own instructions go too: the
|
|
608
|
-
* summary is written by the bot the transcript belongs to, and the provider's
|
|
609
|
-
* cached prefix, instructions first, still matches the run's. A context too
|
|
610
|
-
* long to summarise whole — the very thing a compaction is for — is tried once
|
|
611
|
-
* more without the tool calls and results but the last few. A failure throws
|
|
612
|
-
* with its cause kept. The room pauses for manual recovery; the transcript stays.
|
|
613
|
-
*/
|
|
614
|
-
async function compact(
|
|
615
|
-
model: LanguageModel,
|
|
616
|
-
tools: ToolSet,
|
|
617
|
-
messages: ModelMessage[],
|
|
618
|
-
options: { signal?: AbortSignal; budget: number; instructions: string },
|
|
619
|
-
): Promise<{ text: string; usage: TokenUsage }> {
|
|
620
|
-
let failure: unknown;
|
|
621
|
-
try {
|
|
622
|
-
return await summarize(model, tools, messages, options);
|
|
623
|
-
} catch (cause) {
|
|
624
|
-
if (options.signal?.aborted) throw cause;
|
|
625
|
-
failure = cause;
|
|
626
|
-
}
|
|
627
|
-
if (isContextOverflow(failure)) {
|
|
628
|
-
// Too long even to be summarised: asked once more of its words alone (ai/words), each
|
|
629
|
-
// step that only used a tool as the line the thread screen draws for it
|
|
630
|
-
const words = asWords(
|
|
631
|
-
messages,
|
|
632
|
-
(name, input) => `${name}: ${argumentLine(name, input)}`,
|
|
633
|
-
);
|
|
634
|
-
try {
|
|
635
|
-
return await summarize(model, tools, words, options);
|
|
636
|
-
} catch (cause) {
|
|
637
|
-
if (options.signal?.aborted) throw cause;
|
|
638
|
-
failure = cause;
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
throw new Error(
|
|
642
|
-
`Could not compact the context (${modelErrorToString(failure)}).`,
|
|
643
|
-
{ cause: failure },
|
|
644
|
-
);
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
/** One summarising call. Nothing streams back, so its whole length is one silence (config BOT_RUN.silenceMs). */
|
|
648
|
-
async function summarize(
|
|
649
|
-
model: LanguageModel,
|
|
650
|
-
tools: ToolSet,
|
|
651
|
-
messages: ModelMessage[],
|
|
652
|
-
options: { signal?: AbortSignal; budget: number; instructions: string },
|
|
653
|
-
): Promise<{ text: string; usage: TokenUsage }> {
|
|
654
|
-
const { text, usage } = await generateText({
|
|
655
|
-
model,
|
|
656
|
-
instructions: options.instructions,
|
|
657
|
-
tools,
|
|
658
|
-
toolChoice: "none",
|
|
659
|
-
messages: [
|
|
660
|
-
...messages,
|
|
661
|
-
{
|
|
662
|
-
role: "user",
|
|
663
|
-
content: compactInstructions(summaryWords(options.budget)),
|
|
664
|
-
},
|
|
665
|
-
],
|
|
666
|
-
abortSignal: options.signal,
|
|
667
|
-
timeout: BOT_RUN.silenceMs,
|
|
668
|
-
});
|
|
669
|
-
const summary = text.trim();
|
|
670
|
-
if (!summary) {
|
|
671
|
-
// A blank reply is the model's hiccup, not the job's. It carries no status, so it is
|
|
672
|
-
// not a refusal (ai/model isProviderRefusal) and the runner gives it one more try
|
|
673
|
-
throw new Error(
|
|
674
|
-
"The summary of the context came back empty, so there is nothing to carry on from.",
|
|
675
|
-
);
|
|
676
|
-
}
|
|
677
|
-
return { text: `${COMPACT_PREAMBLE}\n\n${summary}`, usage: usageOf(usage) };
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
/**
|
|
681
|
-
* A step's messages as the thread stores them. The sdk fills `response.messages` with what
|
|
682
|
-
* each tool sent the model — `toModelOutput` where a tool has one — so a tool answering with
|
|
683
|
-
* a picture writes its bytes into the row and carries them into every resume of that thread.
|
|
684
|
-
* Stored instead is what `execute` returned, which is also what a step is written as while it
|
|
685
|
-
* streams (bot.runner), so the two writes of one step agree. Tool errors are left as they came.
|
|
686
|
-
*/
|
|
687
|
-
function storedMessages(step: {
|
|
688
|
-
response: { messages: ModelMessage[] };
|
|
689
|
-
toolResults: Array<{ toolCallId: string; output: unknown }>;
|
|
690
|
-
}): ModelMessage[] {
|
|
691
|
-
if (!step.toolResults.length) return step.response.messages;
|
|
692
|
-
const executed = new Map(
|
|
693
|
-
step.toolResults.map((result) => [result.toolCallId, result.output]),
|
|
694
|
-
);
|
|
695
|
-
return step.response.messages.map((message) => {
|
|
696
|
-
if (message.role !== "tool") return message;
|
|
697
|
-
return {
|
|
698
|
-
...message,
|
|
699
|
-
content: message.content.map((part) => {
|
|
700
|
-
if (part.type !== "tool-result" || !executed.has(part.toolCallId))
|
|
701
|
-
return part;
|
|
702
|
-
const output = executed.get(part.toolCallId);
|
|
703
|
-
return {
|
|
704
|
-
...part,
|
|
705
|
-
output:
|
|
706
|
-
typeof output === "string"
|
|
707
|
-
? ({ type: "text", value: output } as const)
|
|
708
|
-
: ({ type: "json", value: output as never } as const),
|
|
709
|
-
};
|
|
710
|
-
}),
|
|
711
|
-
};
|
|
712
|
-
});
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
/** Step messages handed from `onStepEnd` to the loop. A take that arrives before the push waits. */
|
|
716
|
-
type FinishedStep = { messages: ModelMessage[]; usage: TokenUsage };
|
|
717
|
-
|
|
718
|
-
function stepQueue() {
|
|
719
|
-
const ready: FinishedStep[] = [];
|
|
720
|
-
const waiting: Array<(step: FinishedStep | null) => void> = [];
|
|
721
|
-
let ended = false;
|
|
722
|
-
return {
|
|
723
|
-
push(step: FinishedStep) {
|
|
724
|
-
const waiter = waiting.shift();
|
|
725
|
-
if (waiter) waiter(step);
|
|
726
|
-
else ready.push(step);
|
|
727
|
-
},
|
|
728
|
-
take(): Promise<FinishedStep | null> {
|
|
729
|
-
const next = ready.shift();
|
|
730
|
-
if (next) return Promise.resolve(next);
|
|
731
|
-
if (ended) return Promise.resolve(null);
|
|
732
|
-
return new Promise((resolve) => waiting.push(resolve));
|
|
733
|
-
},
|
|
734
|
-
/**
|
|
735
|
-
* No more steps are coming; release waiting takes with `null`. Without
|
|
736
|
-
* this, a `finish-step` whose `onStepEnd` never fires (abort, provider
|
|
737
|
-
* error mid-step) parks the loop forever, and `answerThread` waits on
|
|
738
|
-
* `run.done` while holding the job's lock (bot.runner).
|
|
739
|
-
*/
|
|
740
|
-
end() {
|
|
741
|
-
ended = true;
|
|
742
|
-
for (const waiter of waiting.splice(0)) waiter(null);
|
|
743
|
-
},
|
|
744
|
-
};
|
|
745
|
-
}
|
|
746
|
-
|
|
747
|
-
/**
|
|
748
|
-
* The clock behind `BOT_RUN.silenceMs`: aborts its signal once nothing has
|
|
749
|
-
* arrived for that long. Held while something other than the model does the
|
|
750
|
-
* work — a tool, a compaction — since those send nothing and bound themselves;
|
|
751
|
-
* `touch` starts it over. Not the sdk's `timeout.chunkMs`: that clock keeps
|
|
752
|
-
* running while tools execute, so a long command
|
|
753
|
-
* would trip it.
|
|
754
|
-
*/
|
|
755
|
-
function silenceWatch(ms: number) {
|
|
756
|
-
const stop = new AbortController();
|
|
757
|
-
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
758
|
-
let held = 0;
|
|
759
|
-
let ended = false;
|
|
760
|
-
const arm = () => {
|
|
761
|
-
clearTimeout(timer);
|
|
762
|
-
timer = undefined;
|
|
763
|
-
if (ended || held > 0) return;
|
|
764
|
-
timer = setTimeout(() => {
|
|
765
|
-
stop.abort(
|
|
766
|
-
new DOMException(
|
|
767
|
-
`The model sent nothing for ${Math.round(ms / 60_000)} minutes.`,
|
|
768
|
-
"TimeoutError",
|
|
769
|
-
),
|
|
770
|
-
);
|
|
771
|
-
}, ms);
|
|
772
|
-
};
|
|
773
|
-
return {
|
|
774
|
-
signal: stop.signal,
|
|
775
|
-
touch: arm,
|
|
776
|
-
hold: () => {
|
|
777
|
-
held += 1;
|
|
778
|
-
arm();
|
|
779
|
-
},
|
|
780
|
-
release: () => {
|
|
781
|
-
held = Math.max(0, held - 1);
|
|
782
|
-
arm();
|
|
783
|
-
},
|
|
784
|
-
/** The run is over; nothing is watched any more. */
|
|
785
|
-
end: () => {
|
|
786
|
-
ended = true;
|
|
787
|
-
arm();
|
|
788
|
-
},
|
|
789
|
-
};
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
/** The sdk gives undefined when unknown; 0 sums correctly. */
|
|
793
|
-
const usageOf = (usage: LanguageModelUsage): TokenUsage => ({
|
|
794
|
-
input: usage.inputTokens ?? 0,
|
|
795
|
-
output: usage.outputTokens ?? 0,
|
|
796
|
-
});
|
|
797
|
-
|
|
798
|
-
/** A bot with both model columns set uses them; otherwise the app default (resolveDefaultModel). */
|
|
799
|
-
function resolveModel(bot: JobBot) {
|
|
800
|
-
if (bot.provider && bot.model) {
|
|
801
|
-
return getTextModel({ provider: bot.provider, model: bot.model });
|
|
802
|
-
}
|
|
803
|
-
return resolveDefaultModel().then(getTextModel);
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
/** Build a valid model projection without changing the recorded interruption history. */
|
|
807
|
-
export function resumeTranscript(
|
|
808
|
-
transcript: ModelMessage[],
|
|
809
|
-
receipts: ReadonlyMap<string, { messageId: string; to: string }> = new Map(),
|
|
810
|
-
): ModelMessage[] {
|
|
811
|
-
type Result = Extract<
|
|
812
|
-
Extract<ModelMessage, { role: "tool" }>["content"][number],
|
|
813
|
-
{ type: "tool-result" }
|
|
814
|
-
>;
|
|
815
|
-
const results = new Map<string, Result>();
|
|
816
|
-
const embedded = new Set<string>();
|
|
817
|
-
for (const message of transcript) {
|
|
818
|
-
if (message.role !== "tool" && message.role !== "assistant") continue;
|
|
819
|
-
if (!Array.isArray(message.content)) continue;
|
|
820
|
-
for (const part of message.content) {
|
|
821
|
-
if (part.type !== "tool-result") continue;
|
|
822
|
-
if (!results.has(part.toolCallId)) results.set(part.toolCallId, part);
|
|
823
|
-
if (message.role === "assistant") embedded.add(part.toolCallId);
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
const out: ModelMessage[] = [];
|
|
827
|
-
const used = new Set<string>();
|
|
828
|
-
for (const message of transcript) {
|
|
829
|
-
if (message.role === "tool") {
|
|
830
|
-
const other = message.content.filter(
|
|
831
|
-
(part) => part.type !== "tool-result",
|
|
832
|
-
);
|
|
833
|
-
if (other.length) out.push({ ...message, content: other });
|
|
834
|
-
continue;
|
|
835
|
-
}
|
|
836
|
-
if (message.role !== "assistant" || typeof message.content === "string") {
|
|
837
|
-
out.push(message);
|
|
838
|
-
continue;
|
|
839
|
-
}
|
|
840
|
-
const owed: Result[] = [];
|
|
841
|
-
const content: typeof message.content = [];
|
|
842
|
-
for (const part of message.content) {
|
|
843
|
-
if (part.type !== "tool-call") {
|
|
844
|
-
content.push(part);
|
|
845
|
-
continue;
|
|
846
|
-
}
|
|
847
|
-
if (used.has(part.toolCallId)) continue;
|
|
848
|
-
let input = part.input;
|
|
849
|
-
if (typeof input === "string") {
|
|
850
|
-
try {
|
|
851
|
-
input = JSON.parse(input);
|
|
852
|
-
} catch {
|
|
853
|
-
input = undefined;
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
if (!part.toolCallId || input === undefined) {
|
|
857
|
-
content.push({
|
|
858
|
-
type: "text",
|
|
859
|
-
text: "A tool argument stream was interrupted before a complete call was recorded. Inspect the saved work before continuing.",
|
|
860
|
-
});
|
|
861
|
-
continue;
|
|
862
|
-
}
|
|
863
|
-
const receipt =
|
|
864
|
-
part.toolName === TOOL_NAMES.send_message
|
|
865
|
-
? receipts.get(part.toolCallId)
|
|
866
|
-
: undefined;
|
|
867
|
-
const result =
|
|
868
|
-
results.get(part.toolCallId) ??
|
|
869
|
-
(receipt
|
|
870
|
-
? {
|
|
871
|
-
type: "tool-result" as const,
|
|
872
|
-
toolCallId: part.toolCallId,
|
|
873
|
-
toolName: part.toolName,
|
|
874
|
-
output: { type: "json" as const, value: receipt },
|
|
875
|
-
}
|
|
876
|
-
: undefined);
|
|
877
|
-
if (
|
|
878
|
-
part.providerExecuted &&
|
|
879
|
-
(!result || !embedded.has(part.toolCallId))
|
|
880
|
-
) {
|
|
881
|
-
content.push({
|
|
882
|
-
type: "text",
|
|
883
|
-
text: result
|
|
884
|
-
? `The provider operation ${part.toolName} returned this data before its native continuation was interrupted: ${JSON.stringify(result.output)}`
|
|
885
|
-
: `The provider operation ${part.toolName} was interrupted without a recorded result. Its remote execution state is unknown.`,
|
|
886
|
-
});
|
|
887
|
-
continue;
|
|
888
|
-
}
|
|
889
|
-
used.add(part.toolCallId);
|
|
890
|
-
content.push({ ...part, input });
|
|
891
|
-
if (!embedded.has(part.toolCallId))
|
|
892
|
-
owed.push(
|
|
893
|
-
result ?? {
|
|
894
|
-
type: "tool-result",
|
|
895
|
-
toolCallId: part.toolCallId,
|
|
896
|
-
toolName: part.toolName,
|
|
897
|
-
output: {
|
|
898
|
-
type: "text",
|
|
899
|
-
value:
|
|
900
|
-
"No result: execution was interrupted before a result was recorded. The outcome is unknown. Inspect the current state before repeating the action.",
|
|
901
|
-
},
|
|
902
|
-
},
|
|
903
|
-
);
|
|
904
|
-
}
|
|
905
|
-
if (content.length) out.push({ ...message, content });
|
|
906
|
-
if (owed.length) out.push({ role: "tool", content: owed });
|
|
907
|
-
}
|
|
908
|
-
return out;
|
|
909
|
-
}
|