thursday-agent 0.2.0 → 0.4.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 +12 -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 +25 -0
- 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 +134 -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/{_0pppbb5._.js → _1c78vw5._.js} +166 -37
- 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]__092knlj._.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]__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]__0s9dq5u._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__0m1b5ky._.js → [root-of-the-server]__0s9l2sv._.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]__0xsog8n._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0xtssj3._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +61 -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]__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]__1qfqvmg._.js → [root-of-the-server]__202p40z._.js} +2 -2
- package/.next/server/chunks/ssr/{_1mznrxk._.js → _001_ms1._.js} +3 -3
- package/.next/server/chunks/ssr/_01n3o0m._.js +3 -0
- package/.next/server/chunks/ssr/_0ap2fzn._.js +3 -0
- package/.next/server/chunks/ssr/_0fz4mf_._.js +3 -0
- package/.next/server/chunks/ssr/_0gb4gmf._.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/_0ilna52._.js +42 -0
- package/.next/server/chunks/ssr/_0n3toaw._.js +3 -0
- package/.next/server/chunks/ssr/{_13punpm._.js → _0q0zan6._.js} +2 -2
- package/.next/server/chunks/ssr/{_077-g6s._.js → _0s99bgb._.js} +3 -3
- package/.next/server/chunks/ssr/_0zcjrbg._.js +3 -0
- package/.next/server/chunks/ssr/_0zhoc3r._.js +3 -0
- package/.next/server/chunks/ssr/{_1lip4th._.js → _1-_etts._.js} +2 -2
- package/.next/server/chunks/ssr/_1-teee5._.js +3 -3
- package/.next/server/chunks/ssr/_13fke0x._.js +3 -0
- package/.next/server/chunks/ssr/_15j2_8f._.js +3 -0
- package/.next/server/chunks/ssr/_1b2mjwr._.js +3 -0
- package/.next/server/chunks/ssr/{_09ja_w1._.js → _1f-dg-6._.js} +2 -2
- package/.next/server/chunks/ssr/_1fojd41._.js +4 -0
- package/.next/server/chunks/ssr/_1gd8q8l._.js +3 -0
- package/.next/server/chunks/ssr/{_1m3bsfr._.js → _1h0rw11._.js} +2 -2
- package/.next/server/chunks/ssr/_1jhd09t._.js +3 -0
- package/.next/server/chunks/ssr/{_040sk32._.js → _1lz_cq2._.js} +84 -88
- package/.next/server/chunks/ssr/_1nnsk7z._.js +3 -0
- package/.next/server/chunks/ssr/_1sji22n._.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/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/{node_modules_0kxz4gt._.js → node_modules_00etblx._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_18_dk7_._.js → node_modules_04jf_m8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0_n241r._.js → node_modules_08dhkiq._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0n1kj4p._.js → node_modules_0940ns5._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_17lrt3y._.js → node_modules_09q35v_._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1toafc-._.js → node_modules_0_-_a--._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0lrjk5t._.js → node_modules_0arus10._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_04n7mjs._.js → node_modules_0b__sgl._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0iz1rzd._.js → node_modules_0cxaxk9._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0ndvxub._.js → node_modules_0g7fzk3._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0kl7-tn._.js → node_modules_0had7xd._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_19dp7ko._.js → node_modules_0pvd7q-._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_0x3-ply._.js +3 -0
- package/.next/server/chunks/ssr/{node_modules_1dwguw_._.js → node_modules_0yugy6m._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_004qlr4._.js → node_modules_14om4ar._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1q0p85z._.js → node_modules_14q6g4n._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_17bwo43._.js +55 -0
- package/.next/server/chunks/ssr/{node_modules_1hd-5tv._.js → node_modules_198nmll._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0m93zeg._.js → node_modules_1_pc9kq._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1n5ygqe._.js → node_modules_1aaxuef._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_01qnv-a._.js → node_modules_1cx_ql6._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1zu988w._.js → node_modules_1cz2hle._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1xyd7ov._.js → node_modules_1efrqxi._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_13r44jq._.js → node_modules_1eg7m6c._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_08d8bke._.js → node_modules_1gdh31p._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1hn8z1f._.js → node_modules_1hpopmo._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_20yebtj._.js → node_modules_1qpjvy5._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_09xhur7._.js → node_modules_1vh5ntv._.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_1b748ic._.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_1z4hm5e._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_@vercel_oidc_dist_06mk8id._.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/00rd4-v8r7axp.js +1 -0
- package/.next/static/chunks/08qe4as2q428z.js +3 -0
- package/.next/static/chunks/{31ttnjt6g35a0.js → 0ev4hyghq0mbb.js} +1 -1
- package/.next/static/chunks/0fl3gwe4-l6tz.js +1 -0
- package/.next/static/chunks/0gnqdjn2lvdad.js +2 -0
- package/.next/static/chunks/0hwap1-p0m5sa.js +1 -0
- package/.next/static/chunks/0r5qcctujhxli.js +1 -0
- package/.next/static/chunks/0w52rrrmuj9r9.js +1 -0
- package/.next/static/chunks/{07kl352c-lvcz.js → 0wcprt5ot5she.js} +1 -1
- package/.next/static/chunks/10teww7wt-f6h.js +1 -0
- package/.next/static/chunks/15m575979un5f.js +38 -0
- package/.next/static/chunks/17p6tk6k88dq6.js +1 -0
- package/.next/static/chunks/{3_h9txt3tq8t8.js → 1dkjg87pxk0n9.js} +1 -1
- package/.next/static/chunks/1jd09sxcjddu1.js +1 -0
- package/.next/static/chunks/1kq8h8wi_e0bc.js +53 -0
- package/.next/static/chunks/{18vhba44l1fc9.js → 1w73ece_6bheu.js} +1 -1
- package/.next/static/chunks/{3ard_noqapnw1.js → 214ya3n5gxeih.js} +1 -1
- package/.next/static/chunks/22_zkas21rpna.js +1 -0
- package/.next/static/chunks/2h0sd2vumhb15.js +1 -0
- package/.next/static/chunks/2t4vhi3m8ahya.js +1 -0
- package/.next/static/chunks/2tigdtz3dpcy8.js +1 -0
- package/.next/static/chunks/2u7xt6mxg44lf.js +1 -0
- package/.next/static/chunks/39j0fvpybzabl.js +40 -0
- package/.next/static/chunks/3akmqm77muj4-.js +1 -0
- package/.next/static/chunks/3cq5g494yuke8.css +1 -0
- package/.next/static/chunks/3woj-xd7ki5_i.js +1 -0
- package/.next/static/chunks/3xk7yqgomx7yq.js +1 -0
- package/.next/static/chunks/3zmcsnuo25zvq.js +1 -0
- package/.next/static/media/favicon.37o1pjldwi2uc.ico +0 -0
- package/README.md +47 -22
- 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 -7
- 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/port.mjs +65 -0
- package/bin/thursday.mjs +5 -33
- 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/docs/how-it-works.md +11 -7
- package/docs/images/face-dark.png +0 -0
- package/docs/images/face-light.png +0 -0
- package/docs/images/keeps-going.png +0 -0
- package/features/ai/chatgpt.ts +639 -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 +78 -56
- package/features/ai/model.schema.ts +232 -34
- package/features/ai/model.ts +169 -24
- package/features/ai/prompts/bot.prompt.ts +207 -114
- 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 +57 -27
- package/features/ai/tools/bot.tool.ts +35 -52
- package/features/ai/tools/connected.ts +17 -4
- package/features/ai/tools/memory.tool.ts +181 -117
- package/features/ai/tools/search.tool.ts +136 -47
- package/features/ai/tools/tool-name.ts +2 -6
- package/features/ai/tools/workspace.tool.ts +5 -1
- package/features/bot/bot.action.ts +14 -19
- package/features/bot/bot.memory.ts +89 -0
- package/features/bot/bot.query.ts +37 -57
- package/features/bot/bot.run.ts +512 -242
- package/features/bot/bot.runner.ts +434 -120
- package/features/bot/bot.schema.ts +104 -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 +214 -132
- package/features/bot/components/bot-setting.tsx +790 -402
- package/features/bot/components/bot-tool.tsx +2 -7
- 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 +240 -34
- package/features/bot/task.store.ts +76 -13
- 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 +340 -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 -98
- 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 -12
- package/features/thursday/use-thursday.ts +87 -60
- 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/components/memory-view.tsx +0 -84
- 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 → kaTO0UHqF1bMnWgCDik2f}/_buildManifest.js +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → kaTO0UHqF1bMnWgCDik2f}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → kaTO0UHqF1bMnWgCDik2f}/_ssgManifest.js +0 -0
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import type { AssistantContent, ModelMessage, ToolContent } from "ai";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
and,
|
|
4
|
+
desc,
|
|
5
|
+
eq,
|
|
6
|
+
inArray,
|
|
7
|
+
isNotNull,
|
|
8
|
+
isNull,
|
|
9
|
+
lt,
|
|
10
|
+
max,
|
|
11
|
+
sql,
|
|
12
|
+
} from "drizzle-orm";
|
|
3
13
|
import { appEvents } from "@/app/api/events/app-event.server";
|
|
14
|
+
import { INBOX_FINISHED } from "@/config";
|
|
4
15
|
import { database } from "@/database/db";
|
|
5
16
|
import { taskMessageTable, taskTable } from "@/database/tables";
|
|
6
|
-
import {
|
|
17
|
+
import { answerAccepted, isAnswerCall } from "@/features/ai/tools/bot.tool";
|
|
7
18
|
import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
|
|
8
19
|
import { clip } from "@/lib/utils";
|
|
9
20
|
import {
|
|
@@ -11,8 +22,10 @@ import {
|
|
|
11
22
|
TASK_HISTORY_PAGE,
|
|
12
23
|
type Task,
|
|
13
24
|
type TaskLine,
|
|
25
|
+
type TaskPending,
|
|
14
26
|
type TaskStatus,
|
|
15
27
|
type TokenUsage,
|
|
28
|
+
untagSpeaker,
|
|
16
29
|
} from "./bot.schema";
|
|
17
30
|
|
|
18
31
|
// Tasks and their threads. Bots themselves (roster, pinned tools) are bot.query.
|
|
@@ -29,7 +42,7 @@ const taskView = {
|
|
|
29
42
|
status: taskTable.status,
|
|
30
43
|
outcome: taskTable.outcome,
|
|
31
44
|
pending: taskTable.pending,
|
|
32
|
-
|
|
45
|
+
seen: taskTable.seen,
|
|
33
46
|
inputTokens: taskTable.inputTokens,
|
|
34
47
|
outputTokens: taskTable.outputTokens,
|
|
35
48
|
contextTokens: taskTable.contextTokens,
|
|
@@ -45,8 +58,8 @@ type TaskRow = {
|
|
|
45
58
|
request: string;
|
|
46
59
|
status: TaskStatus;
|
|
47
60
|
outcome: string | null;
|
|
48
|
-
pending:
|
|
49
|
-
|
|
61
|
+
pending: TaskPending | null;
|
|
62
|
+
seen: boolean;
|
|
50
63
|
inputTokens: number;
|
|
51
64
|
outputTokens: number;
|
|
52
65
|
contextTokens: number;
|
|
@@ -55,12 +68,9 @@ type TaskRow = {
|
|
|
55
68
|
updatedAt: Date;
|
|
56
69
|
};
|
|
57
70
|
|
|
58
|
-
/** How many finished tasks the inbox keeps; the rest live in Settings > Tasks. */
|
|
59
|
-
const INBOX_RECENT_FINISHED = 3;
|
|
60
|
-
|
|
61
71
|
/**
|
|
62
72
|
* One row plus the thread's first message. `request` is what the screen shows;
|
|
63
|
-
* `opening` is what the model reads (
|
|
73
|
+
* `opening` is what the model reads (who is who, the job, the call it came from). The screen
|
|
64
74
|
* skips seq 0 and shows `request` instead (linesOf).
|
|
65
75
|
*/
|
|
66
76
|
export async function insertTask(input: {
|
|
@@ -68,7 +78,7 @@ export async function insertTask(input: {
|
|
|
68
78
|
label: string;
|
|
69
79
|
request: string;
|
|
70
80
|
callId?: string | null;
|
|
71
|
-
opening:
|
|
81
|
+
opening: Extract<ModelMessage, { role: "user" }>["content"];
|
|
72
82
|
}) {
|
|
73
83
|
const { opening, ...row } = input;
|
|
74
84
|
const [task] = await database
|
|
@@ -90,9 +100,11 @@ export async function updateTask(
|
|
|
90
100
|
patch: Partial<{
|
|
91
101
|
status: TaskStatus;
|
|
92
102
|
outcome: string | null;
|
|
93
|
-
pending:
|
|
94
|
-
|
|
103
|
+
pending: TaskPending | null;
|
|
104
|
+
seen: boolean;
|
|
95
105
|
endedAt: Date | null;
|
|
106
|
+
/** Where the job compacts from now on; also written at every step (addTaskUsage). */
|
|
107
|
+
contextBudget: number;
|
|
96
108
|
}>,
|
|
97
109
|
) {
|
|
98
110
|
await database
|
|
@@ -102,12 +114,12 @@ export async function updateTask(
|
|
|
102
114
|
changed();
|
|
103
115
|
}
|
|
104
116
|
|
|
105
|
-
/** Bypasses `updateTask` on purpose:
|
|
106
|
-
export async function
|
|
117
|
+
/** Bypasses `updateTask` on purpose: being seen is not movement and must not reorder the inbox by updatedAt. */
|
|
118
|
+
export async function markSeen(ids: string[]) {
|
|
107
119
|
if (ids.length === 0) return;
|
|
108
120
|
await database
|
|
109
121
|
.update(taskTable)
|
|
110
|
-
.set({
|
|
122
|
+
.set({ seen: true })
|
|
111
123
|
.where(inArray(taskTable.id, ids));
|
|
112
124
|
changed();
|
|
113
125
|
}
|
|
@@ -155,7 +167,7 @@ export async function findTask(id: string) {
|
|
|
155
167
|
return task ?? null;
|
|
156
168
|
}
|
|
157
169
|
|
|
158
|
-
/** Inbox: everything running or waiting plus the
|
|
170
|
+
/** Inbox: everything running or waiting plus the latest INBOX_FINISHED endings, newest first. `seen` is not a filter here. */
|
|
159
171
|
export async function listInboxTasks(): Promise<Task[]> {
|
|
160
172
|
const [open, finished] = await Promise.all([
|
|
161
173
|
database
|
|
@@ -168,7 +180,7 @@ export async function listInboxTasks(): Promise<Task[]> {
|
|
|
168
180
|
.from(taskTable)
|
|
169
181
|
.where(inArray(taskTable.status, ["done", "failed"]))
|
|
170
182
|
.orderBy(desc(taskTable.updatedAt))
|
|
171
|
-
.limit(
|
|
183
|
+
.limit(INBOX_FINISHED),
|
|
172
184
|
]);
|
|
173
185
|
const rows = [...open, ...finished].sort(
|
|
174
186
|
(a, b) => b.updatedAt.getTime() - a.updatedAt.getTime(),
|
|
@@ -251,6 +263,177 @@ export async function listRunningTaskIds() {
|
|
|
251
263
|
return rows.map((row) => row.id);
|
|
252
264
|
}
|
|
253
265
|
|
|
266
|
+
/** Every job with what names its folder and whether it still keeps it (bot.runner sweepJobFiles). */
|
|
267
|
+
export async function listTaskFolders() {
|
|
268
|
+
return await database
|
|
269
|
+
.select({
|
|
270
|
+
id: taskTable.id,
|
|
271
|
+
label: taskTable.label,
|
|
272
|
+
status: taskTable.status,
|
|
273
|
+
endedAt: taskTable.endedAt,
|
|
274
|
+
updatedAt: taskTable.updatedAt,
|
|
275
|
+
})
|
|
276
|
+
.from(taskTable);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/** Jobs the app parked to pick back up by itself (bot.runner parkTask), and when each may go. */
|
|
280
|
+
export async function listAutoStoppedTasks() {
|
|
281
|
+
const rows = await database
|
|
282
|
+
.select({ id: taskTable.id, pending: taskTable.pending })
|
|
283
|
+
.from(taskTable)
|
|
284
|
+
.where(eq(taskTable.status, "waiting"));
|
|
285
|
+
return rows.flatMap((row) =>
|
|
286
|
+
row.pending?.auto
|
|
287
|
+
? [{ id: row.id, retryAt: row.pending.retryAt ?? 0 }]
|
|
288
|
+
: [],
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* How many times the app has stopped this job since a person last said anything
|
|
294
|
+
* to it: the notes it left in the thread — a break, a park — back to the last row
|
|
295
|
+
* a person wrote: the opening, an answer, a word to a running job. Read off the
|
|
296
|
+
* rows rather than kept as a count, so it cannot drift from what the thread shows.
|
|
297
|
+
*/
|
|
298
|
+
export async function countStopsSinceSpoken(taskId: string): Promise<number> {
|
|
299
|
+
const rows = await database
|
|
300
|
+
.select({
|
|
301
|
+
role: taskMessageTable.role,
|
|
302
|
+
bot: taskMessageTable.bot,
|
|
303
|
+
note: taskMessageTable.note,
|
|
304
|
+
compact: taskMessageTable.compact,
|
|
305
|
+
})
|
|
306
|
+
.from(taskMessageTable)
|
|
307
|
+
.where(
|
|
308
|
+
and(eq(taskMessageTable.taskId, taskId), isNull(taskMessageTable.parent)),
|
|
309
|
+
)
|
|
310
|
+
.orderBy(desc(taskMessageTable.seq));
|
|
311
|
+
let stops = 0;
|
|
312
|
+
for (const row of rows) {
|
|
313
|
+
if (row.note) {
|
|
314
|
+
if (!row.compact) stops += 1;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
// A person: the opening and every answer are written with no bot, and a
|
|
318
|
+
// word to a running job is a user row in the bot's name
|
|
319
|
+
if (row.bot === null || row.role === "user") break;
|
|
320
|
+
}
|
|
321
|
+
return stops;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/** How much of a cut-off borrowed bot's prose a resume carries: its last few paragraphs. */
|
|
325
|
+
const TAIL = { texts: 3, chars: 600 };
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* What each borrowed bot had written when its `ask_bot` call stopped, by that
|
|
329
|
+
* call's id: its last few paragraphs, and the tool it reached for after them. A
|
|
330
|
+
* resumed run reads it where the call's result never arrived (bot.run
|
|
331
|
+
* resumeThread), so a part cut off half-way is carried on, not asked for afresh.
|
|
332
|
+
*/
|
|
333
|
+
export async function listBorrowedTails(
|
|
334
|
+
taskId: string,
|
|
335
|
+
): Promise<Map<string, { bot: string; tail: string }>> {
|
|
336
|
+
const rows = await database
|
|
337
|
+
.select({
|
|
338
|
+
parent: taskMessageTable.parent,
|
|
339
|
+
bot: taskMessageTable.bot,
|
|
340
|
+
content: taskMessageTable.content,
|
|
341
|
+
})
|
|
342
|
+
.from(taskMessageTable)
|
|
343
|
+
.where(
|
|
344
|
+
and(
|
|
345
|
+
eq(taskMessageTable.taskId, taskId),
|
|
346
|
+
isNotNull(taskMessageTable.parent),
|
|
347
|
+
eq(taskMessageTable.role, "assistant"),
|
|
348
|
+
),
|
|
349
|
+
)
|
|
350
|
+
.orderBy(taskMessageTable.seq);
|
|
351
|
+
|
|
352
|
+
const calls = new Map<
|
|
353
|
+
string,
|
|
354
|
+
{ bot: string; texts: string[]; then: string | null }
|
|
355
|
+
>();
|
|
356
|
+
for (const row of rows) {
|
|
357
|
+
if (!row.parent) continue;
|
|
358
|
+
const call = calls.get(row.parent) ?? {
|
|
359
|
+
bot: row.bot ?? "",
|
|
360
|
+
texts: [],
|
|
361
|
+
then: null,
|
|
362
|
+
};
|
|
363
|
+
const content = row.content as AssistantContent;
|
|
364
|
+
const parts =
|
|
365
|
+
typeof content === "string"
|
|
366
|
+
? [{ type: "text" as const, text: content }]
|
|
367
|
+
: content;
|
|
368
|
+
for (const part of parts) {
|
|
369
|
+
if (part.type === "text" && part.text.trim()) {
|
|
370
|
+
call.texts.push(part.text.trim());
|
|
371
|
+
call.then = null;
|
|
372
|
+
} else if (part.type === "tool-call") {
|
|
373
|
+
call.then =
|
|
374
|
+
`${part.toolName} ${toolLine(part.toolName, part.input)}`.trim();
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
calls.set(row.parent, call);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const tails = new Map<string, { bot: string; tail: string }>();
|
|
381
|
+
for (const [id, call] of calls) {
|
|
382
|
+
const tail = [
|
|
383
|
+
...call.texts.slice(-TAIL.texts).map((text) => clip(text, TAIL.chars)),
|
|
384
|
+
call.then ? `Then: ${call.then}` : "",
|
|
385
|
+
]
|
|
386
|
+
.filter(Boolean)
|
|
387
|
+
.join("\n\n");
|
|
388
|
+
if (tail) tails.set(id, { bot: call.bot, tail });
|
|
389
|
+
}
|
|
390
|
+
return tails;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Paths a list of message contents gave `write_file`, oldest first and each once; a
|
|
395
|
+
* path written again moves to the end. A refused write is here too, so whoever shows
|
|
396
|
+
* them checks the disk (workspace.ts filesOnDisk).
|
|
397
|
+
*/
|
|
398
|
+
export function writtenPathsIn(contents: unknown[]): string[] {
|
|
399
|
+
const paths = new Set<string>();
|
|
400
|
+
for (const content of contents) {
|
|
401
|
+
if (!Array.isArray(content)) continue;
|
|
402
|
+
for (const part of content as {
|
|
403
|
+
type?: unknown;
|
|
404
|
+
toolName?: unknown;
|
|
405
|
+
input?: unknown;
|
|
406
|
+
}[]) {
|
|
407
|
+
if (
|
|
408
|
+
part.type !== "tool-call" ||
|
|
409
|
+
part.toolName !== TOOL_NAMES.write_file
|
|
410
|
+
) {
|
|
411
|
+
continue;
|
|
412
|
+
}
|
|
413
|
+
const path = (part.input as { path?: unknown } | null)?.path;
|
|
414
|
+
if (typeof path !== "string" || !path.trim()) continue;
|
|
415
|
+
paths.delete(path.trim());
|
|
416
|
+
paths.add(path.trim());
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return [...paths];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/** Every path this job gave `write_file`: its own bot and each bot it borrowed (writtenPathsIn). */
|
|
423
|
+
export async function listWrittenPaths(taskId: string): Promise<string[]> {
|
|
424
|
+
const rows = await database
|
|
425
|
+
.select({ content: taskMessageTable.content })
|
|
426
|
+
.from(taskMessageTable)
|
|
427
|
+
.where(
|
|
428
|
+
and(
|
|
429
|
+
eq(taskMessageTable.taskId, taskId),
|
|
430
|
+
eq(taskMessageTable.role, "assistant"),
|
|
431
|
+
),
|
|
432
|
+
)
|
|
433
|
+
.orderBy(taskMessageTable.seq);
|
|
434
|
+
return writtenPathsIn(rows.map((row) => row.content));
|
|
435
|
+
}
|
|
436
|
+
|
|
254
437
|
/**
|
|
255
438
|
* Finds a task by id or by exact label (case-insensitive). No looser matching:
|
|
256
439
|
* a miss returns null and the caller lists recent tasks instead.
|
|
@@ -337,7 +520,8 @@ export async function lastSeq(taskId: string): Promise<number> {
|
|
|
337
520
|
/**
|
|
338
521
|
* The task's own thread as the model sees it: parent-less messages in order.
|
|
339
522
|
* What a borrowed bot said inside an `ask_bot` call is not here; its result is.
|
|
340
|
-
*
|
|
523
|
+
* After a compaction it is the opening, then the last compact row on: a summary
|
|
524
|
+
* replaces what came after the job and the call, never the job and the call.
|
|
341
525
|
*/
|
|
342
526
|
export async function listThread(taskId: string): Promise<ModelMessage[]> {
|
|
343
527
|
const rows = await database
|
|
@@ -352,9 +536,10 @@ export async function listThread(taskId: string): Promise<ModelMessage[]> {
|
|
|
352
536
|
)
|
|
353
537
|
.orderBy(taskMessageTable.seq);
|
|
354
538
|
const from = rows.findLastIndex((row) => row.compact);
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
539
|
+
const kept = from > 0 ? [rows[0], ...rows.slice(from)] : rows;
|
|
540
|
+
return kept.map(
|
|
541
|
+
(row) => ({ role: row.role, content: row.content }) as ModelMessage,
|
|
542
|
+
);
|
|
358
543
|
}
|
|
359
544
|
|
|
360
545
|
/** One row in the screen's shape; `pending` folds into `ask`. */
|
|
@@ -365,7 +550,11 @@ function viewOf(row: TaskRow, lines: TaskLine[]): Task {
|
|
|
365
550
|
...rest,
|
|
366
551
|
ask:
|
|
367
552
|
row.status === "waiting"
|
|
368
|
-
? {
|
|
553
|
+
? {
|
|
554
|
+
question: row.outcome ?? "",
|
|
555
|
+
options: pending?.options ?? [],
|
|
556
|
+
auto: pending?.auto === true,
|
|
557
|
+
}
|
|
369
558
|
: null,
|
|
370
559
|
tokens: { input: inputTokens, output: outputTokens },
|
|
371
560
|
lines,
|
|
@@ -428,8 +617,7 @@ function labelOf(args: Record<string, unknown>): string | null {
|
|
|
428
617
|
}
|
|
429
618
|
|
|
430
619
|
/**
|
|
431
|
-
* One tool call as one line
|
|
432
|
-
* re-read history (bot.run condenseThread). No per-tool summary table: the
|
|
620
|
+
* One tool call as one line, for the screen. No per-tool summary table: the
|
|
433
621
|
* label is model-written (bash `description`), other tools use the first
|
|
434
622
|
* telling argument, else the argument shape.
|
|
435
623
|
*/
|
|
@@ -501,6 +689,13 @@ export async function readToolResult(
|
|
|
501
689
|
return null;
|
|
502
690
|
}
|
|
503
691
|
|
|
692
|
+
/** Said to a resumed run after why it stopped. The screen shows only the why (linesOf). */
|
|
693
|
+
const IN_FLIGHT =
|
|
694
|
+
"Anything that was under way — a command, a page loading, a download — may not have finished: check before relying on it, then carry on.";
|
|
695
|
+
|
|
696
|
+
/** The thread line a stop the app made leaves (bot.runner parkTask). */
|
|
697
|
+
export const stopNote = (why: string) => `${why} ${IN_FLIGHT}`;
|
|
698
|
+
|
|
504
699
|
type StoredMessage = typeof taskMessageTable.$inferSelect;
|
|
505
700
|
|
|
506
701
|
/**
|
|
@@ -523,11 +718,17 @@ function linesOf(message: StoredMessage, owner: string): TaskLine[] {
|
|
|
523
718
|
if (message.seq === 0) return [];
|
|
524
719
|
const text = typeof content === "string" ? content : textOf(content);
|
|
525
720
|
if (!text) return [];
|
|
526
|
-
// The app's own
|
|
527
|
-
//
|
|
528
|
-
if (message.note
|
|
529
|
-
|
|
530
|
-
|
|
721
|
+
// The app's own lines, never the user's words. `compact` alone marks a
|
|
722
|
+
// compaction: rows written before `note` existed carry only that.
|
|
723
|
+
if (message.compact) return [{ ...base, id: id(0), kind: "note", text }];
|
|
724
|
+
if (message.note) {
|
|
725
|
+
const why = text.endsWith(IN_FLIGHT)
|
|
726
|
+
? text.slice(0, -IN_FLIGHT.length).trimEnd()
|
|
727
|
+
: text;
|
|
728
|
+
return [{ ...base, id: id(0), kind: "stop", text: why }];
|
|
729
|
+
}
|
|
730
|
+
// Tagged with who said it for the bot (bot.schema tagSpeaker); the screen draws the words
|
|
731
|
+
return [{ ...base, id: id(0), kind: "user", text: untagSpeaker(text) }];
|
|
531
732
|
}
|
|
532
733
|
|
|
533
734
|
if (message.role === "assistant") {
|
|
@@ -560,8 +761,8 @@ function linesOf(message: StoredMessage, owner: string): TaskLine[] {
|
|
|
560
761
|
question: String(args.question ?? ""),
|
|
561
762
|
options: optionsOf(args.options),
|
|
562
763
|
});
|
|
563
|
-
} else if (part.toolName
|
|
564
|
-
// The
|
|
764
|
+
} else if (isAnswerCall(part.toolName)) {
|
|
765
|
+
// The answer is a tool call but draws as text: it is the last thing said
|
|
565
766
|
// in the thread, and taskFromRow promotes it to the result line
|
|
566
767
|
const text = String(args.result ?? "").trim();
|
|
567
768
|
if (text) lines.push({ ...base, id: id(index), kind: "text", text });
|
|
@@ -620,8 +821,8 @@ function linesOf(message: StoredMessage, owner: string): TaskLine[] {
|
|
|
620
821
|
const lines: TaskLine[] = [];
|
|
621
822
|
(message.content as ToolContent).forEach((part, index) => {
|
|
622
823
|
if (part.type !== "tool-result") return;
|
|
623
|
-
if (part.toolName
|
|
624
|
-
// An accepted
|
|
824
|
+
if (isAnswerCall(part.toolName) && answerAccepted(part.output)) {
|
|
825
|
+
// An accepted answer's result is only a confirmation; the answer itself
|
|
625
826
|
// was drawn from the call. A rejected one is drawn: it explains the next step
|
|
626
827
|
return;
|
|
627
828
|
}
|
|
@@ -630,7 +831,12 @@ function linesOf(message: StoredMessage, owner: string): TaskLine[] {
|
|
|
630
831
|
const text = resultParts(part.output, RESULT_LINES)
|
|
631
832
|
.flatMap((result) => (result.type === "text" ? [result.text] : []))
|
|
632
833
|
.join("\n");
|
|
633
|
-
lines.push({
|
|
834
|
+
lines.push({
|
|
835
|
+
...base,
|
|
836
|
+
id: id(index),
|
|
837
|
+
kind: "user",
|
|
838
|
+
text: untagSpeaker(text),
|
|
839
|
+
});
|
|
634
840
|
} else if (
|
|
635
841
|
part.toolName === TOOL_NAMES.ask_bot ||
|
|
636
842
|
part.toolName === TOOL_NAMES.ask_back
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useSyncExternalStore } from "react";
|
|
3
|
+
import { useEffect, useRef, useSyncExternalStore } from "react";
|
|
4
|
+
import { queryKey } from "@/app/api/query-key";
|
|
5
|
+
import { toast } from "@/components/ui/toast";
|
|
6
|
+
import { markSeenAction } from "@/features/bot/bot.action";
|
|
4
7
|
import type {
|
|
5
8
|
Bot,
|
|
6
9
|
BotIcon,
|
|
@@ -8,7 +11,10 @@ import type {
|
|
|
8
11
|
Task,
|
|
9
12
|
TokenUsage,
|
|
10
13
|
} from "@/features/bot/bot.schema";
|
|
11
|
-
import type
|
|
14
|
+
import { type DateLike, toDate } from "@/lib/date-like";
|
|
15
|
+
import { unwrapResult } from "@/lib/protocol/result";
|
|
16
|
+
import { revalidate } from "@/lib/protocol/use-server-route";
|
|
17
|
+
import { errorToString } from "@/lib/utils";
|
|
12
18
|
|
|
13
19
|
/**
|
|
14
20
|
* Client mirror of tasks, keyed by task rather than as one message stream so
|
|
@@ -18,7 +24,11 @@ import type { DateLike } from "@/lib/date-like";
|
|
|
18
24
|
|
|
19
25
|
export type BotRef = { name: string; icon?: BotIcon | null };
|
|
20
26
|
|
|
21
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* `note` and `stop` are the app's markers, not speech. `note` is a compaction
|
|
29
|
+
* summary (bot.run compact), drawn as a divider; `stop` is where the app stopped
|
|
30
|
+
* the run (bot.runner parkTask), drawn muted in the bot's turn.
|
|
31
|
+
*/
|
|
22
32
|
export type ChatterKind =
|
|
23
33
|
| "say"
|
|
24
34
|
| "ask"
|
|
@@ -26,7 +36,8 @@ export type ChatterKind =
|
|
|
26
36
|
| "user"
|
|
27
37
|
| "result"
|
|
28
38
|
| "error"
|
|
29
|
-
| "note"
|
|
39
|
+
| "note"
|
|
40
|
+
| "stop";
|
|
30
41
|
|
|
31
42
|
/** One tool call. `name` picks the renderer (components/bot-tool); `results` arrive after the call. */
|
|
32
43
|
export type ToolUse = {
|
|
@@ -57,6 +68,8 @@ export type Chatter = {
|
|
|
57
68
|
tool?: ToolUse;
|
|
58
69
|
/** Options attached to a question; only on the line where the bot stopped to ask. */
|
|
59
70
|
options?: string[];
|
|
71
|
+
/** When it was written; only for kind `stop`, whose repeats fold into one line. */
|
|
72
|
+
at?: DateLike;
|
|
60
73
|
};
|
|
61
74
|
|
|
62
75
|
/** `waiting`: the bot stopped to ask the user something. */
|
|
@@ -76,9 +89,9 @@ export type TaskView = {
|
|
|
76
89
|
/** Text it came back with; only after it returned. */
|
|
77
90
|
outcome: string | null;
|
|
78
91
|
/** What it is asking while `waiting`. */
|
|
79
|
-
ask:
|
|
80
|
-
/** Whether
|
|
81
|
-
|
|
92
|
+
ask: Task["ask"];
|
|
93
|
+
/** Whether the user has had the ending (Task `seen`). */
|
|
94
|
+
seen: boolean;
|
|
82
95
|
/** Burned so far. */
|
|
83
96
|
tokens: TokenUsage;
|
|
84
97
|
/** Context read on the last step and the compaction threshold; the header meter is their ratio. Both 0 means no step ran yet. */
|
|
@@ -153,6 +166,16 @@ export function taskFromRow(row: Task, bots?: Bot[]): TaskView {
|
|
|
153
166
|
case "note":
|
|
154
167
|
lines.push({ id: line.id, bot, to, text: line.text, kind: "note" });
|
|
155
168
|
break;
|
|
169
|
+
case "stop":
|
|
170
|
+
lines.push({
|
|
171
|
+
id: line.id,
|
|
172
|
+
bot,
|
|
173
|
+
to,
|
|
174
|
+
text: line.text,
|
|
175
|
+
kind: "stop",
|
|
176
|
+
at: line.at,
|
|
177
|
+
});
|
|
178
|
+
break;
|
|
156
179
|
case "tool":
|
|
157
180
|
openLines.set(line.callId, lines.length);
|
|
158
181
|
lines.push({
|
|
@@ -219,9 +242,9 @@ export function taskFromRow(row: Task, bots?: Bot[]): TaskView {
|
|
|
219
242
|
}
|
|
220
243
|
}
|
|
221
244
|
|
|
222
|
-
// The ending lives on the row, not in the thread: the
|
|
245
|
+
// The ending lives on the row, not in the thread: the answer is the last text
|
|
223
246
|
// said, failure exists only here. `waiting` is treated like done: a job that
|
|
224
|
-
//
|
|
247
|
+
// the app stopped answered first, so that line is a result.
|
|
225
248
|
if (row.status === "failed" && row.outcome) {
|
|
226
249
|
lines.push({
|
|
227
250
|
id: `${row.id}-end`,
|
|
@@ -246,7 +269,7 @@ export function taskFromRow(row: Task, bots?: Bot[]): TaskView {
|
|
|
246
269
|
status: row.status === "running" ? "working" : row.status,
|
|
247
270
|
outcome: row.outcome,
|
|
248
271
|
ask: row.ask,
|
|
249
|
-
|
|
272
|
+
seen: row.seen,
|
|
250
273
|
tokens: row.tokens,
|
|
251
274
|
contextTokens: row.contextTokens,
|
|
252
275
|
contextBudget: row.contextBudget,
|
|
@@ -258,7 +281,8 @@ export function taskFromRow(row: Task, bots?: Bot[]): TaskView {
|
|
|
258
281
|
export function lastSaid(task: TaskView): Chatter | null {
|
|
259
282
|
for (let at = task.lines.length - 1; at >= 0; at--) {
|
|
260
283
|
const line = task.lines[at];
|
|
261
|
-
if (line.kind !== "user" && line.kind !== "note"
|
|
284
|
+
if (line.kind !== "user" && line.kind !== "note" && line.kind !== "stop")
|
|
285
|
+
return line;
|
|
262
286
|
}
|
|
263
287
|
return null;
|
|
264
288
|
}
|
|
@@ -266,7 +290,7 @@ export function lastSaid(task: TaskView): Chatter | null {
|
|
|
266
290
|
/**
|
|
267
291
|
* What the screen did to a task. Announced so the call can hear it: a poll
|
|
268
292
|
* cannot tell a screen answer from a voice answer, and a cancel is never relayed
|
|
269
|
-
* (bot.runner cancelTask marks it
|
|
293
|
+
* (bot.runner cancelTask marks it seen).
|
|
270
294
|
*/
|
|
271
295
|
export type ScreenAct =
|
|
272
296
|
/** Answered a waiting task, interjected into a running one, or continued a finished one. */
|
|
@@ -406,7 +430,8 @@ export function latestPerBot(list: TaskView[]): BotLine[] {
|
|
|
406
430
|
byBot.set(task.bot.name, { bot: task.bot, task, line: null, open: 0 });
|
|
407
431
|
}
|
|
408
432
|
for (const line of task.lines) {
|
|
409
|
-
if (line.kind === "user" || line.kind === "note")
|
|
433
|
+
if (line.kind === "user" || line.kind === "note" || line.kind === "stop")
|
|
434
|
+
continue;
|
|
410
435
|
byBot.set(line.bot.name, {
|
|
411
436
|
bot: line.bot,
|
|
412
437
|
task,
|
|
@@ -424,3 +449,41 @@ export function latestPerBot(list: TaskView[]): BotLine[] {
|
|
|
424
449
|
|
|
425
450
|
return [...byBot.values()];
|
|
426
451
|
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Opening a job's detail is reading its ending: the thread in the room, a row
|
|
455
|
+
* expanded in Settings › Tasks. That is what clears its dot — a list scrolled
|
|
456
|
+
* past or a line heard on a call is not. Keyed by `updatedAt` as well, because a
|
|
457
|
+
* follow-up ends a job a second time and that ending is new again.
|
|
458
|
+
*/
|
|
459
|
+
export function useSeenOnDetail(
|
|
460
|
+
task:
|
|
461
|
+
| { id: string; status: string; seen: boolean; updatedAt: DateLike }
|
|
462
|
+
| null
|
|
463
|
+
| undefined,
|
|
464
|
+
) {
|
|
465
|
+
const sent = useRef(new Set<string>());
|
|
466
|
+
const id = task?.id ?? null;
|
|
467
|
+
const key = task ? `${task.id}@${toDate(task.updatedAt).getTime()}` : null;
|
|
468
|
+
const owed =
|
|
469
|
+
!!task &&
|
|
470
|
+
(task.status === "done" || task.status === "failed") &&
|
|
471
|
+
!task.seen;
|
|
472
|
+
|
|
473
|
+
useEffect(() => {
|
|
474
|
+
if (!id || !key || !owed || sent.current.has(key)) return;
|
|
475
|
+
sent.current.add(key);
|
|
476
|
+
void markSeenAction([id])
|
|
477
|
+
.then(unwrapResult)
|
|
478
|
+
.then(() => revalidate(queryKey.tasks))
|
|
479
|
+
.catch((cause) => {
|
|
480
|
+
// Released, so opening it again tries again
|
|
481
|
+
sent.current.delete(key);
|
|
482
|
+
toast.add({
|
|
483
|
+
type: "error",
|
|
484
|
+
title: "Could not mark the task as read",
|
|
485
|
+
description: errorToString(cause),
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
}, [id, key, owed]);
|
|
489
|
+
}
|