thursday-agent 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +5 -2
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +5 -5
- package/.next/routes-manifest.json +24 -6
- package/.next/server/app/_global-error/page.js +2 -2
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +2 -2
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js +2 -2
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +14 -14
- package/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +12 -12
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/artifact/route.js +3 -3
- package/.next/server/app/api/artifact/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/files/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/bot/memory/files/route.js +10 -0
- package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -0
- package/.next/server/app/api/bot/memory/files/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/bot/memory/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/bot/memory/route.js +14 -0
- package/.next/server/app/api/bot/{notes → memory}/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/bot/route.js +6 -6
- package/.next/server/app/api/bot/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/task/[id]/route.js +8 -8
- package/.next/server/app/api/bot/task/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/task/route.js +8 -8
- package/.next/server/app/api/bot/task/route.js.nft.json +1 -1
- package/.next/server/app/api/config/route.js +5 -5
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/events/route.js +4 -5
- package/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/server/app/api/file/[...path]/route.js +3 -3
- package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/catalog/route.js +9 -8
- package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/credits/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/llm-model/credits/route/build-manifest.json +12 -0
- package/.next/server/app/api/llm-model/credits/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/llm-model/credits/route.js +16 -0
- package/.next/server/app/api/llm-model/credits/route.js.map +5 -0
- package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -0
- package/.next/server/app/api/llm-model/credits/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/llm-model/route.js +10 -8
- package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/subscription/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/llm-model/subscription/route/build-manifest.json +12 -0
- package/.next/server/app/api/llm-model/subscription/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/llm-model/subscription/route.js +15 -0
- package/.next/server/app/api/llm-model/subscription/route.js.map +5 -0
- package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -0
- package/.next/server/app/api/llm-model/subscription/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/mcp/[name]/route.js +4 -4
- package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth/callback/route.js +5 -5
- package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js +4 -4
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/tools/route.js +4 -4
- package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/edit/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/memory/edit/route/build-manifest.json +12 -0
- package/.next/server/app/api/memory/edit/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/memory/edit/route.js +24 -0
- package/.next/server/app/api/memory/edit/route.js.map +5 -0
- package/.next/server/app/api/memory/edit/route.js.nft.json +1 -0
- package/.next/server/app/api/memory/{tidy → edit}/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/memory/route.js +6 -7
- package/.next/server/app/api/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[source]/[name]/route.js +3 -3
- package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js +3 -3
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/call/route.js +9 -7
- package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/skills/route.js +9 -7
- package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/tool-call/route.js +17 -15
- package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/route.js +4 -5
- package/.next/server/app/api/workspace/route.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +1 -1
- package/.next/server/app/artifact/[...path]/page.js +5 -6
- package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/favicon.ico/route.js +3 -4
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/server/app/favicon.ico.body +0 -0
- package/.next/server/app/page/server-reference-manifest.json +57 -90
- package/.next/server/app/page.js +10 -10
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app-paths-manifest.json +5 -2
- package/.next/server/chunks/[externals]__0dzuk6_._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__01dkp4a._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__02xjoto._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__04q--0f._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0bl-e63._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0ce8nf8._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__0ffbg85._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0j7z0r3._.js +12 -0
- package/.next/server/chunks/[root-of-the-server]__0jq4ohy._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0ls6_8y._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__0ncs9uu._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0pa2n68._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0q0vvt2._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1-ga0kh._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__11n256_._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__12cabg9._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1339jnv._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__15bjnu5._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__18_teo8._.js +8 -0
- package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +5 -0
- package/.next/server/chunks/[root-of-the-server]__1anc1p9._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1ccon1w._.js +5 -5
- package/.next/server/chunks/[root-of-the-server]__1fizn31._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1llj3-b._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +11 -0
- package/.next/server/chunks/[root-of-the-server]__1p8m3f4._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1wa1k7r._.js +8 -0
- package/.next/server/chunks/_0-73of8._.js +5 -5
- package/.next/server/chunks/_0-fjql4._.js +26 -0
- package/.next/server/chunks/_00xh_q0._.js +27 -0
- package/.next/server/chunks/{_0pppbb5._.js → _03kp0jp._.js} +163 -36
- package/.next/server/chunks/_051qh8u._.js +3 -0
- package/.next/server/chunks/{node_modules_next_04q-o58._.js → _05dla15._.js} +2 -2
- package/.next/server/chunks/_05h2cii._.js +1 -1
- package/.next/server/chunks/_0c9j6rb._.js +49 -0
- package/.next/server/chunks/_0fzqt2y._.js +130 -0
- package/.next/server/chunks/{_0vnutv9._.js → _0ioz3nd._.js} +1 -1
- package/.next/server/chunks/_0iwfby5._.js +3 -0
- package/.next/server/chunks/_0mecv0f._.js +26 -0
- package/.next/server/chunks/_0mh8j4m._.js +3 -0
- package/.next/server/chunks/_0n74zsf._.js +4 -4
- package/.next/server/chunks/_0obojvv._.js +3 -0
- package/.next/server/chunks/_0recufk._.js +49 -0
- package/.next/server/chunks/_0rnf-6n._.js +4 -4
- package/.next/server/chunks/_0sb7tlz._.js +3 -0
- package/.next/server/chunks/_0u10wmw._.js +5 -5
- package/.next/server/chunks/_0u4aiy2._.js +3 -0
- package/.next/server/chunks/_0wp4le3._.js +1 -1
- package/.next/server/chunks/_0y5fg-x._.js +1 -1
- package/.next/server/chunks/_1230wbx._.js +10 -0
- package/.next/server/chunks/_12nheja._.js +3 -0
- package/.next/server/chunks/_13510xh._.js +3 -0
- package/.next/server/chunks/_15hq89o._.js +1 -1
- package/.next/server/chunks/_17l5ygt._.js +49 -0
- package/.next/server/chunks/_18-1wcc._.js +5 -5
- package/.next/server/chunks/_1_5mnq4._.js +4 -4
- package/.next/server/chunks/_1_9mjx-._.js +3 -0
- package/.next/server/chunks/_1d0j961._.js +6 -0
- package/.next/server/chunks/_1d5zmy8._.js +1 -1
- package/.next/server/chunks/_1drgfx4._.js +4 -4
- package/.next/server/chunks/_1f46eie._.js +3 -0
- package/.next/server/chunks/_1h5_8sk._.js +3 -0
- package/.next/server/chunks/_1hdnxb7._.js +3 -0
- package/.next/server/chunks/_1j8k_j5._.js +3 -0
- package/.next/server/chunks/_1krd9rf._.js +3 -0
- package/.next/server/chunks/_1nc0eui._.js +11 -0
- package/.next/server/chunks/_1nula3v._.js +3 -0
- package/.next/server/chunks/_1pf4qe-._.js +3 -0
- package/.next/server/chunks/_1php4eq._.js +1 -1
- package/.next/server/chunks/_1qxheoa._.js +3 -0
- package/.next/server/chunks/_1x6kd1r._.js +3 -0
- package/.next/server/chunks/_1yuv4vp._.js +1 -1
- package/.next/server/chunks/_1zjrdag._.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_bot_memory_files_route_actions_1_xd_8f.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_bot_memory_route_actions_1a8xfr7.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_llm-model_credits_route_actions_0v424pb.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_llm-model_subscription_route_actions_0-udcm5.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_memory_edit_route_actions_02sfnmr.js +3 -0
- package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
- package/.next/server/chunks/features_0rpfxbk._.js +3 -0
- package/.next/server/chunks/features_1qf3cei._.js +3 -0
- package/.next/server/chunks/features_bot_0zt92oh._.js +3 -0
- package/.next/server/chunks/features_bot_bot_query_ts_12mgkl2._.js +3 -0
- package/.next/server/chunks/features_memory_1uqvksn._.js +6 -0
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0a1rd09._.js → node_modules_consola_dist_chunks_prompt_mjs_0i7cvml._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_06067w6._.js → node_modules_consola_dist_chunks_prompt_mjs_0icqaqw._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_096ais_._.js → node_modules_consola_dist_chunks_prompt_mjs_0r28-sm._.js} +1 -1
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_02s3hjt._.js → node_modules_consola_dist_chunks_prompt_mjs_0v_7drq._.js} +1 -1
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1xoq2rl._.js +3 -0
- package/.next/server/chunks/{node_modules_consola_dist_chunks_prompt_mjs_0tvkfgh._.js → node_modules_consola_dist_chunks_prompt_mjs_1y49572._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__09q9med._.js +1 -1
- package/.next/server/chunks/ssr/{[root-of-the-server]__1qfqvmg._.js → [root-of-the-server]__0_69wqr._.js} +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__0hg5gib._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0i8ie7f._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__0jsmmb-._.js → [root-of-the-server]__0mz33a7._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0tbkdlx._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0vnmv-s._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__0f6s48x._.js → [root-of-the-server]__0xpcv9w._.js} +3 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0xtssj3._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0zkv7z_._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +57 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__15_uhip._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__16jc196._.js +1 -1
- package/.next/server/chunks/ssr/{[root-of-the-server]__0m1b5ky._.js → [root-of-the-server]__1cyjywu._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1eh7hid._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1gtlw6v._.js +43 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1ox7hbk._.js +4 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1pduf5n._.js +3 -0
- package/.next/server/chunks/ssr/{_1mznrxk._.js → _001_ms1._.js} +3 -3
- package/.next/server/chunks/ssr/_01_6m32._.js +3 -0
- package/.next/server/chunks/ssr/_01n3o0m._.js +3 -0
- package/.next/server/chunks/ssr/_07uchnc._.js +3 -0
- package/.next/server/chunks/ssr/_0ap2fzn._.js +3 -0
- package/.next/server/chunks/ssr/_0c-ql2m._.js +3 -0
- package/.next/server/chunks/ssr/_0h42fze._.js +3 -0
- package/.next/server/chunks/ssr/_0h7zdni._.js +1 -1
- package/.next/server/chunks/ssr/_0i_6q1w._.js +41 -0
- package/.next/server/chunks/ssr/_0kbkmar._.js +3 -0
- package/.next/server/chunks/ssr/{_077-g6s._.js → _0mb8zc8._.js} +3 -3
- package/.next/server/chunks/ssr/_0mo2w06._.js +3 -0
- package/.next/server/chunks/ssr/{_13punpm._.js → _0q0zan6._.js} +2 -2
- package/.next/server/chunks/ssr/{_040sk32._.js → _0u2jv_x._.js} +76 -82
- package/.next/server/chunks/ssr/_0y0tiht._.js +4 -0
- package/.next/server/chunks/ssr/_0zhoc3r._.js +3 -0
- package/.next/server/chunks/ssr/_1-teee5._.js +3 -3
- package/.next/server/chunks/ssr/_13fke0x._.js +3 -0
- package/.next/server/chunks/ssr/{_1lip4th._.js → _13z3f85._.js} +2 -2
- package/.next/server/chunks/ssr/_14_lw10._.js +3 -0
- package/.next/server/chunks/ssr/_15j2_8f._.js +3 -0
- package/.next/server/chunks/ssr/{_09ja_w1._.js → _1eoqg_g._.js} +2 -2
- package/.next/server/chunks/ssr/_1sji22n._.js +3 -0
- package/.next/server/chunks/ssr/_1spzm8z._.js +3 -0
- package/.next/server/chunks/ssr/{_0x_nu5e._.js → _1vi_uo7._.js} +2 -2
- package/.next/server/chunks/ssr/_1vyd1ji._.js +1 -1
- package/.next/server/chunks/ssr/{_1m3bsfr._.js → _1xvgn77._.js} +2 -2
- package/.next/server/chunks/ssr/_20kd_n0._.js +42 -0
- package/.next/server/chunks/ssr/features_bot_1s_-2vj._.js +3 -0
- package/.next/server/chunks/ssr/features_config_components_config-setting_tsx_0xfwqdg._.js +1 -1
- package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
- package/.next/server/chunks/ssr/lib_date-like_ts_02is0pw._.js +3 -0
- package/.next/server/chunks/ssr/{node_modules_18_dk7_._.js → node_modules_063xwpp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_01qnv-a._.js → node_modules_0bvraul._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0n1kj4p._.js → node_modules_0eu1va6._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0kl7-tn._.js → node_modules_0h50b8n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0_n241r._.js → node_modules_0h5hnr1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0lrjk5t._.js → node_modules_0h7u60n._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0ndvxub._.js → node_modules_0lm7_vm._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_13r44jq._.js → node_modules_0mwym0g._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_17lrt3y._.js → node_modules_0rjg6t1._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_0x3-ply._.js +3 -0
- package/.next/server/chunks/ssr/{node_modules_004qlr4._.js → node_modules_0y_cded._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0kxz4gt._.js → node_modules_0z5tsu8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0iz1rzd._.js → node_modules_0zp9r92._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_19dp7ko._.js → node_modules_1-hc6uv._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1q0p85z._.js → node_modules_113tz0l._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1toafc-._.js → node_modules_124bue5._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_17bwo43._.js +55 -0
- package/.next/server/chunks/ssr/{node_modules_08d8bke._.js → node_modules_1_n3ztw._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1dwguw_._.js → node_modules_1bc7gu8._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_20yebtj._.js → node_modules_1bgb6-f._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1n5ygqe._.js → node_modules_1h4a4pp._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_04n7mjs._.js → node_modules_1i7u1ia._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1hn8z1f._.js → node_modules_1juq3hs._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1xyd7ov._.js → node_modules_1l0qtdu._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0m93zeg._.js → node_modules_1t9cyee._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_09xhur7._.js → node_modules_1uuj9x1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1hd-5tv._.js → node_modules_1vqb6po._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1zu988w._.js → node_modules_1xx28h1._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0m9a4y0._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0d3skpl._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_13w_wy9._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0i44kk5._.js} +1 -1
- package/.next/server/chunks/ssr/node_modules_@vercel_oidc_dist_0qe30a_._.js +3 -0
- package/.next/server/chunks/ssr/{node_modules_next_dist_0w6mzq5._.js → node_modules_next_dist_0drixxt._.js} +4 -4
- package/.next/server/chunks/ssr/node_modules_next_dist_1n3w9lb._.js +2 -2
- package/.next/server/instrumentation.js +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +58 -91
- package/.next/static/chunks/{31ttnjt6g35a0.js → 0ev4hyghq0mbb.js} +1 -1
- package/.next/static/chunks/0r5qcctujhxli.js +1 -0
- package/.next/static/chunks/0tmgrnlje14-s.js +3 -0
- package/.next/static/chunks/0x79tx04dxbpp.js +1 -0
- package/.next/static/chunks/0xzgvc0fkdb6t.js +1 -0
- package/.next/static/chunks/10teww7wt-f6h.js +1 -0
- package/.next/static/chunks/14hgtsjg-kael.css +1 -0
- package/.next/static/chunks/17donp69y4do7.js +40 -0
- package/.next/static/chunks/{3_h9txt3tq8t8.js → 1dkjg87pxk0n9.js} +1 -1
- package/.next/static/chunks/1ekc7ul556kbl.js +1 -0
- package/.next/static/chunks/{3ard_noqapnw1.js → 1grhjo7a5a0_-.js} +1 -1
- package/.next/static/chunks/1kq8h8wi_e0bc.js +53 -0
- package/.next/static/chunks/1okqiww3pnwka.js +1 -0
- package/.next/static/chunks/26-pr2c9ro222.js +1 -0
- package/.next/static/chunks/{18vhba44l1fc9.js → 280t0_e99i276.js} +1 -1
- package/.next/static/chunks/28cizcdaabd4h.js +1 -0
- package/.next/static/chunks/2a0k6jlq0_v1u.js +2 -0
- package/.next/static/chunks/2fzs9fm8yarvq.js +1 -0
- package/.next/static/chunks/2h0sd2vumhb15.js +1 -0
- package/.next/static/chunks/2hw2f6zmt7fmt.js +1 -0
- package/.next/static/chunks/2t4vhi3m8ahya.js +1 -0
- package/.next/static/chunks/2tigdtz3dpcy8.js +1 -0
- package/.next/static/chunks/3111pj5wnjgos.js +1 -0
- package/.next/static/chunks/{07kl352c-lvcz.js → 3agpgkwaa321p.js} +1 -1
- package/.next/static/chunks/3cfi_q6d_wtci.js +1 -0
- package/.next/static/chunks/3ok9_x74rip3v.js +1 -0
- package/.next/static/chunks/3xk7yqgomx7yq.js +1 -0
- package/.next/static/chunks/3xpbkl66ssib5.js +38 -0
- package/.next/static/media/favicon.37o1pjldwi2uc.ico +0 -0
- package/README.md +6 -4
- package/app/api/bot/memory/files/route.ts +14 -0
- package/app/api/bot/memory/route.ts +5 -0
- package/app/api/events/app-event.ts +3 -5
- package/app/api/llm-model/credits/route.ts +11 -0
- package/app/api/llm-model/route.ts +6 -1
- package/app/api/llm-model/subscription/route.ts +11 -0
- package/app/api/memory/edit/route.ts +7 -0
- package/app/api/memory/route.ts +21 -0
- package/app/api/query-key.ts +19 -4
- package/bin/thursday.mjs +3 -0
- package/components/ui/shiny-text.tsx +48 -134
- package/database/migrations/{20260909060813_optimal_sabretooth → 20260910173049_numerous_spirit}/migration.sql +24 -34
- package/database/migrations/{20260909060813_optimal_sabretooth → 20260910173049_numerous_spirit}/snapshot.json +71 -145
- package/database/migrations/20260911030320_opposite_jack_power/migration.sql +1 -0
- package/database/migrations/{20260909063821_bitter_tenebrous → 20260911030320_opposite_jack_power}/snapshot.json +57 -184
- package/features/ai/chatgpt.ts +617 -0
- package/features/ai/components/chatgpt-sign-in.tsx +66 -0
- package/features/ai/components/model-picker.tsx +17 -1
- package/features/ai/components/provider-icon.tsx +1 -0
- package/features/ai/load-tools.ts +58 -42
- package/features/ai/model.schema.ts +232 -34
- package/features/ai/model.ts +169 -24
- package/features/ai/prompts/bot.prompt.ts +156 -65
- package/features/ai/prompts/memory-edit.prompt.ts +33 -0
- package/features/ai/prompts/prompt-helper.ts +45 -26
- package/features/ai/prompts/thursday.prompt.ts +40 -17
- package/features/ai/tools/bot.tool.ts +35 -52
- package/features/ai/tools/connected.ts +17 -4
- package/features/ai/tools/memory.tool.ts +133 -72
- package/features/ai/tools/search.tool.ts +136 -47
- package/features/ai/tools/tool-name.ts +2 -5
- package/features/ai/tools/workspace.tool.ts +2 -1
- package/features/bot/bot.action.ts +8 -18
- package/features/bot/bot.memory.ts +89 -0
- package/features/bot/bot.query.ts +37 -57
- package/features/bot/bot.run.ts +507 -241
- package/features/bot/bot.runner.ts +410 -114
- package/features/bot/bot.schema.ts +79 -19
- package/features/bot/bot.seed.ts +89 -16
- package/features/bot/components/bot-mark.tsx +122 -20
- package/features/bot/components/bot-room.tsx +159 -130
- package/features/bot/components/bot-setting.tsx +790 -402
- package/features/bot/components/bot-tool.tsx +2 -6
- package/features/bot/components/mark-palette.tsx +54 -0
- package/features/bot/components/path-chips.tsx +1 -1
- package/features/bot/components/task-badge.tsx +26 -6
- package/features/bot/components/task-reply.tsx +22 -33
- package/features/bot/components/task-setting.tsx +20 -17
- package/features/bot/task.query.ts +215 -28
- package/features/bot/task.store.ts +53 -9
- package/features/config/components/config-setting.tsx +265 -34
- package/features/config/components/models-badge.tsx +42 -0
- package/features/config/config.action.ts +12 -0
- package/features/config/config.const.ts +38 -2
- package/features/connectors/mcp.manager.ts +10 -2
- package/features/intro/components/intro.tsx +47 -46
- package/features/memory/components/memory-edit.tsx +338 -0
- package/features/memory/components/memory-setting.tsx +75 -77
- package/features/memory/memory.action.ts +3 -43
- package/features/memory/memory.edit.ts +87 -0
- package/features/memory/memory.query.ts +24 -42
- package/features/memory/memory.schema.ts +29 -106
- package/features/settings/components/settings.tsx +2 -0
- package/features/settings/settings.alert.ts +3 -1
- package/features/thursday/components/ascii-orb.tsx +106 -90
- package/features/thursday/components/boot.tsx +7 -0
- package/features/thursday/components/call-log.tsx +219 -92
- package/features/thursday/components/face.tsx +6 -4
- package/features/thursday/components/tab-state.tsx +97 -0
- package/features/thursday/components/thursday-mark.tsx +4 -1
- package/features/thursday/components/thursday-setting.tsx +17 -47
- package/features/thursday/components/thursday.tsx +208 -95
- package/features/thursday/thursday.action.ts +12 -17
- package/features/thursday/thursday.query.ts +61 -70
- package/features/thursday/thursday.schema.ts +20 -7
- package/features/thursday/tool-line.ts +85 -11
- package/features/thursday/use-thursday.ts +86 -59
- package/features/workspace/components/file-view.tsx +4 -2
- package/features/workspace/workspace.ts +110 -26
- package/lib/limits.ts +1 -1
- package/lib/oauth-page.ts +27 -0
- package/lib/realtime/openai.ts +2 -2
- package/lib/realtime/realtime.protocol.ts +1 -1
- package/lib/realtime/realtime.tap.ts +122 -0
- package/lib/sandbox.ts +59 -36
- package/package.json +1 -1
- package/skills/browser/SKILL.md +55 -34
- package/.next/server/app/api/bot/notes/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/bot/notes/route.js +0 -14
- package/.next/server/app/api/bot/notes/route_client-reference-manifest.js +0 -3
- package/.next/server/app/api/memory/tidy/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/memory/tidy/route.js +0 -22
- package/.next/server/app/api/memory/tidy/route.js.nft.json +0 -1
- package/.next/server/chunks/0d-b_next_dist_server_app-render_after-task-async-storage_external_0-exn7p.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0-npkh_._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__005var5._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__019dx9f._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__02_2sm-._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__04_8spk._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__05luceg._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__06t77t4._.js +0 -11
- package/.next/server/chunks/[root-of-the-server]__0bed6hu._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0cro2dz._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0dupqt7._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0emr6go._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0le4d-p._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0m8ywyo._.js +0 -10
- package/.next/server/chunks/[root-of-the-server]__0nfuugi._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__0p32jfz._.js +0 -12
- package/.next/server/chunks/[root-of-the-server]__0phdgco._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__0wvgrsl._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__10qshki._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__11j52t0._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1692zrv._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__16thabu._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__173nhwf._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1_aoyr9._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1bn73ih._.js +0 -10
- package/.next/server/chunks/[root-of-the-server]__1bqhuh9._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1cqizfq._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1e-ci13._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1fboj2j._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1lr7j9t._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1oli73c._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__1txedx6._.js +0 -8
- package/.next/server/chunks/[root-of-the-server]__1untqv8._.js +0 -5
- package/.next/server/chunks/[root-of-the-server]__1zgpz1w._.js +0 -3
- package/.next/server/chunks/_00_584r._.js +0 -293
- package/.next/server/chunks/_012yhfm._.js +0 -39
- package/.next/server/chunks/_06mxlgn._.js +0 -3
- package/.next/server/chunks/_07rtlxv._.js +0 -3
- package/.next/server/chunks/_0a351g7._.js +0 -6
- package/.next/server/chunks/_0kjjmag._.js +0 -3
- package/.next/server/chunks/_0nn99o2._.js +0 -3
- package/.next/server/chunks/_0zuzmt_._.js +0 -39
- package/.next/server/chunks/_106co2o._.js +0 -3
- package/.next/server/chunks/_12bbv5i._.js +0 -100
- package/.next/server/chunks/_15q1pig._.js +0 -3
- package/.next/server/chunks/_19wg5yn._.js +0 -138
- package/.next/server/chunks/_1bt95p9._.js +0 -55
- package/.next/server/chunks/_1cbk7ms._.js +0 -26
- package/.next/server/chunks/_1drv2et._.js +0 -40
- package/.next/server/chunks/_1ic3bew._.js +0 -5
- package/.next/server/chunks/_1mxn_lb._.js +0 -3
- package/.next/server/chunks/_1rysr-r._.js +0 -10
- package/.next/server/chunks/_1u3rwbr._.js +0 -3
- package/.next/server/chunks/_1x7p319._.js +0 -6
- package/.next/server/chunks/_next-internal_server_app_api_bot_notes_route_actions_0qcsyu7.js +0 -3
- package/.next/server/chunks/_next-internal_server_app_api_memory_tidy_route_actions_0_cfuom.js +0 -3
- package/.next/server/chunks/features_bot_task_query_ts_11xuzl3._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0gzvgfv._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_0vorg6w._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1tpvamf._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1vmaq9f._.js +0 -3
- package/.next/server/chunks/node_modules_consola_dist_chunks_prompt_mjs_1y9-wcr._.js +0 -3
- package/.next/server/chunks/ssr/[externals]_node_crypto_1kn79-7._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0iuoa-r._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0un-erv._.js +0 -4
- package/.next/server/chunks/ssr/[root-of-the-server]__1-mnhyd._.js +0 -92
- package/.next/server/chunks/ssr/[root-of-the-server]__1bww500._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1vcdast._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__1xwnu-h._.js +0 -3
- package/.next/server/chunks/ssr/_0-mc7ro._.js +0 -3
- package/.next/server/chunks/ssr/_01p5r6-._.js +0 -3
- package/.next/server/chunks/ssr/_03webdr._.js +0 -3
- package/.next/server/chunks/ssr/_09-0k3z._.js +0 -3
- package/.next/server/chunks/ssr/_0f_b_9s._.js +0 -3
- package/.next/server/chunks/ssr/_0fafgvl._.js +0 -3
- package/.next/server/chunks/ssr/_0sf1isi._.js +0 -3
- package/.next/server/chunks/ssr/_0su6_08._.js +0 -3
- package/.next/server/chunks/ssr/_0ti51xc._.js +0 -3
- package/.next/server/chunks/ssr/_0w5bgak._.js +0 -3
- package/.next/server/chunks/ssr/_0y84qo6._.js +0 -3
- package/.next/server/chunks/ssr/_1ciyoo3._.js +0 -3
- package/.next/server/chunks/ssr/_1e-dgz0._.js +0 -4
- package/.next/server/chunks/ssr/_1fq7zgb._.js +0 -3
- package/.next/server/chunks/ssr/_1g6l4uj._.js +0 -3
- package/.next/server/chunks/ssr/_1ruzehw._.js +0 -3
- package/.next/server/chunks/ssr/features_bot_components_bot-setting_tsx_01ajft6._.js +0 -4
- package/.next/server/chunks/ssr/features_config_components_14jqgy4._.js +0 -3
- package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +0 -4
- package/.next/server/chunks/ssr/node_modules_zod_v4_classic_external_15fmmz3.js +0 -55
- package/.next/static/chunks/05b6nx_o3_f_n.js +0 -1
- package/.next/static/chunks/0dmns-gi0raa4.js +0 -1
- package/.next/static/chunks/0f9sq-7q_yxyl.js +0 -1
- package/.next/static/chunks/0oc4_xoia77dg.css +0 -1
- package/.next/static/chunks/0pheo8m3a-rzi.js +0 -1
- package/.next/static/chunks/19i8h2t-5evjx.js +0 -1
- package/.next/static/chunks/1c5fcj473025q.js +0 -1
- package/.next/static/chunks/1pi_hbmjw-f-z.js +0 -1
- package/.next/static/chunks/1twt6k09vg4np.js +0 -1
- package/.next/static/chunks/1ytnip8wdng93.js +0 -1
- package/.next/static/chunks/28gotuisldmom.js +0 -1
- package/.next/static/chunks/2998p0y7k1c8z.js +0 -3
- package/.next/static/chunks/29gyb3nubj51j.js +0 -53
- package/.next/static/chunks/2l233xfycjpd8.js +0 -1
- package/.next/static/chunks/2p5n7pa3c40t-.js +0 -2
- package/.next/static/chunks/2ru1q132af7h7.js +0 -1
- package/.next/static/chunks/2t8wqycwg3y04.js +0 -2
- package/.next/static/chunks/2uxum7qbyeyxd.js +0 -1
- package/.next/static/chunks/32z_ypgtchw48.js +0 -1
- package/.next/static/chunks/33pyjb3xd1iez.js +0 -1
- package/.next/static/chunks/3omud5xunrk1f.js +0 -1
- package/.next/static/chunks/42dnrkbph9e-1.js +0 -1
- package/.next/static/media/favicon.2vob68tjqpejf.ico +0 -0
- package/database/migrations/20260909063821_bitter_tenebrous/migration.sql +0 -1
- package/features/ai/prompts/memory-tidy.prompt.ts +0 -129
- package/features/ai/tools/tidy.tool.ts +0 -22
- package/features/bot/bot.notes.ts +0 -120
- package/features/memory/components/memory-tidy.tsx +0 -395
- package/features/memory/memory.tidy.ts +0 -332
- package/features/memory/tidy.query.ts +0 -135
- package/features/thursday/use-call-title.ts +0 -31
- /package/.next/server/app/api/bot/{notes → memory/files}/route/build-manifest.json +0 -0
- /package/.next/server/app/api/bot/{notes → memory/files}/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/bot/{notes → memory/files}/route.js.map +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory}/route/build-manifest.json +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory}/route/server-reference-manifest.json +0 -0
- /package/.next/server/app/api/{memory/tidy → bot/memory}/route.js.map +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → x1cCqY0kWpR_VcYx_lWO5}/_buildManifest.js +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → x1cCqY0kWpR_VcYx_lWO5}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{YR4NWcDDuzwLbTTU7U7Vr → x1cCqY0kWpR_VcYx_lWO5}/_ssgManifest.js +0 -0
|
@@ -2,13 +2,12 @@ import { z } from "zod";
|
|
|
2
2
|
import { type DateLike, DateLikeSchema, toDate } from "@/lib/date-like";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Who put a fact here. Memory is one note kept by
|
|
6
|
-
* on the screen, the call as they talk, a bot that turned something up
|
|
7
|
-
* and
|
|
8
|
-
*
|
|
9
|
-
* inferred as something the user said.
|
|
5
|
+
* Who put a fact here. Memory is one note kept by three hands — the user typing
|
|
6
|
+
* on the screen, the call as they talk, and a bot that turned something up
|
|
7
|
+
* mid-job — and they are not equally close to the user. A reader that cannot
|
|
8
|
+
* tell them apart reads what a bot inferred as something the user said.
|
|
10
9
|
*/
|
|
11
|
-
export const MemorySourceSchema = z.enum(["user", "call", "bot"
|
|
10
|
+
export const MemorySourceSchema = z.enum(["user", "call", "bot"]);
|
|
12
11
|
|
|
13
12
|
export type MemorySource = z.infer<typeof MemorySourceSchema>;
|
|
14
13
|
|
|
@@ -25,15 +24,13 @@ export const memorySourceLabel = (source: MemorySource | null | undefined) =>
|
|
|
25
24
|
? "on a call"
|
|
26
25
|
: source === "bot"
|
|
27
26
|
? "a bot"
|
|
28
|
-
:
|
|
29
|
-
? "read back"
|
|
30
|
-
: "";
|
|
27
|
+
: "";
|
|
31
28
|
|
|
32
29
|
// Storage is fact-based: one row per fact, history via isLatest.
|
|
33
30
|
export const MemoryFactSchema = z.object({
|
|
34
31
|
id: z.number(),
|
|
35
32
|
text: z.string(),
|
|
36
|
-
/** Loaded into every prompt without opening the note (
|
|
33
|
+
/** Loaded into every prompt without opening the note (config MEMORY_LIMITS.carried). */
|
|
37
34
|
alwaysLoad: z.boolean(),
|
|
38
35
|
/** Null on rows written before the hand was recorded. */
|
|
39
36
|
source: MemorySourceSchema.nullish(),
|
|
@@ -65,17 +62,16 @@ export type MemoryNote = z.infer<typeof MemoryNoteSchema>;
|
|
|
65
62
|
export const MEMORY_PATHS = [
|
|
66
63
|
{
|
|
67
64
|
path: "profile",
|
|
68
|
-
of: "The user themselves —
|
|
65
|
+
of: "The user themselves — their name, age, what they do, where they live, and whatever else says who they are",
|
|
69
66
|
},
|
|
70
|
-
{ path: "preferences", of: "How they
|
|
67
|
+
{ path: "preferences", of: "How they want things done, and said" },
|
|
68
|
+
{ path: "people/", of: "Someone in their life, and what matters about them" },
|
|
71
69
|
{
|
|
72
|
-
path: "
|
|
73
|
-
of: "
|
|
70
|
+
path: "projects/",
|
|
71
|
+
of: "Something with an end — a trip, a purchase, a deadline, a thing being built",
|
|
74
72
|
},
|
|
75
|
-
{ path: "
|
|
76
|
-
{ path: "
|
|
77
|
-
{ path: "topics/", of: "Anything else worth its own note" },
|
|
78
|
-
{ path: "inbox", of: "Nowhere obvious to go" },
|
|
73
|
+
{ path: "topics/", of: "Something ongoing that keeps coming back" },
|
|
74
|
+
{ path: "inbox", of: "Nowhere obvious yet" },
|
|
79
75
|
] as const;
|
|
80
76
|
|
|
81
77
|
/** Where anything outside the convention lands. */
|
|
@@ -92,7 +88,6 @@ export const MEMORY_SECTIONS = MEMORY_PATHS.filter((entry) =>
|
|
|
92
88
|
).map((entry) => entry.path.slice(0, -1)) as (
|
|
93
89
|
| "people"
|
|
94
90
|
| "projects"
|
|
95
|
-
| "plans"
|
|
96
91
|
| "topics"
|
|
97
92
|
)[];
|
|
98
93
|
|
|
@@ -108,11 +103,20 @@ export const MEMORY_ALWAYS_LISTED: string[] = ["profile", "preferences"];
|
|
|
108
103
|
export const isAlwaysListed = (path: string) =>
|
|
109
104
|
MEMORY_ALWAYS_LISTED.includes(path);
|
|
110
105
|
|
|
111
|
-
/**
|
|
112
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Notes whose listing line the app writes rather than a model: the two root
|
|
108
|
+
* notes it keeps (memory.query ensureRootNotes) and the inbox, which is where
|
|
109
|
+
* a fact lands when its path is not one this listing can carry. A model's
|
|
110
|
+
* `description` for one of these is ignored, so the line cannot drift with
|
|
111
|
+
* whoever wrote last (ai/tools/memory.tool).
|
|
112
|
+
*/
|
|
113
|
+
export const APP_NAMED_NOTES = [...MEMORY_ALWAYS_LISTED, MEMORY_INBOX];
|
|
114
|
+
|
|
115
|
+
export const isAppNamed = (path: string) => APP_NAMED_NOTES.includes(path);
|
|
113
116
|
|
|
114
|
-
/**
|
|
115
|
-
export const
|
|
117
|
+
/** The line the app writes for one of those. */
|
|
118
|
+
export const appNoteLine = (path: string) =>
|
|
119
|
+
MEMORY_PATHS.find((entry) => entry.path === path)?.of ?? null;
|
|
116
120
|
|
|
117
121
|
export type MemorySection =
|
|
118
122
|
| "you"
|
|
@@ -134,6 +138,8 @@ export type MemoryFactRef = {
|
|
|
134
138
|
/** What `memory_forget` and `replaces` take. */
|
|
135
139
|
id: number;
|
|
136
140
|
text: string;
|
|
141
|
+
/** When the call it was said in started, when a call wrote it. Formatted by the tool, never sent as a Date. */
|
|
142
|
+
saidAt?: Date;
|
|
137
143
|
};
|
|
138
144
|
|
|
139
145
|
/** A fact carried at the top of the prompt, with its note path. */
|
|
@@ -209,86 +215,3 @@ export function isFading(
|
|
|
209
215
|
): boolean {
|
|
210
216
|
return !isAlwaysListed(note.path) && recallScore(note) < 0.15;
|
|
211
217
|
}
|
|
212
|
-
|
|
213
|
-
// Reading calls back (memory.tidy): its settings and the run row the screen draws.
|
|
214
|
-
|
|
215
|
-
/** Config keys (features/config config.query) the settings live under. */
|
|
216
|
-
export const MEMORY_TIDY_KEYS = {
|
|
217
|
-
/** "on" switches it on; anything else, unset included, is off. */
|
|
218
|
-
on: "MEMORY_TIDY",
|
|
219
|
-
/** `provider/model`; unset runs on the app default (ai/model resolveDefaultModel). */
|
|
220
|
-
model: "MEMORY_TIDY_MODEL",
|
|
221
|
-
} as const;
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Off unless switched on. A read costs a whole context of a text model, so
|
|
225
|
-
* nothing starts spending until the user asks for it — and a model must be
|
|
226
|
-
* picked as well (memory.tidy startTidy).
|
|
227
|
-
*/
|
|
228
|
-
export const isTidyOn = (value: string | undefined) => value?.trim() === "on";
|
|
229
|
-
|
|
230
|
-
export const MEMORY_TIDY_STATUSES = [
|
|
231
|
-
"running",
|
|
232
|
-
"done",
|
|
233
|
-
"stopped",
|
|
234
|
-
"failed",
|
|
235
|
-
] as const;
|
|
236
|
-
export type MemoryTidyStatus = (typeof MEMORY_TIDY_STATUSES)[number];
|
|
237
|
-
|
|
238
|
-
/** One thing a read changed; the run row keeps them in order. */
|
|
239
|
-
export const MemoryTidyChangeSchema = z.object({
|
|
240
|
-
op: z.enum(["add", "replace", "forget", "carry", "uncarry"]),
|
|
241
|
-
path: z.string(),
|
|
242
|
-
text: z.string(),
|
|
243
|
-
});
|
|
244
|
-
export type MemoryTidyChange = z.infer<typeof MemoryTidyChangeSchema>;
|
|
245
|
-
|
|
246
|
-
export const MemoryTidyRunSchema = z.object({
|
|
247
|
-
id: z.string(),
|
|
248
|
-
status: z.enum(MEMORY_TIDY_STATUSES),
|
|
249
|
-
provider: z.string(),
|
|
250
|
-
model: z.string(),
|
|
251
|
-
/** The calls this read covered and stamped, oldest first. */
|
|
252
|
-
callIds: z.string().array(),
|
|
253
|
-
/** Turns it actually read. Fewer than were owed when older ones were dropped. */
|
|
254
|
-
messages: z.number(),
|
|
255
|
-
changes: MemoryTidyChangeSchema.array(),
|
|
256
|
-
error: z.string().nullable(),
|
|
257
|
-
inputTokens: z.number(),
|
|
258
|
-
outputTokens: z.number(),
|
|
259
|
-
startedAt: DateLikeSchema,
|
|
260
|
-
endedAt: DateLikeSchema.nullable(),
|
|
261
|
-
});
|
|
262
|
-
export type MemoryTidyRun = z.infer<typeof MemoryTidyRunSchema>;
|
|
263
|
-
|
|
264
|
-
/** What the setting reads (app/api/memory/tidy). */
|
|
265
|
-
export type MemoryTidyStatusView = {
|
|
266
|
-
on: boolean;
|
|
267
|
-
/** The picked model as `provider/model`, or null for the app default. */
|
|
268
|
-
model: string | null;
|
|
269
|
-
/** Turns said since the last read, and how many it takes to run. */
|
|
270
|
-
pending: number;
|
|
271
|
-
every: number;
|
|
272
|
-
/** The read in progress, if any. */
|
|
273
|
-
current: MemoryTidyRun | null;
|
|
274
|
-
/** The most recent finished read. */
|
|
275
|
-
last: MemoryTidyRun | null;
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
/** Counts per op for one line on screen: "3 added, 1 revised". */
|
|
279
|
-
export function tidyTally(changes: MemoryTidyChange[]): string {
|
|
280
|
-
const count = (op: MemoryTidyChange["op"]) =>
|
|
281
|
-
changes.filter((change) => change.op === op).length;
|
|
282
|
-
const said = (
|
|
283
|
-
[
|
|
284
|
-
[count("add"), "added"],
|
|
285
|
-
[count("replace"), "revised"],
|
|
286
|
-
[count("forget"), "dropped"],
|
|
287
|
-
[count("carry"), "carried"],
|
|
288
|
-
[count("uncarry"), "uncarried"],
|
|
289
|
-
] as const
|
|
290
|
-
)
|
|
291
|
-
.filter(([n]) => n > 0)
|
|
292
|
-
.map(([n, word]) => `${n} ${word}`);
|
|
293
|
-
return said.length ? said.join(", ") : "nothing to change";
|
|
294
|
-
}
|
|
@@ -29,6 +29,7 @@ import { BotBadge } from "@/features/bot/components/bot-badge";
|
|
|
29
29
|
import { BotsMark } from "@/features/bot/components/bot-mark";
|
|
30
30
|
import { TaskBadge } from "@/features/bot/components/task-badge";
|
|
31
31
|
import { ConfigBadge } from "@/features/config/components/config-badge";
|
|
32
|
+
import { ModelsBadge } from "@/features/config/components/models-badge";
|
|
32
33
|
import { McpBadge } from "@/features/connectors/components/mcp-badge";
|
|
33
34
|
import { McpMark } from "@/features/connectors/components/mcp-mark";
|
|
34
35
|
import { MemoryMark } from "@/features/memory/components/memory-mark";
|
|
@@ -203,6 +204,7 @@ export const SECTIONS: readonly {
|
|
|
203
204
|
hint: "What bots draw, film, speak and transcribe with",
|
|
204
205
|
icon: Aperture,
|
|
205
206
|
Component: ModelsSetting,
|
|
207
|
+
Badge: ModelsBadge,
|
|
206
208
|
},
|
|
207
209
|
{
|
|
208
210
|
id: "config",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { useBotAlert } from "@/features/bot/components/bot-badge";
|
|
4
4
|
import { useTaskAlert } from "@/features/bot/components/task-badge";
|
|
5
5
|
import { useConfigAlert } from "@/features/config/components/config-badge";
|
|
6
|
+
import { useModelsAlert } from "@/features/config/components/models-badge";
|
|
6
7
|
import { useMcpAlert } from "@/features/connectors/components/mcp-badge";
|
|
7
8
|
import type { SettingSectionId } from "./settings.store";
|
|
8
9
|
|
|
@@ -32,5 +33,6 @@ export function useSectionAlerts(): Partial<
|
|
|
32
33
|
const tasks = useTaskAlert();
|
|
33
34
|
const mcp = useMcpAlert();
|
|
34
35
|
const config = useConfigAlert();
|
|
35
|
-
|
|
36
|
+
const models = useModelsAlert();
|
|
37
|
+
return { bot, tasks, mcp, config, models };
|
|
36
38
|
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useEffect, useRef } from "react";
|
|
4
|
+
import { ASCII_FACE } from "@/config";
|
|
5
|
+
import {
|
|
6
|
+
createVoiceFollower,
|
|
7
|
+
SPECTRUM_BANDS,
|
|
8
|
+
} from "@/lib/realtime/realtime.tap";
|
|
4
9
|
import {
|
|
5
10
|
ALPHA_TOP,
|
|
6
11
|
CHAR_RATE,
|
|
@@ -132,44 +137,47 @@ const DESIGN = 680;
|
|
|
132
137
|
/** Radius (reference units) within which cells exist. Must stay under DESIGN/2 or the canvas clips it. */
|
|
133
138
|
const FIELD_R = 328;
|
|
134
139
|
|
|
135
|
-
/** Gain on incoming band values: speech bands average 0.15-0.35, and the top is clamped anyway. */
|
|
136
|
-
const VOICE_GAIN = 2.6;
|
|
137
|
-
|
|
138
140
|
/** Speaking: reference-unit px the rim is pushed by each channel. */
|
|
139
|
-
/**
|
|
140
|
-
const
|
|
141
|
+
/** Where the rim sits while the voice is at the bottom of its range */
|
|
142
|
+
const SPEAK_BASE = 184;
|
|
143
|
+
/** Swell across a phrase at the top of the voice's range */
|
|
144
|
+
const SPEAK_SWELL = 40;
|
|
141
145
|
/** Kick per syllable */
|
|
142
|
-
const SPEAK_KICK =
|
|
146
|
+
const SPEAK_KICK = 120;
|
|
143
147
|
/** Rotating lobes, harmonics 2 and up (the first harmonic shifts the whole circle) */
|
|
144
148
|
const SPEAK_LOBES = 4;
|
|
145
149
|
/** Max depth of one lobe */
|
|
146
|
-
const SPEAK_LOBE_R =
|
|
150
|
+
const SPEAK_LOBE_R = 34;
|
|
147
151
|
/**
|
|
148
|
-
* Rim range.
|
|
149
|
-
*
|
|
152
|
+
* Rim range. Past SPEAK_KNEE the rim slows into SPEAK_MAX rather than stopping
|
|
153
|
+
* at it, so a loud syllable still reads as a push instead of a flat edge. Max
|
|
154
|
+
* stays inside FIELD_R or thrown crumbs die at the edge; min keeps a deep
|
|
155
|
+
* breath from collapsing to a dot.
|
|
150
156
|
*/
|
|
151
157
|
const SPEAK_MIN = 130;
|
|
158
|
+
const SPEAK_KNEE = 244;
|
|
152
159
|
const SPEAK_MAX = 278;
|
|
153
|
-
/**
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
160
|
+
/** How far a rim cell sits in or out of the rim: the edge is crumbly, not drawn with a compass */
|
|
161
|
+
const SPEAK_ROUGH = 20;
|
|
162
|
+
/** Share of cells a syllable throws outward; the rest stay, so what leaves is crumbs, not a ring */
|
|
163
|
+
const SPECK_SHARE = 0.22;
|
|
164
|
+
/** Crumb speed (px/s) and lifetime (s) */
|
|
165
|
+
const RING_SPEED = 90;
|
|
166
|
+
const RING_LIFE = 0.7;
|
|
167
|
+
/** Syllables in flight at once, so fast speech does not flood the field */
|
|
157
168
|
const MAX_RINGS = 5;
|
|
158
169
|
|
|
159
170
|
/** Per-frame values derived from the voice; every cell reads the same ones. */
|
|
160
171
|
type Voice = {
|
|
161
|
-
/**
|
|
162
|
-
|
|
163
|
-
mid: number;
|
|
164
|
-
slow: number;
|
|
172
|
+
/** The voice inside its own range over about half a second (realtime.tap createVoiceFollower) */
|
|
173
|
+
phrase: number;
|
|
165
174
|
/** Spring kicked by each syllable */
|
|
166
175
|
bob: number;
|
|
167
176
|
bobVel: number;
|
|
168
|
-
lastOnset: number;
|
|
169
177
|
/** Lobe strength and angle */
|
|
170
178
|
amp: number[];
|
|
171
179
|
phase: number[];
|
|
172
|
-
/** One
|
|
180
|
+
/** One throw of crumbs per syllable */
|
|
173
181
|
rings: { born: number; power: number }[];
|
|
174
182
|
};
|
|
175
183
|
|
|
@@ -228,6 +236,8 @@ type Cell = {
|
|
|
228
236
|
death: number;
|
|
229
237
|
/** Emoji slot in emoji mode */
|
|
230
238
|
emoji: boolean;
|
|
239
|
+
/** Below SPECK_SHARE, a crumb a syllable throws outward */
|
|
240
|
+
speck: number;
|
|
231
241
|
/** Index of the ERROR letter this cell belongs to, or -1 */
|
|
232
242
|
letter: number;
|
|
233
243
|
};
|
|
@@ -276,6 +286,13 @@ function idleValue(cell: Cell, t: number) {
|
|
|
276
286
|
return (0.58 + w * 0.2 + breath) * body;
|
|
277
287
|
}
|
|
278
288
|
|
|
289
|
+
/** The rim's radius for a raw push: as pushed up to SPEAK_KNEE, then easing into SPEAK_MAX. */
|
|
290
|
+
function rimAt(raw: number) {
|
|
291
|
+
if (raw <= SPEAK_KNEE) return Math.max(SPEAK_MIN, raw);
|
|
292
|
+
const room = SPEAK_MAX - SPEAK_KNEE;
|
|
293
|
+
return SPEAK_KNEE + room * Math.tanh((raw - SPEAK_KNEE) / room);
|
|
294
|
+
}
|
|
295
|
+
|
|
279
296
|
/**
|
|
280
297
|
* Brightness of one mode; mode transitions blend two of these.
|
|
281
298
|
* @param e seconds since the mode started
|
|
@@ -305,12 +322,16 @@ function valueFor(m: AsciiOrbMode, cell: Cell, t: number, e: number, v: Voice) {
|
|
|
305
322
|
* Speaking. Frequency is not mapped to angle: a voice's spectrum barely
|
|
306
323
|
* moves within a sentence, so that freezes into a fixed star. The voice
|
|
307
324
|
* gives size, syllables and lobe strength; rotation comes from time, each
|
|
308
|
-
* lobe at its own speed in alternating directions.
|
|
325
|
+
* lobe at its own speed in alternating directions. No line in it is clean:
|
|
326
|
+
* the rim is crumbly, and a syllable throws crumbs rather than a ring.
|
|
309
327
|
*/
|
|
310
328
|
case "speaking": {
|
|
311
329
|
const grow = smoothstep(0, 1, Math.min(1, e / 0.8));
|
|
312
330
|
|
|
313
|
-
let raw =
|
|
331
|
+
let raw =
|
|
332
|
+
IDLE_R +
|
|
333
|
+
(SPEAK_BASE - IDLE_R + SPEAK_SWELL * v.phrase + SPEAK_KICK * v.bob) *
|
|
334
|
+
grow;
|
|
314
335
|
for (let i = 0; i < SPEAK_LOBES; i++) {
|
|
315
336
|
raw +=
|
|
316
337
|
SPEAK_LOBE_R *
|
|
@@ -318,26 +339,41 @@ function valueFor(m: AsciiOrbMode, cell: Cell, t: number, e: number, v: Voice) {
|
|
|
318
339
|
Math.sin((i + 2) * cell.angle + v.phase[i]) *
|
|
319
340
|
grow;
|
|
320
341
|
}
|
|
321
|
-
const edge =
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
342
|
+
const edge = rimAt(raw);
|
|
343
|
+
|
|
344
|
+
// each cell sits a little in or out of the rim, and the offset drifts
|
|
345
|
+
const rough =
|
|
346
|
+
(cell.grain - 0.5) * SPEAK_ROUGH +
|
|
347
|
+
Math.sin(cell.angle * 5 + t * 0.9 + cell.seed * 6.283) *
|
|
348
|
+
SPEAK_ROUGH *
|
|
349
|
+
0.3;
|
|
350
|
+
const d = cell.dist - (edge + rough);
|
|
351
|
+
const rim = Math.exp(-(d * d) / 800);
|
|
352
|
+
const core = Math.exp(-(cell.dist * cell.dist) / 6000) * 0.5;
|
|
353
|
+
// a soft fill toward the center, with the idle wave still moving through it
|
|
354
|
+
const inside =
|
|
355
|
+
cell.dist < edge
|
|
356
|
+
? 0.3 *
|
|
357
|
+
(1 - cell.dist / edge) ** 0.6 *
|
|
358
|
+
(0.75 + 0.25 * Math.sin(cell.dist * 0.05 - t * 1.2))
|
|
359
|
+
: 0;
|
|
360
|
+
|
|
361
|
+
// crumbs: a sparse share of cells, each thrown past the rim at its own speed
|
|
329
362
|
let out = 0;
|
|
330
|
-
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
363
|
+
if (cell.speck < SPECK_SHARE) {
|
|
364
|
+
const speed = RING_SPEED * (0.6 + cell.grain * 0.9);
|
|
365
|
+
for (let i = 0; i < v.rings.length; i++) {
|
|
366
|
+
const ring = v.rings[i];
|
|
367
|
+
const age = t - ring.born;
|
|
368
|
+
const dd = cell.dist - (edge + 6 + age * speed);
|
|
369
|
+
out +=
|
|
370
|
+
Math.exp(-(dd * dd) / 500) *
|
|
371
|
+
ring.power *
|
|
372
|
+
Math.max(0, 1 - age / RING_LIFE);
|
|
373
|
+
}
|
|
338
374
|
}
|
|
339
375
|
|
|
340
|
-
return rim + core + inside + out
|
|
376
|
+
return rim + core + inside + out;
|
|
341
377
|
}
|
|
342
378
|
|
|
343
379
|
/**
|
|
@@ -387,10 +423,10 @@ function valueFor(m: AsciiOrbMode, cell: Cell, t: number, e: number, v: Voice) {
|
|
|
387
423
|
export function AsciiOrb({
|
|
388
424
|
className,
|
|
389
425
|
mode = "idle",
|
|
390
|
-
charset =
|
|
426
|
+
charset = ASCII_FACE.charset,
|
|
391
427
|
emotion = null,
|
|
392
|
-
fontSize =
|
|
393
|
-
density =
|
|
428
|
+
fontSize = ASCII_FACE.fontSize.default,
|
|
429
|
+
density = ASCII_FACE.density.default,
|
|
394
430
|
size = DESIGN,
|
|
395
431
|
color = DEFAULT_COLOR,
|
|
396
432
|
getSpectrum,
|
|
@@ -432,12 +468,9 @@ export function AsciiOrb({
|
|
|
432
468
|
specRef.current = getSpectrum;
|
|
433
469
|
|
|
434
470
|
const voiceRef = useRef<Voice>({
|
|
435
|
-
|
|
436
|
-
mid: 0,
|
|
437
|
-
slow: 0,
|
|
471
|
+
phrase: 0,
|
|
438
472
|
bob: 0,
|
|
439
473
|
bobVel: 0,
|
|
440
|
-
lastOnset: -Infinity,
|
|
441
474
|
amp: new Array<number>(SPEAK_LOBES).fill(0),
|
|
442
475
|
// distinct start phases, or the lobes overlap into one lump at first
|
|
443
476
|
phase: Array.from({ length: SPEAK_LOBES }, (_, i) => i * 2.1),
|
|
@@ -502,6 +535,7 @@ export function AsciiOrb({
|
|
|
502
535
|
birth: hash(c * 3.1 + 7, r * 5.7 + 2),
|
|
503
536
|
death: hash(c * 9.4 + 3, r * 2.6 + 8),
|
|
504
537
|
emoji: hash(c * 2.7 + 31, r * 5.9 + 17) < EMOJI_RATIO,
|
|
538
|
+
speck: hash(c * 4.1 + 23, r * 6.3 + 41),
|
|
505
539
|
letter,
|
|
506
540
|
});
|
|
507
541
|
}
|
|
@@ -583,8 +617,8 @@ export function AsciiOrb({
|
|
|
583
617
|
// animation loop
|
|
584
618
|
useEffect(() => {
|
|
585
619
|
let raf = 0;
|
|
586
|
-
const
|
|
587
|
-
const
|
|
620
|
+
const follower = createVoiceFollower();
|
|
621
|
+
const murmur = new Array<number>(SPECTRUM_BANDS).fill(0);
|
|
588
622
|
|
|
589
623
|
let lastT = performance.now() * 0.001;
|
|
590
624
|
|
|
@@ -604,49 +638,27 @@ export function AsciiOrb({
|
|
|
604
638
|
bk.asciiN.fill(0);
|
|
605
639
|
bk.emojiN.fill(0);
|
|
606
640
|
|
|
607
|
-
// Live voice when available
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
const last = live.length - 1;
|
|
612
|
-
for (let i = 0; i < BINS; i++) {
|
|
613
|
-
// fold the band index so it returns to the first band over one revolution; a plain stretch shows a seam at 0 degrees
|
|
614
|
-
const fold = Math.abs((((i / BINS) * 2 + 1) % 2) - 1);
|
|
615
|
-
const at = fold * last;
|
|
616
|
-
const lo = Math.floor(at);
|
|
617
|
-
const hi = Math.min(last, lo + 1);
|
|
618
|
-
spec[i] = live[lo] + (live[hi] - live[lo]) * (at - lo);
|
|
619
|
-
}
|
|
620
|
-
} else {
|
|
621
|
-
for (let i = 0; i < BINS; i++) {
|
|
641
|
+
// Live voice when available; without one a murmur keeps the orb alive (previews)
|
|
642
|
+
let live: ArrayLike<number> | undefined = specRef.current?.();
|
|
643
|
+
if (!live || live.length < 2) {
|
|
644
|
+
for (let k = 0; k < murmur.length; k++) {
|
|
622
645
|
const a =
|
|
623
|
-
Math.sin(t * 1.7 +
|
|
624
|
-
Math.sin(t * 0.8 +
|
|
625
|
-
Math.sin(t * 3.0 +
|
|
626
|
-
|
|
646
|
+
Math.sin(t * 1.7 + k * 1.7) * 0.5 +
|
|
647
|
+
Math.sin(t * 0.8 + k * 0.6) * 0.3 +
|
|
648
|
+
Math.sin(t * 3.0 + k * 2.9) * 0.2;
|
|
649
|
+
murmur[k] = a * 0.5 + 0.5;
|
|
627
650
|
}
|
|
651
|
+
live = murmur;
|
|
628
652
|
}
|
|
629
653
|
|
|
630
|
-
//
|
|
654
|
+
// size, syllables and lobes from the voice, once per frame; each band is
|
|
655
|
+
// read inside its own range, or a voice's narrow loud spectrum pins the rim
|
|
631
656
|
const voice = voiceRef.current;
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
voice.fast += (loud - voice.fast) * 0.3;
|
|
638
|
-
voice.mid += (loud - voice.mid) * 0.06;
|
|
639
|
-
voice.slow += (loud - voice.slow) * 0.02;
|
|
640
|
-
|
|
641
|
-
if (
|
|
642
|
-
voice.fast > voice.mid * 1.25 + 0.02 &&
|
|
643
|
-
voice.fast > 0.07 &&
|
|
644
|
-
t - voice.lastOnset > 0.14
|
|
645
|
-
) {
|
|
646
|
-
voice.lastOnset = t;
|
|
647
|
-
const power = Math.min(1, voice.fast * 1.7);
|
|
648
|
-
voice.bobVel += 0.05 * power;
|
|
649
|
-
voice.rings.push({ born: t, power });
|
|
657
|
+
const heard = follower.read(live, dt);
|
|
658
|
+
voice.phrase = heard.phrase;
|
|
659
|
+
if (heard.onset > 0) {
|
|
660
|
+
voice.bobVel += 0.06 * heard.onset;
|
|
661
|
+
voice.rings.push({ born: t, power: heard.onset });
|
|
650
662
|
if (voice.rings.length > MAX_RINGS) voice.rings.shift();
|
|
651
663
|
}
|
|
652
664
|
// a spring with a period of about 1s; kick it on syllables instead of driving position, or 60fps noise becomes jitter
|
|
@@ -654,15 +666,19 @@ export function AsciiOrb({
|
|
|
654
666
|
voice.bob += voice.bobVel;
|
|
655
667
|
|
|
656
668
|
for (let i = 0; i < SPEAK_LOBES; i++) {
|
|
657
|
-
|
|
658
|
-
const
|
|
669
|
+
// neighbouring bands per lobe, low lobes from low bands
|
|
670
|
+
const from = Math.floor((i * heard.bands.length) / SPEAK_LOBES);
|
|
671
|
+
const to = Math.max(
|
|
672
|
+
from + 1,
|
|
673
|
+
Math.floor(((i + 1) * heard.bands.length) / SPEAK_LOBES),
|
|
674
|
+
);
|
|
659
675
|
let energy = 0;
|
|
660
|
-
for (let j = from; j < to; j++) energy +=
|
|
661
|
-
energy
|
|
676
|
+
for (let j = from; j < to; j++) energy += heard.bands[j];
|
|
677
|
+
energy /= to - from;
|
|
662
678
|
// a random factor that changes about once per second, so lobes keep moving through a held vowel
|
|
663
679
|
const wander = 0.7 + hash(((t * 0.9) | 0) + i * 31, i) * 0.6;
|
|
664
680
|
// different time constants per harmonic, or the star only scales
|
|
665
|
-
voice.amp[i] += (energy * wander - voice.amp[i]) * (0.
|
|
681
|
+
voice.amp[i] += (energy * wander - voice.amp[i]) * (0.05 + i * 0.02);
|
|
666
682
|
// own speed, alternating direction, so no standing wave forms
|
|
667
683
|
voice.phase[i] += dt * (0.5 + i * 0.37) * (i % 2 ? -1 : 1);
|
|
668
684
|
}
|
|
@@ -63,6 +63,13 @@ export function Boot({
|
|
|
63
63
|
}}
|
|
64
64
|
>
|
|
65
65
|
<AsciiField boot rim={face.rim} centerY={face.centerY} onSettled={lift} />
|
|
66
|
+
|
|
67
|
+
{/* Nothing here can lift the curtain without the client, so a load that
|
|
68
|
+
never hydrates is a blank screen. Revealed by CSS alone (globals.css
|
|
69
|
+
`stalled`), well after any healthy start. */}
|
|
70
|
+
<p className="absolute inset-x-0 bottom-16 animate-stalled text-center text-[13px] text-muted-foreground opacity-0">
|
|
71
|
+
The page did not start. Reload it.
|
|
72
|
+
</p>
|
|
66
73
|
</div>
|
|
67
74
|
);
|
|
68
75
|
}
|