thursday-agent 0.10.0 → 0.12.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 +0 -1
- package/.next/build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/routes-manifest.json +0 -6
- package/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/api/artifact/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/keep-working/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/thread/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/bot/thread/route.js.nft.json +1 -1
- package/.next/server/app/api/config/route.js.nft.json +1 -1
- package/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/server/app/api/favicon/[host]/route.js.nft.json +1 -1
- package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
- package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/edit/route.js.nft.json +1 -1
- package/.next/server/app/api/memory/route.js.nft.json +1 -1
- package/.next/server/app/api/reach/route.js +13 -13
- package/.next/server/app/api/reach/route.js.nft.json +1 -1
- package/.next/server/app/api/routine/route.js.nft.json +1 -1
- package/.next/server/app/api/signins/route.js +1 -1
- package/.next/server/app/api/signins/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
- package/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/text/route.js.nft.json +1 -1
- package/.next/server/app/api/thursday/tool-call/route.js +14 -15
- package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
- package/.next/server/app/api/workspace/files/route.js.nft.json +1 -1
- 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.nft.json +1 -1
- package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/favicon.ico/route.js.nft.json +1 -1
- package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -1
- package/.next/server/app/page/server-reference-manifest.json +56 -56
- package/.next/server/app/page.js +4 -4
- 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 +0 -1
- package/.next/server/chunks/[root-of-the-server]__014ydvq._.js +2 -2
- package/.next/server/chunks/[root-of-the-server]__0209ah4._.js +7 -5
- package/.next/server/chunks/[root-of-the-server]__04r4h-2._.js +4 -2
- package/.next/server/chunks/[root-of-the-server]__04wldw9._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0542v_d._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0cfszwn._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0gewdg9._.js +2 -2
- package/.next/server/chunks/[root-of-the-server]__0mrk2it._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0npn_pn._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0nr-v8s._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0rqgb17._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1-swlkw._.js +2 -2
- package/.next/server/chunks/[root-of-the-server]__12iddfq._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1ai5lme._.js +3 -3
- package/.next/server/chunks/[root-of-the-server]__1cjxw0-._.js +2 -2
- package/.next/server/chunks/{[root-of-the-server]__1fy2g82._.js → [root-of-the-server]__1k3j52n._.js} +1 -1
- package/.next/server/chunks/[root-of-the-server]__1kyjt5m._.js +3 -3
- package/.next/server/chunks/[root-of-the-server]__1tg5got._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__1ygplx1._.js +1 -1
- package/.next/server/chunks/_05v8k21._.js +3 -1
- package/.next/server/chunks/_0awtznl._.js +1 -1
- package/.next/server/chunks/_0f6ts7z._.js +1 -1
- package/.next/server/chunks/_0na2fj1._.js +1 -1
- package/.next/server/chunks/_0x-ej3f._.js +17 -17
- package/.next/server/chunks/_10tkr26._.js +1 -1
- package/.next/server/chunks/_12-amdu._.js +2 -2
- package/.next/server/chunks/_15740dw._.js +60 -0
- package/.next/server/chunks/_1dc_d1q._.js +3 -3
- package/.next/server/chunks/_1i350l5._.js +3 -1
- package/.next/server/chunks/_1jc5g4p._.js +2 -2
- package/.next/server/chunks/_1jn-aep._.js +4 -4
- package/.next/server/chunks/_1m88lkh._.js +11 -11
- package/.next/server/chunks/_1ogqovh._.js +4 -4
- package/.next/server/chunks/_1taa4bs._.js +1 -1
- package/.next/server/chunks/_1tpr507._.js +1 -1
- package/.next/server/chunks/_1uuucy-._.js +1 -1
- package/.next/server/chunks/_1zxp-p6._.js +1 -1
- package/.next/server/chunks/features_0rfvely._.js +5 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0a967km._.js +3 -0
- package/.next/server/chunks/ssr/{[root-of-the-server]__1se25x0._.js → [root-of-the-server]__0hpp3nw._.js} +29 -13
- package/.next/server/chunks/ssr/[root-of-the-server]__0tzekbl._.js +24 -60
- package/.next/server/chunks/ssr/{[root-of-the-server]__0tvavy9._.js → [root-of-the-server]__1iwyp1e._.js} +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1r77-88._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1w9hqq8._.js +1 -1
- package/.next/server/chunks/ssr/_026qnc9._.js +1 -1
- package/.next/server/chunks/ssr/{_173siic._.js → _02c7o30._.js} +2 -2
- package/.next/server/chunks/ssr/_097-ljd._.js +1 -1
- package/.next/server/chunks/ssr/_0euzzf8._.js +3 -0
- package/.next/server/chunks/ssr/{_1u2jw0i._.js → _0fbi6om._.js} +3 -3
- package/.next/server/chunks/ssr/_0fqhhwi._.js +1 -1
- package/.next/server/chunks/ssr/_0igfcax._.js +20 -0
- package/.next/server/chunks/ssr/_0ld9_qq._.js +1 -1
- package/.next/server/chunks/ssr/_0nvh1h9._.js +3 -0
- package/.next/server/chunks/ssr/_0qmpw35._.js +3 -0
- package/.next/server/chunks/ssr/{_1yk6yak._.js → _0rmaf32._.js} +2 -2
- package/.next/server/chunks/ssr/_0uv-qs4._.js +3 -0
- package/.next/server/chunks/ssr/{_1doidrw._.js → _10f-jib._.js} +2 -2
- package/.next/server/chunks/ssr/{_05rxyf9._.js → _10mo72m._.js} +2 -2
- package/.next/server/chunks/ssr/_12mijol._.js +11 -11
- package/.next/server/chunks/ssr/_132qkfz._.js +1 -1
- package/.next/server/chunks/ssr/_15zqt-t._.js +1 -1
- package/.next/server/chunks/ssr/_16gfxpn._.js +3 -0
- package/.next/server/chunks/ssr/_184327j._.js +1 -1
- package/.next/server/chunks/ssr/{_1ng831c._.js → _18ujhhq._.js} +2 -2
- package/.next/server/chunks/ssr/_1d423aj._.js +7 -5
- package/.next/server/chunks/ssr/_1lx6w_o._.js +67 -0
- package/.next/server/chunks/ssr/_1mqn9mc._.js +1 -1
- package/.next/server/chunks/ssr/_1neoj22._.js +1 -1
- package/.next/server/chunks/ssr/{_19n08g5._.js → _1ntpny5._.js} +2 -2
- package/.next/server/chunks/ssr/{_0bp-_fi._.js → _1o1g4uk._.js} +3 -3
- package/.next/server/chunks/ssr/_1xoch6f._.js +1 -1
- package/.next/server/chunks/ssr/_1yh5bj5._.js +1 -1
- package/.next/server/chunks/ssr/{_0tg0vf8._.js → _2008vmi._.js} +8 -8
- package/.next/server/chunks/ssr/{features_bot_1yr-_pm._.js → features_bot_1n1s7bh._.js} +2 -2
- package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
- package/.next/server/chunks/ssr/features_memory_components_memory-setting_tsx_0oa43sw._.js +1 -1
- package/.next/server/chunks/ssr/features_routine_components_routine-setting_tsx_055fknz._.js +1 -1
- package/.next/server/chunks/ssr/features_workspace_00jz2hu._.js +1 -1
- package/.next/server/chunks/ssr/{node_modules_1n0h9sf._.js → node_modules_0-x0zxm._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1xzo2wn._.js → node_modules_00nrzz_._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0511ha-._.js → node_modules_01ed0yi._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_18woe20._.js → node_modules_01u4ea3._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1expacw._.js → node_modules_05b6e99._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0eb4rx7._.js → node_modules_07jp6tj._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0piws2a._.js → node_modules_0azd56x._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0f2k5l0._.js → node_modules_0b0iy01._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0wq4-ts._.js → node_modules_0fpnetd._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_11hbkuj._.js → node_modules_0ky76fz._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_048wmmj._.js → node_modules_0lautv3._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1dcbvfw._.js → node_modules_0m3_5ge._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0pk6i-e._.js → node_modules_0operbz._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1zkpek5._.js → node_modules_0ou0all._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_04t200t._.js → node_modules_0ucridu._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_08g12f-._.js → node_modules_0v_-uht._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1m2ho33._.js → node_modules_0yzmxfq._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1ksh9gy._.js → node_modules_19b0bir._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1qehmwm._.js → node_modules_1c2ikr9._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1_afpz7._.js → node_modules_1hv-j1l._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0cdu6jq._.js → node_modules_1iau_ea._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1zf46lp._.js → node_modules_1ma_y68._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0s1lwc9._.js → node_modules_1omg9xr._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1cxc8kn._.js → node_modules_1wgnj8q._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_0zjqwz7._.js → node_modules_1wvf3oo._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_1_ban4u._.js → node_modules_1z3sh11._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0avl8-1._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0tmjn9w._.js} +1 -1
- package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_14oslro._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1_e8c3o._.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 +57 -57
- package/.next/static/chunks/09pkygbht7ki8.js +18 -0
- package/.next/static/chunks/0bm-nhblcmmj4.js +17 -0
- package/.next/static/chunks/{22shnca_6zfzs.js → 0hhza87hkbqaz.js} +1 -1
- package/.next/static/chunks/{19ojn4lomsk0r.js → 0mscosx0eh3ee.js} +1 -1
- package/.next/static/chunks/{3vynnr71ghvom.js → 0p50d-au6-3hx.js} +2 -2
- package/.next/static/chunks/{42890jqk049q1.js → 0p9jcyqkpq71f.js} +1 -1
- package/.next/static/chunks/{35kwn237o4wdn.js → 0qgn3u86jkbm7.js} +1 -1
- package/.next/static/chunks/{2d4z3er53ng8r.js → 0samf80yu2b17.js} +1 -1
- package/.next/static/chunks/{1pjygp7hqib6j.js → 1czfknd4luo6t.js} +1 -1
- package/.next/static/chunks/{09120tms63y21.js → 1jz8n0mhtdzr8.js} +1 -1
- package/.next/static/chunks/206laxm6maiz2.js +1 -0
- package/.next/static/chunks/{24dst4mgurbsh.js → 2_c7mu6x1lu49.js} +1 -1
- package/.next/static/chunks/{2ky81z-jgvasc.js → 2h-tlhb2ffhkk.js} +1 -1
- package/.next/static/chunks/{0oz3rs47yy3p8.js → 2i5_w8olnrvo0.js} +2 -2
- package/.next/static/chunks/{1mwee7xvitlp9.js → 2m8iqwc6sykln.js} +1 -1
- package/.next/static/chunks/{0o980477kfqez.js → 2r6xnyg7ezyxr.js} +1 -1
- package/.next/static/chunks/33fyp-byw48ju.js +65 -0
- package/.next/static/chunks/{2ndw4w4u2x51r.js → 35yd_27d9ylra.js} +1 -1
- package/.next/static/chunks/{3exjsi8pfdvzj.js → 3ag1i3__yl94f.js} +1 -1
- package/.next/static/chunks/{3obf9n3cxj99k.js → 3jvldk2wvwbge.js} +1 -1
- package/.next/static/chunks/3m_ejzg-xn21r.css +1 -0
- package/.next/static/chunks/{0w20wnnfrscq7.js → 3s-jpd3ky49-n.js} +1 -1
- package/.next/static/chunks/40ij3wsn3vt7h.js +1 -0
- package/README.md +1 -1
- package/app/api/thursday/tool-call/route.ts +1 -15
- package/docs/images/demo-still.jpg +0 -0
- package/docs/live-calls.md +19 -11
- package/features/ai/components/model-picker.tsx +8 -2
- package/features/ai/model.schema.ts +26 -0
- package/features/ai/prompts/live.prompt.ts +51 -26
- package/features/ai/prompts/prompt-helper.ts +1 -9
- package/features/ai/prompts/thursday.prompt.ts +8 -2
- package/features/bot/bot.run.ts +9 -3
- package/features/bot/bot.seed.ts +35 -91
- package/features/bot/components/bot-room.tsx +3 -12
- package/features/bot/components/room-list.tsx +1 -1
- package/features/bot/components/room-pill.tsx +44 -55
- package/features/bot/seed-bots.ts +2 -2
- package/features/config/components/config-badge.tsx +6 -0
- package/features/config/components/config-setting.tsx +20 -1
- package/features/config/components/models-badge.tsx +5 -7
- package/features/config/components/voice-key.tsx +24 -1
- package/features/config/config.const.ts +7 -0
- package/features/intro/components/intro.tsx +4 -19
- package/features/reach/reach.ts +2 -2
- package/features/settings/components/setting-ui.tsx +14 -5
- package/features/settings/components/settings.tsx +3 -1
- package/features/settings/settings.alert.ts +12 -11
- package/features/signins/signins.query.ts +66 -1
- package/features/thursday/components/side-captions.tsx +31 -8
- package/features/thursday/components/tab-state.tsx +5 -2
- package/features/thursday/components/thursday.tsx +158 -68
- package/features/thursday/components/write-line.tsx +37 -17
- package/features/thursday/thursday.action.ts +4 -20
- package/features/thursday/thursday.schema.ts +0 -9
- package/features/thursday/thursday.store.ts +11 -15
- package/features/thursday/thursday.text.ts +10 -8
- package/features/thursday/tool-line.ts +17 -6
- package/features/thursday/use-call-ring.ts +1 -5
- package/features/thursday/use-text-call.ts +37 -21
- package/features/thursday/use-thursday.ts +14 -44
- package/features/workspace/workspace.ts +4 -2
- package/guide/bots.md +12 -2
- package/guide/calls.md +9 -6
- package/guide/setup.md +4 -1
- package/lib/live/live.session.ts +0 -39
- package/package.json +1 -1
- package/scripts/live-session.test.mts +19 -26
- package/seed-skills/analyst/README.md +3 -4
- package/seed-skills/analyst/data-report/SKILL.md +5 -4
- package/seed-skills/insta/instagram/SKILL.md +5 -2
- package/seed-skills/insta/instagram/references/post.md +2 -2
- package/seed-skills/insta/instagram/scripts/compose.mjs +5 -1
- package/seed-skills/insta/instagram/scripts/inbox.mjs +5 -1
- package/seed-skills/insta/instagram/scripts/lib.mjs +12 -70
- package/seed-skills/insta/instagram/scripts/media.mjs +1 -1
- package/seed-skills/insta/instagram/scripts/profile.mjs +6 -2
- package/seed-skills/insta/instagram/scripts/read.mjs +5 -1
- package/seed-skills/insta/instagram/scripts/search.mjs +6 -2
- package/seed-skills/insta/instagram/scripts/sheet.mjs +31 -88
- package/seed-skills/insta/instagram/templates/carousel.html +1 -1
- package/seed-skills/tutor/picture-book/SKILL.md +16 -0
- package/seed-skills/tutor/picture-book/book/book.css +181 -0
- package/seed-skills/tutor/picture-book/book/book.html +33 -0
- package/seed-skills/tutor/picture-book/book/book.js +60 -0
- package/seed-skills/tutor/picture-book/references/picture-book.md +104 -0
- package/seed-skills/tutor/picture-book/scripts/book-video.mjs +177 -0
- package/seed-skills/tutor/picture-book/scripts/book.mjs +98 -0
- package/skills/browser/SKILL.md +13 -4
- package/skills/browser/references/scripts.md +55 -0
- package/{seed-skills/insta/instagram → skills/browser}/scripts/render.mjs +1 -1
- package/skills/browser/scripts/session.mjs +105 -0
- package/skills/browser/scripts/sheet.mjs +97 -0
- package/{seed-skills/insta/instagram → skills/browser}/scripts/webimage.mjs +1 -1
- package/skills/interactive-page/SKILL.md +4 -3
- package/{seed-skills/analyst/data-report → skills/interactive-page}/scripts/chart.mjs +3 -3
- package/skills/interactive-page/scripts/page.mjs +1 -0
- package/.next/server/app/api/probe/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/probe/route/build-manifest.json +0 -12
- package/.next/server/app/api/probe/route/server-reference-manifest.json +0 -4
- package/.next/server/app/api/probe/route.js +0 -10
- package/.next/server/app/api/probe/route.js.map +0 -5
- package/.next/server/app/api/probe/route.js.nft.json +0 -1
- package/.next/server/app/api/probe/route_client-reference-manifest.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__012s2o8._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0z0hc1f._.js +0 -4
- package/.next/server/chunks/[root-of-the-server]__1v7-zke._.js +0 -5
- package/.next/server/chunks/_0whlpyi._.js +0 -4
- package/.next/server/chunks/_next-internal_server_app_api_probe_route_actions_0cqd30j.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0cxqzfc._.js +0 -103
- package/.next/server/chunks/ssr/[root-of-the-server]__1-d2tgh._.js +0 -3
- package/.next/server/chunks/ssr/_070nv1_._.js +0 -3
- package/.next/server/chunks/ssr/_0hlxij-._.js +0 -3
- package/.next/server/chunks/ssr/_0p9pmxe._.js +0 -3
- package/.next/server/chunks/ssr/_0s41irp._.js +0 -3
- package/.next/server/chunks/ssr/_157yfrk._.js +0 -3
- package/.next/server/chunks/ssr/_17v-33v._.js +0 -20
- package/.next/server/chunks/ssr/_1flsjeo._.js +0 -3
- package/.next/static/chunks/03kgfyrli_0gz.js +0 -1
- package/.next/static/chunks/1p764d75_0lhv.js +0 -18
- package/.next/static/chunks/25zq8gzhbdsr7.js +0 -1
- package/.next/static/chunks/2qod5tqlpz8b7.js +0 -17
- package/.next/static/chunks/30skcjexa57zn.js +0 -101
- package/.next/static/chunks/3qq4o8w2rv_e9.css +0 -1
- package/lib/probe.server.ts +0 -17
- package/lib/probe.ts +0 -55
- package/seed-skills/mail/mail/SKILL.md +0 -37
- package/seed-skills/mail/mail/recipes/gmail.mjs +0 -448
- package/seed-skills/mail/mail/references/recipes.md +0 -55
- package/seed-skills/mail/mail/scripts/mail.mjs +0 -202
- /package/.next/static/{Ar5V4kMdL4CE1trx8anrH → QSe0rTdXU5kh5BBzr2XBB}/_buildManifest.js +0 -0
- /package/.next/static/{Ar5V4kMdL4CE1trx8anrH → QSe0rTdXU5kh5BBzr2XBB}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{Ar5V4kMdL4CE1trx8anrH → QSe0rTdXU5kh5BBzr2XBB}/_ssgManifest.js +0 -0
- /package/{seed-skills/insta/instagram → skills/browser}/scripts/image-size.mjs +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,616816,e=>{"use strict";var t=e.i(843476),r=e.i(375775),n=e.i(689664),a=e.i(263676),l=e.i(271645),i=e.i(798120),s=e.i(167881),o=e.i(23750),u=e.i(968978),c=e.i(149666),h=e.i(265402),f=e.i(609856),d=e.i(283653),m=e.i(647163),g=e.i(722560),p=e.i(992112);function y({provider:e,saved:r,autoFocus:n,dense:a,plain:l,value:i,ready:s,saving:o,onValue:c,onSubmit:h}){return(0,t.jsxs)("div",{className:"space-y-2",children:[!l&&(0,t.jsxs)("span",{className:"flex items-center gap-2 px-0.5 text-muted-foreground",children:[(0,t.jsx)(u.ProviderIcon,{provider:e.id,className:"size-4 shrink-0"}),(0,t.jsx)("span",{className:(0,m.cn)("font-mono",a?"text-[11px]":"text-[12.5px]"),children:e.label})]}),(0,t.jsx)(x,{provider:e,saved:r,autoFocus:n,dense:a,mark:l,value:i,ready:s,saving:o,onValue:c,onSubmit:h})]})}function x({provider:e,saved:r,autoFocus:a,dense:l,mark:i,value:c,ready:h,saving:f,onValue:d,onSubmit:g}){let p=c.trim().startsWith("xai-")||c.trim().startsWith("sk-ant-");return(0,t.jsxs)("form",{onSubmit:e=>{e.preventDefault(),g()},className:(0,m.cn)("flex items-center gap-3 rounded-2xl border bg-muted/40 px-4 transition-colors",l?"h-11 rounded-xl px-3":"h-14",r||h?"border-foreground bg-transparent":"border-border"),children:[i&&(0,t.jsx)(u.ProviderIcon,{provider:e.id,className:"size-4 shrink-0 text-muted-foreground"}),(0,t.jsx)(o.Input,{autoFocus:a,type:"password","aria-label":"OpenAI API key",autoComplete:"off",value:c,spellCheck:!1,placeholder:r?"Replace it":"sk-…",onChange:e=>d(e.target.value),className:(0,m.cn)("min-w-0 flex-1 border-0 bg-transparent px-0 font-mono shadow-none focus-visible:ring-0 dark:bg-transparent",l?"h-7 text-[13px]":"h-9 text-[15px]")}),c?(0,t.jsx)(s.Button,{type:"submit",size:"sm",variant:p?"outline":"default",loading:f,disabled:!h,className:(0,m.cn)("shrink-0",l?"h-7 px-3":"h-9 px-4"),children:p?`Not ${e.label}?`:"Save"}):r&&(0,t.jsx)("span",{className:(0,m.cn)("grid shrink-0 animate-in place-items-center rounded-full bg-foreground text-background zoom-in-50 duration-300",l?"size-5":"size-7"),children:(0,t.jsx)(n.Check,{className:l?"size-3":"size-4"})})]})}e.s(["GetKeyLink",0,function(){let e=h.TEXT_MODEL_PROVIDERS[c.LIVE_PROVIDER.id].keysAt;return e?(0,t.jsxs)("a",{href:e,target:"_blank",rel:"noreferrer",className:"flex items-center gap-2.5 text-[13px] font-medium text-foreground no-underline",children:[(0,t.jsxs)("span",{className:"flex h-7.5 shrink-0 items-center gap-1.5 rounded-full bg-muted px-3.5 whitespace-nowrap transition-colors hover:bg-accent",children:["Get a key",(0,t.jsx)(r.ArrowUpRight,{className:"size-3.5"})]}),(0,t.jsx)("span",{className:"truncate font-mono text-[11px] font-normal text-muted-foreground/70",children:e.replace(/^https:\/\//,"")})]}):null},"KEY_MIN",0,8,"KeyInput",0,x,"VoiceKeys",0,function({ref:e,autoFocus:r,dense:n=!1,plain:o=!1,onCancel:u,onSaved:h,className:x}){let{data:M}=(0,d.useServerRoute)(i.queryKey.config),[O,A]=(0,l.useState)({}),[b,E]=(0,l.useState)(null),[S,_]=(0,l.useState)(null),[w]=(0,f.useServerAction)(g.setConfigAction,{errorMessage:!1,onError:e=>_(e??"That key was not saved."),onOk:()=>{(0,d.revalidate)(i.queryKey.config),(0,d.revalidate)(i.queryKey.llmModel)}}),N=e=>(O[e]?.trim().length??0)>=8,v=async e=>{let t=e.apiKeyName;if(!N(t)||b)return!1;_(null),E(t);try{return await w(t,O[t]),A(e=>({...e,[t]:""})),h?.(e.id),!0}catch{return!1}finally{E(null)}};return(0,l.useImperativeHandle)(e,()=>({pending:()=>N(c.LIVE_PROVIDER.apiKeyName),flush:async()=>!N(c.LIVE_PROVIDER.apiKeyName)||v(c.LIVE_PROVIDER)})),(0,t.jsxs)("div",{className:(0,m.cn)("w-full",n?"space-y-2":"space-y-4",x),children:[n&&!o&&(0,t.jsxs)("div",{className:"flex h-6 items-center justify-between gap-2",children:[(0,t.jsx)("span",{className:"px-0.5 font-mono text-[11px] text-muted-foreground",children:"Voice key"}),u&&(0,t.jsx)(s.Button,{type:"button",size:"icon",variant:"ghost","aria-label":"Not now",onClick:u,className:"-my-1 size-6",children:(0,t.jsx)(a.X,{className:"size-3.5"})})]}),(0,t.jsx)(y,{provider:c.LIVE_PROVIDER,saved:(0,p.isConfigSet)(M,c.LIVE_PROVIDER.apiKeyName),autoFocus:r,dense:n,plain:o,value:O[c.LIVE_PROVIDER.apiKeyName]??"",ready:N(c.LIVE_PROVIDER.apiKeyName),saving:b===c.LIVE_PROVIDER.apiKeyName,onValue:e=>{_(null),A(t=>({...t,[c.LIVE_PROVIDER.apiKeyName]:e}))},onSubmit:()=>void v(c.LIVE_PROVIDER)}),S&&(0,t.jsx)("p",{className:(0,m.cn)("px-0.5 leading-5 break-words",n?"text-xs":"text-center text-[13px]",m.WAITING_INK),children:S}),!o&&(0,t.jsx)("p",{className:(0,m.cn)("px-0.5 font-mono text-muted-foreground",n?"text-[11px]":"pt-1 text-center text-[12.5px]"),children:n?"Live voice and reasoning share this OpenAI API key.":"Live uses an OpenAI API key, billed separately from ChatGPT. Stored on this machine, in this app's database."})]})}])},333495,e=>{"use strict";var t=e.i(843476),r=e.i(271645),n=e.i(41533),a=e.i(218080),l=e.i(567334);let i=[235,235,235];function s(e){let t=[[],[],[],[],[]],r=0;for(let n of Array.from(e.toUpperCase())){let e=l.LETTERS[n];if(e){if(t[0].length)for(let e of t)e.push(-1);e.forEach((e,n)=>{for(let a of e)t[n].push("#"===a?r:-1)})," "!==n&&r++}}return t}let o=s("ERROR");function u(e,t,r,n,a){return e+(t-e)*Math.min(1,a/(t>e?r:n))}function c(e,t,r,n,a,l){let i=Math.floor(t/(n*l)+e[0].length/2),s=Math.floor(r/(a*l)+e.length/2);return s<0||s>=e.length?-1:e[s][i]??-1}function h(e,t,r,n){let a=e=>Math.max(1,Math.min(3,Math.floor(625.6/(e[0].length*t)),Math.floor(421.6/(e.length*r)))),l=s(n),i=3>a(l)?function(e){let t=Array.from(e.trim()),r=t.flatMap((e,t)=>" "===e?[t]:[]);if(!r.length)return null;let n=t.length/2,a=r.reduce((e,t)=>Math.abs(t-n)<Math.abs(e-n)?t:e),l=s(t.slice(0,a).join("")),i=s(t.slice(a+1).join(""));if(!l[0].length||!i[0].length)return null;let o=Math.max(-1,...l.flat())+1,u=Math.max(l[0].length,i[0].length),c=(e,t)=>{let r=Math.floor((u-e.length)/2);return[...Array(r).fill(-1),...e.map(e=>e<0?e:e+t),...Array(u-e.length-r).fill(-1)]},h=()=>Array(u).fill(-1);return[...l.map(e=>c(e,0)),h(),h(),...i.map(e=>c(e,o))]}(n):null,o=i&&a(i)>a(l)?i:l,u=a(o),h=0;for(let n of e)n.word=c(o,n.dx,n.dy,t,r,u),h=Math.max(h,n.word+1);return h}function f({className:e,mode:s="idle",charset:d=n.ASCII_FACE.charset,fontSize:m=n.ASCII_FACE.fontSize.default,density:g=n.ASCII_FACE.density.default,size:p=680,color:y=i,getSpectrum:x,word:M=null}){let O=(0,r.useRef)(null),A=(0,r.useRef)(null),b=(0,r.useRef)([]),E=(0,r.useRef)(null),S=(0,r.useRef)(d),_=(0,r.useRef)({cur:[...y],target:y}),w=(0,r.useRef)(0),N=(0,r.useRef)(x);N.current=x;let v=(0,r.useRef)({phrase:0,bob:0,bobVel:0,amp:[,,,,].fill(0),phase:Array.from({length:4},(e,t)=>2.1*t),spin:0,rings:[]}),L=(0,r.useRef)({mode:s,start:0}),R=(0,r.useRef)(performance.now()),I=(0,r.useRef)({scale:.3,lift:0,gather:0,comet:0,speech:0,err:0,word:0}),T=(0,r.useRef)(null),k=(0,r.useRef)({cw:1,ch:1});return(0,r.useEffect)(()=>{let e=O.current;if(!e)return;let t=.95*m/g,r=1.25*m/g,n=680/p,a=t*n,i=r*n,s=Math.max(1,Math.floor(625.6/(o[0].length*a)));w.current=p,k.current={cw:a,ch:i};let u=[],f=Math.ceil(p/t),d=Math.ceil(p/r);for(let e=0;e<d;e++)for(let h=0;h<f;h++){let f=h*t,d=e*r,m=(f-p/2)*n,g=(d-p/2)*n,y=Math.hypot(m,g),x=c(o,m,g,a,i,s);x<0&&y>328||u.push({x:f+t/2,y:d+r/2,dx:m,dy:g,dist:y,angle:Math.atan2(g,m),seed:(0,l.hash)(h,e),grain:(0,l.hash)(5.7*h+19,2.3*e+53),gap:.05+.3*(0,l.hash)(7.3*h+11,3.1*e+5),emoji:(0,l.hash)(2.7*h+31,5.9*e+17)<l.EMOJI_RATIO,speck:(0,l.hash)(4.1*h+23,6.3*e+41),letter:x,word:-1})}b.current=u,T.current&&h(u,a,i,T.current.text),E.current={ascii:Array.from({length:l.RAMP.length},()=>new Int32Array(u.length)),emoji:Array.from({length:l.RAMP.length},()=>new Int32Array(u.length)),asciiN:new Int32Array(l.RAMP.length),emojiN:new Int32Array(l.RAMP.length),glyph:Array(u.length)};let y=Math.min(2,window.devicePixelRatio||1);e.width=p*y,e.height=p*y,e.style.width=`${p}px`,e.style.height=`${p}px`;let x=e.getContext("2d");return x&&(x.setTransform(y,0,0,y,0,0),x.font=`700 ${m}px ui-monospace,SFMono-Regular,Menlo,monospace`,x.textAlign="center",x.textBaseline="middle",A.current=x),()=>{x?.clearRect(0,0,p,p),b.current=[],E.current=null}},[m,g,p]),(0,r.useEffect)(()=>{S.current=d},[d]),(0,r.useEffect)(()=>{_.current.target=y},[y]),(0,r.useEffect)(()=>{L.current.mode!==s&&(L.current={mode:s,start:.001*performance.now()})},[s]),(0,r.useEffect)(()=>{if(!M||Date.now()-M.at>(M.hold??3.4)*1e3)return;let{cw:e,ch:t}=k.current,r=performance.now(),n=r-R.current<600?.11*M.text.length+.3+.45:0;T.current={text:M.text,start:.001*r-n,letters:h(b.current,e,t,M.text),hold:M.hold??3.4}},[M]),(0,r.useEffect)(()=>{let e=0,t=(0,a.createVoiceFollower)(),r=Array(a.SPECTRUM_BANDS).fill(0),n=.001*performance.now(),i=0,s=0,o=a=>{let c=.001*a,h=Math.min(.05,Math.max(0,c-n));n=c;let f=A.current,d=E.current;if(!f||!d){e=requestAnimationFrame(o);return}let m=S.current,g=w.current;d.asciiN.fill(0),d.emojiN.fill(0);let p=N.current?.();if(!p||p.length<2){for(let e=0;e<r.length;e++){let t=.5*Math.sin(1.7*c+1.7*e)+.3*Math.sin(.8*c+.6*e)+.2*Math.sin(3*c+2.9*e);r[e]=.5*t+.5}p=r}let y=v.current,x=t.read(p,h);y.phrase=x.phrase,x.onset>0&&(y.bobVel+=.06*x.onset,y.rings.push({born:c,power:x.onset}),y.rings.length>5&&y.rings.shift()),y.bobVel+=-(.012*y.bob)-.09*y.bobVel,y.bob+=y.bobVel,i+=h;for(let e=0;e<4;e++){let t=Math.floor(e*x.bands.length/4),r=Math.max(t+1,Math.floor((e+1)*x.bands.length/4)),n=0;for(let e=t;e<r;e++)n+=x.bands[e];n/=r-t;let a=.7+.6*(0,l.hash)((.9*c|0)+31*e,e);y.amp[e]+=(n*a-y.amp[e])*(.05+.02*e),y.phase[e]+=h*(.9+.5*e)*(e%2?-1:1)}for(y.spin+=h*(1.1+.9*y.phrase);y.rings.length>0&&c-y.rings[0].born>.7;)y.rings.shift();let M=L.current,O=T.current,R=O?c-O.start:0,k=null!==O&&"error"!==M.mode&&R<O.hold+.08*O.letters+.45+.35+.9?{scale:0,lift:0,gather:0,comet:0,speech:0,err:0,word:1}:function(e,t){let r={scale:1,lift:0,gather:0,comet:0,speech:0,err:0,word:0};switch(e){case"idle":return r;case"connecting":{let e=1-Math.exp(-t/1.3);return{...r,scale:.45+.55*e,lift:.06*e,gather:1}}case"speaking":return{...r,speech:1};case"working":return{...r,scale:0,comet:1};case"ending":return{...r,scale:0};case"error":return{...r,scale:0,err:1}}}(M.mode,c-M.start),j=I.current;j.scale=u(j.scale,k.scale,.45,"ending"===M.mode?.4:.7,h),j.lift=u(j.lift,k.lift,.22,.4,h),j.gather=u(j.gather,k.gather,.3,.95,h),j.comet=u(j.comet,k.comet,.45,.9,h),j.speech=u(j.speech,k.speech,.5,.75,h),"error"===M.mode&&(j.err<=.01&&(s=0),s+=h),j.err=u(j.err,k.err,.5,.6,h),j.word=u(j.word,k.word,.35,.5,h);let P=j.err>.5,C=j.word>.5,V="emojiOnly"===m?l.EMOJI_CHAR_RATE:l.CHAR_RATE,D=b.current;for(let e=0;e<D.length;e++){let t=D[e],r=function(e,t,r,n,a,i,s){let o,u,c,h,f=i.scale>.02?function(e,t,r=0,n=1){let a=170*Math.max(.02,n),i=1-(0,l.smoothstep)(.55*a,a,e.dist);return(.58+r+.2*Math.sin(.05*e.dist-.4*t)+.07*Math.sin(.35*t))*i}(e,t,i.lift,i.scale)*(1-.6*i.speech):0;return i.gather>.01&&(f+=function(e,t,r){let n=170*r;if(e.speck>=.55||e.dist<.8*n)return 0;let a=Math.min(55,Math.floor((e.angle+Math.PI)/(2*Math.PI)*56)),i=(.7*t+(0,l.hash)(a,5.3))%1,s=e.dist-(n+(320-n)*(1-i)**1.25)-(e.grain-.5)*16;return Math.exp(-(s*s)/260)*(0,l.smoothstep)(0,.2,i)*(1-i)*1.1}(e,t,i.scale)*i.gather),i.comet>.01&&(f+=(u=Math.exp(-((o=e.dist-210)*o)/1100),u*Math.exp(-((h=Math.atan2(Math.sin(c=e.angle-3*t),Math.cos(c)))*h)/(h<0?2.8:.16))*i.comet)),i.speech>.01&&(f+=function(e,t,r,n){var a;let l=170+40*r.phrase+85*r.bob;for(let t=0;t<4;t++)l+=28*r.amp[t]*Math.sin((t+2)*(e.angle+r.spin)+r.phase[t]);let i=170+(((a=l)<=205?Math.max(110,a):205+30*Math.tanh((a-205)/30))-170)*n,s=(e.grain-.5)*20+20*Math.sin(5*e.angle+.9*t+6.283*e.seed)*.3,o=e.dist-(i+s),u=Math.exp(-(o*o)/800)+.5*Math.exp(-(e.dist*e.dist)/6e3);if(e.dist<i&&(u+=.22*(1-e.dist/i)**.6*(.75+.25*Math.sin(.05*e.dist-1.2*t))),e.speck<.22){let n=90*(.6+.9*e.grain);for(let a=0;a<r.rings.length;a++){let l=r.rings[a],s=t-l.born,o=e.dist-(i+6+s*n);u+=Math.exp(-(o*o)/500)*l.power*Math.max(0,1-s/.7)}}return u}(e,t,s,i.speech)*i.speech),i.err>.01&&(f+=function(e,t,r){if(e.letter<0)return 0;let n=r%9.2,a=.12*e.seed;return Math.max(0,(0,l.smoothstep)(0,1,(n-.65*e.letter-a)/.8)-(0,l.smoothstep)(0,1,(n-5.6-.5*e.letter-a)/.7))*(.86+.14*Math.sin(3.5*t+6*e.seed))}(e,t,r)*i.err),i.word>.01&&(f+=function(e,t,r,n){if(e.word<0)return 0;let a=.45*e.seed,i=(0,l.smoothstep)(0,1,(r-.11*e.word-a)/.3),s=r-n-.08*e.word-a,o=(0,l.smoothstep)(0,1,s/.35),u=.2*(1-(0,l.smoothstep)(0,1,(s-.35)/.9));return Math.max(i-o,i>.5?u*o:0)*((i>0&&i<1||o>0&&u>0)&&.35>(0,l.hash)(Math.floor(14*t)+97*e.seed,31*e.grain)?.25:1)*(.86+.14*Math.sin(3.5*t+6*e.seed))}(e,t,n,a)*i.word),f}(t,c,s,R,O?.hold??3.4,j,y);!(P&&t.letter>=0||C&&t.word>=0)&&((r*=(.66+.72*t.grain)*(.8+.4*(0,l.hash)(Math.floor(.05*t.dx+.5*c),Math.floor(.05*t.dy-.3*c))))>.3&&(0,l.hash)(31.7*Math.floor(1.6*c),613*t.seed)>.992&&(r=Math.max(r,.9)),r<t.gap+.05*Math.sin(.28*c+6.283*t.seed)&&(r=0));let n=(r=r<0?0:r>1?1:r)*(l.RAMP.length-1)|0;if(0===n)continue;let a=i*V+7*t.seed|0;if("emojiOnly"===m||"emoji"===m&&t.emoji&&n>=l.EMOJI_MIN_LEVEL){let r=((t.seed*l.EMOJI_POOL.length|0)+a)%l.EMOJI_POOL.length;d.glyph[e]=l.EMOJI_POOL[r],d.emoji[n][d.emojiN[n]++]=e}else{let r=l.RAMP[n],i=((t.seed*r.length|0)+a)%r.length;d.glyph[e]=r[i],d.ascii[n][d.asciiN[n]++]=e}}f.clearRect(0,0,g,g);let $=b.current,K=l.RAMP.length-1,F=_.current;for(let e=0;e<3;e++)F.cur[e]+=(F.target[e]-F.cur[e])*.05;f.fillStyle=`rgb(${0|F.cur[0]},${0|F.cur[1]},${0|F.cur[2]})`;for(let e=1;e<=K;e++){let t=d.asciiN[e];if(0===t)continue;f.globalAlpha=l.ALPHA_TOP*(e/K);let r=d.ascii[e];for(let e=0;e<t;e++){let t=$[r[e]];f.fillText(d.glyph[r[e]],t.x,t.y)}}for(let e=1;e<=K;e++){let t=d.emojiN[e];if(0===t)continue;f.globalAlpha=.35+e/K*.65;let r=d.emoji[e];for(let e=0;e<t;e++){let t=$[r[e]];f.fillText(d.glyph[r[e]],t.x,t.y)}}f.globalAlpha=1,e=requestAnimationFrame(o)};return e=requestAnimationFrame(o),()=>cancelAnimationFrame(e)},[]),(0,t.jsx)("canvas",{ref:O,className:e,"aria-hidden":!0,style:{display:"block",pointerEvents:"none"}})}var d=e.i(922521),m=e.i(647163);let g={ending:"ending",idle:"idle",connecting:"connecting",listening:"idle",speaking:"speaking",working:"working",delegating:"working"},p=[247,247,247],y=[10,10,10];function x({status:e,failed:r,word:n,size:a,getSpectrum:l,look:i,className:s}){let o="dark"===(0,d.useResolvedTheme)();return(0,t.jsx)(f,{mode:r?"error":g[e],word:n,size:a,color:o?p:y,getSpectrum:l,charset:i.charset,fontSize:i.fontSize,density:i.density,className:s})}let M=(0,r.memo)(function({look:e,status:n="idle",size:a=448,className:l,...i}){let s=(0,r.useRef)(null),[o,u]=(0,r.useState)(a),[c,h]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{let e=s.current;if(!e)return;let t=new ResizeObserver(([e])=>{let t=Math.round(e.contentRect.width);t>0&&u(t)});return t.observe(e),()=>t.disconnect()},[]),(0,r.useEffect)(()=>{let e=requestAnimationFrame(()=>h(!0));return()=>cancelAnimationFrame(e)},[]),(0,t.jsx)("div",{ref:s,className:(0,m.cn)("aspect-square transition-opacity duration-700 ease-out",c?"opacity-100":"opacity-0",l),children:(0,t.jsx)(x,{...i,look:e,status:n,size:o})})});e.s(["Face",0,M],333495)},67045,e=>{"use strict";let t,r;var n=e.i(768834);let a=e=>t=>{try{let r=e(t);if(r instanceof Promise)return r;return{then:e=>a(e)(r),catch(e){return this}}}catch(e){return{then(e){return this},catch:t=>a(t)(e)}}};var l=e.i(149666),i=e.i(265402),s=e.i(671228);let o=l.LiveSettingsSchema.extend({wake:s.WakeSchema.catch(s.WAKE_DEFAULT),hotkey:s.HotkeySchema.catch(s.HOTKEY_DEFAULT),callBack:s.CallBackSchema.catch(s.CALL_BACK_DEFAULT),captionView:s.CaptionViewSchema.catch("sides"),textModel:i.textModelRefSchema.nullable().catch(null)}),u={...l.LIVE_DEFAULTS,wake:s.WAKE_DEFAULT,hotkey:s.HOTKEY_DEFAULT,callBack:s.CALL_BACK_DEFAULT,captionView:"sides",textModel:null},c=(0,n.create)()((t=e=>({...u,patch:t=>e(t)}),r={name:"thursday.settings",version:1,migrate:(e,t)=>t<1&&e&&"object"==typeof e?{...e,webSearch:!0}:e,merge:(e,t)=>{let r=o.safeParse((0,l.migrateLiveSettings)(e)),n=r.success?r.data:u;return{...t,...n}}},(e,n,l)=>{let i,s={storage:function(e){let t;try{t=e()}catch(e){return}return{getItem:e=>{var r;let n=e=>null===e?null:JSON.parse(e,void 0),a=null!=(r=t.getItem(e))?r:null;return a instanceof Promise?a.then(n):n(a)},setItem:(e,r)=>t.setItem(e,JSON.stringify(r,void 0)),removeItem:e=>t.removeItem(e)}}(()=>window.localStorage),partialize:e=>e,version:0,merge:(e,t)=>({...t,...e}),...r},o=!1,u=0,c=new Set,h=new Set,f=s.storage;if(!f)return t((...t)=>{console.warn(`[zustand persist middleware] Unable to update item '${s.name}', the given storage is currently unavailable.`),e(...t)});let d=()=>{let e=s.partialize({...n()});return f.setItem(s.name,{state:e,version:s.version})},m=l.setState;l.setState=(e,t)=>(m(e,t),d());let g=t((...t)=>(e(...t),d()));l.getInitialState=()=>g;let p=()=>{var t,r;if(!f)return;let l=++u;o=!1,c.forEach(e=>{var t;return e(null!=(t=n())?t:g)});let m=(null==(r=s.onRehydrateStorage)?void 0:r.call(s,null!=(t=n())?t:g))||void 0;return a(f.getItem.bind(f))(s.name).then(e=>{if(e)if("number"!=typeof e.version||e.version===s.version)return[!1,e.state];else{if(s.migrate){let t=s.migrate(e.state,e.version);return t instanceof Promise?t.then(e=>[!0,e]):[!0,t]}console.error("State loaded from storage couldn't be migrated since no migrate function was provided")}return[!1,void 0]}).then(t=>{var r;if(l!==u)return;let[a,o]=t;if(e(i=s.merge(o,null!=(r=n())?r:g),!0),a)return d()}).then(()=>{l===u&&(null==m||m(n(),void 0),i=n(),o=!0,h.forEach(e=>e(i)))}).catch(e=>{l===u&&(null==m||m(void 0,e))})};return l.persist={setOptions:e=>{s={...s,...e},e.storage&&(f=e.storage)},clearStorage:()=>{++u,null==f||f.removeItem(s.name)},getOptions:()=>s,rehydrate:()=>p(),hasHydrated:()=>o,onHydrate:e=>(c.add(e),()=>{c.delete(e)}),onFinishHydration:e=>(h.add(e),()=>{h.delete(e)})},s.skipHydration||p(),i||g}));e.s(["thursdaySettings",0,()=>l.LiveSettingsSchema.parse(c.getState()),"useThursdayStore",0,c],67045)},561540,e=>{"use strict";var t=e.i(213377);let r={[t.TOOL_NAMES.memory_recall]:"Checking your notes",[t.TOOL_NAMES.memory_remember]:"Noting that down",[t.TOOL_NAMES.memory_forget]:"Forgetting that",[t.TOOL_NAMES.memory_conversation]:"Reading back an earlier call",[t.TOOL_NAMES.bash]:"Doing it on this computer",[t.TOOL_NAMES.web_search]:"Searching the web",[t.TOOL_NAMES.load_skill]:"Reading how to do this",[t.TOOL_NAMES.look_at]:"Looking at the picture",[t.TOOL_NAMES.end_call]:"Ending the call",[t.TOOL_NAMES.routine]:"Checking your routines"};function n(e){if(!e)return null;try{let t=JSON.parse(e);if(t&&"object"==typeof t&&!Array.isArray(t))return t}catch{}return null}let a=new Set([t.TOOL_NAMES.thread_tell,t.TOOL_NAMES.thread_answer,t.TOOL_NAMES.thread_status,t.TOOL_NAMES.thread_show,t.TOOL_NAMES.thread_cancel,t.TOOL_NAMES.thread_seen]);function l(e,r){if(e!==t.TOOL_NAMES.web_search)return null;try{let e=JSON.parse(r),t=Array.isArray(e.sources)?e.sources.flatMap(e=>e&&"object"==typeof e&&"string"==typeof e.url?[e]:[]):[];return{query:"string"==typeof e.query?e.query:null,sources:t}}catch{return null}}e.s(["searchOf",0,l,"searchQueryOf",0,function(e){let t=n(e)?.query;return"string"==typeof t&&t.trim()?t.trim():null},"searchSourcesOf",0,function(e){let r=n(e);return r?l(t.TOOL_NAMES.web_search,JSON.stringify(r))?.sources??[]:[]},"startedLabel",0,function(e,r){if(e!==t.TOOL_NAMES.thread_start)return null;try{let e=JSON.parse(r);return"string"==typeof e.label?e.label:null}catch{return null}},"toolBot",0,function(e,r,l,i){let s=n(r);if(!s)return null;if(e===t.TOOL_NAMES.thread_start)return"string"==typeof s.bot&&s.bot.trim()?s.bot.trim():null;if(!a.has(e))return null;let o="string"==typeof s.thread?s.thread.trim():"";if(!o||"all"===o.toLowerCase())return null;let u=o.toLowerCase(),c=l?.find(e=>e.id===o)??l?.find(e=>e.label.toLowerCase()===u);return c?e===t.TOOL_NAMES.thread_answer?c.room.questions[0]?.bot??c.bot:c.bot:function(e){let t=n(e);if(!t)return null;if("string"==typeof t.bot&&t.bot.trim())return t.bot.trim();let r=t.answered;return"string"==typeof r?.bot?r.bot:null}(i)},"toolLine",0,function(e,a,l=null){let i;if(e===t.TOOL_NAMES.tool_search||e===t.TOOL_NAMES.tool_call)return"Reaching a connected service";let s=n(a);return(s&&function(e,r,n){if(e===t.TOOL_NAMES.memory_remember){let e="string"==typeof r.path?r.path.trim():"",t=function(e){if(!Array.isArray(e.facts))return null;let t=e.facts.map(e=>e&&"object"==typeof e&&"string"==typeof e.text?e.text.trim():"").filter(Boolean);return t.length?{text:t[0],more:t.length-1}:null}(r);if(!e)return null;if(!t)return`Noting that under ${e}`;let n=t.more>0?` (+${t.more})`:"";return`Noting under ${e}: ${function(e){let t=e.trim().replace(/\s+/g," ");if(t.length<=28)return t;let r=t.slice(0,28),n=r.lastIndexOf(" ");return`${(n>14?r.slice(0,n):r).trimEnd()}…`}(t.text)}${n}`}if(e===t.TOOL_NAMES.thread_start){let e="string"==typeof r.bot?r.bot.trim():"";return e?`Handing this to ${e}`:"Handing this over"}if(e===t.TOOL_NAMES.web_search){let e="string"==typeof r.query?r.query.trim():"";return e?`Searching \xb7 ${e}`:null}if(e===t.TOOL_NAMES.routine){if("create"===r.action){let e=["string"==typeof r.bot?r.bot.trim():"",function(e){if("string"==typeof e.at&&e.at.length>=16){let[t,r]=e.at.split(" "),[n,a,l]=t.split("-").map(Number),i=new Date(n,a-1,l);if(i.toDateString()===new Date().toDateString())return`once at ${r}`;let s=i.toLocaleDateString("en-US",{month:"short",day:"numeric"});return`once, ${s} ${r}`}return"string"==typeof e.time&&e.time?`daily at ${e.time}`:"number"==typeof e.everyHours?`every ${e.everyHours} hours`:null}(r)].filter(Boolean).join(", ");return e?`Setting a routine \xb7 ${e}`:"Setting a routine"}return"change"===r.action?"Changing a routine":"delete"===r.action?"Deleting a routine":null}let a="string"==typeof r.thread?r.thread.trim():"";return e===t.TOOL_NAMES.thread_tell?n?`Telling ${n}`:"Passing that on":e===t.TOOL_NAMES.thread_answer?n?`Answering ${n}`:"Answering that":e===t.TOOL_NAMES.thread_cancel?a?`Stopping ${a}`:"Stopping that":e===t.TOOL_NAMES.thread_seen?a?`Marking ${a} as read`:"Marking that as read":e===t.TOOL_NAMES.thread_show?a?`Opening ${a}`:"Opening that":e===t.TOOL_NAMES.thread_status?a&&"all"!==a.toLowerCase()?`Checking on ${a}`:"Checking on the work":null}(e,s,l))??r[e]??((i=e.indexOf("__"))<=0?null:`Reaching ${e.slice(0,i).replace(/[-_]/g," ")}`)}])},319841,e=>{"use strict";var t=e.i(271645);let r=["ctrl","alt","meta"],n=/^(Control|Alt|Shift|Meta|OS)/,a=/^(input|textarea|select)$/i,l=e=>!!e&&!!(a.test(e.tagName)||e.isContentEditable||e.closest?.("[data-hotkey-capture]"));function i(e){let{code:t,ctrlKey:r,altKey:a,shiftKey:l,metaKey:i}=e;if(!t||n.test(t)||!r&&!a&&!i)return null;let s=[];return r&&s.push("ctrl"),a&&s.push("alt"),l&&s.push("shift"),i&&s.push("meta"),[...s,t].join("+")}let s={ctrl:["Ctrl","⌃"],alt:["Alt","⌥"],shift:["Shift","⇧"],meta:["Meta","⌘"]};e.s(["HOTKEY_CAPTURE",0,{"data-hotkey-capture":""},"capturesKeys",0,l,"comboOf",0,i,"isCombo",0,e=>{let t=e.split("+"),a=t.at(-1);return!!(a&&!n.test(a)&&t.slice(0,-1).some(e=>r.includes(e)))},"useHotkey",0,function({enabled:e,combo:r,onPress:n}){let a=(0,t.useRef)(n);a.current=n,(0,t.useEffect)(()=>{if(!e||!r)return;let t=e=>{e.repeat||l(e.target)||i(e)===r&&(e.preventDefault(),a.current())};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[e,r])},"useHotkeyLabel",0,function(e){let[r,n]=(0,t.useState)(!1);return(0,t.useEffect)(()=>n(/mac/i.test(navigator.userAgent)),[]),e?function(e,t=!1){let r=e.split("+"),n=r.at(-1)??"",a=r.slice(0,-1).map(e=>s[e]?.[+!!t]??e),l=n.replace(/^(Key|Digit|Numpad)/,"").replace(/([a-z])([A-Z])/g,"$1 $2")||n;return t?[...a,l].join(""):[...a,l].join(" + ")}(e,r):null}])}]);
|
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ You talk. Bots take the slow work to a real browser, a shell and your files, and
|
|
|
14
14
|
|
|
15
15
|
[English](README.md) · [한국어](README.ko.md)
|
|
16
16
|
|
|
17
|
-

|
|
18
18
|
|
|
19
19
|
[▶ Watch the 90-second demo, with sound](https://youtu.be/V7fBDY3cYRU)
|
|
20
20
|
|
|
@@ -2,12 +2,9 @@ import { asSchema } from "ai";
|
|
|
2
2
|
import z from "zod";
|
|
3
3
|
import { loadTools } from "@/features/ai/load-tools";
|
|
4
4
|
import { modelErrorToString } from "@/features/ai/model";
|
|
5
|
-
import { createServerProbe } from "@/lib/probe.server";
|
|
6
5
|
import { serverRoute } from "@/lib/protocol/server-route";
|
|
7
6
|
import { publicError } from "@/lib/public-error";
|
|
8
7
|
|
|
9
|
-
const probe = createServerProbe("server");
|
|
10
|
-
|
|
11
8
|
/**
|
|
12
9
|
* Executes a tool call from the voice session. The page forwards what the model
|
|
13
10
|
* asked for; bots never come through here (they call `execute` directly).
|
|
@@ -58,7 +55,6 @@ export const POST = serverRoute(async (request) => {
|
|
|
58
55
|
);
|
|
59
56
|
}
|
|
60
57
|
|
|
61
|
-
const began = Date.now();
|
|
62
58
|
try {
|
|
63
59
|
const output = await tool.execute(parsed?.value ?? input ?? {}, {
|
|
64
60
|
toolCallId,
|
|
@@ -66,18 +62,8 @@ export const POST = serverRoute(async (request) => {
|
|
|
66
62
|
context: undefined,
|
|
67
63
|
abortSignal: request.signal,
|
|
68
64
|
});
|
|
69
|
-
|
|
70
|
-
probe("tool", {
|
|
71
|
-
callId,
|
|
72
|
-
name,
|
|
73
|
-
input,
|
|
74
|
-
ms: Date.now() - began,
|
|
75
|
-
// The rows keep a tool's arguments only; what it answered is kept here
|
|
76
|
-
output: JSON.stringify(drained)?.slice(0, 3000),
|
|
77
|
-
});
|
|
78
|
-
return { output: drained };
|
|
65
|
+
return { output: await drain(output) };
|
|
79
66
|
} catch (cause) {
|
|
80
|
-
probe("tool.failed", { callId, name, input, error: String(cause) });
|
|
81
67
|
// A tool failure is a line the model reads and recovers from, not a masked server error.
|
|
82
68
|
publicError(`"${name}" failed: ${modelErrorToString(cause)}`);
|
|
83
69
|
}
|
|
Binary file
|
package/docs/live-calls.md
CHANGED
|
@@ -23,17 +23,20 @@ delegation is a different integration: its notification contains metadata, not t
|
|
|
23
23
|
text, so the application would have to reconstruct the request and operate the backend.
|
|
24
24
|
|
|
25
25
|
The voice and the backend are one assistant. Both prompts open with the same identity
|
|
26
|
-
(`thursdayIdentity`)
|
|
26
|
+
(`thursdayIdentity`), each followed by its own rule for ending the call, read the same
|
|
27
27
|
memory, and neither is told it is part of something else. The voice holds conversation and
|
|
28
28
|
memory only. Right under the identity, `## Always` groups what holds on every turn: the ending
|
|
29
29
|
rule (the only line marked `IMPORTANT`), the guide's starter backchannel and interruption
|
|
30
|
-
policies, and
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
policies, and the guide's `Delegation policy` under its three labels: `Backend tools` names
|
|
31
|
+
what the backend can do (end the call, background work, routines, memory, this computer and the
|
|
32
|
+
web) and never how; `Delegate to the backend when` is the user wanting the call to end, anything
|
|
33
|
+
on that list or a change to work already asked for, and whatever the user says about themselves,
|
|
34
|
+
their people, their plans or how they want things done, unless it is already written in the
|
|
35
|
+
prompt; `Do not delegate to the backend when` is greetings, small talk, only wanting her to stop
|
|
36
|
+
talking, what the conversation already answers, and a brief clarification. Live decides by
|
|
37
|
+
itself whether to delegate, and it decides from that list: without it (09-17 to 09-19) a
|
|
38
|
+
hang-up, a stop or a routine was answered and never handed over. It says nothing else about how
|
|
39
|
+
to speak; it sees no tool schema and no tool name but `end_call`, in the ending rule. The backend prompt holds the work: memory (merging a fact that repeats or changes one
|
|
37
40
|
already kept, and tidying with the user past the limits), background work and threads, this
|
|
38
41
|
computer, what to return, and the earlier calls. A request that carries earlier work further goes to
|
|
39
42
|
that thread; one that stands on its own opens a new one; it asks the user only when it could be
|
|
@@ -212,10 +215,15 @@ for a goodbye, which would leave the ending to the model.
|
|
|
212
215
|
|
|
213
216
|
The user wanting the call to end, however they say it, sets everything else aside: the
|
|
214
217
|
voice answers yes and hands it to the backend at once, and the backend runs `end_call`
|
|
215
|
-
without deliberating. The
|
|
216
|
-
|
|
218
|
+
without deliberating. The voice's rule names `end_call` too, the one tool name it holds:
|
|
219
|
+
without it, ending read as something to say rather than do. The two rules say what each
|
|
220
|
+
side can do: while they were one sentence ("forget every other task, answer yes, then use
|
|
221
|
+
the tool"), the voice said yes and went quiet with the line open, four times in five
|
|
222
|
+
(09-20), so its rule says to hand the turn over, and that a yes alone leaves the line open.
|
|
217
223
|
Whether that turn reaches the backend at all is the voice's own decision, and it often
|
|
218
|
-
answers and hands nothing over
|
|
224
|
+
answers and hands nothing over. Ending the call leads the `Backend tools` list for that
|
|
225
|
+
reason: with the list, five calls in seven ended by asking (09-16); without it, one in 21,
|
|
226
|
+
then none in 34 (09-17 to 09-19). The
|
|
219
227
|
quiet hang-up below is what ends such a call.
|
|
220
228
|
The page does not close on `end_call` itself: it waits until her voice has been quiet
|
|
221
229
|
for `CALL_END.quietMs`, or `CALL_END.unsaidMs` when nothing was said, never past
|
|
@@ -20,7 +20,11 @@ import type {
|
|
|
20
20
|
MediaKind,
|
|
21
21
|
TextModelProviderId,
|
|
22
22
|
} from "../model.schema";
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
canMakeKind,
|
|
25
|
+
MEDIA_MODEL_PROVIDERS,
|
|
26
|
+
TEXT_MODEL_PROVIDERS,
|
|
27
|
+
} from "../model.schema";
|
|
24
28
|
import { ChatGptSignIn } from "./chatgpt-sign-in";
|
|
25
29
|
import { ModelBrowser } from "./model-browser";
|
|
26
30
|
import { ProviderIcon } from "./provider-icon";
|
|
@@ -312,7 +316,9 @@ function AskForKey({
|
|
|
312
316
|
<Input
|
|
313
317
|
value={value}
|
|
314
318
|
onChange={(event) => setValue(event.target.value)}
|
|
315
|
-
placeholder={
|
|
319
|
+
placeholder={
|
|
320
|
+
TEXT_MODEL_PROVIDERS[provider.id].keyLooks ?? "Paste the key"
|
|
321
|
+
}
|
|
316
322
|
spellCheck={false}
|
|
317
323
|
type="password"
|
|
318
324
|
/>
|
|
@@ -378,12 +378,18 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
378
378
|
apiKeyName: string;
|
|
379
379
|
/** Reached by signing in to an account rather than a pasted key; `apiKeyName` is where the sign-in is kept. */
|
|
380
380
|
signIn?: true;
|
|
381
|
+
/** Where a key is made: the link beside its field. */
|
|
382
|
+
keysAt?: string;
|
|
383
|
+
/** How a key begins, shown in its empty field in place of the setting's name. */
|
|
384
|
+
keyLooks?: string;
|
|
381
385
|
suggestModels: SuggestModel[];
|
|
382
386
|
}
|
|
383
387
|
> = {
|
|
384
388
|
openai: {
|
|
385
389
|
label: "Open AI",
|
|
386
390
|
apiKeyName: "OPENAI_API_KEY",
|
|
391
|
+
keysAt: "https://platform.openai.com/api-keys",
|
|
392
|
+
keyLooks: "sk-…",
|
|
387
393
|
suggestModels: [
|
|
388
394
|
{
|
|
389
395
|
id: "gpt-5.6-luna",
|
|
@@ -450,6 +456,8 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
450
456
|
anthropic: {
|
|
451
457
|
label: "Claude",
|
|
452
458
|
apiKeyName: "ANTHROPIC_API_KEY",
|
|
459
|
+
keysAt: "https://platform.claude.com/settings/keys",
|
|
460
|
+
keyLooks: "sk-ant-…",
|
|
453
461
|
suggestModels: [
|
|
454
462
|
{ id: "claude-haiku-4-5", label: "Haiku 4.5", tier: "small" },
|
|
455
463
|
{
|
|
@@ -470,6 +478,8 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
470
478
|
google: {
|
|
471
479
|
label: "Gemini",
|
|
472
480
|
apiKeyName: "GOOGLE_GENERATIVE_AI_API_KEY",
|
|
481
|
+
keysAt: "https://aistudio.google.com/apikey",
|
|
482
|
+
keyLooks: "AIza…",
|
|
473
483
|
suggestModels: [
|
|
474
484
|
{
|
|
475
485
|
id: "gemini-3.5-flash-lite",
|
|
@@ -488,6 +498,8 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
488
498
|
xai: {
|
|
489
499
|
label: "xAI",
|
|
490
500
|
apiKeyName: "XAI_API_KEY",
|
|
501
|
+
keysAt: "https://console.x.ai",
|
|
502
|
+
keyLooks: "xai-…",
|
|
491
503
|
suggestModels: [
|
|
492
504
|
{ id: "grok-4.6", label: "Grok 4.6", tier: "large", context: 500_000 },
|
|
493
505
|
],
|
|
@@ -499,6 +511,8 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
499
511
|
"vercel-ai-gateway": {
|
|
500
512
|
label: "Vercel AI GateWay",
|
|
501
513
|
apiKeyName: "AI_GATEWAY_API_KEY",
|
|
514
|
+
keysAt:
|
|
515
|
+
"https://vercel.com/docs/ai-gateway/authentication-and-byok/authentication",
|
|
502
516
|
suggestModels: [
|
|
503
517
|
{ id: "zai/glm-5.3-flash", label: "GLM 5.3 Flash", tier: "small" },
|
|
504
518
|
{
|
|
@@ -554,6 +568,7 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
554
568
|
mistral: {
|
|
555
569
|
label: "Mistral",
|
|
556
570
|
apiKeyName: "MISTRAL_API_KEY",
|
|
571
|
+
keysAt: "https://console.mistral.ai/api-keys",
|
|
557
572
|
suggestModels: [
|
|
558
573
|
{ id: "ministral-8b-latest", label: "Ministral 8B", tier: "small" },
|
|
559
574
|
{ id: "mistral-small-latest", label: "Small", tier: "mid" },
|
|
@@ -564,6 +579,8 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
564
579
|
deepseek: {
|
|
565
580
|
label: "DeepSeek",
|
|
566
581
|
apiKeyName: "DEEPSEEK_API_KEY",
|
|
582
|
+
keysAt: "https://platform.deepseek.com/api_keys",
|
|
583
|
+
keyLooks: "sk-…",
|
|
567
584
|
suggestModels: [
|
|
568
585
|
{
|
|
569
586
|
id: "deepseek-flash",
|
|
@@ -583,6 +600,8 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
583
600
|
groq: {
|
|
584
601
|
label: "Groq",
|
|
585
602
|
apiKeyName: "GROQ_API_KEY",
|
|
603
|
+
keysAt: "https://console.groq.com/keys",
|
|
604
|
+
keyLooks: "gsk_…",
|
|
586
605
|
suggestModels: [
|
|
587
606
|
{
|
|
588
607
|
id: "openai/gpt-oss-20b",
|
|
@@ -608,6 +627,8 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
608
627
|
cerebras: {
|
|
609
628
|
label: "Cerebras",
|
|
610
629
|
apiKeyName: "CEREBRAS_API_KEY",
|
|
630
|
+
keysAt: "https://cloud.cerebras.ai",
|
|
631
|
+
keyLooks: "csk-…",
|
|
611
632
|
suggestModels: [
|
|
612
633
|
{
|
|
613
634
|
id: "qwen-3.8-27b",
|
|
@@ -626,6 +647,7 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
626
647
|
togetherai: {
|
|
627
648
|
label: "Together",
|
|
628
649
|
apiKeyName: "TOGETHER_AI_API_KEY",
|
|
650
|
+
keysAt: "https://api.together.ai/settings/api-keys",
|
|
629
651
|
suggestModels: [
|
|
630
652
|
{
|
|
631
653
|
id: "Qwen/Qwen3.5-9B",
|
|
@@ -668,6 +690,8 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
668
690
|
fireworks: {
|
|
669
691
|
label: "Fireworks",
|
|
670
692
|
apiKeyName: "FIREWORKS_API_KEY",
|
|
693
|
+
keysAt: "https://app.fireworks.ai/account/api-keys",
|
|
694
|
+
keyLooks: "fw_…",
|
|
671
695
|
suggestModels: [
|
|
672
696
|
{
|
|
673
697
|
id: "accounts/fireworks/models/glm-5p3-flash",
|
|
@@ -704,6 +728,7 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
704
728
|
deepinfra: {
|
|
705
729
|
label: "DeepInfra",
|
|
706
730
|
apiKeyName: "DEEPINFRA_API_KEY",
|
|
731
|
+
keysAt: "https://deepinfra.com/dash/api_keys",
|
|
707
732
|
suggestModels: [
|
|
708
733
|
{
|
|
709
734
|
id: "deepseek-ai/DeepSeek-V4-Flash-0731",
|
|
@@ -740,6 +765,7 @@ export const TEXT_MODEL_PROVIDERS: Record<
|
|
|
740
765
|
cohere: {
|
|
741
766
|
label: "Cohere",
|
|
742
767
|
apiKeyName: "COHERE_API_KEY",
|
|
768
|
+
keysAt: "https://dashboard.cohere.com/api-keys",
|
|
743
769
|
suggestModels: [
|
|
744
770
|
{
|
|
745
771
|
id: "command-r7b-12-2024",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TOOL_NAMES } from "@/features/ai/tools/tool-name";
|
|
1
2
|
import {
|
|
2
3
|
listAlwaysLoaded,
|
|
3
4
|
listNoteIndex,
|
|
@@ -10,7 +11,6 @@ import {
|
|
|
10
11
|
type MemoryNoteView,
|
|
11
12
|
} from "@/features/memory/memory.schema";
|
|
12
13
|
import {
|
|
13
|
-
callEnding,
|
|
14
14
|
carriedLines,
|
|
15
15
|
expandedFacts,
|
|
16
16
|
logPromptSize,
|
|
@@ -21,16 +21,15 @@ import {
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Everything the Live voice hears: who Thursday is and how a call ends (the words the backend
|
|
24
|
-
* opens with too), the guide's starter backchannel and interruption policies,
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* hands everything but conversation over and answers from what
|
|
28
|
-
* call, never cached.
|
|
24
|
+
* opens with too), the guide's starter backchannel and interruption policies, its delegation
|
|
25
|
+
* policy (what the backend can do, when to hand over and when not), and what she knows about
|
|
26
|
+
* the user. How the work is done, earlier calls and tidying memory are the backend's
|
|
27
|
+
* (thursday.prompt): the voice hands everything but conversation over and answers from what
|
|
28
|
+
* comes back. Assembled on every call, never cached.
|
|
29
29
|
*/
|
|
30
30
|
export async function loadLivePrompt(options: {
|
|
31
31
|
/** Settings › Thursday › Voice instructions; added to, never replacing, what is below. */
|
|
32
32
|
voicePrompt?: string | null;
|
|
33
|
-
locale?: string | null;
|
|
34
33
|
/** The page placed this call because background work waits on the user (call-back). */
|
|
35
34
|
calledBack?: boolean;
|
|
36
35
|
/** The last call is in the conversation ahead of the opening (call-last). */
|
|
@@ -45,11 +44,6 @@ export async function loadLivePrompt(options: {
|
|
|
45
44
|
|
|
46
45
|
const first = !open.notes.find((note) => note.path === "profile")?.facts
|
|
47
46
|
.length;
|
|
48
|
-
// Only the first-call greeting reads it: before they have said anything, the
|
|
49
|
-
// browser's locale is the one sign of their language
|
|
50
|
-
const language = options.locale
|
|
51
|
-
? `the language of \`${options.locale}\`, their browser's setting`
|
|
52
|
-
: "the language they use";
|
|
53
47
|
|
|
54
48
|
const text = [
|
|
55
49
|
thursdayIdentity(),
|
|
@@ -69,7 +63,7 @@ export async function loadLivePrompt(options: {
|
|
|
69
63
|
opening: options.calledBack
|
|
70
64
|
? "You placed this call because background work has something for the user; it comes in next. Speak first: greet them in one line and say that is why you called."
|
|
71
65
|
: first
|
|
72
|
-
?
|
|
66
|
+
? "Open the call now: say who you are and what you are here to do for them, in a line or two, then ask what to call them. Then stop and listen."
|
|
73
67
|
: options.remembers
|
|
74
68
|
? "The call has just started. Speak first: greet the user naturally, in one line, as someone who remembers the last call."
|
|
75
69
|
: "The call has just started. Speak first: greet the user naturally, in one line.",
|
|
@@ -79,40 +73,71 @@ export async function loadLivePrompt(options: {
|
|
|
79
73
|
/**
|
|
80
74
|
* The rules for every turn, together right under the identity, where the model weighs most.
|
|
81
75
|
* One heading marks them; `IMPORTANT` stays on the ending rule alone, the one that failed
|
|
82
|
-
* without it (09-17), so stamping it on all
|
|
76
|
+
* without it (09-17), so stamping it on all of them would thin it out.
|
|
83
77
|
*/
|
|
84
78
|
const always = () => `## Always
|
|
85
79
|
|
|
86
|
-
${
|
|
80
|
+
${ending()}
|
|
87
81
|
|
|
88
82
|
${speaking()}
|
|
89
83
|
|
|
90
84
|
${delegation()}`;
|
|
91
85
|
|
|
86
|
+
/**
|
|
87
|
+
* How a call ends, as the voice can end it: it holds no tools, so it says yes and hands the turn
|
|
88
|
+
* over, and the backend runs the tool. The rule both prompts shared until 09-20 ("forget every
|
|
89
|
+
* other task, answer yes, then use the tool") left the voice saying yes and going quiet with the
|
|
90
|
+
* line still open, four times in five. The tool is still named, the one name the voice sees, so
|
|
91
|
+
* ending reads as something done rather than said.
|
|
92
|
+
*/
|
|
93
|
+
const ending = () =>
|
|
94
|
+
`IMPORTANT — always follow this: when the user wants the call to end, however they say it, answer yes in one word of their language and hand it to the backend at once. Only the backend can end the line, with the ${TOOL_NAMES.end_call} tool; saying yes alone leaves it open.`;
|
|
95
|
+
|
|
92
96
|
/**
|
|
93
97
|
* The guide's starter lines on listening and interruptions, labels kept as it says. The
|
|
94
98
|
* backchannel line is the one it invites changing: a long turn heard in silence reads as
|
|
95
|
-
* nobody listening.
|
|
99
|
+
* nobody listening. The language is the one being spoken, never the browser's: a first call
|
|
100
|
+
* opened in the browser's language kept an English speaker in Korean.
|
|
96
101
|
*/
|
|
97
102
|
function speaking(): string {
|
|
98
103
|
return `Backchannel policy: Use moderate backchannels. When the user speaks at length, acknowledge now and then with a short listening sound so they know you are following, without competing with the main response.
|
|
99
104
|
|
|
100
|
-
Interruption policy: Stop speaking when the user interrupts. Listen to what they say
|
|
105
|
+
Interruption policy: Stop speaking when the user interrupts. Listen to what they say.
|
|
106
|
+
|
|
107
|
+
Speak the language the user is speaking, whatever language came before; when they switch, switch with them.`;
|
|
101
108
|
}
|
|
102
109
|
|
|
103
110
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
111
|
+
* The guide's three labels, as it asks: Live decides for itself whether to hand a turn over,
|
|
112
|
+
* and reads that from what the list says the backend can do. Without the list (09-17 to 09-19)
|
|
113
|
+
* it said "yes" to a hang-up, a stop or a routine and handed nothing over: 1 `end_call` in 21
|
|
114
|
+
* calls, then none in 34, where the list had drawn 5 in 7. The list names what can be done,
|
|
115
|
+
* never how: tools, bots and threads stay the backend's. What they say about themselves is
|
|
116
|
+
* its own line: nothing is kept that is not handed over, and it is rarely a request. The voice
|
|
117
|
+
* sees only profile and preferences whole, so "already written" is a rough filter; the backend
|
|
118
|
+
* merges the rest (thursday.prompt memory). Stopping her voice is not stopping a job (the
|
|
119
|
+
* guide's interruptions): the one is hers, the other the backend's.
|
|
110
120
|
*/
|
|
111
121
|
function delegation(): string {
|
|
112
122
|
return `Delegation policy:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
Backend tools:
|
|
124
|
+
- Ending the call: hangs up the line.
|
|
125
|
+
- Background work: hands a job to a bot, passes words on, stops or changes a job, answers a bot's question, says how the work stands.
|
|
126
|
+
- Routines: jobs that start by themselves later.
|
|
127
|
+
- Memory: keeps what the user tells you about themselves, and looks it up.
|
|
128
|
+
- This computer and the web: runs a command, searches.
|
|
129
|
+
|
|
130
|
+
Delegate to the backend when:
|
|
131
|
+
- The user wants the call to end.
|
|
132
|
+
- They ask for anything on that list, or change or stop work already asked for.
|
|
133
|
+
- They tell you about themselves, the people in their life, their plans or how they want things done, however small, unless it is already written below.
|
|
134
|
+
|
|
135
|
+
Do not delegate to the backend when:
|
|
136
|
+
- They greet you, make small talk, or only want you to stop talking.
|
|
137
|
+
- You can answer from the conversation or a result still current.
|
|
138
|
+
- You need a brief clarification to understand the request.
|
|
139
|
+
|
|
140
|
+
Delegate before giving an answer that depends on backend work. Do not guess the result while waiting.`;
|
|
116
141
|
}
|
|
117
142
|
|
|
118
143
|
/**
|
|
@@ -22,7 +22,7 @@ import { clip } from "@/lib/utils";
|
|
|
22
22
|
/**
|
|
23
23
|
* Row-to-line formatters shared by the call prompts (live, thursday) and bot.prompt, plus the tidying check.
|
|
24
24
|
* Nothing here wraps a sentence; headings and paragraphs live in the prompt that says them. The
|
|
25
|
-
*
|
|
25
|
+
* exception is `thursdayIdentity`, the words both call prompts open with.
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
/**
|
|
@@ -85,14 +85,6 @@ export const thursdayIdentity = (now = new Date()) =>
|
|
|
85
85
|
|
|
86
86
|
What they tell you is kept, so you know them better over time, and whatever they want done can be done for them in the background.`;
|
|
87
87
|
|
|
88
|
-
/**
|
|
89
|
-
* How a call ends, in the same words right after the identity in both call prompts. It names
|
|
90
|
-
* the tool in both, the one tool name the voice sees: without it, ending the call read as
|
|
91
|
-
* something to say rather than do, and the line stayed open through repeated requests.
|
|
92
|
-
*/
|
|
93
|
-
export const callEnding = () =>
|
|
94
|
-
`IMPORTANT — always follow this: when the user wants the call to end, however they say it, forget every other task, answer yes in one word of their language, then immediately, without thinking, use the ${TOOL_NAMES.end_call} tool.`;
|
|
95
|
-
|
|
96
88
|
/**
|
|
97
89
|
* When a call happened, the one way every prompt and tool says it: local, the
|
|
98
90
|
* same shape as `Now` (clockNow), with how long ago. A UTC stamp beside a local
|
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
import { openWorkspace } from "@/features/workspace/workspace";
|
|
29
29
|
import { listConnectedToolNames } from "../tools/connected";
|
|
30
30
|
import {
|
|
31
|
-
callEnding,
|
|
32
31
|
carriedLines,
|
|
33
32
|
expandedFacts,
|
|
34
33
|
logPromptSize,
|
|
@@ -88,7 +87,7 @@ export async function loadThursdayPrompt(
|
|
|
88
87
|
// Order matters: earlier calls go last so the current call follows them in time order
|
|
89
88
|
const text = [
|
|
90
89
|
thursdayIdentity(),
|
|
91
|
-
written ? "" :
|
|
90
|
+
written ? "" : ending(),
|
|
92
91
|
memory(index, carried, open.notes),
|
|
93
92
|
// A skill is named once, on the side that can read it: this computer's chapter
|
|
94
93
|
// when the setting hands the call the tool, the bots' reach when it does not
|
|
@@ -110,6 +109,13 @@ export async function loadThursdayPrompt(
|
|
|
110
109
|
return text;
|
|
111
110
|
}
|
|
112
111
|
|
|
112
|
+
/**
|
|
113
|
+
* How a call ends, right after the identity. Only the backend can end the line, so its rule is
|
|
114
|
+
* to do it at once, with the tool named; the voice's own rule (live.prompt) is to hand it over.
|
|
115
|
+
*/
|
|
116
|
+
const ending = () =>
|
|
117
|
+
`IMPORTANT — always follow this: when the user wants the call to end, however they say it, forget every other task, answer yes in one word of their language, then immediately, without thinking, use the ${TOOL_NAMES.end_call} tool.`;
|
|
118
|
+
|
|
113
119
|
/**
|
|
114
120
|
* What goes back is said aloud, so it is what a tool or a note confirmed and nothing more — or
|
|
115
121
|
* the one question the voice puts to the user before work is handed over (backgroundWork).
|
package/features/bot/bot.run.ts
CHANGED
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
type JobBot,
|
|
31
31
|
type TokenUsage,
|
|
32
32
|
} from "@/features/bot/bot.schema";
|
|
33
|
+
import { renewSignIns } from "@/features/signins/signins.query";
|
|
33
34
|
import {
|
|
34
35
|
botBrowserSession,
|
|
35
36
|
filesOnDisk,
|
|
@@ -154,6 +155,9 @@ export async function runBot(
|
|
|
154
155
|
: null,
|
|
155
156
|
openBotFolders(name),
|
|
156
157
|
]);
|
|
158
|
+
const session =
|
|
159
|
+
options.session ??
|
|
160
|
+
(options.threadId ? botBrowserSession(options.threadId, name) : null);
|
|
157
161
|
const [prompt, tools] = await Promise.all([
|
|
158
162
|
loadBotPrompt(
|
|
159
163
|
name,
|
|
@@ -170,9 +174,7 @@ export async function runBot(
|
|
|
170
174
|
target: "bot",
|
|
171
175
|
bot: name,
|
|
172
176
|
thread: options.threadId ?? null,
|
|
173
|
-
session
|
|
174
|
-
options.session ??
|
|
175
|
-
(options.threadId ? botBrowserSession(options.threadId, name) : null),
|
|
177
|
+
session,
|
|
176
178
|
model,
|
|
177
179
|
}),
|
|
178
180
|
]);
|
|
@@ -474,6 +476,10 @@ export async function runBot(
|
|
|
474
476
|
quiet.end();
|
|
475
477
|
acknowledgeStep();
|
|
476
478
|
await Promise.allSettled([...inFlight]);
|
|
479
|
+
if (session)
|
|
480
|
+
void renewSignIns(session).catch((cause) =>
|
|
481
|
+
logger.warn(`${name}: kept sign-ins were not renewed`, cause),
|
|
482
|
+
);
|
|
477
483
|
}
|
|
478
484
|
|
|
479
485
|
try {
|