thursday-agent 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +5 -2
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +5 -5
- package/.next/routes-manifest.json +24 -6
- package/.next/server/app/_global-error/page.js +2 -2
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +2 -2
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +2 -2
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +14 -14
- package/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/artifact/route.js +3 -3
- package/.next/server/app/api/artifact/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/files/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/bot/memory/files/route.js +10 -0
- package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -0
- package/.next/server/app/api/bot/memory/files/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/bot/memory/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/bot/memory/route.js +14 -0
- package/.next/server/app/api/bot/{notes → memory}/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/bot/route.js +6 -6
- package/.next/server/app/api/bot/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/task/[id]/route.js +8 -8
- package/.next/server/app/api/bot/task/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/task/route.js +8 -8
- package/.next/server/app/api/bot/task/route.js.nft.json +1 -1
- package/.next/server/app/api/config/route.js +5 -5
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/events/route.js +4 -5
- package/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/server/app/api/file/[...path]/route.js +3 -3
- package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/catalog/route.js +9 -8
- package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/credits/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/llm-model/credits/route/build-manifest.json +12 -0
- package/.next/server/app/api/llm-model/credits/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/llm-model/credits/route.js +16 -0
- package/.next/server/app/api/llm-model/credits/route.js.map +5 -0
- package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -0
- package/.next/server/app/api/llm-model/credits/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/llm-model/route.js +10 -8
- package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/subscription/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/llm-model/subscription/route/build-manifest.json +12 -0
- package/.next/server/app/api/llm-model/subscription/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/llm-model/subscription/route.js +15 -0
- package/.next/server/app/api/llm-model/subscription/route.js.map +5 -0
- package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -0
- package/.next/server/app/api/llm-model/subscription/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/mcp/[name]/route.js +4 -4
- package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth/callback/route.js +5 -5
- package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js +4 -4
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/tools/route.js +4 -4
- package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/edit/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/memory/edit/route/build-manifest.json +12 -0
- package/.next/server/app/api/memory/edit/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/memory/edit/route.js +24 -0
- package/.next/server/app/api/memory/edit/route.js.map +5 -0
- package/.next/server/app/api/memory/edit/route.js.nft.json +1 -0
- package/.next/server/app/api/memory/{tidy → edit}/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/memory/route.js +6 -7
- package/.next/server/app/api/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[source]/[name]/route.js +3 -3
- package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js +3 -3
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/call/route.js +9 -7
- package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/skills/route.js +9 -7
- package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/tool-call/route.js +17 -15
- package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/route.js +4 -5
- package/.next/server/app/api/workspace/route.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +1 -1
- package/.next/server/app/artifact/[...path]/page.js +5 -6
- package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/favicon.ico/route.js +3 -4
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/server/app/favicon.ico.body +0 -0
- package/.next/server/app/page/server-reference-manifest.json +57 -90
- package/.next/server/app/page.js +10 -10
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +5 -2
- package/.next/server/chunks/[externals]__0dzuk6_._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__01dkp4a._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__02xjoto._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__04q--0f._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0bl-e63._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0ce8nf8._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__0ffbg85._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0j7z0r3._.js +12 -0
- package/.next/server/chunks/[root-of-the-server]__0jq4ohy._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0ls6_8y._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0ncs9uu._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0pa2n68._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0q0vvt2._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1-ga0kh._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__11n256_._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__12cabg9._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1339jnv._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__15bjnu5._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__18_teo8._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1anc1p9._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1ccon1w._.js +5 -5
- package/.next/server/chunks/[root-of-the-server]__1fizn31._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1llj3-b._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +11 -0
- package/.next/server/chunks/[root-of-the-server]__1p8m3f4._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1wa1k7r._.js +8 -0
- package/.next/server/chunks/_0-73of8._.js +5 -5
- package/.next/server/chunks/_0-fjql4._.js +26 -0
- package/.next/server/chunks/_00xh_q0._.js +27 -0
- package/.next/server/chunks/{_0pppbb5._.js → _03kp0jp._.js} +163 -36
- package/.next/server/chunks/_051qh8u._.js +3 -0
- package/.next/server/chunks/{node_modules_next_04q-o58._.js → _05dla15._.js} +2 -2
- package/.next/server/chunks/_05h2cii._.js +1 -1
- package/.next/server/chunks/_0c9j6rb._.js +49 -0
- package/.next/server/chunks/_0fzqt2y._.js +130 -0
- package/.next/server/chunks/{_0vnutv9._.js → _0ioz3nd._.js} +1 -1
- package/.next/server/chunks/_0iwfby5._.js +3 -0
- package/.next/server/chunks/_0mecv0f._.js +26 -0
- package/.next/server/chunks/_0mh8j4m._.js +3 -0
- package/.next/server/chunks/_0n74zsf._.js +4 -4
- package/.next/server/chunks/_0obojvv._.js +3 -0
- package/.next/server/chunks/_0recufk._.js +49 -0
- package/.next/server/chunks/_0rnf-6n._.js +4 -4
- package/.next/server/chunks/_0sb7tlz._.js +3 -0
- package/.next/server/chunks/_0u10wmw._.js +5 -5
- package/.next/server/chunks/_0u4aiy2._.js +3 -0
- package/.next/server/chunks/_0wp4le3._.js +1 -1
- package/.next/server/chunks/_0y5fg-x._.js +1 -1
- package/.next/server/chunks/_1230wbx._.js +10 -0
- package/.next/server/chunks/_12nheja._.js +3 -0
- package/.next/server/chunks/_13510xh._.js +3 -0
- package/.next/server/chunks/_15hq89o._.js +1 -1
- package/.next/server/chunks/_17l5ygt._.js +49 -0
- package/.next/server/chunks/_18-1wcc._.js +5 -5
- package/.next/server/chunks/_1_5mnq4._.js +4 -4
- package/.next/server/chunks/_1_9mjx-._.js +3 -0
- package/.next/server/chunks/_1d0j961._.js +6 -0
- package/.next/server/chunks/_1d5zmy8._.js +1 -1
- package/.next/server/chunks/_1drgfx4._.js +4 -4
- package/.next/server/chunks/_1f46eie._.js +3 -0
- package/.next/server/chunks/_1h5_8sk._.js +3 -0
- package/.next/server/chunks/_1hdnxb7._.js +3 -0
- package/.next/server/chunks/_1j8k_j5._.js +3 -0
- package/.next/server/chunks/_1krd9rf._.js +3 -0
- package/.next/server/chunks/_1nc0eui._.js +11 -0
- package/.next/server/chunks/_1nula3v._.js +3 -0
- package/.next/server/chunks/_1pf4qe-._.js +3 -0
- package/.next/server/chunks/_1php4eq._.js +1 -1
- package/.next/server/chunks/_1qxheoa._.js +3 -0
- package/.next/server/chunks/_1x6kd1r._.js +3 -0
- package/.next/server/chunks/_1yuv4vp._.js +1 -1
- package/.next/server/chunks/_1zjrdag._.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_bot_memory_files_route_actions_1_xd_8f.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_bot_memory_route_actions_1a8xfr7.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_llm-model_credits_route_actions_0v424pb.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_llm-model_subscription_route_actions_0-udcm5.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_memory_edit_route_actions_02sfnmr.js +3 -0
- package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
- package/.next/server/chunks/features_0rpfxbk._.js +3 -0
- package/.next/server/chunks/features_1qf3cei._.js +3 -0
- package/.next/server/chunks/features_bot_0zt92oh._.js +3 -0
- package/.next/server/chunks/features_bot_bot_query_ts_12mgkl2._.js +3 -0
- package/.next/server/chunks/features_memory_1uqvksn._.js +6 -0
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0a1rd09._.js → node_modules_consola_dist_chunks_prompt_mjs_0i7cvml._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_06067w6._.js → node_modules_consola_dist_chunks_prompt_mjs_0icqaqw._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_096ais_._.js → node_modules_consola_dist_chunks_prompt_mjs_0r28-sm._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_02s3hjt._.js → node_modules_consola_dist_chunks_prompt_mjs_0v_7drq._.js} +1 -1
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1xoq2rl._.js +3 -0
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0tvkfgh._.js → node_modules_consola_dist_chunks_prompt_mjs_1y49572._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__09q9med._.js +1 -1
- package/.next/server/chunks/ssr/{[root-of-the-server]__1qfqvmg._.js → [root-of-the-server]__0_69wqr._.js} +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__0hg5gib._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0i8ie7f._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__0jsmmb-._.js → [root-of-the-server]__0mz33a7._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0tbkdlx._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0vnmv-s._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__0f6s48x._.js → [root-of-the-server]__0xpcv9w._.js} +3 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0xtssj3._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0zkv7z_._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +57 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__15_uhip._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__16jc196._.js +1 -1
- package/.next/server/chunks/ssr/{[root-of-the-server]__0m1b5ky._.js → [root-of-the-server]__1cyjywu._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1eh7hid._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1gtlw6v._.js +43 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1ox7hbk._.js +4 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1pduf5n._.js +3 -0
- package/.next/server/chunks/ssr/{_1mznrxk._.js → _001_ms1._.js} +3 -3
- package/.next/server/chunks/ssr/_01_6m32._.js +3 -0
- package/.next/server/chunks/ssr/_01n3o0m._.js +3 -0
- package/.next/server/chunks/ssr/_07uchnc._.js +3 -0
- package/.next/server/chunks/ssr/_0ap2fzn._.js +3 -0
- package/.next/server/chunks/ssr/_0c-ql2m._.js +3 -0
- package/.next/server/chunks/ssr/_0h42fze._.js +3 -0
- package/.next/server/chunks/ssr/_0h7zdni._.js +1 -1
- package/.next/server/chunks/ssr/_0i_6q1w._.js +41 -0
- package/.next/server/chunks/ssr/_0kbkmar._.js +3 -0
- package/.next/server/chunks/ssr/{_077-g6s._.js → _0mb8zc8._.js} +3 -3
- package/.next/server/chunks/ssr/_0mo2w06._.js +3 -0
- package/.next/server/chunks/ssr/{_13punpm._.js → _0q0zan6._.js} +2 -2
- package/.next/server/chunks/ssr/{_040sk32._.js → _0u2jv_x._.js} +76 -82
- package/.next/server/chunks/ssr/_0y0tiht._.js +4 -0
- package/.next/server/chunks/ssr/_0zhoc3r._.js +3 -0
- package/.next/server/chunks/ssr/_1-teee5._.js +3 -3
- package/.next/server/chunks/ssr/_13fke0x._.js +3 -0
- package/.next/server/chunks/ssr/{_1lip4th._.js → _13z3f85._.js} +2 -2
- package/.next/server/chunks/ssr/_14_lw10._.js +3 -0
- package/.next/server/chunks/ssr/_15j2_8f._.js +3 -0
- package/.next/server/chunks/ssr/{_09ja_w1._.js → _1eoqg_g._.js} +2 -2
- package/.next/server/chunks/ssr/_1sji22n._.js +3 -0
- package/.next/server/chunks/ssr/_1spzm8z._.js +3 -0
- package/.next/server/chunks/ssr/{_0x_nu5e._.js → _1vi_uo7._.js} +2 -2
- package/.next/server/chunks/ssr/_1vyd1ji._.js +1 -1
- package/.next/server/chunks/ssr/{_1m3bsfr._.js → _1xvgn77._.js} +2 -2
- package/.next/server/chunks/ssr/_20kd_n0._.js +42 -0
- package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +3 -0
- package/.next/server/chunks/ssr/features_config_components_config-setting_tsx_0xfwqdg._.js +1 -1
- package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
- package/.next/server/chunks/ssr/lib_date-like_ts_02is0pw._.js +3 -0
- package/.next/server/chunks/ssr/{node_modules_18_dk7_._.js → node_modules_063xwpp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_01qnv-a._.js → node_modules_0bvraul._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0n1kj4p._.js → node_modules_0eu1va6._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0kl7-tn._.js → node_modules_0h50b8n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0_n241r._.js → node_modules_0h5hnr1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0lrjk5t._.js → node_modules_0h7u60n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0ndvxub._.js → node_modules_0lm7_vm._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_13r44jq._.js → node_modules_0mwym0g._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_17lrt3y._.js → node_modules_0rjg6t1._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_0x3-ply._.js +3 -0
- package/.next/server/chunks/ssr/{node_modules_004qlr4._.js → node_modules_0y_cded._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0kxz4gt._.js → node_modules_0z5tsu8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0iz1rzd._.js → node_modules_0zp9r92._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_19dp7ko._.js → node_modules_1-hc6uv._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1q0p85z._.js → node_modules_113tz0l._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1toafc-._.js → node_modules_124bue5._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_17bwo43._.js +55 -0
- package/.next/server/chunks/ssr/{node_modules_08d8bke._.js → node_modules_1_n3ztw._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1dwguw_._.js → node_modules_1bc7gu8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_20yebtj._.js → node_modules_1bgb6-f._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1n5ygqe._.js → node_modules_1h4a4pp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_04n7mjs._.js → node_modules_1i7u1ia._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1hn8z1f._.js → node_modules_1juq3hs._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1xyd7ov._.js → node_modules_1l0qtdu._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0m93zeg._.js → node_modules_1t9cyee._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_09xhur7._.js → node_modules_1uuj9x1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1hd-5tv._.js → node_modules_1vqb6po._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1zu988w._.js → node_modules_1xx28h1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0m9a4y0._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0d3skpl._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_13w_wy9._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0i44kk5._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_@vercel_oidc_dist_0qe30a_._.js +3 -0
- package/.next/server/chunks/ssr/{node_modules_next_dist_0w6mzq5._.js → node_modules_next_dist_0drixxt._.js} +4 -4
- package/.next/server/chunks/ssr/node_modules_next_dist_1n3w9lb._.js +2 -2
- package/.next/server/instrumentation.js +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +58 -91
- package/.next/static/chunks/{31ttnjt6g35a0.js → 0ev4hyghq0mbb.js} +1 -1
- package/.next/static/chunks/0r5qcctujhxli.js +1 -0
- package/.next/static/chunks/0tmgrnlje14-s.js +3 -0
- package/.next/static/chunks/0x79tx04dxbpp.js +1 -0
- package/.next/static/chunks/0xzgvc0fkdb6t.js +1 -0
- package/.next/static/chunks/10teww7wt-f6h.js +1 -0
- package/.next/static/chunks/14hgtsjg-kael.css +1 -0
- package/.next/static/chunks/17donp69y4do7.js +40 -0
- package/.next/static/chunks/{3_h9txt3tq8t8.js → 1dkjg87pxk0n9.js} +1 -1
- package/.next/static/chunks/1ekc7ul556kbl.js +1 -0
- package/.next/static/chunks/{3ard_noqapnw1.js → 1grhjo7a5a0_-.js} +1 -1
- package/.next/static/chunks/1kq8h8wi_e0bc.js +53 -0
- package/.next/static/chunks/1okqiww3pnwka.js +1 -0
- package/.next/static/chunks/26-pr2c9ro222.js +1 -0
- package/.next/static/chunks/{18vhba44l1fc9.js → 280t0_e99i276.js} +1 -1
- package/.next/static/chunks/28cizcdaabd4h.js +1 -0
- package/.next/static/chunks/2a0k6jlq0_v1u.js +2 -0
- package/.next/static/chunks/2fzs9fm8yarvq.js +1 -0
- package/.next/static/chunks/2h0sd2vumhb15.js +1 -0
- package/.next/static/chunks/2hw2f6zmt7fmt.js +1 -0
- package/.next/static/chunks/2t4vhi3m8ahya.js +1 -0
- package/.next/static/chunks/2tigdtz3dpcy8.js +1 -0
- package/.next/static/chunks/3111pj5wnjgos.js +1 -0
- package/.next/static/chunks/{07kl352c-lvcz.js → 3agpgkwaa321p.js} +1 -1
- package/.next/static/chunks/3cfi_q6d_wtci.js +1 -0
- package/.next/static/chunks/3ok9_x74rip3v.js +1 -0
- package/.next/static/chunks/3xk7yqgomx7yq.js +1 -0
- package/.next/static/chunks/3xpbkl66ssib5.js +38 -0
- package/.next/static/media/favicon.37o1pjldwi2uc.ico +0 -0
- package/README.md +6 -4
- package/app/api/bot/memory/files/route.ts +14 -0
- package/app/api/bot/memory/route.ts +5 -0
- package/app/api/events/app-event.ts +3 -5
- package/app/api/llm-model/credits/route.ts +11 -0
- package/app/api/llm-model/route.ts +6 -1
- package/app/api/llm-model/subscription/route.ts +11 -0
- package/app/api/memory/edit/route.ts +7 -0
- package/app/api/memory/route.ts +21 -0
- package/app/api/query-key.ts +19 -4
- package/bin/thursday.mjs +3 -0
- package/components/ui/shiny-text.tsx +48 -134
- package/database/migrations/{20260909060813_optimal_sabretooth → 20260910173049_numerous_spirit}/migration.sql +24 -34
- package/database/migrations/{20260909060813_optimal_sabretooth → 20260910173049_numerous_spirit}/snapshot.json +71 -145
- package/database/migrations/20260911030320_opposite_jack_power/migration.sql +1 -0
- package/database/migrations/{20260909063821_bitter_tenebrous → 20260911030320_opposite_jack_power}/snapshot.json +57 -184
- package/features/ai/chatgpt.ts +617 -0
- package/features/ai/components/chatgpt-sign-in.tsx +66 -0
- package/features/ai/components/model-picker.tsx +17 -1
- package/features/ai/components/provider-icon.tsx +1 -0
- package/features/ai/load-tools.ts +58 -42
- package/features/ai/model.schema.ts +232 -34
- package/features/ai/model.ts +169 -24
- package/features/ai/prompts/bot.prompt.ts +156 -65
- package/features/ai/prompts/memory-edit.prompt.ts +33 -0
- package/features/ai/prompts/prompt-helper.ts +45 -26
- package/features/ai/prompts/thursday.prompt.ts +40 -17
- package/features/ai/tools/bot.tool.ts +35 -52
- package/features/ai/tools/connected.ts +17 -4
- package/features/ai/tools/memory.tool.ts +133 -72
- package/features/ai/tools/search.tool.ts +136 -47
- package/features/ai/tools/tool-name.ts +2 -5
- package/features/ai/tools/workspace.tool.ts +2 -1
- package/features/bot/bot.action.ts +8 -18
- package/features/bot/bot.memory.ts +89 -0
- package/features/bot/bot.query.ts +37 -57
- package/features/bot/bot.run.ts +507 -241
- package/features/bot/bot.runner.ts +410 -114
- package/features/bot/bot.schema.ts +79 -19
- package/features/bot/bot.seed.ts +89 -16
- package/features/bot/components/bot-mark.tsx +122 -20
- package/features/bot/components/bot-room.tsx +159 -130
- package/features/bot/components/bot-setting.tsx +790 -402
- package/features/bot/components/bot-tool.tsx +2 -6
- package/features/bot/components/mark-palette.tsx +54 -0
- package/features/bot/components/path-chips.tsx +1 -1
- package/features/bot/components/task-badge.tsx +26 -6
- package/features/bot/components/task-reply.tsx +22 -33
- package/features/bot/components/task-setting.tsx +20 -17
- package/features/bot/task.query.ts +215 -28
- package/features/bot/task.store.ts +53 -9
- package/features/config/components/config-setting.tsx +265 -34
- package/features/config/components/models-badge.tsx +42 -0
- package/features/config/config.action.ts +12 -0
- package/features/config/config.const.ts +38 -2
- package/features/connectors/mcp.manager.ts +10 -2
- package/features/intro/components/intro.tsx +47 -46
- package/features/memory/components/memory-edit.tsx +338 -0
- package/features/memory/components/memory-setting.tsx +75 -77
- package/features/memory/memory.action.ts +3 -43
- package/features/memory/memory.edit.ts +87 -0
- package/features/memory/memory.query.ts +24 -42
- package/features/memory/memory.schema.ts +29 -106
- package/features/settings/components/settings.tsx +2 -0
- package/features/settings/settings.alert.ts +3 -1
- package/features/thursday/components/ascii-orb.tsx +106 -90
- package/features/thursday/components/boot.tsx +7 -0
- package/features/thursday/components/call-log.tsx +219 -92
- package/features/thursday/components/face.tsx +6 -4
- package/features/thursday/components/tab-state.tsx +97 -0
- package/features/thursday/components/thursday-mark.tsx +4 -1
- package/features/thursday/components/thursday-setting.tsx +17 -47
- package/features/thursday/components/thursday.tsx +208 -95
- package/features/thursday/thursday.action.ts +12 -17
- package/features/thursday/thursday.query.ts +61 -70
- package/features/thursday/thursday.schema.ts +20 -7
- package/features/thursday/tool-line.ts +85 -11
- package/features/thursday/use-thursday.ts +86 -59
- package/features/workspace/components/file-view.tsx +4 -2
- package/features/workspace/workspace.ts +110 -26
- package/lib/limits.ts +1 -1
- package/lib/oauth-page.ts +27 -0
- package/lib/realtime/openai.ts +2 -2
- package/lib/realtime/realtime.protocol.ts +1 -1
- package/lib/realtime/realtime.tap.ts +122 -0
- package/lib/sandbox.ts +59 -36
- package/package.json +1 -1
- package/skills/browser/SKILL.md +55 -34
- package/.next/server/app/api/bot/notes/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/bot/notes/route.js +0 -14
- package/.next/server/app/api/bot/notes/route_client-reference-manifest.js +0 -3
- package/.next/server/app/api/memory/tidy/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/memory/tidy/route.js +0 -22
- package/.next/server/app/api/memory/tidy/route.js.nft.json +0 -1
- package/.next/server/chunks/0d-b_next_dist_server_app-render_after-task-async-storage_external_0-exn7p.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0-npkh_._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__005var5._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__019dx9f._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__02_2sm-._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__04_8spk._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__05luceg._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__06t77t4._.js +0 -11
- package/.next/server/chunks/[root-of-the-server]__0bed6hu._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0cro2dz._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0dupqt7._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0emr6go._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0le4d-p._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0m8ywyo._.js +0 -10
- package/.next/server/chunks/[root-of-the-server]__0nfuugi._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0p32jfz._.js +0 -12
- package/.next/server/chunks/[root-of-the-server]__0phdgco._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0wvgrsl._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__10qshki._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__11j52t0._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1692zrv._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__16thabu._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__173nhwf._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1_aoyr9._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1bn73ih._.js +0 -10
- package/.next/server/chunks/[root-of-the-server]__1bqhuh9._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1cqizfq._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1e-ci13._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1fboj2j._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1lr7j9t._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1oli73c._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1txedx6._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1untqv8._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1zgpz1w._.js +0 -3
- package/.next/server/chunks/_00_584r._.js +0 -293
- package/.next/server/chunks/_012yhfm._.js +0 -39
- package/.next/server/chunks/_06mxlgn._.js +0 -3
- package/.next/server/chunks/_07rtlxv._.js +0 -3
- package/.next/server/chunks/_0a351g7._.js +0 -6
- package/.next/server/chunks/_0kjjmag._.js +0 -3
- package/.next/server/chunks/_0nn99o2._.js +0 -3
- package/.next/server/chunks/_0zuzmt_._.js +0 -39
- package/.next/server/chunks/_106co2o._.js +0 -3
- package/.next/server/chunks/_12bbv5i._.js +0 -100
- package/.next/server/chunks/_15q1pig._.js +0 -3
- package/.next/server/chunks/_19wg5yn._.js +0 -138
- package/.next/server/chunks/_1bt95p9._.js +0 -55
- package/.next/server/chunks/_1cbk7ms._.js +0 -26
- package/.next/server/chunks/_1drv2et._.js +0 -40
- package/.next/server/chunks/_1ic3bew._.js +0 -5
- package/.next/server/chunks/_1mxn_lb._.js +0 -3
- package/.next/server/chunks/_1rysr-r._.js +0 -10
- package/.next/server/chunks/_1u3rwbr._.js +0 -3
- package/.next/server/chunks/_1x7p319._.js +0 -6
- package/.next/server/chunks/_next-internal_server_app_api_bot_notes_route_actions_0qcsyu7.js +0 -3
- package/.next/server/chunks/_next-internal_server_app_api_memory_tidy_route_actions_0_cfuom.js +0 -3
- package/.next/server/chunks/features_bot_task_query_ts_11xuzl3._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0gzvgfv._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0vorg6w._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1tpvamf._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1vmaq9f._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1y9-wcr._.js +0 -3
- package/.next/server/chunks/ssr/[externals]_node_crypto_1kn79-7._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0iuoa-r._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0un-erv._.js +0 -4
- package/.next/server/chunks/ssr/[root-of-the-server]__1-mnhyd._.js +0 -92
- package/.next/server/chunks/ssr/[root-of-the-server]__1bww500._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1vcdast._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1xwnu-h._.js +0 -3
- package/.next/server/chunks/ssr/_0-mc7ro._.js +0 -3
- package/.next/server/chunks/ssr/_01p5r6-._.js +0 -3
- package/.next/server/chunks/ssr/_03webdr._.js +0 -3
- package/.next/server/chunks/ssr/_09-0k3z._.js +0 -3
- package/.next/server/chunks/ssr/_0f_b_9s._.js +0 -3
- package/.next/server/chunks/ssr/_0fafgvl._.js +0 -3
- package/.next/server/chunks/ssr/_0sf1isi._.js +0 -3
- package/.next/server/chunks/ssr/_0su6_08._.js +0 -3
- package/.next/server/chunks/ssr/_0ti51xc._.js +0 -3
- package/.next/server/chunks/ssr/_0w5bgak._.js +0 -3
- package/.next/server/chunks/ssr/_0y84qo6._.js +0 -3
- package/.next/server/chunks/ssr/_1ciyoo3._.js +0 -3
- package/.next/server/chunks/ssr/_1e-dgz0._.js +0 -4
- package/.next/server/chunks/ssr/_1fq7zgb._.js +0 -3
- package/.next/server/chunks/ssr/_1g6l4uj._.js +0 -3
- package/.next/server/chunks/ssr/_1ruzehw._.js +0 -3
- package/.next/server/chunks/ssr/features_bot_components_bot-setting_tsx_01ajft6._.js +0 -4
- package/.next/server/chunks/ssr/features_config_components_14jqgy4._.js +0 -3
- package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +0 -4
- package/.next/server/chunks/ssr/node_modules_zod_v4_classic_external_15fmmz3.js +0 -55
- package/.next/static/chunks/05b6nx_o3_f_n.js +0 -1
- package/.next/static/chunks/0dmns-gi0raa4.js +0 -1
- package/.next/static/chunks/0f9sq-7q_yxyl.js +0 -1
- package/.next/static/chunks/0oc4_xoia77dg.css +0 -1
- package/.next/static/chunks/0pheo8m3a-rzi.js +0 -1
- package/.next/static/chunks/19i8h2t-5evjx.js +0 -1
- package/.next/static/chunks/1c5fcj473025q.js +0 -1
- package/.next/static/chunks/1pi_hbmjw-f-z.js +0 -1
- package/.next/static/chunks/1twt6k09vg4np.js +0 -1
- package/.next/static/chunks/1ytnip8wdng93.js +0 -1
- package/.next/static/chunks/28gotuisldmom.js +0 -1
- package/.next/static/chunks/2998p0y7k1c8z.js +0 -3
- package/.next/static/chunks/29gyb3nubj51j.js +0 -53
- package/.next/static/chunks/2l233xfycjpd8.js +0 -1
- package/.next/static/chunks/2p5n7pa3c40t-.js +0 -2
- package/.next/static/chunks/2ru1q132af7h7.js +0 -1
- package/.next/static/chunks/2t8wqycwg3y04.js +0 -2
- package/.next/static/chunks/2uxum7qbyeyxd.js +0 -1
- package/.next/static/chunks/32z_ypgtchw48.js +0 -1
- package/.next/static/chunks/33pyjb3xd1iez.js +0 -1
- package/.next/static/chunks/3omud5xunrk1f.js +0 -1
- package/.next/static/chunks/42dnrkbph9e-1.js +0 -1
- package/.next/static/media/favicon.2vob68tjqpejf.ico +0 -0
- package/database/migrations/20260909063821_bitter_tenebrous/migration.sql +0 -1
- package/features/ai/prompts/memory-tidy.prompt.ts +0 -129
- package/features/ai/tools/tidy.tool.ts +0 -22
- package/features/bot/bot.notes.ts +0 -120
- package/features/memory/components/memory-tidy.tsx +0 -395
- package/features/memory/memory.tidy.ts +0 -332
- package/features/memory/tidy.query.ts +0 -135
- package/features/thursday/use-call-title.ts +0 -31
- /package/.next/server/app/api/bot/{notes → memory/files}/route/build-manifest.json +0 -0
- /package/.next/server/app/api/bot/{notes → memory/files}/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/bot/{notes → memory/files}/route.js.map +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory}/route/build-manifest.json +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory}/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory}/route.js.map +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → x1cCqY0kWpR_VcYx_lWO5}/_buildManifest.js +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → x1cCqY0kWpR_VcYx_lWO5}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → x1cCqY0kWpR_VcYx_lWO5}/_ssgManifest.js +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import { formatDistanceToNowStrict } from "date-fns";
|
|
3
4
|
import {
|
|
4
5
|
AudioLines,
|
|
5
6
|
Captions,
|
|
@@ -7,7 +8,9 @@ import {
|
|
|
7
8
|
ChevronRight,
|
|
8
9
|
Clapperboard,
|
|
9
10
|
Image as ImageIcon,
|
|
11
|
+
KeyRound,
|
|
10
12
|
type LucideIcon,
|
|
13
|
+
Search,
|
|
11
14
|
TriangleAlert,
|
|
12
15
|
} from "lucide-react";
|
|
13
16
|
import { useState } from "react";
|
|
@@ -15,12 +18,17 @@ import { queryKey } from "@/app/api/query-key";
|
|
|
15
18
|
import { Button } from "@/components/ui/button";
|
|
16
19
|
import { Input } from "@/components/ui/input";
|
|
17
20
|
import { notify } from "@/components/ui/notify";
|
|
21
|
+
import { Skeleton } from "@/components/ui/skeleton";
|
|
22
|
+
import { ChatGptSignIn } from "@/features/ai/components/chatgpt-sign-in";
|
|
18
23
|
import { ModelPicker } from "@/features/ai/components/model-picker";
|
|
19
24
|
import { ProviderIcon } from "@/features/ai/components/provider-icon";
|
|
20
25
|
import {
|
|
26
|
+
type AiProvider,
|
|
27
|
+
type GatewayCredits,
|
|
21
28
|
type MediaKind,
|
|
22
29
|
parseMediaModel,
|
|
23
30
|
parseTextModel,
|
|
31
|
+
type SubscriptionUsage,
|
|
24
32
|
type TextModelProviderId,
|
|
25
33
|
} from "@/features/ai/model.schema";
|
|
26
34
|
import { BotsMark } from "@/features/bot/components/bot-mark";
|
|
@@ -34,6 +42,7 @@ import {
|
|
|
34
42
|
type ConfigEntry,
|
|
35
43
|
type ConfigGroup,
|
|
36
44
|
type ConfigStatus,
|
|
45
|
+
EXA_API_KEY,
|
|
37
46
|
groupSatisfied,
|
|
38
47
|
isConfigSet,
|
|
39
48
|
} from "@/features/config/config.const";
|
|
@@ -43,6 +52,7 @@ import {
|
|
|
43
52
|
SettingError,
|
|
44
53
|
SettingGroup,
|
|
45
54
|
SettingItems,
|
|
55
|
+
SettingNote,
|
|
46
56
|
SettingRailNote,
|
|
47
57
|
SettingScreen,
|
|
48
58
|
SettingSkeleton,
|
|
@@ -56,6 +66,9 @@ export function ConfigSetting() {
|
|
|
56
66
|
return <ConfigGroups section="keys" />;
|
|
57
67
|
}
|
|
58
68
|
|
|
69
|
+
/** A key that is not a provider's still wears a mark, or its row is a hole in the column. */
|
|
70
|
+
const KEY_MARKS: Record<string, LucideIcon> = { [EXA_API_KEY]: Search };
|
|
71
|
+
|
|
59
72
|
/** One mark per studio kind, drawn as the output (transcription is captions, not a mic). */
|
|
60
73
|
const KIND_MARKS: Record<MediaKind, LucideIcon> = {
|
|
61
74
|
image: ImageIcon,
|
|
@@ -175,46 +188,164 @@ function KeyRow({
|
|
|
175
188
|
/** Its group must have a key and has none, so this row is waiting on the user. */
|
|
176
189
|
needed: boolean;
|
|
177
190
|
}) {
|
|
191
|
+
const credits = useGatewayCredits(entry, set);
|
|
192
|
+
const usage = useSubscriptionUsage(entry, set);
|
|
193
|
+
const plan = useSignInPlan(entry, set);
|
|
194
|
+
const state = usage.data
|
|
195
|
+
? usageState(usage.data)
|
|
196
|
+
: keyState(set, needed, credits.data, entry.signIn);
|
|
197
|
+
|
|
178
198
|
return (
|
|
179
199
|
<button
|
|
180
200
|
type="button"
|
|
181
|
-
onClick={() =>
|
|
201
|
+
onClick={() =>
|
|
202
|
+
entry.signIn ? openSignInDialog(entry) : openConfigDialog(entry, set)
|
|
203
|
+
}
|
|
182
204
|
className="group flex w-full items-center gap-3 p-4 text-left outline-none transition-colors hover:bg-muted/50 focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:ring-inset"
|
|
183
205
|
>
|
|
184
|
-
|
|
185
|
-
<
|
|
186
|
-
|
|
187
|
-
</span>
|
|
188
|
-
)}
|
|
206
|
+
<span className="grid size-8 shrink-0 place-items-center rounded-lg bg-muted/60">
|
|
207
|
+
<KeyMark entry={entry} />
|
|
208
|
+
</span>
|
|
189
209
|
<span className="min-w-0 flex-1 space-y-0.5">
|
|
190
210
|
<span className="block truncate text-sm font-medium">
|
|
191
211
|
{entry.label}
|
|
192
212
|
</span>
|
|
193
213
|
<span className="block truncate font-mono text-xs text-muted-foreground">
|
|
194
|
-
{
|
|
214
|
+
{/* A sign-in's config key is nothing to read; the plan it is on is */}
|
|
215
|
+
{entry.signIn
|
|
216
|
+
? set
|
|
217
|
+
? usageLine(usage.data, plan)
|
|
218
|
+
: "sign in with your account"
|
|
219
|
+
: entry.key}
|
|
195
220
|
</span>
|
|
196
221
|
</span>
|
|
197
222
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
223
|
+
{credits.isLoading || usage.isLoading ? (
|
|
224
|
+
// Only this end waits, so the row keeps its shape while the gateway or the plan answers
|
|
225
|
+
<Skeleton className="h-3 w-20 shrink-0" />
|
|
226
|
+
) : (
|
|
227
|
+
<span
|
|
228
|
+
className={cn(
|
|
229
|
+
"flex shrink-0 items-center gap-1.5 font-mono text-xs",
|
|
230
|
+
state.ink,
|
|
231
|
+
)}
|
|
232
|
+
>
|
|
233
|
+
{state.warn ? (
|
|
234
|
+
<TriangleAlert className="size-3" />
|
|
235
|
+
) : (
|
|
236
|
+
set && <Check className="size-3" />
|
|
237
|
+
)}
|
|
238
|
+
{state.text}
|
|
239
|
+
</span>
|
|
240
|
+
)}
|
|
212
241
|
|
|
213
242
|
<ChevronRight className="size-4 shrink-0 text-muted-foreground/60 transition-colors group-hover:text-foreground" />
|
|
214
243
|
</button>
|
|
215
244
|
);
|
|
216
245
|
}
|
|
217
246
|
|
|
247
|
+
/** US dollars, as the gateway bills. */
|
|
248
|
+
const USD = new Intl.NumberFormat("en-US", {
|
|
249
|
+
style: "currency",
|
|
250
|
+
currency: "USD",
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* What a key says at the end of its row. A key only knows whether it is set, except the
|
|
255
|
+
* gateway's, which also says what is left on it: amber waits on a top-up, red is a refusal.
|
|
256
|
+
*/
|
|
257
|
+
function keyState(
|
|
258
|
+
set: boolean,
|
|
259
|
+
needed: boolean,
|
|
260
|
+
credits: GatewayCredits | null | undefined,
|
|
261
|
+
signIn?: true,
|
|
262
|
+
): { text: string; ink: string; warn: boolean } {
|
|
263
|
+
if (!set)
|
|
264
|
+
return needed
|
|
265
|
+
? { text: "Needed", ink: WAITING_INK, warn: true }
|
|
266
|
+
: {
|
|
267
|
+
text: signIn ? "Signed out" : "Not set",
|
|
268
|
+
ink: "text-muted-foreground/60",
|
|
269
|
+
warn: false,
|
|
270
|
+
};
|
|
271
|
+
if (!credits)
|
|
272
|
+
return {
|
|
273
|
+
text: signIn ? "Signed in" : "Set",
|
|
274
|
+
ink: "text-muted-foreground",
|
|
275
|
+
warn: false,
|
|
276
|
+
};
|
|
277
|
+
if ("refused" in credits)
|
|
278
|
+
return { text: "Key refused", ink: "text-destructive", warn: true };
|
|
279
|
+
return {
|
|
280
|
+
text: `${USD.format(credits.balance)} left`,
|
|
281
|
+
ink: credits.low ? WAITING_INK : "text-muted-foreground",
|
|
282
|
+
warn: credits.low,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/** What is left on the gateway key (ai/model readGatewayCredits); any other key reads nothing. */
|
|
287
|
+
function useGatewayCredits(entry: ConfigEntry, set: boolean) {
|
|
288
|
+
return useServerRoute<GatewayCredits | null>(
|
|
289
|
+
set && entry.provider === "vercel-ai-gateway"
|
|
290
|
+
? queryKey.gatewayCredits
|
|
291
|
+
: null,
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/** The plan a signed-in account is on (llm-model route); a key row reads nothing. */
|
|
296
|
+
function useSignInPlan(entry: ConfigEntry, set: boolean) {
|
|
297
|
+
const { data } = useServerRoute<AiProvider[]>(
|
|
298
|
+
set && entry.signIn ? queryKey.llmModel : null,
|
|
299
|
+
);
|
|
300
|
+
return data?.find((provider) => provider.id === entry.provider)?.plan ?? null;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** How much of the subscription's plan is used (ai/chatgpt readChatGptUsage); a key row reads nothing. */
|
|
304
|
+
function useSubscriptionUsage(entry: ConfigEntry, set: boolean) {
|
|
305
|
+
return useServerRoute<SubscriptionUsage | null>(
|
|
306
|
+
set && entry.signIn ? queryKey.subscriptionUsage : null,
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* What a subscription says at the end of its row: the share of its tightest window used. Amber
|
|
312
|
+
* once it is nearly or wholly spent, because the jobs on it are about to wait for the reset; red
|
|
313
|
+
* is a sign-in the plan refused.
|
|
314
|
+
*/
|
|
315
|
+
function usageState(usage: SubscriptionUsage): {
|
|
316
|
+
text: string;
|
|
317
|
+
ink: string;
|
|
318
|
+
warn: boolean;
|
|
319
|
+
} {
|
|
320
|
+
if ("refused" in usage)
|
|
321
|
+
return { text: "Sign-in refused", ink: "text-destructive", warn: true };
|
|
322
|
+
return {
|
|
323
|
+
text: usage.spent ? "Limit reached" : `${usage.usedPercent}% used`,
|
|
324
|
+
ink: usage.high ? WAITING_INK : "text-muted-foreground",
|
|
325
|
+
warn: usage.high,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/** A signed-in row's second line: the plan as the backend names it now, and when its window frees up. */
|
|
330
|
+
function usageLine(
|
|
331
|
+
usage: SubscriptionUsage | null | undefined,
|
|
332
|
+
plan: string | null,
|
|
333
|
+
): string {
|
|
334
|
+
const live = usage && !("refused" in usage) ? usage : null;
|
|
335
|
+
const name = `${live?.plan ?? plan ?? "unknown"} plan`;
|
|
336
|
+
return live?.resetsAt
|
|
337
|
+
? `${name} · resets in ${formatDistanceToNowStrict(new Date(live.resetsAt))}`
|
|
338
|
+
: name;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/** Whose key it is, or what it buys when it belongs to no provider. */
|
|
342
|
+
function KeyMark({ entry }: { entry: ConfigEntry }) {
|
|
343
|
+
if (entry.provider)
|
|
344
|
+
return <ProviderIcon provider={entry.provider} className="size-4" />;
|
|
345
|
+
const Mark = KEY_MARKS[entry.key] ?? KeyRound;
|
|
346
|
+
return <Mark className="size-4 text-muted-foreground" />;
|
|
347
|
+
}
|
|
348
|
+
|
|
218
349
|
/**
|
|
219
350
|
* A choice, not a secret. Unset is normal, so the row says what runs
|
|
220
351
|
* automatically. The value sits under the label rather than across the row:
|
|
@@ -438,6 +569,91 @@ function ChoiceDialog({
|
|
|
438
569
|
);
|
|
439
570
|
}
|
|
440
571
|
|
|
572
|
+
function openSignInDialog(entry: ConfigEntry) {
|
|
573
|
+
return notify.component({
|
|
574
|
+
className: "sm:max-w-md",
|
|
575
|
+
renderer: ({ close }) => <SignInDialog entry={entry} onDone={close} />,
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
/**
|
|
580
|
+
* An account instead of a key. Read live: the sign-in finishes in a window of its own, and the
|
|
581
|
+
* `config` signal it raises (use-thursday) is what turns this dialog to signed in.
|
|
582
|
+
*/
|
|
583
|
+
function SignInDialog({
|
|
584
|
+
entry,
|
|
585
|
+
onDone,
|
|
586
|
+
}: {
|
|
587
|
+
entry: ConfigEntry;
|
|
588
|
+
onDone: () => void;
|
|
589
|
+
}) {
|
|
590
|
+
const { data } = useServerRoute<ConfigStatus[]>(queryKey.config);
|
|
591
|
+
const signedIn = isConfigSet(data, entry.key);
|
|
592
|
+
const plan = useSignInPlan(entry, signedIn);
|
|
593
|
+
const usage = useSubscriptionUsage(entry, signedIn);
|
|
594
|
+
const state = usage.data ? usageState(usage.data) : null;
|
|
595
|
+
const [signOut, signingOut] = useServerAction(removeConfigAction, {
|
|
596
|
+
okMessage: `Signed out of ${entry.label}`,
|
|
597
|
+
onOk: () => {
|
|
598
|
+
revalidate(queryKey.config);
|
|
599
|
+
revalidate(queryKey.llmModel);
|
|
600
|
+
onDone();
|
|
601
|
+
},
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
return (
|
|
605
|
+
<SettingDialogContent
|
|
606
|
+
title={entry.label}
|
|
607
|
+
description={
|
|
608
|
+
signedIn ? (
|
|
609
|
+
<>
|
|
610
|
+
Signed in ·{" "}
|
|
611
|
+
<span className="font-mono">{usageLine(usage.data, plan)}</span>
|
|
612
|
+
{state && (
|
|
613
|
+
<>
|
|
614
|
+
{" · "}
|
|
615
|
+
<span className={cn("font-mono", state.ink)}>{state.text}</span>
|
|
616
|
+
</>
|
|
617
|
+
)}
|
|
618
|
+
</>
|
|
619
|
+
) : (
|
|
620
|
+
"Sign in with your ChatGPT account instead of a key"
|
|
621
|
+
)
|
|
622
|
+
}
|
|
623
|
+
footer={
|
|
624
|
+
<>
|
|
625
|
+
{signedIn && (
|
|
626
|
+
<Button
|
|
627
|
+
variant="ghost"
|
|
628
|
+
loading={signingOut}
|
|
629
|
+
onClick={() => signOut(entry.key)}
|
|
630
|
+
>
|
|
631
|
+
Sign out
|
|
632
|
+
</Button>
|
|
633
|
+
)}
|
|
634
|
+
<Button variant="ghost" onClick={onDone}>
|
|
635
|
+
{signedIn ? "Close" : "Cancel"}
|
|
636
|
+
</Button>
|
|
637
|
+
{!signedIn && <ChatGptSignIn />}
|
|
638
|
+
</>
|
|
639
|
+
}
|
|
640
|
+
>
|
|
641
|
+
<div className="space-y-2">
|
|
642
|
+
<SettingNote>
|
|
643
|
+
{signedIn
|
|
644
|
+
? "Bots on this subscription spend your plan's usage, not a key. When it runs out, the job stops and says when it resets."
|
|
645
|
+
: "The sign-in opens in its own window. Approve it there, and this turns to signed in by itself."}
|
|
646
|
+
</SettingNote>
|
|
647
|
+
{usage.data && "refused" in usage.data && (
|
|
648
|
+
<SettingNote className="wrap-break-word text-destructive">
|
|
649
|
+
{usage.data.refused}
|
|
650
|
+
</SettingNote>
|
|
651
|
+
)}
|
|
652
|
+
</div>
|
|
653
|
+
</SettingDialogContent>
|
|
654
|
+
);
|
|
655
|
+
}
|
|
656
|
+
|
|
441
657
|
function openConfigDialog(entry: ConfigEntry, set: boolean) {
|
|
442
658
|
return notify.component({
|
|
443
659
|
className: "sm:max-w-md",
|
|
@@ -458,8 +674,10 @@ function ConfigDialog({
|
|
|
458
674
|
onDone: () => void;
|
|
459
675
|
}) {
|
|
460
676
|
const [value, setValue] = useState("");
|
|
677
|
+
const { data: credits } = useGatewayCredits(entry, set);
|
|
678
|
+
const state = credits ? keyState(set, false, credits) : null;
|
|
461
679
|
|
|
462
|
-
// The model picker reads hasKey too
|
|
680
|
+
// The model picker reads hasKey too, and the gateway's credits sit under the same url
|
|
463
681
|
const refresh = () => {
|
|
464
682
|
revalidate(queryKey.config);
|
|
465
683
|
revalidate(queryKey.llmModel);
|
|
@@ -487,6 +705,12 @@ function ConfigDialog({
|
|
|
487
705
|
<>
|
|
488
706
|
<span className="font-mono">{entry.key}</span>
|
|
489
707
|
{entry.hint && <> · {entry.hint}</>}
|
|
708
|
+
{state && (
|
|
709
|
+
<>
|
|
710
|
+
{" · "}
|
|
711
|
+
<span className={cn("font-mono", state.ink)}>{state.text}</span>
|
|
712
|
+
</>
|
|
713
|
+
)}
|
|
490
714
|
</>
|
|
491
715
|
}
|
|
492
716
|
footer={
|
|
@@ -513,18 +737,25 @@ function ConfigDialog({
|
|
|
513
737
|
</>
|
|
514
738
|
}
|
|
515
739
|
>
|
|
516
|
-
<
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
740
|
+
<div className="space-y-2">
|
|
741
|
+
<Input
|
|
742
|
+
value={value}
|
|
743
|
+
onChange={(event) => setValue(event.target.value)}
|
|
744
|
+
onKeyDown={(event) => {
|
|
745
|
+
if (event.key === "Enter" && value.trim().length >= 8)
|
|
746
|
+
save(entry.key, value);
|
|
747
|
+
}}
|
|
748
|
+
placeholder={set ? "New value — replaces the current key" : entry.key}
|
|
749
|
+
spellCheck={false}
|
|
750
|
+
type="password"
|
|
751
|
+
autoFocus
|
|
752
|
+
/>
|
|
753
|
+
{credits && "refused" in credits && (
|
|
754
|
+
<SettingNote className="wrap-break-word text-destructive">
|
|
755
|
+
{credits.refused}
|
|
756
|
+
</SettingNote>
|
|
757
|
+
)}
|
|
758
|
+
</div>
|
|
528
759
|
</SettingDialogContent>
|
|
529
760
|
);
|
|
530
761
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { queryKey } from "@/app/api/query-key";
|
|
4
|
+
import {
|
|
5
|
+
CONFIG_GROUPS,
|
|
6
|
+
type ConfigStatus,
|
|
7
|
+
isConfigSet,
|
|
8
|
+
} from "@/features/config/config.const";
|
|
9
|
+
import { NavBadge } from "@/features/settings/components/setting-ui";
|
|
10
|
+
import type { SectionAlert } from "@/features/settings/settings.alert";
|
|
11
|
+
import { useServerRoute } from "@/lib/protocol/use-server-route";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Every studio model key, read off the catalogue so a new kind counts without a
|
|
15
|
+
* second list. `kind` is the test rather than the section: the bots' default model
|
|
16
|
+
* sits in the same section but resolves when unset (ai/model resolveDefaultModel),
|
|
17
|
+
* and a key with a fallback is not something waiting on anyone.
|
|
18
|
+
*/
|
|
19
|
+
const MODEL_KEYS = CONFIG_GROUPS.filter(
|
|
20
|
+
(group) => group.section === "models",
|
|
21
|
+
).flatMap((group) =>
|
|
22
|
+
group.entries.filter((entry) => entry.kind).map((entry) => entry.key),
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Nobody has picked a studio model at all. Not one unpicked — all of them: each
|
|
27
|
+
* costs money per call, so leaving video or speech off is a choice, and a badge
|
|
28
|
+
* that only clears when every kind is set is a standing demand to spend. What is
|
|
29
|
+
* worth saying once is that the whole drawer exists, because until one is picked
|
|
30
|
+
* a bot that would have drawn just finds out mid-job. Picking any answers it.
|
|
31
|
+
* A loading read reports nothing rather than flashing a dot on every open.
|
|
32
|
+
*/
|
|
33
|
+
export function useModelsAlert(): SectionAlert {
|
|
34
|
+
const { data, isLoading } = useServerRoute<ConfigStatus[]>(queryKey.config);
|
|
35
|
+
if (isLoading || !data) return null;
|
|
36
|
+
return MODEL_KEYS.every((key) => !isConfigSet(data, key)) ? "amber" : null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** A dot, not a count: the number would only ever be "all of them". */
|
|
40
|
+
export function ModelsBadge() {
|
|
41
|
+
return useModelsAlert() ? <NavBadge tone="amber" /> : null;
|
|
42
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use server";
|
|
2
2
|
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import { startChatGptSignIn } from "@/features/ai/chatgpt";
|
|
4
5
|
import { serverAction } from "@/lib/protocol/server-action";
|
|
5
6
|
import { publicError } from "@/lib/public-error";
|
|
6
7
|
import { acceptsChoice, CONFIG_ENTRIES, CONFIG_KEYS } from "./config.const";
|
|
@@ -17,6 +18,9 @@ export const setConfigAction = serverAction(
|
|
|
17
18
|
.parse({ key, value });
|
|
18
19
|
|
|
19
20
|
const entry = CONFIG_ENTRIES[parsed.key];
|
|
21
|
+
if (entry?.signIn) {
|
|
22
|
+
publicError(`${entry.label} takes a sign-in, not a key.`);
|
|
23
|
+
}
|
|
20
24
|
if (entry?.choices) {
|
|
21
25
|
if (!acceptsChoice(entry, parsed.value)) {
|
|
22
26
|
publicError("That is not one of the options.");
|
|
@@ -31,3 +35,11 @@ export const setConfigAction = serverAction(
|
|
|
31
35
|
export const removeConfigAction = serverAction(async (key: unknown) => {
|
|
32
36
|
await removeConfig(KeySchema.parse(key));
|
|
33
37
|
});
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Starts signing in to ChatGPT and returns the page to open (ai/chatgpt). The answer lands on
|
|
41
|
+
* the server, which keeps the sign-in and signals the screen (`config`).
|
|
42
|
+
*/
|
|
43
|
+
export const startChatGptSignInAction = serverAction(async () =>
|
|
44
|
+
startChatGptSignIn(),
|
|
45
|
+
);
|
|
@@ -29,6 +29,8 @@ export type ConfigEntry = {
|
|
|
29
29
|
text?: true;
|
|
30
30
|
/** Whose key this is; draws the mark in front of the row. */
|
|
31
31
|
provider?: TextModelProviderId;
|
|
32
|
+
/** Signed in to rather than typed: the row signs in, and the write action takes no value for it. */
|
|
33
|
+
signIn?: true;
|
|
32
34
|
/** Present means a choice, not a secret: the value may be shown and served. */
|
|
33
35
|
choices?: ConfigChoice[];
|
|
34
36
|
/** A studio kind. The value is `provider/model`, picked with the model picker, so ids outside `choices` are accepted. */
|
|
@@ -39,7 +41,13 @@ export type ConfigEntry = {
|
|
|
39
41
|
* Every group id. A union, not a string, because `isCallable` looks the voice
|
|
40
42
|
* group up by id and a typo there silently makes the app always callable.
|
|
41
43
|
*/
|
|
42
|
-
export const CONFIG_GROUP_IDS = [
|
|
44
|
+
export const CONFIG_GROUP_IDS = [
|
|
45
|
+
"voice",
|
|
46
|
+
"text",
|
|
47
|
+
"search",
|
|
48
|
+
"bots",
|
|
49
|
+
"studio",
|
|
50
|
+
] as const;
|
|
43
51
|
export type ConfigGroupId = (typeof CONFIG_GROUP_IDS)[number];
|
|
44
52
|
|
|
45
53
|
/** The group a call runs on: one of its keys must be set (config.query isCallable). */
|
|
@@ -84,6 +92,10 @@ const MEDIA_ENTRY: Record<MediaKind, { label: string; hint: string }> = {
|
|
|
84
92
|
},
|
|
85
93
|
};
|
|
86
94
|
|
|
95
|
+
/** "an image model" — how a screen names one that is missing. The article differs by kind. */
|
|
96
|
+
export const mediaModelWords = (kind: MediaKind) =>
|
|
97
|
+
`${kind === "image" ? "an" : "a"} ${kind} model`;
|
|
98
|
+
|
|
87
99
|
/** Each of these costs real money per call, so none is offered until it is picked (ai/model resolveMediaRef). */
|
|
88
100
|
|
|
89
101
|
const mediaEntry = (kind: MediaKind): ConfigEntry => ({
|
|
@@ -100,6 +112,13 @@ const mediaEntry = (kind: MediaKind): ConfigEntry => ({
|
|
|
100
112
|
),
|
|
101
113
|
});
|
|
102
114
|
|
|
115
|
+
/**
|
|
116
|
+
* What a bot searches the web with. Set, every bot searches through Exa in one HTTP call;
|
|
117
|
+
* unset, only a bot whose own model carries a native search has the tool at all — there is
|
|
118
|
+
* no borrowed model to search on (ai/tools/search.tool).
|
|
119
|
+
*/
|
|
120
|
+
export const EXA_API_KEY = "EXA_API_KEY";
|
|
121
|
+
|
|
103
122
|
/** What a bot runs on when it has not picked its own model (bot.schema `provider`/`model`). */
|
|
104
123
|
export const DEFAULT_MODEL_KEY = "DEFAULT_MODEL";
|
|
105
124
|
|
|
@@ -140,10 +159,13 @@ export function acceptsChoice(entry: ConfigEntry, value: string): boolean {
|
|
|
140
159
|
const isVoiceKey = (provider: { apiKeyName: string }) =>
|
|
141
160
|
voiceKeys.includes(provider.apiKeyName);
|
|
142
161
|
|
|
143
|
-
const keyEntry = (
|
|
162
|
+
const keyEntry = (
|
|
163
|
+
provider: (typeof TEXT_MODEL_PROVIDER_LIST)[number],
|
|
164
|
+
): ConfigEntry => ({
|
|
144
165
|
key: provider.apiKeyName,
|
|
145
166
|
label: provider.label,
|
|
146
167
|
provider: provider.id,
|
|
168
|
+
signIn: provider.signIn,
|
|
147
169
|
});
|
|
148
170
|
|
|
149
171
|
export const CONFIG_GROUPS: ConfigGroup[] = [
|
|
@@ -166,6 +188,20 @@ export const CONFIG_GROUPS: ConfigGroup[] = [
|
|
|
166
188
|
(provider) => !isVoiceKey(provider),
|
|
167
189
|
).map(keyEntry),
|
|
168
190
|
},
|
|
191
|
+
{
|
|
192
|
+
id: "search",
|
|
193
|
+
title: "search",
|
|
194
|
+
hint: "how bots look things up — one key, or their own model's",
|
|
195
|
+
section: "keys",
|
|
196
|
+
require: "none",
|
|
197
|
+
entries: [
|
|
198
|
+
{
|
|
199
|
+
key: EXA_API_KEY,
|
|
200
|
+
label: "Exa",
|
|
201
|
+
hint: "web search in one call — dashboard.exa.ai",
|
|
202
|
+
},
|
|
203
|
+
],
|
|
204
|
+
},
|
|
169
205
|
{
|
|
170
206
|
id: "bots",
|
|
171
207
|
title: "Bots",
|
|
@@ -221,15 +221,23 @@ export class McpManager {
|
|
|
221
221
|
return attempt;
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
/**
|
|
224
|
+
/**
|
|
225
|
+
* Run a tool, opening or reviving the session if needed. Every call pushes the idle timer back.
|
|
226
|
+
* `signal` is the only bound: the client waits forever when given none.
|
|
227
|
+
*/
|
|
225
228
|
async callTool(
|
|
226
229
|
name: string,
|
|
227
230
|
tool: string,
|
|
228
231
|
args?: Record<string, unknown>,
|
|
232
|
+
signal?: AbortSignal,
|
|
229
233
|
): Promise<CallToolResult> {
|
|
230
234
|
const client = await this.ensureClient(name);
|
|
231
235
|
try {
|
|
232
|
-
const result = await client.callTool({
|
|
236
|
+
const result = await client.callTool({
|
|
237
|
+
name: tool,
|
|
238
|
+
arguments: args,
|
|
239
|
+
options: signal ? { signal } : undefined,
|
|
240
|
+
});
|
|
233
241
|
this.touch(name);
|
|
234
242
|
return result;
|
|
235
243
|
} catch (error) {
|