thursday-agent 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +3 -2
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.json +8 -1
- package/.next/routes-manifest.json +18 -6
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +13 -13
- package/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/artifact/route.js +10 -6
- package/.next/server/app/api/artifact/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/files/route.js +5 -4
- package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/route.js +8 -8
- package/.next/server/app/api/bot/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/route.js +8 -8
- package/.next/server/app/api/bot/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/thread/[id]/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/bot/thread/[id]/route.js +15 -0
- package/.next/server/app/api/bot/thread/[id]/route.js.nft.json +1 -0
- package/.next/server/app/api/bot/thread/[id]/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/bot/thread/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/bot/thread/route.js +15 -0
- package/.next/server/app/api/bot/thread/route.js.nft.json +1 -0
- package/.next/server/app/api/bot/thread/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/config/route.js +7 -7
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/events/route.js +3 -3
- package/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/server/app/api/file/[...path]/route.js +4 -4
- package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/catalog/route.js +8 -8
- package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/credits/route.js +8 -8
- package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/route.js +8 -8
- package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/subscription/route.js +8 -8
- package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/[name]/route.js +6 -6
- package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth/callback/route.js +4 -4
- package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js +6 -6
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/tools/route.js +6 -6
- package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/edit/route.js +15 -15
- package/.next/server/app/api/memory/edit/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/route.js +7 -6
- package/.next/server/app/api/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[source]/[name]/route.js +6 -6
- package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js +6 -6
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/call/route.js +10 -11
- package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/skills/route.js +9 -10
- package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/tool-call/route.js +15 -15
- package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/missing/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/workspace/missing/route/build-manifest.json +12 -0
- package/.next/server/app/api/workspace/missing/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/workspace/missing/route.js +12 -0
- package/.next/server/app/api/workspace/missing/route.js.map +5 -0
- package/.next/server/app/api/workspace/missing/route.js.nft.json +1 -0
- package/.next/server/app/api/workspace/missing/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/workspace/route.js +5 -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 +4 -3
- package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/server/app/page/server-reference-manifest.json +67 -45
- package/.next/server/app/page.js +11 -9
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +3 -2
- package/.next/server/chunks/[root-of-the-server]__0-06t3f._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__02846fb._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__05luceg._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__06--3q3._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__06l05n_._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__07bnah_._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__08eae20._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0_ue8oe._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0btqrct._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0c9fgca._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__0h_x6q6._.js +5 -0
- package/.next/server/chunks/{[root-of-the-server]__0pa2n68._.js → [root-of-the-server]__0kxrvxf._.js} +2 -2
- package/.next/server/chunks/{[root-of-the-server]__0q0vvt2._.js → [root-of-the-server]__0ov3iir._.js} +2 -2
- package/.next/server/chunks/[root-of-the-server]__0qwtlmx._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0sm5xvm._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0zp35ul._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__144u9d_._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__18-2tsq._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1e-ci13._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1e2365e._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__1fix932._.js +8 -0
- package/.next/server/chunks/{[root-of-the-server]__0ce8nf8._.js → [root-of-the-server]__1g3t7vn._.js} +3 -3
- package/.next/server/chunks/[root-of-the-server]__1kp-83u._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1kv8p3e._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +2 -3
- package/.next/server/chunks/_02szwk8._.js +5 -0
- package/.next/server/chunks/_05h2cii._.js +1 -1
- package/.next/server/chunks/_06c9kie._.js +216 -0
- package/.next/server/chunks/{_1x6kd1r._.js → _07y2gj-._.js} +1 -1
- package/.next/server/chunks/_0a43a-0._.js +3 -0
- package/.next/server/chunks/_0bujjey._.js +5 -0
- package/.next/server/chunks/_0c9j6rb._.js +1 -1
- package/.next/server/chunks/_0dkd549._.js +3 -0
- package/.next/server/chunks/_0ej1kvv._.js +3 -0
- package/.next/server/chunks/_0f6ts7z._.js +3 -0
- package/.next/server/chunks/_0gm9hyv._.js +55 -0
- package/.next/server/chunks/_0i55en5._.js +25 -0
- package/.next/server/chunks/_0k50n27._.js +18 -0
- package/.next/server/chunks/_0khihjk._.js +3 -3
- package/.next/server/chunks/_0n74zsf._.js +5 -5
- package/.next/server/chunks/_0nvm9ef._.js +3 -0
- package/.next/server/chunks/_0p56fn0._.js +3 -0
- package/.next/server/chunks/_0recufk._.js +1 -1
- package/.next/server/chunks/_0xbkz10._.js +3 -0
- package/.next/server/chunks/_10tkr26._.js +3 -0
- package/.next/server/chunks/{_0ioz3nd._.js → _11u2kp7._.js} +1 -1
- package/.next/server/chunks/_11ujpya._.js +3 -0
- package/.next/server/chunks/_127nx_p._.js +5 -0
- package/.next/server/chunks/_17l5ygt._.js +1 -1
- package/.next/server/chunks/_19uauj6._.js +3 -0
- package/.next/server/chunks/_1_5mnq4._.js +5 -5
- package/.next/server/chunks/_1abl6t9._.js +55 -0
- package/.next/server/chunks/_1d0j961._.js +3 -3
- package/.next/server/chunks/_1dbixxz._.js +3 -0
- package/.next/server/chunks/_1dc_d1q._.js +98 -0
- package/.next/server/chunks/_1drgfx4._.js +5 -5
- package/.next/server/chunks/_1e48czp._.js +3 -3
- package/.next/server/chunks/_1f31u5x._.js +5 -0
- package/.next/server/chunks/_1gnjfli._.js +3 -0
- package/.next/server/chunks/_1kg70wc._.js +3 -3
- package/.next/server/chunks/_1klbcft._.js +5 -0
- package/.next/server/chunks/_1krd9rf._.js +4 -1
- package/.next/server/chunks/_1kwmzab._.js +3 -0
- package/.next/server/chunks/{_1pf4qe-._.js → _1oxj9fa._.js} +1 -1
- package/.next/server/chunks/{_1f46eie._.js → _1pcmdbb._.js} +1 -1
- package/.next/server/chunks/_1qgix-j._.js +3 -0
- package/.next/server/chunks/{lib_logger_ts_1exwjut._.js → _1rpchta._.js} +5 -5
- package/.next/server/chunks/_1vsej-s._.js +5 -0
- package/.next/server/chunks/_1yx0p_s._.js +5 -0
- package/.next/server/chunks/{_0rnf-6n._.js → _20fsr_z._.js} +6 -6
- package/.next/server/chunks/_2128hkj._.js +5 -0
- package/.next/server/chunks/_next-internal_server_app_api_bot_thread_[id]_route_actions_1fstjn2.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_bot_thread_route_actions_003ccso.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_workspace_missing_route_actions_1fidi6p.js +3 -0
- package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
- package/.next/server/chunks/features_0-cnt0l._.js +4 -0
- package/.next/server/chunks/features_0hdaci0._.js +4 -0
- package/.next/server/chunks/features_1e39j7-._.js +8 -0
- package/.next/server/chunks/features_bot_bot_query_ts_12mgkl2._.js +1 -1
- package/.next/server/chunks/features_memory_1uqvksn._.js +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0v_7drq._.js → node_modules_consola_dist_chunks_prompt_mjs_0a7-pbw._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_17k8irj._.js → node_modules_consola_dist_chunks_prompt_mjs_0gzvgfv._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0i7cvml._.js → node_modules_consola_dist_chunks_prompt_mjs_107pxfn._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0icqaqw._.js → node_modules_consola_dist_chunks_prompt_mjs_15hbel8._.js} +1 -1
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_18i-23e._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1bewgf3._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1nlww1m._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1q77nfx._.js +3 -0
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1xqdzx_._.js +3 -0
- package/.next/server/chunks/{node_modules_zod_v4_1801ax7._.js → node_modules_zod_v4_0lkux5-._.js} +2 -2
- package/.next/server/chunks/{node_modules_zod_v4_1cha_bw._.js → node_modules_zod_v4_1jmr9cq._.js} +2 -2
- package/.next/server/chunks/{node_modules_zod_v4_0ubdflj._.js → node_modules_zod_v4_1yrxmek._.js} +2 -2
- package/.next/server/chunks/node_modules_zod_v4_classic_errors_0tp0y-q.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0-e011f._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__09q9med._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0lyi8i2._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0pd8yr7._.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]__18dthbp._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__18e68w8._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1nygfik._.js +5 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1sdphb0._.js +8 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1vdmfbe._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1waa3rc._.js +85 -0
- package/.next/server/chunks/ssr/_0-2qsxo._.js +3 -0
- package/.next/server/chunks/ssr/_00rehl_._.js +3 -0
- package/.next/server/chunks/ssr/{_1lz_cq2._.js → _02oc_h5._.js} +76 -97
- package/.next/server/chunks/ssr/_05yghx6._.js +3 -0
- package/.next/server/chunks/ssr/_07nbwap._.js +3 -0
- package/.next/server/chunks/ssr/_08c4z-9._.js +3 -0
- package/.next/server/chunks/ssr/_0_qfdlw._.js +4 -0
- package/.next/server/chunks/ssr/{_0m2lsd1._.js → _0b6_jv-._.js} +2 -2
- package/.next/server/chunks/ssr/_0evkpto._.js +3 -0
- package/.next/server/chunks/ssr/_0geg212._.js +3 -0
- package/.next/server/chunks/ssr/{_1jdgjv9._.js → _0hxt2ul._.js} +2 -2
- package/.next/server/chunks/ssr/_0i_6q1w._.js +2 -2
- package/.next/server/chunks/ssr/_0lu1n_x._.js +1 -1
- package/.next/server/chunks/ssr/_0no7i1o._.js +3 -0
- package/.next/server/chunks/ssr/_0tzg--b._.js +3 -0
- package/.next/server/chunks/ssr/{_15j2_8f._.js → _0wzaht-._.js} +2 -2
- package/.next/server/chunks/ssr/_0z-g0uy._.js +3 -0
- package/.next/server/chunks/ssr/_114ylv7._.js +7 -0
- package/.next/server/chunks/ssr/_123y-ah._.js +3 -0
- package/.next/server/chunks/ssr/_12c-iwh._.js +3 -0
- package/.next/server/chunks/ssr/_12w42gi._.js +3 -0
- package/.next/server/chunks/ssr/_161kqav._.js +3 -0
- package/.next/server/chunks/ssr/_167hchk._.js +3 -0
- package/.next/server/chunks/ssr/{_0ap2fzn._.js → _16c6_xm._.js} +2 -2
- package/.next/server/chunks/ssr/_18opah7._.js +3 -0
- package/.next/server/chunks/ssr/_1_krfph._.js +3 -0
- package/.next/server/chunks/ssr/{_0rzucul._.js → _1_x5spz._.js} +3 -3
- package/.next/server/chunks/ssr/_1a61fc9._.js +3 -0
- package/.next/server/chunks/ssr/_1ey7qn-._.js +70 -0
- package/.next/server/chunks/ssr/_1g9vs7q._.js +3 -0
- package/.next/server/chunks/ssr/_1jmz33w._.js +3 -0
- package/.next/server/chunks/ssr/_1rgtxhr._.js +5 -0
- package/.next/server/chunks/ssr/_1slp25y._.js +3 -0
- package/.next/server/chunks/ssr/_1w_t7h7._.js +101 -0
- package/.next/server/chunks/ssr/{_0s99bgb._.js → _1wyfaq_._.js} +9 -3
- package/.next/server/chunks/ssr/_200gt-m._.js +102 -0
- package/.next/server/chunks/ssr/components_ui_tabs_tsx_0ej40b4._.js +3 -0
- package/.next/server/chunks/ssr/features_bot_thread_query_ts_023eklt._.js +4 -0
- package/.next/server/chunks/ssr/features_config_components_config-setting_tsx_0xfwqdg._.js +1 -1
- package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
- package/.next/server/chunks/ssr/features_workspace_00jz2hu._.js +8 -0
- package/.next/server/chunks/ssr/{_1-teee5._.js → lib_logger_ts_0-olsze._.js} +2 -7
- package/.next/server/chunks/ssr/{node_modules_05-n6dz._.js → node_modules_02ai7br._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1chvq5f._.js → node_modules_02deexj._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0m383r2._.js → node_modules_07za262._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_07dsgkx._.js → node_modules_0_s9get._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1a0kmjl._.js → node_modules_0n3c7h0._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0zeg3x_._.js → node_modules_0od6jwr._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1y79i83._.js → node_modules_0rdt7pk._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_17bwo43._.js → node_modules_0tusx4d._.js} +3 -3
- package/.next/server/chunks/ssr/{node_modules_04sksn9._.js → node_modules_0w1z7kz._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1uyk91w._.js → node_modules_0wdupfz._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0ifp389._.js → node_modules_1720w0a._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0u9da1h._.js → node_modules_18lsg7d._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1k6n600._.js → node_modules_1b94fxf._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_20c28js._.js → node_modules_1ecdo1s._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0fkeku3._.js → node_modules_1fa9ag7._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1j8j4pt._.js → node_modules_1fv-_si._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0-dr_o7._.js → node_modules_1hf461g._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1lz0oxc._.js → node_modules_1m71ta-._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1t77e4n._.js → node_modules_1n93n-g._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_16mkxuo._.js → node_modules_1n9lqu9._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1k7z2j6._.js → node_modules_1npnsvd._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_056qgf-._.js → node_modules_1rn2r0n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0x3-ply._.js → node_modules_1seuurl._.js} +2 -2
- package/.next/server/chunks/ssr/{node_modules_0bvopy2._.js → node_modules_1vq-mfk._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0iur59s._.js → node_modules_1vzyw1t._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1k8j8n0._.js → node_modules_1w359w4._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1x0ztf4._.js → node_modules_1yajbl6._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1-y7nni._.js → node_modules_20eqhy8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0bkwd0u._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_019sbis._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0p9a9su._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0s6piq3._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@vercel_oidc_dist_1o553h-._.js → node_modules_@vercel_oidc_dist_05itbb1._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_trash_mjs_0px2gzr._.js +3 -0
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +68 -46
- package/.next/static/chunks/07vqbk_9t4em4.js +2 -0
- package/.next/static/chunks/08krja1zx7nqg.js +1 -0
- package/.next/static/chunks/0g4b348l0pve7.js +1 -0
- package/.next/static/chunks/0qcuwdk132jjt.js +1 -0
- package/.next/static/chunks/0vlgzqo9ka90v.js +1 -0
- package/.next/static/chunks/{11r2yp_yh9_qn.js → 0z69gvysmave7.js} +1 -1
- package/.next/static/chunks/0zrupxgci5gqc.js +1 -0
- package/.next/static/chunks/12fvz1w5ows75.js +1 -0
- package/.next/static/chunks/14t03ned286iu.js +1 -0
- package/.next/static/chunks/156xxbkrz5lzu.js +18 -0
- package/.next/static/chunks/1fz14reod4lft.js +1 -0
- package/.next/static/chunks/1g23dbabl-vkr.js +1 -0
- package/.next/static/chunks/1ohslk4568tm3.js +1 -0
- package/.next/static/chunks/1qy_rc3oxfxok.js +1 -0
- package/.next/static/chunks/1sbmwswc9k2-1.js +1 -0
- package/.next/static/chunks/1vqezbhjm3goq.js +1 -0
- package/.next/static/chunks/1zea7qdl-7365.js +1 -0
- package/.next/static/chunks/1zvqumkg7kmo0.css +1 -0
- package/.next/static/chunks/26hpqt3y6bogl.js +12 -0
- package/.next/static/chunks/2_j5mqm6d-z18.js +99 -0
- package/.next/static/chunks/2dt6tu7a22svs.js +1 -0
- package/.next/static/chunks/2h5ls3d86kya6.js +1 -0
- package/.next/static/chunks/2wc6y1ht6dfuy.js +1 -0
- package/.next/static/chunks/{435atsnhs7ksu.js → 2xr0zpll7thyi.js} +2 -2
- package/.next/static/chunks/31jztc-yq30m7.js +1 -0
- package/.next/static/chunks/391af0i8eljzk.js +1 -0
- package/.next/static/chunks/3bfwpww3m3x4u.js +1 -0
- package/.next/static/chunks/{38gweqdo4jpfj.js → 3izg0a3k87q1-.js} +5 -5
- package/.next/static/chunks/3p2s2cjokx1aa.js +5 -0
- package/.next/static/chunks/{408ueu4hfvcg7.js → 41s3fml5oivsa.js} +1 -1
- package/README.md +45 -193
- package/app/api/events/app-event.ts +6 -4
- package/app/api/query-key.ts +25 -16
- package/bin/database.mjs +37 -0
- package/bin/thursday.mjs +44 -28
- package/components/ui/custom-icon.tsx +0 -60
- package/components/ui/radio-group.tsx +37 -0
- package/components/ui/shiny-text.tsx +33 -6
- package/database/migrations/{20260910173049_numerous_spirit → 20260916145701_clever_multiple_man}/migration.sql +80 -24
- package/database/migrations/{20260910173049_numerous_spirit → 20260916145701_clever_multiple_man}/snapshot.json +689 -110
- package/database/migrations/20260916160713_thread_cancelled/migration.sql +2 -0
- package/database/migrations/{20260911030320_opposite_jack_power → 20260916160713_thread_cancelled}/snapshot.json +706 -84
- package/docs/how-it-works.md +40 -35
- package/docs/images/keeps-going.png +0 -0
- package/docs/images/two-minds.png +0 -0
- package/docs/live-calls.md +236 -0
- package/docs/thread-rooms.md +71 -0
- package/features/ai/chatgpt.ts +1 -2
- package/features/ai/live.schema.ts +128 -0
- package/features/ai/load-tools.ts +152 -79
- package/features/ai/model.schema.ts +2 -120
- package/features/ai/model.ts +52 -88
- package/features/ai/prompts/bot.prompt.ts +91 -214
- package/features/ai/prompts/live.prompt.ts +169 -0
- package/features/ai/prompts/prompt-helper.ts +92 -32
- package/features/ai/prompts/thursday.prompt.ts +164 -190
- package/features/ai/tools/bot.tool.ts +38 -145
- package/features/ai/tools/call.tool.ts +33 -5
- package/features/ai/tools/connected.ts +5 -3
- package/features/ai/tools/mcp.tool.ts +7 -4
- package/features/ai/tools/memory.tool.ts +35 -31
- package/features/ai/tools/skills.tool.ts +11 -6
- package/features/ai/tools/studio.tool.ts +26 -21
- package/features/ai/tools/tool-name.ts +3 -5
- package/features/ai/tools/workspace.tool.ts +33 -10
- package/features/artifact/artifact.action.ts +2 -2
- package/features/artifact/artifact.query.ts +112 -61
- package/features/artifact/artifact.schema.ts +8 -6
- package/features/artifact/components/artifact-setting.tsx +83 -33
- package/features/bot/bot.action.ts +43 -36
- package/features/bot/bot.memory.ts +137 -20
- package/features/bot/bot.query.ts +28 -11
- package/features/bot/bot.run.ts +296 -744
- package/features/bot/bot.runner.ts +463 -864
- package/features/bot/bot.schema.ts +93 -82
- package/features/bot/bot.seed.ts +141 -64
- package/features/bot/components/bot-mark.tsx +324 -232
- package/features/bot/components/bot-room.tsx +1613 -697
- package/features/bot/components/bot-roster.tsx +8 -13
- package/features/bot/components/bot-setting.tsx +58 -42
- package/features/bot/components/bot-tool.tsx +55 -87
- package/features/bot/components/mark-palette.tsx +35 -32
- package/features/bot/components/path-chips.tsx +33 -3
- package/features/bot/components/thread-badge.tsx +34 -0
- package/features/bot/components/thread-reply.tsx +639 -0
- package/features/bot/components/thread-setting.tsx +674 -0
- package/features/bot/mark.const.ts +79 -31
- package/features/bot/room.query.ts +889 -0
- package/features/bot/room.schema.ts +64 -0
- package/features/bot/seed-bots.ts +2 -1
- package/features/bot/thread.query.ts +971 -0
- package/features/bot/thread.store.ts +587 -0
- package/features/config/components/voice-key.tsx +113 -88
- package/features/config/config.const.ts +5 -9
- package/features/connectors/mcp.schema.ts +0 -2
- package/features/intro/components/intro.tsx +169 -139
- package/features/memory/components/memory-setting.tsx +2 -7
- package/features/memory/memory.schema.ts +14 -23
- package/features/settings/components/setting-ui.tsx +0 -44
- package/features/settings/components/settings.tsx +12 -12
- package/features/settings/settings.alert.ts +3 -3
- package/features/settings/settings.store.ts +1 -1
- package/features/skills/skills.schema.ts +0 -2
- package/features/thursday/ascii.const.ts +74 -0
- package/features/thursday/components/ascii-field.tsx +24 -44
- package/features/thursday/components/ascii-orb.tsx +525 -381
- package/features/thursday/components/call-log.tsx +46 -44
- package/features/thursday/components/face.tsx +40 -10
- package/features/thursday/components/side-captions.tsx +273 -0
- package/features/thursday/components/tab-state.tsx +14 -6
- package/features/thursday/components/thursday-mark.tsx +1 -0
- package/features/thursday/components/thursday-setting.tsx +633 -333
- package/features/thursday/components/thursday.tsx +315 -274
- package/features/thursday/components/voice-picker.tsx +255 -0
- package/features/thursday/face.store.ts +5 -0
- package/features/thursday/thursday.action.ts +96 -72
- package/features/thursday/thursday.query.ts +49 -30
- package/features/thursday/thursday.schema.ts +37 -35
- package/features/thursday/thursday.store.ts +14 -7
- package/features/thursday/tool-call.ts +3 -3
- package/features/thursday/tool-line.ts +5 -3
- package/features/thursday/use-thursday.ts +801 -457
- package/features/workspace/file-kind.ts +9 -0
- package/features/workspace/workspace.query.ts +17 -0
- package/features/workspace/workspace.ts +82 -36
- package/hooks/use-hotkey.ts +3 -2
- package/lib/live/live.schema.ts +26 -0
- package/lib/live/live.server.ts +153 -0
- package/lib/live/live.session.ts +574 -0
- package/lib/{realtime/realtime.tap.ts → live/live.tap.ts} +41 -12
- package/lib/live/live.transport.ts +152 -0
- package/lib/protocol/use-server-pages.ts +9 -5
- package/lib/utils.ts +21 -20
- package/package.json +2 -2
- package/public/voices/alloy.ogg +0 -0
- package/public/voices/ash.ogg +0 -0
- package/public/voices/ballad.ogg +0 -0
- package/public/voices/beacon.ogg +0 -0
- package/public/voices/bossa.ogg +0 -0
- package/public/voices/cedar.ogg +0 -0
- package/public/voices/cinder.ogg +0 -0
- package/public/voices/coral.ogg +0 -0
- package/public/voices/delta.ogg +0 -0
- package/public/voices/echo.ogg +0 -0
- package/public/voices/gleam.ogg +0 -0
- package/public/voices/marin.ogg +0 -0
- package/public/voices/meridian.ogg +0 -0
- package/public/voices/quartz.ogg +0 -0
- package/public/voices/ripple.ogg +0 -0
- package/public/voices/sage.ogg +0 -0
- package/public/voices/shimmer.ogg +0 -0
- package/public/voices/stone.ogg +0 -0
- package/public/voices/tempo.ogg +0 -0
- package/public/voices/verse.ogg +0 -0
- package/public/voices/vesper.ogg +0 -0
- package/public/voices/willow.ogg +0 -0
- package/scripts/artifact-paths.test.mts +38 -0
- package/scripts/bot-context.test.mts +1408 -0
- package/scripts/live-history.test.mts +115 -0
- package/scripts/live-session.test.mts +938 -0
- package/server.js +1 -1
- package/skills/browser/SKILL.md +11 -1
- package/skills/computer/SKILL.md +1 -1
- package/skills/find-skills/SKILL.md +3 -8
- package/skills/interactive-page/SKILL.md +12 -7
- package/skills/interactive-page/references/diagram.md +89 -0
- package/skills/interactive-page/scripts/archify/LICENSE +22 -0
- package/skills/interactive-page/scripts/archify/README.md +25 -0
- package/skills/interactive-page/scripts/archify/assets/JetBrainsMono-OFL.txt +93 -0
- package/skills/interactive-page/scripts/archify/assets/template.html +14934 -0
- package/skills/interactive-page/scripts/archify/bin/archify.mjs +2126 -0
- package/skills/interactive-page/scripts/archify/bin/open-artifact.mjs +86 -0
- package/skills/interactive-page/scripts/archify/bin/preview.mjs +653 -0
- package/skills/interactive-page/scripts/archify/bin/visual-check.mjs +829 -0
- package/skills/interactive-page/scripts/archify/delta/architecture-delta.mjs +1223 -0
- package/skills/interactive-page/scripts/archify/examples/agent-run.lifecycle.json +60 -0
- package/skills/interactive-page/scripts/archify/examples/agent-tool-call.workflow.json +94 -0
- package/skills/interactive-page/scripts/archify/examples/async-job-roundtrip.sequence.json +61 -0
- package/skills/interactive-page/scripts/archify/examples/cache-miss-request.sequence.json +82 -0
- package/skills/interactive-page/scripts/archify/examples/checkout-platform.base.architecture.json +31 -0
- package/skills/interactive-page/scripts/archify/examples/checkout-platform.head.architecture.json +31 -0
- package/skills/interactive-page/scripts/archify/examples/deployment-release.lifecycle.json +49 -0
- package/skills/interactive-page/scripts/archify/examples/event-stream.dataflow.json +57 -0
- package/skills/interactive-page/scripts/archify/examples/incident-response.workflow.json +64 -0
- package/skills/interactive-page/scripts/archify/examples/product-analytics.dataflow.json +76 -0
- package/skills/interactive-page/scripts/archify/examples/production-deployment.architecture.json +71 -0
- package/skills/interactive-page/scripts/archify/examples/release-delivery.workflow.json +62 -0
- package/skills/interactive-page/scripts/archify/examples/web-app.architecture.json +46 -0
- package/skills/interactive-page/scripts/archify/migrations/workflow-v2.mjs +279 -0
- package/skills/interactive-page/scripts/archify/recipes/scenarios.mjs +284 -0
- package/skills/interactive-page/scripts/archify/references/authoring-contract.md +243 -0
- package/skills/interactive-page/scripts/archify/references/delivery-contract.md +120 -0
- package/skills/interactive-page/scripts/archify/references/viewer-runtime.md +45 -0
- package/skills/interactive-page/scripts/archify/renderers/architecture/grid.mjs +62 -0
- package/skills/interactive-page/scripts/archify/renderers/architecture/render-architecture.mjs +1078 -0
- package/skills/interactive-page/scripts/archify/renderers/dataflow/README.md +104 -0
- package/skills/interactive-page/scripts/archify/renderers/dataflow/render-dataflow.mjs +483 -0
- package/skills/interactive-page/scripts/archify/renderers/lifecycle/README.md +115 -0
- package/skills/interactive-page/scripts/archify/renderers/lifecycle/render-lifecycle.mjs +561 -0
- package/skills/interactive-page/scripts/archify/renderers/sequence/README.md +114 -0
- package/skills/interactive-page/scripts/archify/renderers/sequence/render-sequence.mjs +464 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/brand-marks.mjs +563 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/cli.mjs +218 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/desktop-readability.mjs +26 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/diagnostics.mjs +127 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/engineering-profiles.mjs +157 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/generated-brand-marks.mjs +3 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/generated-validators.mjs +13 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/geometry.mjs +1423 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/i18n.mjs +595 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/layout-report.mjs +40 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/legend.mjs +217 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/output-path.mjs +340 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/repository-evidence.mjs +238 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/repository-location.mjs +58 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/text-fit.mjs +49 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/utils.mjs +232 -0
- package/skills/interactive-page/scripts/archify/renderers/shared/validator.mjs +86 -0
- package/skills/interactive-page/scripts/archify/renderers/workflow/README.md +223 -0
- package/skills/interactive-page/scripts/archify/renderers/workflow/render-workflow.mjs +35 -0
- package/skills/interactive-page/scripts/archify/renderers/workflow/workflow-compiler.mjs +4400 -0
- package/skills/interactive-page/scripts/archify/renderers/workflow/workflow-migration-geometry.mjs +144 -0
- package/skills/interactive-page/scripts/archify/schemas/README.md +211 -0
- package/skills/interactive-page/scripts/archify/schemas/architecture.schema.json +178 -0
- package/skills/interactive-page/scripts/archify/schemas/common.schema.json +115 -0
- package/skills/interactive-page/scripts/archify/schemas/dataflow.schema.json +243 -0
- package/skills/interactive-page/scripts/archify/schemas/lifecycle.schema.json +266 -0
- package/skills/interactive-page/scripts/archify/schemas/sequence.schema.json +223 -0
- package/skills/interactive-page/scripts/archify/schemas/workflow.schema.json +428 -0
- package/skills/interactive-page/scripts/archify/scripts/check-render-output.mjs +916 -0
- package/skills/interactive-page/scripts/archify/scripts/render-examples.mjs +26 -0
- package/skills/interactive-page/scripts/bundle-artifact.sh +9 -8
- package/skills/skill-creator/SKILL.md +4 -5
- package/.next/server/app/api/bot/task/[id]/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/bot/task/[id]/route.js +0 -16
- package/.next/server/app/api/bot/task/[id]/route.js.nft.json +0 -1
- package/.next/server/app/api/bot/task/[id]/route_client-reference-manifest.js +0 -3
- package/.next/server/app/api/bot/task/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/bot/task/route.js +0 -16
- package/.next/server/app/api/bot/task/route.js.nft.json +0 -1
- package/.next/server/app/api/bot/task/route_client-reference-manifest.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__026u77e._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__050zri4._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0bg9710._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0ffbg85._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0in-d5s._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0ncs9uu._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0pa9k-f._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0qi_m0e._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0tq0m_k._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0xep6j_._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1-ga0kh._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__11n256_._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__144l7qt._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1anc1p9._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1fizn31._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1jg8t86._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1lldzy9._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1llj3-b._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1p8m3f4._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1peqvsi._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1w8gm5h._.js +0 -10
- package/.next/server/chunks/[root-of-the-server]__1xt39nn._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1zb8mfo._.js +0 -8
- package/.next/server/chunks/_0-73of8._.js +0 -55
- package/.next/server/chunks/_0-fjql4._.js +0 -31
- package/.next/server/chunks/_00xh_q0._.js +0 -25
- package/.next/server/chunks/_051qh8u._.js +0 -3
- package/.next/server/chunks/_05sovvj._.js +0 -3
- package/.next/server/chunks/_091bi8d._.js +0 -3
- package/.next/server/chunks/_0fzqt2y._.js +0 -142
- package/.next/server/chunks/_0lr92vd._.js +0 -3
- package/.next/server/chunks/_0mecv0f._.js +0 -31
- package/.next/server/chunks/_0mh8j4m._.js +0 -3
- package/.next/server/chunks/_0sb7tlz._.js +0 -3
- package/.next/server/chunks/_0si7xzn._.js +0 -3
- package/.next/server/chunks/_0u10wmw._.js +0 -55
- package/.next/server/chunks/_0wp4le3._.js +0 -3
- package/.next/server/chunks/_0y5fg-x._.js +0 -3
- package/.next/server/chunks/_1230wbx._.js +0 -10
- package/.next/server/chunks/_12nheja._.js +0 -3
- package/.next/server/chunks/_13510xh._.js +0 -3
- package/.next/server/chunks/_15hq89o._.js +0 -3
- package/.next/server/chunks/_18-1wcc._.js +0 -55
- package/.next/server/chunks/_18d7-5p._.js +0 -3
- package/.next/server/chunks/_1c78vw5._.js +0 -237
- package/.next/server/chunks/_1h5_8sk._.js +0 -3
- package/.next/server/chunks/_1hdnxb7._.js +0 -3
- package/.next/server/chunks/_1j8k_j5._.js +0 -3
- package/.next/server/chunks/_1nula3v._.js +0 -3
- package/.next/server/chunks/_1php4eq._.js +0 -3
- package/.next/server/chunks/_1yuv4vp._.js +0 -3
- package/.next/server/chunks/_1zkfbaa._.js +0 -3
- package/.next/server/chunks/_next-internal_server_app_api_bot_task_[id]_route_actions_1_k_8u3.js +0 -3
- package/.next/server/chunks/_next-internal_server_app_api_bot_task_route_actions_0xln6ra.js +0 -3
- package/.next/server/chunks/features_0rpfxbk._.js +0 -3
- package/.next/server/chunks/features_1qf3cei._.js +0 -8
- package/.next/server/chunks/features_bot_0zt92oh._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1jidylq._.js +0 -3
- package/.next/server/chunks/ssr/[externals]__0dizgek._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0-nob52._.js +0 -4
- package/.next/server/chunks/ssr/[root-of-the-server]__092knlj._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0mz33a7._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0s4wb56._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0s9dq5u._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0sd3izg._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0vnmv-s._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1-13tcn._.js +0 -43
- package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +0 -61
- package/.next/server/chunks/ssr/[root-of-the-server]__1zidpfl._.js +0 -3
- package/.next/server/chunks/ssr/_001_ms1._.js +0 -33
- package/.next/server/chunks/ssr/_01n3o0m._.js +0 -3
- package/.next/server/chunks/ssr/_04z2c7b._.js +0 -3
- package/.next/server/chunks/ssr/_06tssji._.js +0 -3
- package/.next/server/chunks/ssr/_0fk4c7d._.js +0 -3
- package/.next/server/chunks/ssr/_0h42fze._.js +0 -3
- package/.next/server/chunks/ssr/_0h7zdni._.js +0 -3
- package/.next/server/chunks/ssr/_0mggveb._.js +0 -3
- package/.next/server/chunks/ssr/_0nbpc_8._.js +0 -3
- package/.next/server/chunks/ssr/_0q0zan6._.js +0 -70
- package/.next/server/chunks/ssr/_0zcjrbg._.js +0 -3
- package/.next/server/chunks/ssr/_0zhoc3r._.js +0 -3
- package/.next/server/chunks/ssr/_11j92tu._.js +0 -3
- package/.next/server/chunks/ssr/_13fke0x._.js +0 -3
- package/.next/server/chunks/ssr/_18cymkq._.js +0 -3
- package/.next/server/chunks/ssr/_1ebxla1._.js +0 -3
- package/.next/server/chunks/ssr/_1nj4niv._.js +0 -42
- package/.next/server/chunks/ssr/_1ov37if._.js +0 -3
- package/.next/server/chunks/ssr/_1ovmc9s._.js +0 -3
- package/.next/server/chunks/ssr/_1sji22n._.js +0 -3
- package/.next/server/chunks/ssr/_1vi_uo7._.js +0 -3
- package/.next/server/chunks/ssr/_1vyd1ji._.js +0 -3
- package/.next/server/chunks/ssr/_1xx4zlb._.js +0 -3
- package/.next/server/chunks/ssr/components_ui_1y1l7yj._.js +0 -3
- package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +0 -3
- package/.next/server/chunks/ssr/lib_realtime_12wg_dd._.js +0 -27
- package/.next/server/chunks/ssr/lib_realtime_15h_v1v._.js +0 -27
- package/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0npjf8-._.js +0 -3
- package/.next/static/chunks/0n3jle9kbqfr2.js +0 -40
- package/.next/static/chunks/0r5qcctujhxli.js +0 -1
- package/.next/static/chunks/10teww7wt-f6h.js +0 -1
- package/.next/static/chunks/126fj4pga_72k.js +0 -1
- package/.next/static/chunks/159udiexf6dom.js +0 -2
- package/.next/static/chunks/18a96rkhi4_yd.js +0 -1
- package/.next/static/chunks/18gi7o2ibrgh8.js +0 -3
- package/.next/static/chunks/1dkjg87pxk0n9.js +0 -28
- package/.next/static/chunks/1q9z1tohil7xn.js +0 -1
- package/.next/static/chunks/1sjgfets224re.js +0 -1
- package/.next/static/chunks/1wszsr83t01gh.js +0 -1
- package/.next/static/chunks/22_zkas21rpna.js +0 -1
- package/.next/static/chunks/2fh4-3z_q8b_w.js +0 -1
- package/.next/static/chunks/2h0sd2vumhb15.js +0 -1
- package/.next/static/chunks/2szintyibu0s5.js +0 -1
- package/.next/static/chunks/2t4vhi3m8ahya.js +0 -1
- package/.next/static/chunks/2tigdtz3dpcy8.js +0 -1
- package/.next/static/chunks/3-b6b7entqazs.js +0 -1
- package/.next/static/chunks/3786h5vayt80-.js +0 -28
- package/.next/static/chunks/3cq5g494yuke8.css +0 -1
- package/.next/static/chunks/3dmbhsv2u_8kj.js +0 -1
- package/.next/static/chunks/3hibbjnt85-k6.js +0 -1
- package/.next/static/chunks/3i0a5px-oufgc.js +0 -1
- package/.next/static/chunks/3wexk9qo8zuj3.js +0 -18
- package/.next/static/chunks/3xk7yqgomx7yq.js +0 -1
- package/.next/static/chunks/3xre8bu_pk1p_.js +0 -1
- package/.next/static/chunks/3zv6t3i77xhr_.js +0 -1
- package/database/migrations/20260911030320_opposite_jack_power/migration.sql +0 -1
- package/docs/images/task-thread.png +0 -0
- package/features/bot/components/task-badge.tsx +0 -42
- package/features/bot/components/task-reply.tsx +0 -328
- package/features/bot/components/task-setting.tsx +0 -524
- package/features/bot/task.query.ts +0 -1079
- package/features/bot/task.store.ts +0 -487
- package/lib/realtime/client-secret.ts +0 -86
- package/lib/realtime/open-session.ts +0 -31
- package/lib/realtime/openai.ts +0 -35
- package/lib/realtime/realtime.audio.ts +0 -196
- package/lib/realtime/realtime.driver.ts +0 -489
- package/lib/realtime/realtime.protocol.ts +0 -393
- package/lib/realtime/realtime.schema.ts +0 -37
- package/lib/realtime/realtime.session.ts +0 -106
- package/lib/realtime/realtime.transport.ts +0 -384
- package/lib/realtime/xai.ts +0 -39
- /package/.next/server/app/api/bot/{task → thread}/[id]/route/build-manifest.json +0 -0
- /package/.next/server/app/api/bot/{task → thread}/[id]/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/bot/{task → thread}/[id]/route.js.map +0 -0
- /package/.next/server/app/api/bot/{task → thread}/route/build-manifest.json +0 -0
- /package/.next/server/app/api/bot/{task → thread}/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/bot/{task → thread}/route.js.map +0 -0
- /package/.next/static/{G6-gNoyGDEcgAsq-L4PE1 → yyRVBc0xxYQsh3GpbQX9b}/_buildManifest.js +0 -0
- /package/.next/static/{G6-gNoyGDEcgAsq-L4PE1 → yyRVBc0xxYQsh3GpbQX9b}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{G6-gNoyGDEcgAsq-L4PE1 → yyRVBc0xxYQsh3GpbQX9b}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Check, ChevronDown, X } from "lucide-react";
|
|
4
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
5
|
+
import { Button } from "@/components/ui/button";
|
|
6
|
+
import { Input, inputClassName } from "@/components/ui/input";
|
|
7
|
+
import { ShinyText } from "@/components/ui/shiny-text";
|
|
8
|
+
import { toast } from "@/components/ui/toast";
|
|
9
|
+
import {
|
|
10
|
+
LIVE_VOICE_NOTE,
|
|
11
|
+
LIVE_VOICES,
|
|
12
|
+
voiceSamplePath,
|
|
13
|
+
} from "@/features/ai/live.schema";
|
|
14
|
+
import { Face } from "@/features/thursday/components/face";
|
|
15
|
+
import type { ThursdayFace } from "@/features/thursday/thursday.schema";
|
|
16
|
+
import { createClipTap, SPECTRUM_BANDS } from "@/lib/live/live.tap";
|
|
17
|
+
import { cn, errorToString } from "@/lib/utils";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Choosing a voice by ear. A name plays its recorded line and her own face
|
|
21
|
+
* speaks it — the same component and the same bands a call moves her with, so
|
|
22
|
+
* what you hear and see here is what the call will be. Only Save writes, so
|
|
23
|
+
* hearing eleven voices stores none of them.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const SILENT = new Array<number>(SPECTRUM_BANDS).fill(0);
|
|
27
|
+
|
|
28
|
+
export function VoicePicker({
|
|
29
|
+
voice,
|
|
30
|
+
face,
|
|
31
|
+
onChange,
|
|
32
|
+
}: {
|
|
33
|
+
/** The saved voice: what the next call opens with. */
|
|
34
|
+
voice: string;
|
|
35
|
+
face: ThursdayFace;
|
|
36
|
+
onChange: (voice: string) => void;
|
|
37
|
+
}) {
|
|
38
|
+
const [open, setOpen] = useState(false);
|
|
39
|
+
const [heard, setHeard] = useState(voice);
|
|
40
|
+
const [playing, setPlaying] = useState(false);
|
|
41
|
+
const [typed, setTyped] = useState("");
|
|
42
|
+
|
|
43
|
+
const clip = useRef<HTMLAudioElement>(null);
|
|
44
|
+
// A tap belongs to the element it routes, which exists only while the picker is open.
|
|
45
|
+
const tap = useRef<{
|
|
46
|
+
element: HTMLAudioElement;
|
|
47
|
+
clip: ReturnType<typeof createClipTap>;
|
|
48
|
+
} | null>(null);
|
|
49
|
+
// Each play and each stop takes the next number; a failure reported for an
|
|
50
|
+
// earlier one changes nothing.
|
|
51
|
+
const plays = useRef(0);
|
|
52
|
+
// The face reads the spectrum once per animation frame, so what it reads is a
|
|
53
|
+
// ref, not state: a stable function, and silence when nothing is playing.
|
|
54
|
+
const sounding = useRef(false);
|
|
55
|
+
const spectrum = useCallback(
|
|
56
|
+
() => (tap.current && sounding.current ? tap.current.clip.read() : SILENT),
|
|
57
|
+
[],
|
|
58
|
+
);
|
|
59
|
+
const showPlaying = (on: boolean) => {
|
|
60
|
+
sounding.current = on;
|
|
61
|
+
setPlaying(on);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// The element goes when the picker closes; its graph goes with it.
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (!open) return;
|
|
67
|
+
return () => {
|
|
68
|
+
const held = tap.current;
|
|
69
|
+
tap.current = null;
|
|
70
|
+
if (!held) return;
|
|
71
|
+
held.element.pause();
|
|
72
|
+
void held.clip.close();
|
|
73
|
+
};
|
|
74
|
+
}, [open]);
|
|
75
|
+
|
|
76
|
+
const failed = (play: number, cause: unknown) => {
|
|
77
|
+
if (play !== plays.current) return;
|
|
78
|
+
plays.current++;
|
|
79
|
+
showPlaying(false);
|
|
80
|
+
toast.add({
|
|
81
|
+
type: "error",
|
|
82
|
+
title: "Voice sample did not play",
|
|
83
|
+
description: errorToString(cause),
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const stop = () => {
|
|
88
|
+
plays.current++;
|
|
89
|
+
const audio = clip.current;
|
|
90
|
+
if (audio) {
|
|
91
|
+
audio.pause();
|
|
92
|
+
audio.currentTime = 0;
|
|
93
|
+
}
|
|
94
|
+
showPlaying(false);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const audition = (next: string) => {
|
|
98
|
+
const audio = clip.current;
|
|
99
|
+
if (!audio) return;
|
|
100
|
+
if (playing && next === heard) {
|
|
101
|
+
stop();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
setHeard(next);
|
|
105
|
+
setTyped("");
|
|
106
|
+
// The graph is built inside the gesture that plays: an AudioContext made
|
|
107
|
+
// before one is refused. An element is routed once, so it keeps its tap.
|
|
108
|
+
if (tap.current?.element !== audio) {
|
|
109
|
+
void tap.current?.clip.close();
|
|
110
|
+
tap.current = { element: audio, clip: createClipTap(audio) };
|
|
111
|
+
}
|
|
112
|
+
void tap.current.clip.resume();
|
|
113
|
+
const play = ++plays.current;
|
|
114
|
+
audio.src = voiceSamplePath(next);
|
|
115
|
+
showPlaying(true);
|
|
116
|
+
void audio.play().catch((cause: unknown) => {
|
|
117
|
+
// A later click or a stop cut this one short; that play owns the state.
|
|
118
|
+
if (cause instanceof DOMException && cause.name === "AbortError") return;
|
|
119
|
+
failed(play, cause);
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const close = () => {
|
|
124
|
+
stop();
|
|
125
|
+
setOpen(false);
|
|
126
|
+
setTyped("");
|
|
127
|
+
setHeard(voice);
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const save = () => {
|
|
131
|
+
const picked = typed.trim() || heard;
|
|
132
|
+
stop();
|
|
133
|
+
setOpen(false);
|
|
134
|
+
setTyped("");
|
|
135
|
+
setHeard(picked);
|
|
136
|
+
if (picked !== voice) onChange(picked);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
if (!open) {
|
|
140
|
+
return (
|
|
141
|
+
<button
|
|
142
|
+
type="button"
|
|
143
|
+
onClick={() => setOpen(true)}
|
|
144
|
+
aria-label="Voice"
|
|
145
|
+
className={cn(
|
|
146
|
+
inputClassName,
|
|
147
|
+
"flex items-center gap-2 text-left font-mono text-sm hover:border-ring",
|
|
148
|
+
)}
|
|
149
|
+
>
|
|
150
|
+
<span className="shrink-0">{voice}</span>
|
|
151
|
+
<span className="min-w-0 truncate text-[11px] text-muted-foreground">
|
|
152
|
+
{LIVE_VOICE_NOTE[voice as keyof typeof LIVE_VOICE_NOTE]}
|
|
153
|
+
</span>
|
|
154
|
+
<ChevronDown className="ml-auto size-3.5 shrink-0 text-muted-foreground" />
|
|
155
|
+
</button>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<div className="@container space-y-2">
|
|
161
|
+
{/* Nothing here plays through the page's own speakers but this element. */}
|
|
162
|
+
<audio
|
|
163
|
+
ref={clip}
|
|
164
|
+
onEnded={() => showPlaying(false)}
|
|
165
|
+
// A clip that breaks after it starts fails here, not in play()
|
|
166
|
+
onError={(event) => {
|
|
167
|
+
if (!sounding.current) return;
|
|
168
|
+
failed(
|
|
169
|
+
plays.current,
|
|
170
|
+
event.currentTarget.error?.message || "The clip could not be read.",
|
|
171
|
+
);
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
<track kind="captions" />
|
|
175
|
+
</audio>
|
|
176
|
+
|
|
177
|
+
<div className="rounded-xl border border-border/60 p-3">
|
|
178
|
+
<div className="mb-2 flex items-center gap-2">
|
|
179
|
+
<span className="font-mono text-[11px] text-muted-foreground">
|
|
180
|
+
click a name to hear it
|
|
181
|
+
</span>
|
|
182
|
+
<Button
|
|
183
|
+
variant="ghost"
|
|
184
|
+
size="icon-xs"
|
|
185
|
+
className="ml-auto"
|
|
186
|
+
aria-label="Close"
|
|
187
|
+
onClick={close}
|
|
188
|
+
>
|
|
189
|
+
<X />
|
|
190
|
+
</Button>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div className="grid gap-4 @md:grid-cols-[11rem_minmax(0,1fr)]">
|
|
194
|
+
<div className="flex flex-col items-center gap-2">
|
|
195
|
+
<Face
|
|
196
|
+
look={face}
|
|
197
|
+
status={playing ? "speaking" : "idle"}
|
|
198
|
+
getSpectrum={spectrum}
|
|
199
|
+
size={176}
|
|
200
|
+
className="w-44"
|
|
201
|
+
/>
|
|
202
|
+
<span className="text-sm font-medium">
|
|
203
|
+
{playing ? <ShinyText text={heard} /> : heard}
|
|
204
|
+
</span>
|
|
205
|
+
<span className="h-4 font-mono text-[11px] text-muted-foreground">
|
|
206
|
+
{LIVE_VOICE_NOTE[heard as keyof typeof LIVE_VOICE_NOTE]}
|
|
207
|
+
</span>
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<div className="max-h-56 min-w-0 overflow-y-auto">
|
|
211
|
+
{LIVE_VOICES.map((name) => (
|
|
212
|
+
<button
|
|
213
|
+
type="button"
|
|
214
|
+
key={name}
|
|
215
|
+
onClick={() => audition(name)}
|
|
216
|
+
className={cn(
|
|
217
|
+
"flex w-full items-center gap-2 rounded-md px-1.5 py-1.5 text-sm outline-none hover:bg-accent focus-visible:bg-accent",
|
|
218
|
+
name === heard && "bg-accent text-accent-foreground",
|
|
219
|
+
)}
|
|
220
|
+
>
|
|
221
|
+
<span className="flex-1 text-left">
|
|
222
|
+
{playing && name === heard ? <ShinyText text={name} /> : name}
|
|
223
|
+
</span>
|
|
224
|
+
<span className="shrink truncate font-mono text-[11px] text-muted-foreground">
|
|
225
|
+
{LIVE_VOICE_NOTE[name]}
|
|
226
|
+
</span>
|
|
227
|
+
<Check
|
|
228
|
+
className={cn(
|
|
229
|
+
"size-3.5 shrink-0",
|
|
230
|
+
name === voice ? "opacity-100" : "opacity-0",
|
|
231
|
+
)}
|
|
232
|
+
/>
|
|
233
|
+
</button>
|
|
234
|
+
))}
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
{/* A voice id that is not on the list still runs; it simply has no clip. */}
|
|
240
|
+
<div className="flex gap-2">
|
|
241
|
+
<Input
|
|
242
|
+
value={typed}
|
|
243
|
+
onChange={(event) => setTyped(event.target.value)}
|
|
244
|
+
placeholder="another voice id"
|
|
245
|
+
aria-label="Another voice id"
|
|
246
|
+
spellCheck={false}
|
|
247
|
+
className="font-mono text-sm"
|
|
248
|
+
/>
|
|
249
|
+
<Button className="shrink-0" onClick={save}>
|
|
250
|
+
Save
|
|
251
|
+
</Button>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
@@ -40,6 +40,11 @@ export function setThursdayFace(next: ThursdayFace) {
|
|
|
40
40
|
announce();
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/** The face as it is now, for code outside React. */
|
|
44
|
+
export function thursdayFace(): ThursdayFace {
|
|
45
|
+
return face;
|
|
46
|
+
}
|
|
47
|
+
|
|
43
48
|
export function useThursdayFace(): ThursdayFace {
|
|
44
49
|
return useSyncExternalStore(
|
|
45
50
|
(listener) => {
|
|
@@ -2,65 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
import { asSchema } from "ai";
|
|
4
4
|
import z from "zod";
|
|
5
|
+
import { LIVE_PROVIDER } from "@/features/ai/live.schema";
|
|
5
6
|
import { loadTools } from "@/features/ai/load-tools";
|
|
6
|
-
import {
|
|
7
|
-
SPEACH_MODEL_PROVIDER_LIST,
|
|
8
|
-
SPEACH_MODEL_PROVIDERS,
|
|
9
|
-
type SpeachModelRef,
|
|
10
|
-
} from "@/features/ai/model.schema";
|
|
7
|
+
import { loadLivePrompt } from "@/features/ai/prompts/live.prompt";
|
|
11
8
|
import { loadThursdayPrompt } from "@/features/ai/prompts/thursday.prompt";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
9
|
+
import { removeThread } from "@/features/bot/bot.runner";
|
|
10
|
+
import { listAllThreadIds } from "@/features/bot/thread.query";
|
|
14
11
|
import { readConfig } from "@/features/config/config.query";
|
|
15
12
|
import { deleteAllNotes } from "@/features/memory/memory.query";
|
|
13
|
+
import {
|
|
14
|
+
LIVE_MODEL,
|
|
15
|
+
LiveCloseSchema,
|
|
16
|
+
type ToolManifest,
|
|
17
|
+
} from "@/lib/live/live.schema";
|
|
18
|
+
import { acceptedReasoning, createLiveCall } from "@/lib/live/live.server";
|
|
16
19
|
import { serverAction } from "@/lib/protocol/server-action";
|
|
17
20
|
import { publicError } from "@/lib/public-error";
|
|
18
|
-
import { issueClientSecret } from "@/lib/realtime/client-secret";
|
|
19
|
-
import type { ToolManifest } from "@/lib/realtime/realtime.schema";
|
|
20
21
|
import {
|
|
21
22
|
deleteCall,
|
|
22
23
|
deleteEndedCalls,
|
|
23
24
|
endCall,
|
|
24
25
|
insertCall,
|
|
26
|
+
saveThought,
|
|
25
27
|
saveTurns,
|
|
26
28
|
writeCallSkillsOn,
|
|
27
29
|
} from "./thursday.query";
|
|
28
30
|
import {
|
|
29
31
|
type CallHandshake,
|
|
32
|
+
CallThoughtSchema,
|
|
30
33
|
CallTurnSchema,
|
|
31
|
-
type ThursdaySettings,
|
|
32
34
|
ThursdaySettingsSchema,
|
|
33
35
|
} from "./thursday.schema";
|
|
34
36
|
|
|
35
37
|
// Server actions run one at a time per client, so the recording actions stay
|
|
36
38
|
// small: a tool call mid-sentence may be queued behind them.
|
|
37
39
|
|
|
38
|
-
/**
|
|
39
|
-
|
|
40
|
-
picked: ThursdaySettings["model"],
|
|
41
|
-
): Promise<SpeachModelRef> {
|
|
42
|
-
if (
|
|
43
|
-
picked &&
|
|
44
|
-
(await readConfig(SPEACH_MODEL_PROVIDERS[picked.provider].apiKeyName))
|
|
45
|
-
) {
|
|
46
|
-
return picked;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Voice and model ids are provider-specific, so neither carries over.
|
|
50
|
-
for (const provider of SPEACH_MODEL_PROVIDER_LIST) {
|
|
51
|
-
if (await readConfig(provider.apiKeyName)) {
|
|
52
|
-
return { provider: provider.id, voice: null, model: null };
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
publicError("No voice key — calls run on one. Add one in Config.");
|
|
56
|
-
}
|
|
40
|
+
/** An offer with every ICE candidate gathered stays far below this. */
|
|
41
|
+
const SDP_MAX_LENGTH = 65_536;
|
|
57
42
|
|
|
58
43
|
/**
|
|
59
44
|
* The same tool set /api/thursday/tool-call executes. Tools without `execute`
|
|
60
|
-
* (`end_call`) are included: the model must see them and the page intercepts them.
|
|
45
|
+
* (`end_call`, `emote`) are included: the model must see them and the page intercepts them.
|
|
61
46
|
*/
|
|
62
|
-
async function loadToolManifest(): Promise<ToolManifest[]> {
|
|
63
|
-
const tools = await loadTools({ target: "thursday" });
|
|
47
|
+
async function loadToolManifest(faceWords: boolean): Promise<ToolManifest[]> {
|
|
48
|
+
const tools = await loadTools({ target: "thursday", faceWords });
|
|
64
49
|
|
|
65
50
|
return Object.entries(tools).map(([name, definition]) => {
|
|
66
51
|
const { $schema, ...parameters } = asSchema(definition.inputSchema)
|
|
@@ -78,47 +63,65 @@ async function loadToolManifest(): Promise<ToolManifest[]> {
|
|
|
78
63
|
}
|
|
79
64
|
|
|
80
65
|
/**
|
|
81
|
-
* Opens a call
|
|
82
|
-
*
|
|
83
|
-
*
|
|
66
|
+
* Opens a Live call from the browser's SDP offer. Both prompts, the tool manifest
|
|
67
|
+
* and the account key stay here; the browser gets the SDP answer, the call row
|
|
68
|
+
* and what it needs to draw and save the call. `calledBack` is the page placing it
|
|
69
|
+
* for waiting work rather than the user, which changes what she opens with.
|
|
84
70
|
*/
|
|
85
71
|
export const openCallAction = serverAction(
|
|
86
|
-
async (
|
|
72
|
+
async (
|
|
73
|
+
settings: unknown,
|
|
74
|
+
sdp: unknown,
|
|
75
|
+
calledBack?: unknown,
|
|
76
|
+
): Promise<CallHandshake> => {
|
|
87
77
|
const thursday = ThursdaySettingsSchema.parse(settings);
|
|
78
|
+
const offer = z.string().min(1).max(SDP_MAX_LENGTH).parse(sdp);
|
|
79
|
+
const apiKey = await readConfig(LIVE_PROVIDER.apiKeyName);
|
|
80
|
+
if (!apiKey) {
|
|
81
|
+
publicError(`No ${LIVE_PROVIDER.label} key — add one in Config.`);
|
|
82
|
+
}
|
|
88
83
|
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
loadThursdayPrompt(thursday.
|
|
97
|
-
loadToolManifest(),
|
|
84
|
+
// Assembled per call, never cached: both prompts read what earlier calls stored.
|
|
85
|
+
const [voice, backend, tools, reasoning] = await Promise.all([
|
|
86
|
+
loadLivePrompt({
|
|
87
|
+
voicePrompt: thursday.voicePrompt,
|
|
88
|
+
locale: thursday.locale,
|
|
89
|
+
calledBack: z.boolean().default(false).parse(calledBack),
|
|
90
|
+
}),
|
|
91
|
+
loadThursdayPrompt(thursday.backendPrompt),
|
|
92
|
+
loadToolManifest(thursday.faceWords ?? false),
|
|
93
|
+
acceptedReasoning({
|
|
94
|
+
apiKey,
|
|
95
|
+
model: thursday.backendModel,
|
|
96
|
+
effort: thursday.reasoningEffort,
|
|
97
|
+
}),
|
|
98
98
|
]);
|
|
99
99
|
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// nobody can close.
|
|
104
|
-
const credential = await issueClientSecret({
|
|
105
|
-
provider: ref.provider,
|
|
100
|
+
// Connect before insert: a refused key or model must not leave an open row nobody can close.
|
|
101
|
+
// Free-text model ids are not checked here; the provider refuses them and says why.
|
|
102
|
+
const connection = await createLiveCall({
|
|
106
103
|
apiKey,
|
|
107
|
-
|
|
104
|
+
sdp: offer,
|
|
105
|
+
voice: thursday.voice,
|
|
106
|
+
instructions: voice.text,
|
|
107
|
+
backend: {
|
|
108
|
+
model: thursday.backendModel,
|
|
109
|
+
instructions: backend,
|
|
110
|
+
tools,
|
|
111
|
+
reasoning,
|
|
112
|
+
webSearch: thursday.webSearch,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
const callId = await insertCall({
|
|
116
|
+
provider: LIVE_PROVIDER.id,
|
|
117
|
+
model: LIVE_MODEL,
|
|
118
|
+
backendModel: thursday.backendModel,
|
|
108
119
|
});
|
|
109
|
-
const callId = await insertCall({ provider: ref.provider, model });
|
|
110
120
|
|
|
111
121
|
return {
|
|
112
122
|
callId,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
session: {
|
|
116
|
-
model,
|
|
117
|
-
voice: ref.voice ?? provider.defaultVoice,
|
|
118
|
-
instructions: prompt.text,
|
|
119
|
-
tools,
|
|
120
|
-
},
|
|
121
|
-
opening: prompt.opening,
|
|
123
|
+
sdp: connection.transport.sdp,
|
|
124
|
+
opening: voice.opening,
|
|
122
125
|
};
|
|
123
126
|
},
|
|
124
127
|
);
|
|
@@ -132,14 +135,35 @@ export const setCallSkillsAction = serverAction(async (on: unknown) => {
|
|
|
132
135
|
});
|
|
133
136
|
|
|
134
137
|
export const saveTurnsAction = serverAction(
|
|
135
|
-
async (callId:
|
|
136
|
-
await saveTurns(
|
|
138
|
+
async (callId: unknown, turns: unknown) => {
|
|
139
|
+
await saveTurns(
|
|
140
|
+
z.string().min(1).parse(callId),
|
|
141
|
+
CallTurnSchema.array().min(1).parse(turns),
|
|
142
|
+
);
|
|
137
143
|
},
|
|
138
144
|
);
|
|
139
145
|
|
|
140
|
-
export const
|
|
141
|
-
|
|
142
|
-
|
|
146
|
+
export const saveThoughtAction = serverAction(
|
|
147
|
+
async (callId: unknown, thought: unknown) => {
|
|
148
|
+
await saveThought(
|
|
149
|
+
z.string().min(1).parse(callId),
|
|
150
|
+
CallThoughtSchema.parse(thought),
|
|
151
|
+
);
|
|
152
|
+
},
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Ends the row. `close` is what `session.closed` confirmed; absent when the
|
|
157
|
+
* confirmation never came, which leaves the billed seconds unknown.
|
|
158
|
+
*/
|
|
159
|
+
export const endCallAction = serverAction(
|
|
160
|
+
async (callId: unknown, close?: unknown) => {
|
|
161
|
+
await endCall(
|
|
162
|
+
z.string().min(1).parse(callId),
|
|
163
|
+
LiveCloseSchema.nullish().parse(close),
|
|
164
|
+
);
|
|
165
|
+
},
|
|
166
|
+
);
|
|
143
167
|
|
|
144
168
|
/**
|
|
145
169
|
* Deletes a call and its turns; the next call's prompt no longer includes it.
|
|
@@ -161,19 +185,19 @@ export const deleteEndedCallsAction = serverAction(async () =>
|
|
|
161
185
|
|
|
162
186
|
/**
|
|
163
187
|
* Wipes what the app has kept of its own use: every ended call and its turns,
|
|
164
|
-
* every
|
|
188
|
+
* every thread and its messages, and every memory note. Keys, bots and connectors
|
|
165
189
|
* stay — the set `pnpm reset` calls History.
|
|
166
190
|
*
|
|
167
191
|
* History is not one domain, so this reaches into three and each clears its own
|
|
168
|
-
* rows. Live work is stopped before its row goes: `
|
|
192
|
+
* rows. Live work is stopped before its row goes: `removeThread` aborts a running
|
|
169
193
|
* job and closes its shell.
|
|
170
194
|
*/
|
|
171
195
|
export const resetHistoryAction = serverAction(async () => {
|
|
172
|
-
const
|
|
173
|
-
for (const id of
|
|
196
|
+
const threadIds = await listAllThreadIds();
|
|
197
|
+
for (const id of threadIds) await removeThread(id);
|
|
174
198
|
|
|
175
199
|
const calls = await deleteEndedCalls();
|
|
176
200
|
const notes = await deleteAllNotes();
|
|
177
201
|
|
|
178
|
-
return { calls,
|
|
202
|
+
return { calls, threads: threadIds.length, notes };
|
|
179
203
|
});
|
|
@@ -11,11 +11,17 @@ import {
|
|
|
11
11
|
} from "drizzle-orm";
|
|
12
12
|
import { CALL_HISTORY_PAGE } from "@/config";
|
|
13
13
|
import { database } from "@/database/db";
|
|
14
|
-
import {
|
|
15
|
-
|
|
14
|
+
import {
|
|
15
|
+
callMessageTable,
|
|
16
|
+
callTable,
|
|
17
|
+
callThoughtTable,
|
|
18
|
+
} from "@/database/tables";
|
|
19
|
+
import { listCallJobs } from "@/features/bot/thread.query";
|
|
16
20
|
import { readConfig, writeConfig } from "@/features/config/config.query";
|
|
21
|
+
import type { LiveClose } from "@/lib/live/live.schema";
|
|
17
22
|
import {
|
|
18
23
|
type CallRecord,
|
|
24
|
+
type CallThought,
|
|
19
25
|
type CallTurn,
|
|
20
26
|
isSkillsOn,
|
|
21
27
|
THURSDAY_KEYS,
|
|
@@ -35,7 +41,11 @@ export async function writeCallSkillsOn(on: boolean) {
|
|
|
35
41
|
await writeConfig(THURSDAY_KEYS.skills, on ? "on" : "off");
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
export async function insertCall(input: {
|
|
44
|
+
export async function insertCall(input: {
|
|
45
|
+
provider: string;
|
|
46
|
+
model: string;
|
|
47
|
+
backendModel: string;
|
|
48
|
+
}) {
|
|
39
49
|
const [call] = await database
|
|
40
50
|
.insert(callTable)
|
|
41
51
|
.values({ id: crypto.randomUUID(), ...input })
|
|
@@ -43,11 +53,23 @@ export async function insertCall(input: { provider: string; model: string }) {
|
|
|
43
53
|
return call.id;
|
|
44
54
|
}
|
|
45
55
|
|
|
46
|
-
/**
|
|
47
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Ends the call; false if it already ended, so end-of-call work runs once.
|
|
58
|
+
* `close` is what the provider confirmed on `session.closed`; without it the
|
|
59
|
+
* row keeps null seconds, which reads as "never confirmed", not as zero.
|
|
60
|
+
*/
|
|
61
|
+
export async function endCall(
|
|
62
|
+
id: string,
|
|
63
|
+
close?: LiveClose | null,
|
|
64
|
+
): Promise<boolean> {
|
|
48
65
|
const ended = await database
|
|
49
66
|
.update(callTable)
|
|
50
|
-
.set({
|
|
67
|
+
.set({
|
|
68
|
+
endedAt: new Date(),
|
|
69
|
+
...(close
|
|
70
|
+
? { endedReason: close.reason, seconds: close.seconds ?? null }
|
|
71
|
+
: {}),
|
|
72
|
+
})
|
|
51
73
|
.where(and(eq(callTable.id, id), isNull(callTable.endedAt)))
|
|
52
74
|
.returning({ id: callTable.id });
|
|
53
75
|
return ended.length > 0;
|
|
@@ -61,14 +83,28 @@ export async function saveTurns(callId: string, turns: CallTurn[]) {
|
|
|
61
83
|
for (const turn of turns) {
|
|
62
84
|
await database
|
|
63
85
|
.insert(callMessageTable)
|
|
64
|
-
.values({ callId, ...turn })
|
|
86
|
+
.values({ callId, ...turn, fragments: turn.fragments ?? null })
|
|
65
87
|
.onConflictDoUpdate({
|
|
66
88
|
target: [callMessageTable.callId, callMessageTable.id],
|
|
67
|
-
set: {
|
|
89
|
+
set: {
|
|
90
|
+
text: turn.text,
|
|
91
|
+
role: turn.role,
|
|
92
|
+
tool: turn.tool ?? null,
|
|
93
|
+
// A late fragment revises the group; the originals go with it.
|
|
94
|
+
fragments: turn.fragments ?? null,
|
|
95
|
+
},
|
|
68
96
|
});
|
|
69
97
|
}
|
|
70
98
|
}
|
|
71
99
|
|
|
100
|
+
/** A summary part arrives once, whole; a repeat keeps the first. */
|
|
101
|
+
export async function saveThought(callId: string, thought: CallThought) {
|
|
102
|
+
await database
|
|
103
|
+
.insert(callThoughtTable)
|
|
104
|
+
.values({ callId, ...thought })
|
|
105
|
+
.onConflictDoNothing();
|
|
106
|
+
}
|
|
107
|
+
|
|
72
108
|
export type CallGroup = {
|
|
73
109
|
callId: string;
|
|
74
110
|
startedAt: Date;
|
|
@@ -120,27 +156,6 @@ export async function listRecentTurns(limit: number): Promise<CallGroup[]> {
|
|
|
120
156
|
.map((group) => ({ ...group, turns: group.turns.reverse() }));
|
|
121
157
|
}
|
|
122
158
|
|
|
123
|
-
/** The last spoken turns of one call in order, without tool turns. */
|
|
124
|
-
export async function listCallTurns(
|
|
125
|
-
callId: string,
|
|
126
|
-
limit: number,
|
|
127
|
-
): Promise<{ role: "user" | "assistant"; text: string }[]> {
|
|
128
|
-
const rows = await database
|
|
129
|
-
.select({ role: callMessageTable.role, text: callMessageTable.text })
|
|
130
|
-
.from(callMessageTable)
|
|
131
|
-
.where(
|
|
132
|
-
and(
|
|
133
|
-
eq(callMessageTable.callId, callId),
|
|
134
|
-
inArray(callMessageTable.role, ["user", "assistant"]),
|
|
135
|
-
),
|
|
136
|
-
)
|
|
137
|
-
.orderBy(desc(callMessageTable.seq))
|
|
138
|
-
.limit(limit);
|
|
139
|
-
return rows
|
|
140
|
-
.reverse()
|
|
141
|
-
.map((row) => ({ role: row.role as "user" | "assistant", text: row.text }));
|
|
142
|
-
}
|
|
143
|
-
|
|
144
159
|
/**
|
|
145
160
|
* One page of a call, every turn in order, tool turns included; null when the
|
|
146
161
|
* call is gone. Tool turns keep their name and nothing else is read by the
|
|
@@ -202,7 +217,7 @@ export async function isAnyCallLive() {
|
|
|
202
217
|
|
|
203
218
|
/**
|
|
204
219
|
* Deletes an ended call and its turns (call_message cascades). A live call is
|
|
205
|
-
* refused: its tab keeps writing turns against the row.
|
|
220
|
+
* refused: its tab keeps writing turns against the row. Threads keep a dangling
|
|
206
221
|
* `callId`, which reads as "not on the line".
|
|
207
222
|
*/
|
|
208
223
|
export async function deleteCall(id: string): Promise<boolean> {
|
|
@@ -238,8 +253,11 @@ export async function listCallHistory(options: {
|
|
|
238
253
|
id: callTable.id,
|
|
239
254
|
provider: callTable.provider,
|
|
240
255
|
model: callTable.model,
|
|
256
|
+
backendModel: callTable.backendModel,
|
|
241
257
|
startedAt: callTable.startedAt,
|
|
242
258
|
endedAt: callTable.endedAt,
|
|
259
|
+
endedReason: callTable.endedReason,
|
|
260
|
+
seconds: callTable.seconds,
|
|
243
261
|
})
|
|
244
262
|
.from(callTable)
|
|
245
263
|
.innerJoin(callMessageTable, eq(callMessageTable.callId, callTable.id))
|
|
@@ -260,6 +278,7 @@ export async function listCallHistory(options: {
|
|
|
260
278
|
tool: callMessageTable.tool,
|
|
261
279
|
text: callMessageTable.text,
|
|
262
280
|
seq: callMessageTable.seq,
|
|
281
|
+
fragments: callMessageTable.fragments,
|
|
263
282
|
at: callMessageTable.at,
|
|
264
283
|
})
|
|
265
284
|
.from(callMessageTable)
|