thursday-agent 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +3 -3
  3. package/.next/prerender-manifest.json +3 -3
  4. package/.next/server/app/_global-error.html +1 -1
  5. package/.next/server/app/_global-error.rsc +1 -1
  6. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  9. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  10. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  11. package/.next/server/app/_not-found.html +1 -1
  12. package/.next/server/app/_not-found.rsc +2 -2
  13. package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  14. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  15. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  16. package/.next/server/app/api/artifact/route.js.nft.json +1 -1
  17. package/.next/server/app/api/bot/memory/files/route.js.nft.json +1 -1
  18. package/.next/server/app/api/bot/memory/route.js.nft.json +1 -1
  19. package/.next/server/app/api/bot/route.js.nft.json +1 -1
  20. package/.next/server/app/api/bot/task/[id]/route.js.nft.json +1 -1
  21. package/.next/server/app/api/bot/task/route.js.nft.json +1 -1
  22. package/.next/server/app/api/config/route.js.nft.json +1 -1
  23. package/.next/server/app/api/events/route.js.nft.json +1 -1
  24. package/.next/server/app/api/file/[...path]/route.js.nft.json +1 -1
  25. package/.next/server/app/api/llm-model/catalog/route.js.nft.json +1 -1
  26. package/.next/server/app/api/llm-model/credits/route.js.nft.json +1 -1
  27. package/.next/server/app/api/llm-model/route.js.nft.json +1 -1
  28. package/.next/server/app/api/llm-model/subscription/route.js.nft.json +1 -1
  29. package/.next/server/app/api/mcp/[name]/route.js.nft.json +1 -1
  30. package/.next/server/app/api/mcp/oauth/callback/route.js.nft.json +1 -1
  31. package/.next/server/app/api/mcp/route.js.nft.json +1 -1
  32. package/.next/server/app/api/mcp/tools/route.js.nft.json +1 -1
  33. package/.next/server/app/api/memory/edit/route.js.nft.json +1 -1
  34. package/.next/server/app/api/memory/route.js.nft.json +1 -1
  35. package/.next/server/app/api/skills/[source]/[name]/route.js.nft.json +1 -1
  36. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  37. package/.next/server/app/api/thursday/call/route.js.nft.json +1 -1
  38. package/.next/server/app/api/thursday/skills/route.js.nft.json +1 -1
  39. package/.next/server/app/api/thursday/tool-call/route.js.nft.json +1 -1
  40. package/.next/server/app/api/workspace/route.js.nft.json +1 -1
  41. package/.next/server/app/artifact/[...path]/page/server-reference-manifest.json +1 -1
  42. package/.next/server/app/artifact/[...path]/page.js.nft.json +1 -1
  43. package/.next/server/app/artifact/[...path]/page_client-reference-manifest.js +1 -1
  44. package/.next/server/app/page/server-reference-manifest.json +40 -40
  45. package/.next/server/app/page.js +2 -2
  46. package/.next/server/app/page.js.nft.json +1 -1
  47. package/.next/server/app/page_client-reference-manifest.js +1 -1
  48. package/.next/server/chunks/[root-of-the-server]__02va5wz._.js +1 -1
  49. package/.next/server/chunks/[root-of-the-server]__0ls6_8y._.js +4 -4
  50. package/.next/server/chunks/[root-of-the-server]__0ncs9uu._.js +1 -1
  51. package/.next/server/chunks/[root-of-the-server]__1-ga0kh._.js +2 -2
  52. package/.next/server/chunks/[root-of-the-server]__1_04mcf._.js +2 -2
  53. package/.next/server/chunks/[root-of-the-server]__1anc1p9._.js +1 -1
  54. package/.next/server/chunks/[root-of-the-server]__1ccon1w._.js +3 -3
  55. package/.next/server/chunks/[root-of-the-server]__1orn-5b._.js +4 -3
  56. package/.next/server/chunks/[root-of-the-server]__1wa1k7r._.js +3 -3
  57. package/.next/server/chunks/_0-fjql4._.js +5 -5
  58. package/.next/server/chunks/_00xh_q0._.js +3 -5
  59. package/.next/server/chunks/_05h2cii._.js +1 -1
  60. package/.next/server/chunks/_0fzqt2y._.js +48 -44
  61. package/.next/server/chunks/_0mecv0f._.js +5 -5
  62. package/.next/server/chunks/_0mh8j4m._.js +1 -1
  63. package/.next/server/chunks/_0wp4le3._.js +1 -1
  64. package/.next/server/chunks/_0y5fg-x._.js +1 -1
  65. package/.next/server/chunks/_1230wbx._.js +3 -3
  66. package/.next/server/chunks/_15hq89o._.js +1 -1
  67. package/.next/server/chunks/{_03kp0jp._.js → _1c78vw5._.js} +58 -56
  68. package/.next/server/chunks/_1j8k_j5._.js +1 -1
  69. package/.next/server/chunks/_1krd9rf._.js +1 -1
  70. package/.next/server/chunks/_1php4eq._.js +1 -1
  71. package/.next/server/chunks/config_ts_1g4sz5o._.js +1 -1
  72. package/.next/server/chunks/features_1qf3cei._.js +1 -1
  73. package/.next/server/chunks/features_memory_1uqvksn._.js +2 -2
  74. package/.next/server/chunks/ssr/[root-of-the-server]__092knlj._.js +3 -0
  75. package/.next/server/chunks/ssr/{[root-of-the-server]__1eh7hid._.js → [root-of-the-server]__0s9dq5u._.js} +1 -1
  76. package/.next/server/chunks/ssr/{[root-of-the-server]__1cyjywu._.js → [root-of-the-server]__0s9l2sv._.js} +1 -1
  77. package/.next/server/chunks/ssr/{[root-of-the-server]__0zkv7z_._.js → [root-of-the-server]__0xsog8n._.js} +2 -2
  78. package/.next/server/chunks/ssr/[root-of-the-server]__10-dz5o._.js +13 -9
  79. package/.next/server/chunks/ssr/[root-of-the-server]__1gtlw6v._.js +2 -2
  80. package/.next/server/chunks/ssr/[root-of-the-server]__1mzi-ju._.js +1 -1
  81. package/.next/server/chunks/ssr/[root-of-the-server]__1ox7hbk._.js +1 -1
  82. package/.next/server/chunks/ssr/{[root-of-the-server]__0_69wqr._.js → [root-of-the-server]__202p40z._.js} +1 -1
  83. package/.next/server/chunks/ssr/_001_ms1._.js +1 -1
  84. package/.next/server/chunks/ssr/{_0c-ql2m._.js → _0fz4mf_._.js} +2 -2
  85. package/.next/server/chunks/ssr/{_07uchnc._.js → _0gb4gmf._.js} +2 -2
  86. package/.next/server/chunks/ssr/_0i_6q1w._.js +2 -2
  87. package/.next/server/chunks/ssr/{_20kd_n0._.js → _0ilna52._.js} +3 -3
  88. package/.next/server/chunks/ssr/{_0mo2w06._.js → _0n3toaw._.js} +2 -2
  89. package/.next/server/chunks/ssr/{_0mb8zc8._.js → _0s99bgb._.js} +2 -2
  90. package/.next/server/chunks/ssr/_0zcjrbg._.js +3 -0
  91. package/.next/server/chunks/ssr/{_13z3f85._.js → _1-_etts._.js} +2 -2
  92. package/.next/server/chunks/ssr/_13fke0x._.js +1 -1
  93. package/.next/server/chunks/ssr/{_01_6m32._.js → _1b2mjwr._.js} +2 -2
  94. package/.next/server/chunks/ssr/{_1eoqg_g._.js → _1f-dg-6._.js} +2 -2
  95. package/.next/server/chunks/ssr/{_0y0tiht._.js → _1fojd41._.js} +3 -3
  96. package/.next/server/chunks/ssr/_1gd8q8l._.js +3 -0
  97. package/.next/server/chunks/ssr/{_1xvgn77._.js → _1h0rw11._.js} +2 -2
  98. package/.next/server/chunks/ssr/_1jhd09t._.js +3 -0
  99. package/.next/server/chunks/ssr/{_0u2jv_x._.js → _1lz_cq2._.js} +46 -44
  100. package/.next/server/chunks/ssr/{_0kbkmar._.js → _1nnsk7z._.js} +2 -2
  101. package/.next/server/chunks/ssr/_1sji22n._.js +1 -1
  102. package/.next/server/chunks/ssr/_1vyd1ji._.js +1 -1
  103. package/.next/server/chunks/ssr/features_config_components_config-setting_tsx_0xfwqdg._.js +1 -1
  104. package/.next/server/chunks/ssr/features_connectors_components_mcp-setting_tsx_0jmbgvp._.js +1 -1
  105. package/.next/server/chunks/ssr/{node_modules_0z5tsu8._.js → node_modules_00etblx._.js} +1 -1
  106. package/.next/server/chunks/ssr/{node_modules_1h4a4pp._.js → node_modules_04jf_m8._.js} +1 -1
  107. package/.next/server/chunks/ssr/{node_modules_0h5hnr1._.js → node_modules_08dhkiq._.js} +1 -1
  108. package/.next/server/chunks/ssr/{node_modules_1vqb6po._.js → node_modules_0940ns5._.js} +1 -1
  109. package/.next/server/chunks/ssr/{node_modules_1i7u1ia._.js → node_modules_09q35v_._.js} +1 -1
  110. package/.next/server/chunks/ssr/{node_modules_124bue5._.js → node_modules_0_-_a--._.js} +1 -1
  111. package/.next/server/chunks/ssr/{node_modules_0h7u60n._.js → node_modules_0arus10._.js} +1 -1
  112. package/.next/server/chunks/ssr/{node_modules_0rjg6t1._.js → node_modules_0b__sgl._.js} +1 -1
  113. package/.next/server/chunks/ssr/{node_modules_113tz0l._.js → node_modules_0cxaxk9._.js} +1 -1
  114. package/.next/server/chunks/ssr/{node_modules_0lm7_vm._.js → node_modules_0g7fzk3._.js} +1 -1
  115. package/.next/server/chunks/ssr/{node_modules_0h50b8n._.js → node_modules_0had7xd._.js} +1 -1
  116. package/.next/server/chunks/ssr/{node_modules_1-hc6uv._.js → node_modules_0pvd7q-._.js} +1 -1
  117. package/.next/server/chunks/ssr/{node_modules_1bc7gu8._.js → node_modules_0yugy6m._.js} +1 -1
  118. package/.next/server/chunks/ssr/{node_modules_0y_cded._.js → node_modules_14om4ar._.js} +1 -1
  119. package/.next/server/chunks/ssr/{node_modules_0zp9r92._.js → node_modules_14q6g4n._.js} +1 -1
  120. package/.next/server/chunks/ssr/{node_modules_0eu1va6._.js → node_modules_198nmll._.js} +1 -1
  121. package/.next/server/chunks/ssr/{node_modules_1t9cyee._.js → node_modules_1_pc9kq._.js} +1 -1
  122. package/.next/server/chunks/ssr/{node_modules_063xwpp._.js → node_modules_1aaxuef._.js} +1 -1
  123. package/.next/server/chunks/ssr/{node_modules_0bvraul._.js → node_modules_1cx_ql6._.js} +1 -1
  124. package/.next/server/chunks/ssr/{node_modules_1xx28h1._.js → node_modules_1cz2hle._.js} +1 -1
  125. package/.next/server/chunks/ssr/{node_modules_1l0qtdu._.js → node_modules_1efrqxi._.js} +1 -1
  126. package/.next/server/chunks/ssr/{node_modules_1juq3hs._.js → node_modules_1eg7m6c._.js} +1 -1
  127. package/.next/server/chunks/ssr/{node_modules_1_n3ztw._.js → node_modules_1gdh31p._.js} +1 -1
  128. package/.next/server/chunks/ssr/{node_modules_0mwym0g._.js → node_modules_1hpopmo._.js} +1 -1
  129. package/.next/server/chunks/ssr/{node_modules_1bgb6-f._.js → node_modules_1qpjvy5._.js} +1 -1
  130. package/.next/server/chunks/ssr/{node_modules_1uuj9x1._.js → node_modules_1vh5ntv._.js} +1 -1
  131. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0d3skpl._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1b748ic._.js} +1 -1
  132. package/.next/server/chunks/ssr/{node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_0i44kk5._.js → node_modules_@mermaid-js_parser_dist_chunks_mermaid-parser_core_1z4hm5e._.js} +1 -1
  133. package/.next/server/chunks/ssr/{node_modules_@vercel_oidc_dist_0qe30a_._.js → node_modules_@vercel_oidc_dist_06mk8id._.js} +1 -1
  134. package/.next/server/middleware-build-manifest.js +3 -3
  135. package/.next/server/pages/404.html +1 -1
  136. package/.next/server/pages/500.html +1 -1
  137. package/.next/server/server-reference-manifest.js +1 -1
  138. package/.next/server/server-reference-manifest.json +41 -41
  139. package/.next/static/chunks/00rd4-v8r7axp.js +1 -0
  140. package/.next/static/chunks/{0tmgrnlje14-s.js → 08qe4as2q428z.js} +2 -2
  141. package/.next/static/chunks/{3ok9_x74rip3v.js → 0fl3gwe4-l6tz.js} +1 -1
  142. package/.next/static/chunks/{2a0k6jlq0_v1u.js → 0gnqdjn2lvdad.js} +2 -2
  143. package/.next/static/chunks/{1okqiww3pnwka.js → 0hwap1-p0m5sa.js} +1 -1
  144. package/.next/static/chunks/{1ekc7ul556kbl.js → 0w52rrrmuj9r9.js} +1 -1
  145. package/.next/static/chunks/{3agpgkwaa321p.js → 0wcprt5ot5she.js} +1 -1
  146. package/.next/static/chunks/{3xpbkl66ssib5.js → 15m575979un5f.js} +6 -6
  147. package/.next/static/chunks/{2fzs9fm8yarvq.js → 17p6tk6k88dq6.js} +1 -1
  148. package/.next/static/chunks/{26-pr2c9ro222.js → 1jd09sxcjddu1.js} +1 -1
  149. package/.next/static/chunks/{280t0_e99i276.js → 1w73ece_6bheu.js} +1 -1
  150. package/.next/static/chunks/{1grhjo7a5a0_-.js → 214ya3n5gxeih.js} +1 -1
  151. package/.next/static/chunks/22_zkas21rpna.js +1 -0
  152. package/.next/static/chunks/{0x79tx04dxbpp.js → 2u7xt6mxg44lf.js} +1 -1
  153. package/.next/static/chunks/{17donp69y4do7.js → 39j0fvpybzabl.js} +8 -8
  154. package/.next/static/chunks/{28cizcdaabd4h.js → 3akmqm77muj4-.js} +1 -1
  155. package/.next/static/chunks/3cq5g494yuke8.css +1 -0
  156. package/.next/static/chunks/3woj-xd7ki5_i.js +1 -0
  157. package/.next/static/chunks/{3cfi_q6d_wtci.js → 3zmcsnuo25zvq.js} +1 -1
  158. package/README.md +46 -23
  159. package/app/api/events/app-event.ts +0 -2
  160. package/bin/port.mjs +65 -0
  161. package/bin/thursday.mjs +2 -33
  162. package/docs/how-it-works.md +11 -7
  163. package/docs/images/face-dark.png +0 -0
  164. package/docs/images/face-light.png +0 -0
  165. package/docs/images/keeps-going.png +0 -0
  166. package/features/ai/chatgpt.ts +42 -20
  167. package/features/ai/load-tools.ts +20 -14
  168. package/features/ai/prompts/bot.prompt.ts +90 -88
  169. package/features/ai/prompts/thursday.prompt.ts +48 -41
  170. package/features/ai/tools/memory.tool.ts +65 -62
  171. package/features/ai/tools/tool-name.ts +0 -1
  172. package/features/ai/tools/workspace.tool.ts +3 -0
  173. package/features/bot/bot.action.ts +6 -1
  174. package/features/bot/bot.run.ts +11 -7
  175. package/features/bot/bot.runner.ts +34 -16
  176. package/features/bot/bot.schema.ts +25 -0
  177. package/features/bot/components/bot-room.tsx +57 -4
  178. package/features/bot/components/bot-tool.tsx +0 -1
  179. package/features/bot/task.query.ts +25 -6
  180. package/features/bot/task.store.ts +23 -4
  181. package/features/memory/components/memory-edit.tsx +7 -5
  182. package/features/thursday/components/thursday.tsx +0 -3
  183. package/features/thursday/tool-line.ts +0 -1
  184. package/features/thursday/use-thursday.ts +1 -1
  185. package/package.json +1 -1
  186. package/.next/server/chunks/ssr/[root-of-the-server]__1pduf5n._.js +0 -3
  187. package/.next/server/chunks/ssr/_14_lw10._.js +0 -3
  188. package/.next/server/chunks/ssr/_1spzm8z._.js +0 -3
  189. package/.next/server/chunks/ssr/lib_date-like_ts_02is0pw._.js +0 -3
  190. package/.next/static/chunks/0xzgvc0fkdb6t.js +0 -1
  191. package/.next/static/chunks/14hgtsjg-kael.css +0 -1
  192. package/.next/static/chunks/2hw2f6zmt7fmt.js +0 -1
  193. package/.next/static/chunks/3111pj5wnjgos.js +0 -1
  194. package/features/memory/components/memory-view.tsx +0 -84
  195. /package/.next/static/{x1cCqY0kWpR_VcYx_lWO5 → kaTO0UHqF1bMnWgCDik2f}/_buildManifest.js +0 -0
  196. /package/.next/static/{x1cCqY0kWpR_VcYx_lWO5 → kaTO0UHqF1bMnWgCDik2f}/_clientMiddlewareManifest.js +0 -0
  197. /package/.next/static/{x1cCqY0kWpR_VcYx_lWO5 → kaTO0UHqF1bMnWgCDik2f}/_ssgManifest.js +0 -0
@@ -1,3 +1,3 @@
1
- module.exports=[1363,e=>e.a(async(t,a)=>{try{var o=e.i(336763),r=e.i(396918),l=e.i(533102),i=e.i(232347),m=e.i(333925),s=e.i(876393),n=e.i(220376),d=e.i(991243),c=e.i(232549),y=t([s]);[s]=y.then?(await y)():y;let F=(0,d.createKeyedLock)(),N=()=>i.appEvents.emit({type:"memory"});async function b(){for(let e of c.MEMORY_ALWAYS_LISTED){let t=c.MEMORY_PATHS.find(t=>t.path===e)?.of??e;await s.database.insert(n.memoryNoteTable).values({path:e,description:t}).onConflictDoUpdate({target:n.memoryNoteTable.path,set:{description:t}})}}async function h(e){let t=e.map(e=>e.trim()).filter(Boolean),a=[],r=[];if(!t.length)return{found:a,missing:r};let l={id:n.memoryNoteTable.id,path:n.memoryNoteTable.path,description:n.memoryNoteTable.description},i=await s.database.select(l).from(n.memoryNoteTable).where((0,o.inArray)(n.memoryNoteTable.path,t)),m=new Map(i.map(e=>[e.path.toLowerCase(),e]));if(t.some(e=>!m.has(e.toLowerCase()))){let e=await s.database.select({...l,aliases:n.memoryNoteTable.aliases}).from(n.memoryNoteTable),t=(e,t)=>{let a=e.trim().toLowerCase();a&&!m.has(a)&&m.set(a,t)};for(let a of e)t(a.path,a);for(let a of e)for(let e of(t(a.path.slice(a.path.indexOf("/")+1),a),a.aliases??[]))t(e,a)}let d=new Set;for(let e of t){let t=m.get(e.toLowerCase());if(!t){r.push(e);continue}d.has(t.id)||(d.add(t.id),a.push(t))}return{found:a,missing:r}}async function w(e){let{found:t}=await h([e]);return t[0]?.path??null}async function T(e,t={}){let{found:a,missing:i}=await h(e);if(!a.length)return{notes:[],missing:i};let m=a.map(e=>e.id),d=await s.database.select({id:n.memoryFactTable.id,noteId:n.memoryFactTable.noteId,text:n.memoryFactTable.text,alwaysLoad:n.memoryFactTable.alwaysLoad,source:n.memoryFactTable.source,createdAt:n.memoryFactTable.createdAt,saidAt:n.callTable.startedAt}).from(n.memoryFactTable).leftJoin(n.callTable,(0,o.eq)(n.memoryFactTable.callId,n.callTable.id)).where((0,o.and)((0,o.eq)(n.memoryFactTable.isLatest,!0),(0,o.inArray)(n.memoryFactTable.noteId,m))).orderBy((0,r.asc)(n.memoryFactTable.id));return!1!==t.touch&&await s.database.update(n.memoryNoteTable).set({hits:l.sql`${n.memoryNoteTable.hits} + 1`,lastReadAt:new Date}).where((0,o.inArray)(n.memoryNoteTable.id,m)),{notes:a.map(e=>({path:e.path,description:e.description,facts:d.filter(t=>t.noteId===e.id).map(e=>({id:e.id,text:e.text,...e.saidAt?{saidAt:e.saidAt}:{}}))})),missing:i}}(0,o.inArray)(n.memoryNoteTable.path,c.MEMORY_ALWAYS_LISTED);let A=e=>e.toLowerCase().replace(/[\s.,!?…·'"`]/g,"");async function p(e,t,a=null){let r,i=[],d=[],c=[];await (r=()=>s.database.transaction(async r=>{let[s]=await r.select({count:l.sql`count(*)`}).from(n.memoryFactTable).where((0,o.and)((0,o.eq)(n.memoryFactTable.alwaysLoad,!0),(0,o.eq)(n.memoryFactTable.isLatest,!0))),y=m.MEMORY_LIMITS.carried-Number(s?.count??0),b=(e,t)=>!!e&&(y>0?(y-=1,!0):(c.push(t),!1));for(let l of e){let e,m=l.path.trim();if(!m)continue;d.push(m);let s=l.description?.trim(),c=l.aliases?.map(e=>e.trim()).filter(Boolean),h=(l.facts??[]).map(e=>({...e,text:e.text.trim()})).filter(e=>e.text),[w]=await r.select({id:n.memoryNoteTable.id}).from(n.memoryNoteTable).where((0,o.eq)(n.memoryNoteTable.path,m));if(w)e=w.id,(s||c)&&await r.update(n.memoryNoteTable).set({...s?{description:s}:{},...c?{aliases:c}:{},updatedAt:new Date}).where((0,o.eq)(n.memoryNoteTable.id,e));else{let[t]=await r.insert(n.memoryNoteTable).values({path:m,description:s??h[0]?.text.slice(0,80)??m,...c?{aliases:c}:{}}).returning({id:n.memoryNoteTable.id});e=t.id,s||i.push(m)}if(!h.length)continue;let T=await r.select({id:n.memoryFactTable.id,text:n.memoryFactTable.text,alwaysLoad:n.memoryFactTable.alwaysLoad}).from(n.memoryFactTable).where((0,o.and)((0,o.eq)(n.memoryFactTable.noteId,e),(0,o.eq)(n.memoryFactTable.isLatest,!0))),p=new Map(T.map(e=>[A(e.text),e])),u=async(e,t,a)=>{if(t===e.alwaysLoad)return;let l=t?b(!0,a):(y+=1,!1);l!==e.alwaysLoad&&(await r.update(n.memoryFactTable).set({alwaysLoad:l}).where((0,o.eq)(n.memoryFactTable.id,e.id)),e.alwaysLoad=l)};for(let l of h){if(null!=l.replaces){let[i]=await r.select({id:n.memoryFactTable.id,text:n.memoryFactTable.text,alwaysLoad:n.memoryFactTable.alwaysLoad}).from(n.memoryFactTable).where((0,o.and)((0,o.eq)(n.memoryFactTable.id,l.replaces),(0,o.eq)(n.memoryFactTable.noteId,e),(0,o.eq)(n.memoryFactTable.isLatest,!0)));if(i){if(A(i.text)===A(l.text)){await u(i,l.alwaysLoad??i.alwaysLoad,l.text),p.set(A(i.text),i);continue}await r.update(n.memoryFactTable).set({isLatest:!1}).where((0,o.eq)(n.memoryFactTable.id,i.id)),p.delete(A(i.text)),i.alwaysLoad&&(y+=1);let[m]=await r.insert(n.memoryFactTable).values({noteId:e,text:l.text,source:t,callId:a,alwaysLoad:b(l.alwaysLoad??i.alwaysLoad,l.text)}).returning({id:n.memoryFactTable.id,alwaysLoad:n.memoryFactTable.alwaysLoad});p.set(A(l.text),{...m,text:l.text});continue}}let i=p.get(A(l.text));if(i){null!=l.alwaysLoad&&await u(i,l.alwaysLoad,l.text);continue}let[m]=await r.insert(n.memoryFactTable).values({noteId:e,text:l.text,source:t,callId:a,alwaysLoad:b(!0===l.alwaysLoad,l.text)}).returning({id:n.memoryFactTable.id,alwaysLoad:n.memoryFactTable.alwaysLoad});p.set(A(l.text),{...m,text:l.text})}await r.update(n.memoryNoteTable).set({updatedAt:new Date}).where((0,o.eq)(n.memoryNoteTable.id,e))}}),F("memory",r));let{notes:y}=await T(d,{touch:!1});return N(),{notes:y,unnamed:i,notLoaded:c}}async function u(){let[e,t]=await Promise.all([s.database.select({id:n.memoryNoteTable.id,path:n.memoryNoteTable.path,description:n.memoryNoteTable.description,aliases:n.memoryNoteTable.aliases,hits:n.memoryNoteTable.hits,lastReadAt:n.memoryNoteTable.lastReadAt,createdAt:n.memoryNoteTable.createdAt}).from(n.memoryNoteTable),s.database.select({noteId:n.memoryFactTable.noteId,count:l.sql`count(*)`}).from(n.memoryFactTable).where((0,o.eq)(n.memoryFactTable.isLatest,!0)).groupBy(n.memoryFactTable.noteId)]),a=new Map(t.map(e=>[e.noteId,e.count]));return e.filter(e=>(0,c.isAlwaysListed)(e.path)||(a.get(e.id)??0)>0).sort((e,t)=>Number((0,c.isAlwaysListed)(t.path))-Number((0,c.isAlwaysListed)(e.path))||(0,c.recallScore)(t)-(0,c.recallScore)(e)).map(e=>({path:e.path,description:e.description,aliases:e.aliases,factCount:a.get(e.id)??0,lastSeenAt:e.lastReadAt??e.createdAt}))}async function f(e){let t,a=await (t=()=>s.database.transaction(async t=>{let a=await t.delete(n.memoryFactTable).where((0,o.eq)(n.memoryFactTable.id,e)).returning({noteId:n.memoryFactTable.noteId});if(0===a.length)return null;let r=a[0].noteId,[i]=await t.select({path:n.memoryNoteTable.path,ownedByUser:n.memoryNoteTable.ownedByUser}).from(n.memoryNoteTable).where((0,o.eq)(n.memoryNoteTable.id,r)),[m]=await t.select({count:l.sql`count(*)`}).from(n.memoryFactTable).where((0,o.and)((0,o.eq)(n.memoryFactTable.noteId,r),(0,o.eq)(n.memoryFactTable.isLatest,!0)));return m?.count!==0||!i||i.ownedByUser||(0,c.isAlwaysListed)(i.path)?(await t.update(n.memoryNoteTable).set({updatedAt:new Date}).where((0,o.eq)(n.memoryNoteTable.id,r)),{path:i?.path??"",noteGone:!1}):(await t.delete(n.memoryNoteTable).where((0,o.eq)(n.memoryNoteTable.id,r)),{path:i.path,noteGone:!0})}),F("memory",t));return a&&N(),a}async function L(e){let[t]=await s.database.select({source:n.memoryFactTable.source,callId:n.memoryFactTable.callId}).from(n.memoryFactTable).where((0,o.eq)(n.memoryFactTable.id,e));return t??null}e.s(["ensureRootNotes",0,b,"findFactCall",0,L,"forgetFactById",0,f,"listAlwaysLoaded",0,function(){return s.database.select({id:n.memoryFactTable.id,path:n.memoryNoteTable.path,text:n.memoryFactTable.text}).from(n.memoryFactTable).innerJoin(n.memoryNoteTable,(0,o.eq)(n.memoryFactTable.noteId,n.memoryNoteTable.id)).where((0,o.and)((0,o.eq)(n.memoryFactTable.alwaysLoad,!0),(0,o.eq)(n.memoryFactTable.isLatest,!0))).orderBy((0,r.asc)(n.memoryNoteTable.path),(0,r.asc)(n.memoryFactTable.id)).limit(m.MEMORY_LIMITS.carried)},"listNoteIndex",0,u,"readNotes",0,T,"resolveNotePath",0,w,"writeNotes",0,p]),a()}catch(e){a(e)}},!1),232549,e=>{"use strict";var t=e.i(853205),a=e.i(900533);let o=t.z.enum(["user","call","bot"]),r=t.z.object({id:t.z.number(),text:t.z.string(),alwaysLoad:t.z.boolean(),source:o.nullish(),createdAt:a.DateLikeSchema});t.z.object({id:t.z.number(),path:t.z.string(),description:t.z.string(),aliases:t.z.string().array().nullish(),ownedByUser:t.z.boolean(),hits:t.z.number(),lastReadAt:a.DateLikeSchema.nullable(),createdAt:a.DateLikeSchema,updatedAt:a.DateLikeSchema,factCount:t.z.number(),facts:r.array()});let l=[{path:"profile",of:"The user themselves — their name, age, what they do, where they live, and whatever else says who they are"},{path:"preferences",of:"How they want things done, and said"},{path:"people/",of:"Someone in their life, and what matters about them"},{path:"projects/",of:"Something with an end — a trip, a purchase, a deadline, a thing being built"},{path:"topics/",of:"Something ongoing that keeps coming back"},{path:"inbox",of:"Nowhere obvious yet"}],i="inbox",m=l.filter(e=>!e.path.endsWith("/")).map(e=>e.path),s=l.filter(e=>e.path.endsWith("/")).map(e=>e.path.slice(0,-1)),n=RegExp(`^(?:${m.join("|")}|(?:${s.join("|")})/.+)$`),d=["profile","preferences"],c=[...d,i];e.s(["APP_NAMED_NOTES",0,c,"MEMORY_ALWAYS_LISTED",0,d,"MEMORY_INBOX",0,i,"MEMORY_PATHS",0,l,"appNoteLine",0,e=>l.find(t=>t.path===e)?.of??null,"isAlwaysListed",0,e=>d.includes(e),"isAppNamed",0,e=>c.includes(e),"isMemoryPath",0,e=>n.test(e),"recallScore",0,function(e){let t=(0,a.toDate)(e.lastReadAt??e.createdAt),o=Math.max(0,(Date.now()-t.getTime())/864e5);return(e.hits+1)/(1+o)}])},991243,e=>{"use strict";var t=e.i(64774);e.s(["createKeyedLock",0,function(){let e=new Map,a=new Map;return function(o,r){let l=e.get(o);l||(l=(0,t.PromiseChain)(),e.set(o,l)),a.set(o,(a.get(o)??0)+1);let i=()=>{let t=(a.get(o)??1)-1;t>0?a.set(o,t):(a.delete(o),e.delete(o))};return l(r).then(e=>(i(),e),e=>{throw i(),e})}}])}];
1
+ module.exports=[1363,e=>e.a(async(t,a)=>{try{var o=e.i(336763),r=e.i(396918),l=e.i(533102),i=e.i(232347),s=e.i(333925),m=e.i(876393),n=e.i(220376),d=e.i(991243),c=e.i(232549),y=t([m]);[m]=y.then?(await y)():y;let F=(0,d.createKeyedLock)(),N=()=>i.appEvents.emit({type:"memory"});async function b(){for(let e of c.MEMORY_ALWAYS_LISTED){let t=c.MEMORY_PATHS.find(t=>t.path===e)?.of??e;await m.database.insert(n.memoryNoteTable).values({path:e,description:t}).onConflictDoUpdate({target:n.memoryNoteTable.path,set:{description:t}})}}async function h(e){let t=e.map(e=>e.trim()).filter(Boolean),a=[],r=[];if(!t.length)return{found:a,missing:r};let l={id:n.memoryNoteTable.id,path:n.memoryNoteTable.path,description:n.memoryNoteTable.description},i=await m.database.select(l).from(n.memoryNoteTable).where((0,o.inArray)(n.memoryNoteTable.path,t)),s=new Map(i.map(e=>[e.path.toLowerCase(),e]));if(t.some(e=>!s.has(e.toLowerCase()))){let e=await m.database.select({...l,aliases:n.memoryNoteTable.aliases}).from(n.memoryNoteTable),t=(e,t)=>{let a=e.trim().toLowerCase();a&&!s.has(a)&&s.set(a,t)};for(let a of e)t(a.path,a);for(let a of e)for(let e of(t(a.path.slice(a.path.indexOf("/")+1),a),a.aliases??[]))t(e,a)}let d=new Set;for(let e of t){let t=s.get(e.toLowerCase());if(!t){r.push(e);continue}d.has(t.id)||(d.add(t.id),a.push(t))}return{found:a,missing:r}}async function w(e){let{found:t}=await h([e]);return t[0]?.path??null}async function p(e,t={}){let{found:a,missing:i}=await h(e);if(!a.length)return{notes:[],missing:i};let s=a.map(e=>e.id),d=await m.database.select({id:n.memoryFactTable.id,noteId:n.memoryFactTable.noteId,text:n.memoryFactTable.text,alwaysLoad:n.memoryFactTable.alwaysLoad,source:n.memoryFactTable.source,createdAt:n.memoryFactTable.createdAt,saidAt:n.callTable.startedAt}).from(n.memoryFactTable).leftJoin(n.callTable,(0,o.eq)(n.memoryFactTable.callId,n.callTable.id)).where((0,o.and)((0,o.eq)(n.memoryFactTable.isLatest,!0),(0,o.inArray)(n.memoryFactTable.noteId,s))).orderBy((0,r.asc)(n.memoryFactTable.id));return!1!==t.touch&&await m.database.update(n.memoryNoteTable).set({hits:l.sql`${n.memoryNoteTable.hits} + 1`,lastReadAt:new Date}).where((0,o.inArray)(n.memoryNoteTable.id,s)),{notes:a.map(e=>({path:e.path,description:e.description,facts:d.filter(t=>t.noteId===e.id).map(e=>({id:e.id,text:e.text,...e.saidAt?{saidAt:e.saidAt}:{}}))})),missing:i}}(0,o.inArray)(n.memoryNoteTable.path,c.MEMORY_ALWAYS_LISTED);let A=e=>e.toLowerCase().replace(/[\s.,!?…·'"`]/g,"");async function u(e,t,a=null){let r,i=[],d=[],c=[];await (r=()=>m.database.transaction(async r=>{let[m]=await r.select({count:l.sql`count(*)`}).from(n.memoryFactTable).where((0,o.and)((0,o.eq)(n.memoryFactTable.alwaysLoad,!0),(0,o.eq)(n.memoryFactTable.isLatest,!0))),y=s.MEMORY_LIMITS.carried-Number(m?.count??0),b=(e,t)=>!!e&&(y>0?(y-=1,!0):(c.push(t),!1));for(let l of e){let e,s=l.path.trim();if(!s)continue;d.push(s);let m=l.description?.trim(),c=l.aliases?.map(e=>e.trim()).filter(Boolean),h=(l.facts??[]).map(e=>({...e,text:e.text.trim()})).filter(e=>e.text),[w]=await r.select({id:n.memoryNoteTable.id}).from(n.memoryNoteTable).where((0,o.eq)(n.memoryNoteTable.path,s));if(w)e=w.id,(m||c)&&await r.update(n.memoryNoteTable).set({...m?{description:m}:{},...c?{aliases:c}:{},updatedAt:new Date}).where((0,o.eq)(n.memoryNoteTable.id,e));else{let[t]=await r.insert(n.memoryNoteTable).values({path:s,description:m??h[0]?.text.slice(0,80)??s,...c?{aliases:c}:{}}).returning({id:n.memoryNoteTable.id});e=t.id,m||i.push(s)}if(!h.length)continue;let p=await r.select({id:n.memoryFactTable.id,text:n.memoryFactTable.text,alwaysLoad:n.memoryFactTable.alwaysLoad}).from(n.memoryFactTable).where((0,o.and)((0,o.eq)(n.memoryFactTable.noteId,e),(0,o.eq)(n.memoryFactTable.isLatest,!0))),u=new Map(p.map(e=>[A(e.text),e])),T=async(e,t,a)=>{if(t===e.alwaysLoad)return;let l=t?b(!0,a):(y+=1,!1);l!==e.alwaysLoad&&(await r.update(n.memoryFactTable).set({alwaysLoad:l}).where((0,o.eq)(n.memoryFactTable.id,e.id)),e.alwaysLoad=l)};for(let l of h){if(null!=l.replaces){let[i]=await r.select({id:n.memoryFactTable.id,text:n.memoryFactTable.text,alwaysLoad:n.memoryFactTable.alwaysLoad}).from(n.memoryFactTable).where((0,o.and)((0,o.eq)(n.memoryFactTable.id,l.replaces),(0,o.eq)(n.memoryFactTable.noteId,e),(0,o.eq)(n.memoryFactTable.isLatest,!0)));if(i){if(A(i.text)===A(l.text)){await T(i,l.alwaysLoad??i.alwaysLoad,l.text),u.set(A(i.text),i);continue}await r.update(n.memoryFactTable).set({isLatest:!1}).where((0,o.eq)(n.memoryFactTable.id,i.id)),u.delete(A(i.text)),i.alwaysLoad&&(y+=1);let[s]=await r.insert(n.memoryFactTable).values({noteId:e,text:l.text,source:t,callId:a,alwaysLoad:b(l.alwaysLoad??i.alwaysLoad,l.text)}).returning({id:n.memoryFactTable.id,alwaysLoad:n.memoryFactTable.alwaysLoad});u.set(A(l.text),{...s,text:l.text});continue}}let i=u.get(A(l.text));if(i){null!=l.alwaysLoad&&await T(i,l.alwaysLoad,l.text);continue}let[s]=await r.insert(n.memoryFactTable).values({noteId:e,text:l.text,source:t,callId:a,alwaysLoad:b(!0===l.alwaysLoad,l.text)}).returning({id:n.memoryFactTable.id,alwaysLoad:n.memoryFactTable.alwaysLoad});u.set(A(l.text),{...s,text:l.text})}await r.update(n.memoryNoteTable).set({updatedAt:new Date}).where((0,o.eq)(n.memoryNoteTable.id,e))}}),F("memory",r));let{notes:y}=await p(d,{touch:!1});return N(),{notes:y,unnamed:i,notLoaded:c}}async function T(){let[e,t]=await Promise.all([m.database.select({id:n.memoryNoteTable.id,path:n.memoryNoteTable.path,description:n.memoryNoteTable.description,aliases:n.memoryNoteTable.aliases,hits:n.memoryNoteTable.hits,lastReadAt:n.memoryNoteTable.lastReadAt,createdAt:n.memoryNoteTable.createdAt}).from(n.memoryNoteTable),m.database.select({noteId:n.memoryFactTable.noteId,count:l.sql`count(*)`}).from(n.memoryFactTable).where((0,o.eq)(n.memoryFactTable.isLatest,!0)).groupBy(n.memoryFactTable.noteId)]),a=new Map(t.map(e=>[e.noteId,e.count]));return e.filter(e=>(0,c.isAlwaysListed)(e.path)||(a.get(e.id)??0)>0).sort((e,t)=>Number((0,c.isAlwaysListed)(t.path))-Number((0,c.isAlwaysListed)(e.path))||(0,c.recallScore)(t)-(0,c.recallScore)(e)).map(e=>({path:e.path,description:e.description,aliases:e.aliases,factCount:a.get(e.id)??0,lastSeenAt:e.lastReadAt??e.createdAt}))}async function f(e){let t,a=await (t=()=>m.database.transaction(async t=>{let a=await t.delete(n.memoryFactTable).where((0,o.eq)(n.memoryFactTable.id,e)).returning({noteId:n.memoryFactTable.noteId});if(0===a.length)return null;let r=a[0].noteId,[i]=await t.select({path:n.memoryNoteTable.path,ownedByUser:n.memoryNoteTable.ownedByUser}).from(n.memoryNoteTable).where((0,o.eq)(n.memoryNoteTable.id,r)),[s]=await t.select({count:l.sql`count(*)`}).from(n.memoryFactTable).where((0,o.and)((0,o.eq)(n.memoryFactTable.noteId,r),(0,o.eq)(n.memoryFactTable.isLatest,!0)));return s?.count!==0||!i||i.ownedByUser||(0,c.isAlwaysListed)(i.path)?(await t.update(n.memoryNoteTable).set({updatedAt:new Date}).where((0,o.eq)(n.memoryNoteTable.id,r)),{path:i?.path??"",noteGone:!1}):(await t.delete(n.memoryNoteTable).where((0,o.eq)(n.memoryNoteTable.id,r)),{path:i.path,noteGone:!0})}),F("memory",t));return a&&N(),a}async function L(e){let[t]=await m.database.select({source:n.memoryFactTable.source,callId:n.memoryFactTable.callId}).from(n.memoryFactTable).where((0,o.eq)(n.memoryFactTable.id,e));return t??null}e.s(["ensureRootNotes",0,b,"findFactCall",0,L,"forgetFactById",0,f,"listNoteIndex",0,T,"readNotes",0,p,"resolveNotePath",0,w,"writeNotes",0,u]),a()}catch(e){a(e)}},!1),232549,e=>{"use strict";var t=e.i(853205),a=e.i(900533);let o=t.z.enum(["user","call","bot"]),r=t.z.object({id:t.z.number(),text:t.z.string(),alwaysLoad:t.z.boolean(),source:o.nullish(),createdAt:a.DateLikeSchema});t.z.object({id:t.z.number(),path:t.z.string(),description:t.z.string(),aliases:t.z.string().array().nullish(),ownedByUser:t.z.boolean(),hits:t.z.number(),lastReadAt:a.DateLikeSchema.nullable(),createdAt:a.DateLikeSchema,updatedAt:a.DateLikeSchema,factCount:t.z.number(),facts:r.array()});let l=[{path:"profile",of:"The user themselves — their name, age, what they do, where they live, and whatever else says who they are"},{path:"preferences",of:"How they want things done, and said"},{path:"people/",of:"Someone in their life, and what matters about them"},{path:"projects/",of:"Something with an end — a trip, a purchase, a deadline, a thing being built"},{path:"topics/",of:"Something ongoing that keeps coming back"},{path:"inbox",of:"Nowhere obvious yet"}],i="inbox",s=l.filter(e=>!e.path.endsWith("/")).map(e=>e.path),m=l.filter(e=>e.path.endsWith("/")).map(e=>e.path.slice(0,-1)),n=RegExp(`^(?:${s.join("|")}|(?:${m.join("|")})/.+)$`),d=["profile","preferences"],c=[...d,i];e.s(["APP_NAMED_NOTES",0,c,"MEMORY_ALWAYS_LISTED",0,d,"MEMORY_INBOX",0,i,"MEMORY_PATHS",0,l,"appNoteLine",0,e=>l.find(t=>t.path===e)?.of??null,"isAlwaysListed",0,e=>d.includes(e),"isAppNamed",0,e=>c.includes(e),"isMemoryPath",0,e=>n.test(e),"recallScore",0,function(e){let t=(0,a.toDate)(e.lastReadAt??e.createdAt),o=Math.max(0,(Date.now()-t.getTime())/864e5);return(e.hits+1)/(1+o)}])},991243,e=>{"use strict";var t=e.i(64774);e.s(["createKeyedLock",0,function(){let e=new Map,a=new Map;return function(o,r){let l=e.get(o);l||(l=(0,t.PromiseChain)(),e.set(o,l)),a.set(o,(a.get(o)??0)+1);let i=()=>{let t=(a.get(o)??1)-1;t>0?a.set(o,t):(a.delete(o),e.delete(o))};return l(r).then(e=>(i(),e),e=>{throw i(),e})}}])}];
2
2
 
3
3
  //# sourceMappingURL=_05h2cii._.js.map
@@ -1,91 +1,95 @@
1
- module.exports=[851372,e=>e.a(async(t,o)=>{try{var a=e.i(687388),n=e.i(353885),s=e.i(393189),r=e.i(265143),i=e.i(148831),l=e.i(619898),h=e.i(636882),u=e.i(786025),d=e.i(640911),c=e.i(41444),p=e.i(660948),w=e.i(54282),y=t([r,i,l,p]);async function m(e,t,o,y){var m,g,S,x,A,E,M,_,j;let I,B,C,P,L,W=await (0,u.openWorkspace)(),q=e.trim(),R=o?.askedBy??null,[U,H,Y,F,D,J,G,K,z]=await Promise.all([(0,h.loadSkills)(W),(0,l.listNoteIndex)(),(0,l.listAlwaysLoaded)(),(0,p.listConnectedToolNames)(),(0,i.findPinnedTools)(q),(0,r.listJobBots)(),(0,s.listBotMemory)(q),(0,r.readBotMemoryOn)(),(0,u.readMachineTools)(W)]),Q=o&&!o.canBorrow?[]:J.filter(e=>e.name!==q&&!o?.above.includes(e.name)),V=[R?(m=q,g=R,[`You are ${m}, a worker. ${g} has handed you one part of a job Thursday handed over; your first message says who holds it and how it reached you. The user speaks to Thursday and to nobody else; you never address them, and what you hand back goes into ${g}'s answer as-is. This thread is drawn on their screen while you work: not written to them, but not private either. ${(0,w.nowLine)()}`,f,b].join("\n\n")):(S=q,[`You are ${S}, a worker. Thursday handed you a job while she keeps talking to the user — they speak to her and to nobody else, and what she says out of your answer is the only part of this that reaches them. You are not in that conversation and never address the user. This thread is drawn on their screen while you work, though: not written to them, but not private either. ${(0,w.nowLine)()}`,f,b].join("\n\n")),(x=H,A=Y,I=`## The user's memory
1
+ module.exports=[851372,e=>e.a(async(t,o)=>{try{var a=e.i(343747),n=e.i(687388),s=e.i(353885),r=e.i(393189),i=e.i(265143),l=e.i(148831),u=e.i(619898),h=e.i(636882),d=e.i(786025),c=e.i(704161),p=e.i(640911),w=e.i(41444),y=e.i(660948),m=e.i(54282),f=t([i,l,u,y]);async function g(e,t,o,f){var g,b,A,E,_,j,I,C;let B,P,L=await (0,d.openWorkspace)(),W=e.trim(),q=o?.askedBy??null,[R,U,Y,H,F,D,J,G]=await Promise.all([(0,h.loadSkills)(L),(0,u.listNoteIndex)(),(0,y.listConnectedToolNames)(),(0,l.findPinnedTools)(W),(0,i.listJobBots)(),(0,r.listBotMemory)(W),(0,i.readBotMemoryOn)(),(0,d.readMachineTools)(L)]),K=o&&!o.canBorrow?[]:F.filter(e=>e.name!==W&&!o?.above.includes(e.name)),z=[q?(g=W,b=q,[`You are ${g}, one of the bots that work for the user. ${(0,m.nowLine)()}
2
2
 
3
- What Thursday knows about the user, kept as she talks with them. Every bot reads it; none writes to it. Open a note with \`${n.TOOL_NAMES.memory_recall}\` when the job needs something about them — the address they sign in with, the name to book under — and put what you find out about them in your answer; she decides what to keep. It describes them, not you: how they are named and spoken to is hers to use. What you learn about the work goes in your own memory, below.`,B=A.length?`Already known:
3
+ ${k}
4
+ - **${b}** — a bot on this job, who handed you one part of it. They cannot see your thread.
5
+ - **You** — you do that part. What you hand back goes into ${b}'s work as it is, never to Thursday or the user.`,T,$].join("\n\n")):(A=W,[`You are ${A}, one of the bots that work for the user. ${(0,m.nowLine)()}
4
6
 
5
- ${(0,w.carriedLines)(A)}`:"",C=`path — what is under it (facts) "what the user calls it"
7
+ ${k}
8
+ - **You** — you do the work. Your answer goes to Thursday, not to the user, and she tells them what they need from it.`,T,$].join("\n\n")),(E=U,`## Thursday's memory of the user
6
9
 
7
- ${(0,w.noteLines)(x)}
10
+ What Thursday keeps from talking with them. Open a note from the listing with \`${s.TOOL_NAMES.memory_recall}\` when the job needs something about them; what you find out about them goes in your answer, and she keeps what matters.
8
11
 
9
- A topic not listed is one nobody knows anything about.`,[I,B,C].filter(Boolean).join("\n\n")),K?(E=(0,s.botMemoryFolder)(q),P=(M=G).entries.length?M.entries.map(({file:e,line:t})=>t?`- ${e} — ${(0,c.clip)(t,a.PROMPT_LINE.botMemory)}`:`- ${e}`).join("\n"):"Empty.",L=M.total>M.entries.length?`
12
+ path — what is under it (facts) "what the user calls it"
10
13
 
11
- The newest ${M.entries.length} of ${M.total}; \`ls ${E}\` for the rest.`:"",`## Your memory
14
+ ${(0,m.noteLines)(E)}`),function(e,t){let o=new Set(t.map(e=>`${e.server}/${e.name}`)),a=e.filter(e=>!o.has(`${e.server}/${e.name}`));if(0===a.length)return"";let n=o.size?" What is not listed above you are already holding — it is in your tools.":"";return`## Connected tools
12
15
 
13
- What you kept from your own earlier jobs, in \`${E}/\`: one topic per file, its first line saying what it holds, read by no other bot. Keep what a later job would otherwise have to find out again — how a site signs in, the way through its screens, a command that turned out right — and fix or delete a file that proved wrong. No passwords, keys or codes.
16
+ ${(0,m.mcpToolLines)(a)}
14
17
 
15
- ${P}${L}`):"",function(e,t){let o=new Set(t.map(e=>`${e.server}/${e.name}`)),a=e.filter(e=>!o.has(`${e.server}/${e.name}`));if(0===a.length)return"";let s=o.size?" What is not listed above you are already holding — it is in your tools.":"";return`## Connected tools
18
+ Names only: \`${s.TOOL_NAMES.tool_search}\` returns what each one takes, \`${s.TOOL_NAMES.tool_call}\` runs one.${n}`}(Y,H),(_=R,0===_.length?"":`## Skills
16
19
 
17
- ${(0,w.mcpToolLines)(a)}
20
+ Written-down methods. When the job is one of these, read it with \`${s.TOOL_NAMES.load_skill}\` before starting.
18
21
 
19
- Names only: \`${n.TOOL_NAMES.tool_search}\` returns what each one takes, \`${n.TOOL_NAMES.tool_call}\` runs one.${s}`}(F,D),(_=U,0===_.length?"":`## Skills
22
+ ${(0,m.skillLines)(_)}`),N(L.cwd,G,f),J?(j=(0,r.botMemoryFolder)(W),B=(I=D).entries.length?I.entries.map(({file:e,line:t,at:o})=>{let s=t?` — ${(0,w.clip)(t,n.PROMPT_LINE.botMemory)}`:"";return`- ${e}${s} \xb7 ${(0,a.format)((0,c.toDate)(o),"yyyy-MM-dd")}`}).join("\n"):"Empty.",P=I.total>I.entries.length?`
20
23
 
21
- Written-down methods. When the job is one of these, read it with \`${n.TOOL_NAMES.load_skill}\` before starting.
24
+ The newest ${I.entries.length} of ${I.total}; \`ls ${j}\` for the rest.`:"",`## Your memory
22
25
 
23
- ${(0,w.skillLines)(_)}`),T(W.cwd,z,y),(j=Q,0===j.length?"":`## Bots
26
+ What you kept from your own earlier jobs, in \`${j}/\` under the Cwd above: one topic per file, its first line saying what it holds, read by no other bot. Keep what a later job would otherwise have to find out again — how a site signs in, the way through its screens, a command that turned out right — with the date you found it true, and fix or delete a file that proved wrong. No passwords, keys or codes.
24
27
 
25
- ${j.map(e=>`- **${e.name}** — ${e.description}`).join("\n")}
28
+ ${B}${P}`):"",(C=K,0===C.length?"":`## Bots
29
+
30
+ ${C.map(e=>`- **${e.name}** — ${e.description}`).join("\n")}
26
31
 
27
32
  These lines were written for the user, who reads them on their own screen: where one says "you" it means them, not you.
28
33
 
29
- A part of your job another bot is for goes to \`${n.TOOL_NAMES.ask_bot}\`, because their tools and their practice are the reason they exist. What you build is made of what they bring back, so send for it before you build. A part you could finish in a couple of commands is yours; one that would take a run of its own is theirs. What you were handed stays yours and you answer for it. They get the job, the call it came from and what you write them — not this thread.`),R?v(R):$,R?O(R):N,k(t)].filter(Boolean).join("\n\n");return(0,w.logPromptSize)("bot",V),d.logger.debug(`bot prompt
30
- ${V}`),{text:V,peers:Q.map(e=>e.name),opening:null}}[r,i,l,p]=y.then?(await y)():y;let f=`**You are on a real computer — the user's own.** You have a shell and a filesystem, and the job is done, not described: where there is no tool for something, write one — in \`node\` unless they asked for another language, the runtime this app itself runs on. Reach for \`${n.TOOL_NAMES.bash}\` before concluding that something cannot be done, but after the roster, not instead of it: a script you write to do another bot's job is the long way round.
34
+ A part of your job another bot is for goes to \`${s.TOOL_NAMES.ask_bot}\`, because their tools and their practice are the reason they exist. What you build is made of what they bring back, so send for it before you build. A part you could finish in a couple of commands is yours; one that would take a run of its own is theirs. What you were handed stays yours and you answer for it. They get the job, the call it came from and what you write them — not this thread.`),q?S(q):O,q?M(q):x,v(t)].filter(Boolean).join("\n\n");return(0,m.logPromptSize)("bot",z),p.logger.debug(`bot prompt
35
+ ${z}`),{text:z,peers:K.map(e=>e.name),opening:null}}[i,l,u,y]=f.then?(await f)():f;let k=`- **The user** — the one person all of this is for. They talk with Thursday by voice, and they follow this job on their screen.
36
+ - **Thursday** — their own personal assistant, one to one. She holds the conversation with them, hands bots the work that takes time, and tells them what comes back.`,T=`**You are on a real computer — the user's own.** You have a shell and a filesystem, and the job is done, not described: where there is no tool for something, write one — in \`node\` unless they asked for another language, the runtime this app itself runs on. Reach for \`${s.TOOL_NAMES.bash}\` before concluding that something cannot be done, but after the roster, not instead of it: a script you write to do another bot's job is the long way round.
31
37
 
32
38
  **What is missing gets installed**, onto the machine once they say yes. What is already there is nobody's question — Environment says what this machine has.
33
39
 
34
- **Bring back the thing itself** — their own machine, their own accounts, their own copy of whatever they sent you for — not a smaller safer version of it, and not a note on why you did not.`,b="**Never present a guess as a result.** She says it out loud as fact. Say which part is unverified and why.",k=e=>e?.trim()?`## Owner's instructions
40
+ **Bring back the thing itself** — their own machine, their own accounts, their own copy of whatever they sent you for — not a smaller safer version of it, and not a note on why you did not.`,$="**Never present a guess as a result.** She says it out loud as fact. Say which part is unverified and why.",v=e=>e?.trim()?`## Owner's instructions
35
41
 
36
42
  Written by the person this bot works for. Where these and anything above disagree, these win.
37
43
 
38
- ${e.trim()}`:"",T=(e,t,o)=>{var s;let r,i;return`## Environment
44
+ ${e.trim()}`:"",N=(e,t,o)=>{var a;let r,i;return`## Environment
39
45
 
40
46
  Current Cwd: ${e}
41
47
  Platform: ${process.platform}
42
- ${s=t,r=(e,t)=>`${e}: ${t.found.length?t.found.join(", "):"none"}.${t.missing.length?` Not here: ${t.missing.join(", ")}.`:""}`,i=s.managers.found.includes("pnpm")?" Use pnpm, not npm — this workspace is fenced for it (`pnpm-workspace.yaml`, `.npmrc`).":"",[r("Runtimes",s.runtimes),`${r("Package managers",s.managers)}${i}`,null===s.browser?"":s.browser?"Browser: installed.":"Browser: not installed — `playwright-cli install-browser chromium` puts one there."].filter(Boolean).join("\n")}
48
+ ${a=t,r=(e,t)=>`${e}: ${t.found.length?t.found.join(", "):"none"}.${t.missing.length?` Not here: ${t.missing.join(", ")}.`:""}`,i=a.managers.found.includes("pnpm")?" Use pnpm, not npm — this workspace is fenced for it (`pnpm-workspace.yaml`, `.npmrc`).":"",[r("Runtimes",a.runtimes),`${r("Package managers",a.managers)}${i}`,null===a.browser?"":a.browser?"Browser: installed.":"Browser: not installed — `playwright-cli install-browser chromium` puts one there."].filter(Boolean).join("\n")}
43
49
 
44
50
  Read off this machine as the job opened, so it is current: reach for what is here instead of checking for it.
45
51
 
46
- Your workspace — \`${n.TOOL_NAMES.bash}\` runs here. Everything you write goes in one of these, and they are kept apart because what is in them lives for different lengths of time:
52
+ Your workspace — \`${s.TOOL_NAMES.bash}\` runs here. Everything you write goes in one of these, and they are kept apart because what is in them lives for different lengths of time:
47
53
 
48
- - \`${a.PATHS.artifacts}/\` — finished work the user opens, one entry per result. Theirs, and it stays.
49
- - \`${a.PATHS.projects}/\` — code you build, one folder each. It outlives this job, and a project's dependencies install inside it, never at the workspace root.
50
- - \`${o?.scratch??a.PATHS.scratch}/\` — this job's working material, one folder for every bot on the job: what another bot on it wrote is here too. It is cleared ${Math.round(a.WORKSPACE_KEEP.forMs/864e5)} days after the job ends, so nothing here is worth keeping.
51
- - \`${o?.own??a.PATHS.bots}/\` — yours, across every job you run here: your memory, a script you wrote once and will want again, a table you built.
54
+ - \`${n.PATHS.artifacts}/\` — finished work the user opens, one entry per result. Theirs, and it stays.
55
+ - \`${n.PATHS.projects}/\` — code you build, one folder each. It outlives this job, and a project's dependencies install inside it, never at the workspace root.
56
+ - \`${o?.scratch??n.PATHS.scratch}/\` — this job's working material, one folder for every bot on the job: what another bot on it wrote is here too. It is cleared ${Math.round(n.WORKSPACE_KEEP.forMs/864e5)} days after the job ends, so nothing here is worth keeping.
57
+ - \`${o?.own??n.PATHS.bots}/\` — yours, across every job you run here: your memory, a script you wrote once and will want again, a table you built.
52
58
 
53
- Never the directory above — that is the app you run in; outside the workspace, only where the user pointed you.`},$=`## Asking
59
+ Never the directory above — that is the app you run in; outside the workspace, only where the user pointed you.`},O=`## Asking
54
60
 
55
- What you cannot get for yourself — a decision between real options, a detail only the conversation has, a go-ahead before deleting or sending — goes to \`${n.TOOL_NAMES.ask_thursday}\`, once, with everything in it. Ask before you start, not after an hour; never ask what one command would tell you.
61
+ What you cannot get for yourself — a decision between real options, a detail only the conversation has, a go-ahead before deleting or sending — goes to \`${s.TOOL_NAMES.ask_thursday}\`, once, with everything in it. Ask before you start, not after an hour; never ask what one command would tell you.
56
62
 
57
63
  A job that arrives without its shape — several ways to do it, no telling what it is for, a scale nobody named — is planned before it is built: put the plan up in two or three lines with what you need decided. A job asked for as one thing is built, not proposed.
58
64
 
59
- Only what is theirs alone stops the job: a password, a one-time code, a passkey, a permission on their machine. Set it up one action away, ask, and carry on when the answer comes back.`,v=e=>`## Asking
65
+ Only what is theirs alone stops the job: a password, a one-time code, a passkey, a permission on their machine. Set it up one action away, ask, and carry on when the answer comes back.`,S=e=>`## Asking
60
66
 
61
- What you cannot get for yourself goes to \`${n.TOOL_NAMES.ask_back}\`: ${e} handed you this part and answers from what they have. They cannot take a question to the user, so for what is the user's alone take the safer reading and say so in what you hand back. Ask before you start, once, whole.`,N=`## Answering
67
+ What you cannot get for yourself goes to \`${s.TOOL_NAMES.ask_back}\`: ${e} handed you this part and answers from what they have. They cannot take a question to the user, so for what is the user's alone take the safer reading and say so in what you hand back. Ask before you start, once, whole.`,x=`## Answering
62
68
 
63
- Every job ends with \`${n.TOOL_NAMES.answer}\`. **Answer what was asked, at the size it was asked**: a question ends in its answer — one number is one line — and a thing to make comes back made, an action done, photos in a page, a comparison in a table. Once you have what they asked for the job is done; the next thing you would go and check is theirs to ask for.
69
+ Every job ends with \`${s.TOOL_NAMES.answer}\`. **Answer what was asked, at the size it was asked**: a question ends in its answer — one number is one line — and a thing to make comes back made, an action done, photos in a page, a comparison in a table. Once you have what they asked for the job is done; the next thing you would go and check is theirs to ask for.
64
70
 
65
- You are answering Thursday, not the user: she is on the call and picks what to say out of this. Write it plainly, in the user's language — the thread is on their screen as you write it. Anything past a few lines is a file under \`${a.PATHS.artifacts}/\`, and the answer names its path — it becomes a link on their screen. In a \`.md\`, images only by absolute route (\`/api/file/${a.PATHS.artifacts}/…\`).`,O=e=>`## Answering
71
+ You are answering Thursday, not the user: she picks what to say out of this. Write it plainly, in the user's language — the thread is on their screen as you write it. Anything past a few lines is a file under \`${n.PATHS.artifacts}/\`, and the answer names its path — it becomes a link on their screen. In a \`.md\`, images only by absolute route (\`/api/file/${n.PATHS.artifacts}/…\`).`,M=e=>`## Answering
66
72
 
67
- Every part ends with \`${n.TOOL_NAMES.answer}\`; what you hand back goes into ${e}'s own answer. Hand back what the brief asked for, in the shape it asked for, with everything you learned that bears on it — exact values, the paths of files you wrote, what did not work. They cannot see your thread, so long is right here.`;function g(e){let t=e.length-1,o=e.map((o,a)=>{if(0===a)return a===t?`- **${o} (you)** — Thursday handed you this job. You answer to Thursday, and your answer is the only part of it that reaches the user.`:`- **${o}** — holds the job Thursday handed over, and answers for it.`;let n=e[a-1];return a===t?`- **${o} (you)** — ${n} handed you one part of it: the last section below. You answer to ${n}; nobody else hears from you.`:`- **${o}** — ${n} handed them one part of it.`});return`## Who is who on this job
73
+ Every part ends with \`${s.TOOL_NAMES.answer}\`; what you hand back goes into ${e}'s own answer. Hand back what the brief asked for, in the shape it asked for, with everything you learned that bears on it — exact values, the paths of files you wrote, what did not work. They cannot see your thread, so long is right here.`;function b(e,t){let o=e.length-1,a=e.map((a,n)=>{if(0===n)return n===o?`- **${a} (you)** — ${"user"===t?"the user handed you this job on their screen, not during a call":"Thursday handed you this job during a call"}.`:`- **${a}** — holds this job and answers for it.`;let s=e[n-1];return n===o?`- **${a} (you)** — ${s} handed you one part of it: the last section below. You answer to ${s}; nobody else hears from you.`:`- **${a}** — ${s} handed them one part of it.`});return`## Who is on this job
68
74
 
69
- - **The user** — talks only to Thursday, on a voice call. No bot addresses them.
70
- - **Thursday** — the user's assistant on that call. Hands jobs to bots and tells the user what comes back.
71
- ${o.join("\n")}`}e.s(["OPENING_TURNS",0,10,"buildHandoff",0,function(e){let t=e.bots.at(-1)??"",o=e.bots.at(-2)??"",a=e.did?.trim()?`## ${o} → ${t}: what ${o} has done, and why this part is ${t}'s
75
+ ${a.join("\n")}`}e.s(["OPENING_TURNS",0,10,"buildHandoff",0,function(e){let t=e.bots.at(-1)??"",o=e.bots.at(-2)??"",a=e.did?.trim()?`## ${o} → ${t}: what ${o} has done, and why this part is ${t}'s
72
76
 
73
77
  ${e.did.trim()}`:"",n=`## ${o} → ${t}: the part
74
78
 
75
- ${e.part.trim()}`;return[{type:"text",text:g(e.bots)},{type:"text",text:[e.chain,a,n].filter(Boolean).join("\n\n")}]},"buildTaskOpening",0,function(e){let t=e.conversation.filter(e=>e.text.trim()),o=`## Thursday → ${e.bot}: the job
79
+ ${e.part.trim()}`;return[{type:"text",text:b(e.bots)},{type:"text",text:[e.chain,a,n].filter(Boolean).join("\n\n")}]},"buildTaskOpening",0,function(e){let t=e.conversation.filter(e=>e.text.trim()),o="user"===e.from?"The user":"Thursday",a=`## ${o} → ${e.bot}: the job
76
80
 
77
- ${e.request.trim()}`,n=t.length?`## The call the job came from — its last ${t.length} turns, verbatim
81
+ ${e.request.trim()}`,s=t.length?`## The call the job came from — its last ${t.length} turns, verbatim
78
82
 
79
83
  A detail missing from the job may be here — a name, a number, which of two. Where the two disagree the job wins, unless they asked out loud for something to be done and the job only asks about it: then the doing is the job.
80
84
 
81
- ${t.map(e=>`${"user"===e.role?"user":"thursday"}: ${(0,c.clip)(e.text,a.PROMPT_LINE.callTurn)}`).join("\n")}`:"";return[{type:"text",text:g([e.bot])},{type:"text",text:[o,n].filter(Boolean).join("\n\n")}]},"chainOf",0,function(e){return e?.role!=="user"?"":"string"==typeof e.content?e.content:e.content.flatMap(e=>"text"===e.type?[e.text]:[]).at(-1)??""},"loadBotPrompt",0,m]),o()}catch(e){o(e)}},!1),585099,e=>e.a(async(t,o)=>{try{var a=e.i(68356),n=e.i(847841),s=e.i(687388),r=e.i(159479),i=e.i(386075),l=e.i(851372),h=e.i(316172),u=e.i(353885),d=e.i(944971),c=e.i(786025),p=e.i(640911),w=e.i(53748),y=e.i(388439),m=e.i(265143),g=e.i(780274),f=t([r,i,l,m,g]);[r,i,l,m,g]=f.then?(await f)():f;let O=s.BOT_RUN.steps;async function b(e,t){var o,w,f;let b,$,A,E,M,_,j,I,B=t.depth??0,C=t.parent??null,P=e.bot.trim(),L=e=>t.emit({...e,bot:P,parent:C}),W=await (0,m.findJobBot)(P);if(!W)return void await L({type:"error",message:`No bot named "${e.bot}". Use a name from the list.`,failure:"fatal"});if(W.disabled&&"request"in e)return void await L({type:"error",message:`${W.name} is switched off. Use a name from the list.`,failure:"fatal"});let q=await ((o=W).provider&&o.model?(0,i.getTextModel)({provider:o.provider,model:o.model}):(0,i.resolveDefaultModel)().then(i.getTextModel)),R=t.taskId?await (0,g.findTask)(t.taskId):null,[U,H]=await Promise.all([t.taskId?(0,c.openJobScratch)(t.taskId,R?.label??"job"):null,(0,c.openBotFolder)(P)]),[Y,F]=await Promise.all([(0,l.loadBotPrompt)(P,W.systemPrompt,"askedBy"in e?{askedBy:e.askedBy,above:e.above,canBorrow:B<s.BOT_RUN.depth}:null,{scratch:U,own:H}),(0,r.loadTools)({target:"bot",bot:P,session:t.session??t.taskId,model:q})]),D=Math.min(await (0,i.compactBudget)(q.ref,W.compactAt),("askedBy"in e?0:R?.contextBudget)||1/0),J="messages"in e?e.messages:[{role:"user",content:(0,l.buildHandoff)({chain:e.chain,bots:[...e.above,P],did:e.context??null,part:e.request})}],G={left:s.BOT_RUN.askBack},K="askedBy"in e?function(e,t,o){let a={...e};delete a[u.TOOL_NAMES.ask_thursday];let{answer:s}=o;return s?{...a,[u.TOOL_NAMES.ask_back]:(0,n.tool)({description:h.askBackSpec.description,inputSchema:h.askBackSpec.parameters,execute:async({question:e})=>(t.left-=1,s(e))})}:a}(F,G,t):F,z=B<s.BOT_RUN.depth?function(e,t){if(0===t.peers.length)return e;let o={...e,[u.TOOL_NAMES.ask_bot]:(0,n.tool)({description:h.askBotSpec.description,inputSchema:h.askBotSpec.parameters,execute:async({bot:e,request:a,context:n},s)=>{if(e===t.name||t.above.includes(e))return`${e} is already on this job, above you and waiting on your part. Pick another bot, or do it yourself.`;let r=t.options.taskId?`${t.options.session??t.options.taskId}-${s.toolCallId.slice(0,8)}`:null,i=[],l=async n=>{let r=await N({model:t.model,instructions:t.instructions,tools:o,messages:s.messages,asked:{bot:e,request:a},question:n,signal:t.options.signal});return await t.emit({type:"answered",question:n,...r}),i.push({question:n,answer:r.text}),r.text};try{var h;let o=await v({bot:e,request:a,context:n,askedBy:t.name,chain:t.chain,above:[...t.above,t.name]},{...t.options,signal:s.abortSignal??t.options.signal,depth:t.depth+1,parent:s.toolCallId,session:r,answer:l});return i.length?`${o}
85
+ ${t.map(e=>`${"user"===e.role?"user":"thursday"}: ${(0,w.clip)(e.text,n.PROMPT_LINE.callTurn)}`).join("\n")}`:"";return[{type:"text",text:b([e.bot],e.from)},{type:"text",text:[a,s].filter(Boolean).join("\n\n")}]},"chainOf",0,function(e){return e?.role!=="user"?"":"string"==typeof e.content?e.content:e.content.flatMap(e=>"text"===e.type?[e.text]:[]).at(-1)??""},"loadBotPrompt",0,g]),o()}catch(e){o(e)}},!1),585099,e=>e.a(async(t,o)=>{try{var a=e.i(68356),n=e.i(847841),s=e.i(687388),r=e.i(159479),i=e.i(386075),l=e.i(851372),u=e.i(316172),h=e.i(353885),d=e.i(944971),c=e.i(786025),p=e.i(640911),w=e.i(53748),y=e.i(388439),m=e.i(265143),f=e.i(780274),g=t([r,i,l,m,f]);[r,i,l,m,f]=g.then?(await g)():g;let O=s.BOT_RUN.steps;async function b(e,t){var o,w,g;let b,$,M,A,E,_,j,I,C=t.depth??0,B=t.parent??null,P=e.bot.trim(),L=e=>t.emit({...e,bot:P,parent:B}),W=await (0,m.findJobBot)(P);if(!W)return void await L({type:"error",message:`No bot named "${e.bot}". Use a name from the list.`,failure:"fatal"});if(W.disabled&&"request"in e)return void await L({type:"error",message:`${W.name} is switched off. Use a name from the list.`,failure:"fatal"});let q=await ((o=W).provider&&o.model?(0,i.getTextModel)({provider:o.provider,model:o.model}):(0,i.resolveDefaultModel)().then(i.getTextModel)),R=t.taskId?await (0,f.findTask)(t.taskId):null,[U,Y]=await Promise.all([t.taskId?(0,c.openJobScratch)(t.taskId,R?.label??"job"):null,(0,c.openBotFolder)(P)]),[H,F]=await Promise.all([(0,l.loadBotPrompt)(P,W.systemPrompt,"askedBy"in e?{askedBy:e.askedBy,above:e.above,canBorrow:C<s.BOT_RUN.depth}:null,{scratch:U,own:Y}),(0,r.loadTools)({target:"bot",bot:P,session:t.session??t.taskId,model:q})]),D=Math.min(await (0,i.compactBudget)(q.ref,W.compactAt),("askedBy"in e?0:R?.contextBudget)||1/0),J="messages"in e?e.messages:[{role:"user",content:(0,l.buildHandoff)({chain:e.chain,bots:[...e.above,P],did:e.context??null,part:e.request})}],G={left:s.BOT_RUN.askBack},K="askedBy"in e?function(e,t,o){let a={...e};delete a[h.TOOL_NAMES.ask_thursday];let{answer:s}=o;return s?{...a,[h.TOOL_NAMES.ask_back]:(0,n.tool)({description:u.askBackSpec.description,inputSchema:u.askBackSpec.parameters,execute:async({question:e})=>(t.left-=1,s(e))})}:a}(F,G,t):F,z=C<s.BOT_RUN.depth?function(e,t){if(0===t.peers.length)return e;let o={...e,[h.TOOL_NAMES.ask_bot]:(0,n.tool)({description:u.askBotSpec.description,inputSchema:u.askBotSpec.parameters,execute:async({bot:e,request:a,context:n},s)=>{if(e===t.name||t.above.includes(e))return`${e} is already on this job, above you and waiting on your part. Pick another bot, or do it yourself.`;let r=t.options.taskId?`${t.options.session??t.options.taskId}-${s.toolCallId.slice(0,8)}`:null,i=[],l=async n=>{let r=await N({model:t.model,instructions:t.instructions,tools:o,messages:s.messages,asked:{bot:e,request:a},question:n,signal:t.options.signal});return await t.emit({type:"answered",question:n,...r}),i.push({question:n,answer:r.text}),r.text};try{var u;let o=await v({bot:e,request:a,context:n,askedBy:t.name,chain:t.chain,above:[...t.above,t.name]},{...t.options,signal:s.abortSignal??t.options.signal,depth:t.depth+1,parent:s.toolCallId,session:r,answer:l});return i.length?`${o}
82
86
 
83
- ${h=e,i.map(({question:e,answer:t})=>`(On the way ${h} asked you: "${e}" — you answered: "${t}")`).join("\n")}`:o}finally{r&&(0,c.closeHiddenBrowser)(r)}}})};return o}(K,{name:P,model:q.model,instructions:Y.text,peers:Y.peers,depth:B,chain:(0,l.chainOf)(J[0]),above:"askedBy"in e?e.above:[],options:t,emit:L}):K,Q={compact:null,interjections:[]},V=(w=s.BOT_RUN.silenceMs,$=new AbortController,A=0,E=!1,M=()=>{clearTimeout(b),b=void 0,E||A>0||(b=setTimeout(()=>{$.abort(new DOMException(`The model sent nothing for ${Math.round(w/6e4)} minutes.`,"TimeoutError"))},w))},{signal:$.signal,touch:M,hold:()=>{A+=1,M()},release:()=>{A=Math.max(0,A-1),M()},end:()=>{E=!0,M()}}),X=0,Z=new a.ToolLoopAgent({model:q.model,instructions:Y.text,tools:z,stopWhen:[(0,a.stepCountIs)(O),S,(0,a.hasToolCall)(u.TOOL_NAMES.ask_thursday)],prepareStep:async({stepNumber:e,steps:o,messages:a})=>{let n=e<O-1?{}:{activeTools:[u.TOOL_NAMES.answer],toolChoice:{type:"tool",toolName:u.TOOL_NAMES.answer}};!n.activeTools&&G.left<=0&&(n={...n,activeTools:Object.keys(z).filter(e=>e!==u.TOOL_NAMES.ask_back)});let s=o.at(-1)?.usage.inputTokens??0,r=Math.max(s,a.reduce((e,t)=>e+(0,y.estimateTokens)("string"==typeof t.content?t.content:JSON.stringify(t.content))+4,0));X=r;let i=a;if(r>D&&a.length>2){V.hold();let e=await T(q.model,z,a,{signal:t.signal,budget:D}).finally(V.release);p.logger.debug(`compacted ${a.length} messages at ${r} tokens (budget ${D})`);let o=`${e.text}${await k(R?.id??null,a,U)}`;Q.compact={type:"compact",text:o,usage:e.usage,messages:a.length,tokens:r},i=[a[0],{role:"user",content:o}]}let l=e>0?t.notes?.()??[]:[];return(l.length&&(Q.interjections.push(...l),i=[...i,...l.map(e=>({role:"user",content:e}))]),i===a)?n:{...n,messages:i}}}),ee=(_=[],j=[],I=!1,{push(e){let t=j.shift();t?t(e):_.push(e)},take(){let e=_.shift();return e?Promise.resolve(e):I?Promise.resolve(null):new Promise(e=>j.push(e))},end(){for(let e of(I=!0,j.splice(0)))e(null)}}),et=t.signal?AbortSignal.any([t.signal,V.signal]):V.signal;V.touch();let eo=await Z.stream({messages:J,abortSignal:et,onStepEnd:e=>ee.push({messages:e.response.messages,usage:x(e.usage)})}),ea="",en=null,es=null,er=null,ei=-1,el=null,eh=new Set,eu=e=>{let t=(0,i.modelFailureOf)(e),o=(0,i.modelErrorToString)(e);if("overflow"!==t)return{type:"error",message:o,failure:t};let a=Math.floor(Math.min(D,X||D)*s.BOT_RUN.overflowShrink);return{type:"error",message:o,failure:t,budget:Math.max(d.COMPACT_AT_MIN,a)}};et.addEventListener("abort",()=>ee.end(),{once:!0});try{for await(let e of eo.fullStream)switch(V.touch(),e.type){case"start-step":for(let e of(ei+=1,Q.compact&&(await L(Q.compact),Q.compact=null),Q.interjections.splice(0)))await L({type:"interjection",text:e});break;case"text-delta":ea+=e.text;break;case"text-end":{let e=ea.trim();if(ea="",!e)break;en=e,await L({type:"text",text:e});break}case"tool-call":if(e.toolName===u.TOOL_NAMES.ask_thursday){let t=e.input;es={id:e.toolCallId,question:String(t.question??""),options:(0,g.optionsOf)(t.options)}}else if(e.toolName===u.TOOL_NAMES.answer){let t=e.input;er={text:String(t.result??"").trim(),stopped:ei>=O-1}}e.providerExecuted||e.toolName===u.TOOL_NAMES.ask_thursday||(eh.add(e.toolCallId),V.hold()),await L({type:"tool",id:e.toolCallId,name:e.toolName,input:e.input});break;case"tool-result":eh.delete(e.toolCallId)&&V.release(),e.toolName===u.TOOL_NAMES.answer&&er&&!(0,h.answerAccepted)(e.output)&&(er={text:`${er.text}
87
+ ${u=e,i.map(({question:e,answer:t})=>`(On the way ${u} asked you: "${e}" — you answered: "${t}")`).join("\n")}`:o}finally{r&&(0,c.closeHiddenBrowser)(r)}}})};return o}(K,{name:P,model:q.model,instructions:H.text,peers:H.peers,depth:C,chain:(0,l.chainOf)(J[0]),above:"askedBy"in e?e.above:[],options:t,emit:L}):K,Q={compact:null,interjections:[]},V=(w=s.BOT_RUN.silenceMs,$=new AbortController,M=0,A=!1,E=()=>{clearTimeout(b),b=void 0,A||M>0||(b=setTimeout(()=>{$.abort(new DOMException(`The model sent nothing for ${Math.round(w/6e4)} minutes.`,"TimeoutError"))},w))},{signal:$.signal,touch:E,hold:()=>{M+=1,E()},release:()=>{M=Math.max(0,M-1),E()},end:()=>{A=!0,E()}}),X=0,Z=new a.ToolLoopAgent({model:q.model,instructions:H.text,tools:z,stopWhen:[(0,a.stepCountIs)(O),S,(0,a.hasToolCall)(h.TOOL_NAMES.ask_thursday)],prepareStep:async({stepNumber:e,steps:o,messages:a})=>{let n=e<O-1?{}:{activeTools:[h.TOOL_NAMES.answer],toolChoice:{type:"tool",toolName:h.TOOL_NAMES.answer}};!n.activeTools&&G.left<=0&&(n={...n,activeTools:Object.keys(z).filter(e=>e!==h.TOOL_NAMES.ask_back)});let s=o.at(-1)?.usage.inputTokens??0,r=Math.max(s,a.reduce((e,t)=>e+(0,y.estimateTokens)("string"==typeof t.content?t.content:JSON.stringify(t.content))+4,0));X=r;let i=a;if(r>D&&a.length>2){V.hold();let e=await T(q.model,z,a,{signal:t.signal,budget:D,instructions:H.text}).finally(V.release);p.logger.debug(`compacted ${a.length} messages at ${r} tokens (budget ${D})`);let o=`${e.text}${await k(R?.id??null,a,U)}`;Q.compact={type:"compact",text:o,usage:e.usage,messages:a.length,tokens:r},i=[a[0],{role:"user",content:o}]}let l=e>0?t.notes?.()??[]:[];return(l.length&&(Q.interjections.push(...l),i=[...i,...l.map(e=>({role:"user",content:e}))]),i===a)?n:{...n,messages:i}}}),ee=(_=[],j=[],I=!1,{push(e){let t=j.shift();t?t(e):_.push(e)},take(){let e=_.shift();return e?Promise.resolve(e):I?Promise.resolve(null):new Promise(e=>j.push(e))},end(){for(let e of(I=!0,j.splice(0)))e(null)}}),et=t.signal?AbortSignal.any([t.signal,V.signal]):V.signal;V.touch();let eo=await Z.stream({messages:J,abortSignal:et,onStepEnd:e=>ee.push({messages:e.response.messages,usage:x(e.usage)})}),ea="",en=null,es=null,er=null,ei=-1,el=null,eu=new Set,eh=e=>{let t=(0,i.modelFailureOf)(e),o=(0,i.modelErrorToString)(e);if("overflow"!==t)return{type:"error",message:o,failure:t};let a=Math.floor(Math.min(D,X||D)*s.BOT_RUN.overflowShrink);return{type:"error",message:o,failure:t,budget:Math.max(d.COMPACT_AT_MIN,a)}};et.addEventListener("abort",()=>ee.end(),{once:!0});try{for await(let e of eo.fullStream)switch(V.touch(),e.type){case"start-step":for(let e of(ei+=1,Q.compact&&(await L(Q.compact),Q.compact=null),Q.interjections.splice(0)))await L({type:"interjection",text:e});break;case"text-delta":ea+=e.text;break;case"text-end":{let e=ea.trim();if(ea="",!e)break;en=e,await L({type:"text",text:e});break}case"tool-call":if(e.toolName===h.TOOL_NAMES.ask_thursday){let t=e.input;es={id:e.toolCallId,question:String(t.question??""),options:(0,f.optionsOf)(t.options)}}else if(e.toolName===h.TOOL_NAMES.answer){let t=e.input;er={text:String(t.result??"").trim(),stopped:ei>=O-1}}e.providerExecuted||e.toolName===h.TOOL_NAMES.ask_thursday||(eu.add(e.toolCallId),V.hold()),await L({type:"tool",id:e.toolCallId,name:e.toolName,input:e.input});break;case"tool-result":eu.delete(e.toolCallId)&&V.release(),e.toolName===h.TOOL_NAMES.answer&&er&&!(0,u.answerAccepted)(e.output)&&(er={text:`${er.text}
84
88
 
85
- ${f=e.output,"string"==typeof f?f:f&&"object"==typeof f&&"value"in f?"string"==typeof f.value?f.value:JSON.stringify(f.value??""):JSON.stringify(f??"")}`,stopped:!0}),await L({type:"tool-result",id:e.toolCallId,name:e.toolName,output:e.output});break;case"tool-error":eh.delete(e.toolCallId)&&V.release(),await L({type:"tool-result",id:e.toolCallId,name:e.toolName,output:(0,i.modelErrorToString)(e.error),error:!0});break;case"finish-step":{el=e.finishReason;let t=await ee.take();t&&await L({type:"step",...t,budget:D});break}case"abort":if(t.signal?.aborted)return;await L({type:"error",message:e.reason??"The model stopped sending.",failure:"transient"});return;case"error":await L(eu(e.error));return}}finally{ee.end(),V.end()}try{await eo.response}catch(e){if(t.signal?.aborted)return;await L(eu(e));return}es?await L({type:"waiting",...es}):er?await L({type:"answer",...er}):"content-filter"===el?await L({type:"error",message:"The provider's content filter stopped the response.",failure:"fatal"}):await L({type:"answer",text:en??"Stopped without handing anything back.",stopped:null===en||"length"===el||ei>=O-1})}let S=({steps:e})=>e.at(-1)?.toolResults.some(e=>e.toolName===u.TOOL_NAMES.answer&&(0,h.answerAccepted)(e.output))??!1;async function k(e,t,o){try{let a=e?await (0,g.listWrittenPaths)(e):(0,g.writtenPathsIn)(t.map(e=>e.content)),n=await (0,c.filesOnDisk)(a,o);if(!n.length)return"";let r=n.slice(-s.BOT_RUN.compactFiles),i=n.length-r.length,l=r.map(e=>`- ${e}`);return i&&l.unshift(`- …and ${i} older ones`),`
89
+ ${g=e.output,"string"==typeof g?g:g&&"object"==typeof g&&"value"in g?"string"==typeof g.value?g.value:JSON.stringify(g.value??""):JSON.stringify(g??"")}`,stopped:!0}),await L({type:"tool-result",id:e.toolCallId,name:e.toolName,output:e.output});break;case"tool-error":eu.delete(e.toolCallId)&&V.release(),await L({type:"tool-result",id:e.toolCallId,name:e.toolName,output:(0,i.modelErrorToString)(e.error),error:!0});break;case"finish-step":{el=e.finishReason;let t=await ee.take();t&&await L({type:"step",...t,budget:D});break}case"abort":if(t.signal?.aborted)return;await L({type:"error",message:e.reason??"The model stopped sending.",failure:"transient"});return;case"error":await L(eh(e.error));return}}finally{ee.end(),V.end()}try{await eo.response}catch(e){if(t.signal?.aborted)return;await L(eh(e));return}es?await L({type:"waiting",...es}):er?await L({type:"answer",...er}):"content-filter"===el?await L({type:"error",message:"The provider's content filter stopped the response.",failure:"fatal"}):await L({type:"answer",text:en??"Stopped without handing anything back.",stopped:null===en||"length"===el||ei>=O-1})}let S=({steps:e})=>e.at(-1)?.toolResults.some(e=>e.toolName===h.TOOL_NAMES.answer&&(0,u.answerAccepted)(e.output))??!1;async function k(e,t,o){try{let a=e?await (0,f.listWrittenPaths)(e):(0,f.writtenPathsIn)(t.map(e=>e.content)),n=await (0,c.filesOnDisk)(a,o);if(!n.length)return"";let r=n.slice(-s.BOT_RUN.compactFiles),i=n.length-r.length,l=r.map(e=>`- ${e}`);return i&&l.unshift(`- …and ${i} older ones`),`
86
90
 
87
91
  Files this job has on disk now — open one rather than fetching again what is in it:
88
- ${l.join("\n")}`}catch(e){return p.logger.warn("files under the summary could not be listed",e),""}}async function T(e,t,o,n){let s;try{return await $(e,t,o,n)}catch(e){if(n.signal?.aborted)throw e;s=e}if("overflow"===(0,i.modelFailureOf)(s)){let r=(0,a.pruneMessages)({messages:o,toolCalls:"before-last-4-messages",emptyMessages:"remove"});try{return await $(e,t,r,n)}catch(e){if(n.signal?.aborted)throw e;s=e}}throw Error(`Could not compact the context (${(0,i.modelErrorToString)(s)}).`,{cause:s})}async function $(e,t,o,n){let r,{text:i,usage:l}=await (0,a.generateText)({model:e,tools:t,toolChoice:"none",messages:[...o,{role:"user",content:(r=(e=>{let{min:t,max:o,perTokens:a}=s.BOT_RUN.summaryWords;return Math.min(o,Math.max(t,Math.round(e/a)))})(n.budget),`Compact your context. The first message above — the job, the call it came from, and anything handed over with it — stays exactly as it is. Everything after it is replaced by what you write now, and you carry on from that first message and this alone; nothing else above can be read again. Write it for a fresh copy of you that has your tools, your instructions and that first message, but has seen none of the rest.
92
+ ${l.join("\n")}`}catch(e){return p.logger.warn("files under the summary could not be listed",e),""}}async function T(e,t,o,n){let s;try{return await $(e,t,o,n)}catch(e){if(n.signal?.aborted)throw e;s=e}if("overflow"===(0,i.modelFailureOf)(s)){let r=(0,a.pruneMessages)({messages:o,toolCalls:"before-last-4-messages",emptyMessages:"remove"});try{return await $(e,t,r,n)}catch(e){if(n.signal?.aborted)throw e;s=e}}throw Error(`Could not compact the context (${(0,i.modelErrorToString)(s)}).`,{cause:s})}async function $(e,t,o,n){let r,{text:i,usage:l}=await (0,a.generateText)({model:e,system:n.instructions,tools:t,toolChoice:"none",messages:[...o,{role:"user",content:(r=(e=>{let{min:t,max:o,perTokens:a}=s.BOT_RUN.summaryWords;return Math.min(o,Math.max(t,Math.round(e/a)))})(n.budget),`Compact your context. The first message above — the job, the call it came from, and anything handed over with it — stays exactly as it is. Everything after it is replaced by what you write now, and you carry on from that first message and this alone; nothing else above can be read again. Write it for a fresh copy of you that has your tools, your instructions and that first message, but has seen none of the rest.
89
93
 
90
94
  Cover all of it, and prefer a fact over a description of a fact:
91
95
 
@@ -96,9 +100,9 @@ Cover all of it, and prefer a fact over a description of a fact:
96
100
  - **What did not work**, and why: the url that 404s, the endpoint that needs POST not GET, the selector that is not there, the site that refuses a headless browser, the argument a tool rejected. This is the part that stops the next steps repeating an hour of yours.
97
101
  - **What is left**, in the order you would do it.
98
102
 
99
- Plain text, under ${r} words. No preamble, no headings about the summary itself, no account of how you have been going.`)}],abortSignal:n.signal,timeout:s.BOT_RUN.silenceMs}),h=i.trim();if(!h)throw Object.assign(Error("The summary of the context came back empty, so there is nothing to carry on from."),{isRetryable:!0});return{text:`Everything between the first message and here was compacted. Below is your own summary of it; carry on from the first message and this.
103
+ Plain text, under ${r} words. No preamble, no headings about the summary itself, no account of how you have been going.`)}],abortSignal:n.signal,timeout:s.BOT_RUN.silenceMs}),u=i.trim();if(!u)throw Object.assign(Error("The summary of the context came back empty, so there is nothing to carry on from."),{isRetryable:!0});return{text:`Everything between the first message and here was compacted. Below is your own summary of it; carry on from the first message and this.
100
104
 
101
- ${h}`,usage:x(l)}}let x=e=>({input:e.inputTokens??0,output:e.outputTokens??0});async function v(e,t){let o="",a=null;return await b(e,{...t,emit:async e=>{"answer"===e.type&&(o=e.stopped?`${e.text}
105
+ ${u}`,usage:x(l)}}let x=e=>({input:e.inputTokens??0,output:e.outputTokens??0});async function v(e,t){let o="",a=null;return await b(e,{...t,emit:async e=>{"answer"===e.type&&(o=e.stopped?`${e.text}
102
106
 
103
107
  (As far as they got — they stopped before finishing.)`:e.text),"error"===e.type&&(a=e.message),await t.emit(e)}}),a&&(0,w.publicError)(a),o}async function N(e){try{let t,o,{text:n,usage:r}=await (0,a.generateText)({model:e.model,system:e.instructions,tools:e.tools,toolChoice:"none",messages:[...e.messages,{role:"user",content:(t=e.asked,o=e.question,`You handed one part of your job to ${t.bot}:
104
108
 
@@ -108,13 +112,13 @@ Before going on, they ask you:
108
112
 
109
113
  > ${o.trim()}
110
114
 
111
- Answer from what you already have — the request as it reached you, the call it came out of, what you found before asking them. A few lines, plain text, and nothing else: no tools run here. If it is not in what you have, say so rather than guess, and say which way to go without it.`)}],abortSignal:e.signal,timeout:s.BOT_RUN.silenceMs});return{text:n.trim()||"They had nothing to add. Go on with your best reading, and say what you assumed in what you hand back.",usage:x(r)}}catch(t){if(e.signal?.aborted)throw t;return p.logger.warn(`ask_back: ${(0,i.modelErrorToString)(t)}`),{text:`No answer came back (${(0,i.modelErrorToString)(t)}). Go on with your best reading, and say what you assumed in what you hand back.`,usage:d.NO_TOKENS}}}e.s(["resumeThread",0,function(e,t=new Map){let o=new Set;for(let t of e)if(("tool"===t.role||"assistant"===t.role)&&"string"!=typeof t.content)for(let e of t.content)"tool-result"===e.type&&o.add(e.toolCallId);let a=[],n=[];for(let s of e){if(n.length&&"tool"===s.role){a.push({...s,content:[...n,...s.content]}),n=[];continue}n.length&&(a.push({role:"tool",content:n}),n=[]),a.push(s),"assistant"===s.role&&"string"!=typeof s.content&&(n=s.content.flatMap(e=>"tool-call"!==e.type||o.has(e.toolCallId)?[]:[{type:"tool-result",toolCallId:e.toolCallId,toolName:e.toolName,output:{type:"text",value:function(e,t){let o=e.toolName===u.TOOL_NAMES.ask_bot?t.get(e.toolCallId):void 0;return o?`No result: the run was stopped before ${o.bot} answered, and they are not working on it any more. What they had written by then:
115
+ Answer from what you already have — the request as it reached you, the call it came out of, what you found before asking them. A few lines, plain text, and nothing else: no tools run here. If it is not in what you have, say so rather than guess, and say which way to go without it.`)}],abortSignal:e.signal,timeout:s.BOT_RUN.silenceMs});return{text:n.trim()||"They had nothing to add. Go on with your best reading, and say what you assumed in what you hand back.",usage:x(r)}}catch(t){if(e.signal?.aborted)throw t;return p.logger.warn(`ask_back: ${(0,i.modelErrorToString)(t)}`),{text:`No answer came back (${(0,i.modelErrorToString)(t)}). Go on with your best reading, and say what you assumed in what you hand back.`,usage:d.NO_TOKENS}}}e.s(["resumeThread",0,function(e,t=new Map){let o=new Set;for(let t of e)if(("tool"===t.role||"assistant"===t.role)&&"string"!=typeof t.content)for(let e of t.content)"tool-result"===e.type&&o.add(e.toolCallId);let a=[],n=[];for(let s of e){if(n.length&&"tool"===s.role){a.push({...s,content:[...n,...s.content]}),n=[];continue}n.length&&(a.push({role:"tool",content:n}),n=[]),a.push(s),"assistant"===s.role&&"string"!=typeof s.content&&(n=s.content.flatMap(e=>"tool-call"!==e.type||o.has(e.toolCallId)?[]:[{type:"tool-result",toolCallId:e.toolCallId,toolName:e.toolName,output:{type:"text",value:function(e,t){let o=e.toolName===h.TOOL_NAMES.ask_bot?t.get(e.toolCallId):void 0;return o?`No result: the run was stopped before ${o.bot} answered, and they are not working on it any more. What they had written by then:
112
116
 
113
117
  ${o.tail}
114
118
 
115
- Check what they did before relying on it, then finish the part yourself or hand them what is left.`:"No result: the run was stopped before this call returned. Check what it did before relying on it."}(e,t)}}]))}return n.length&&a.push({role:"tool",content:n}),a},"runBot",0,b]),o()}catch(e){o(e)}},!1),39803,e=>e.a(async(t,o)=>{try{var a=e.i(380690),n=e.i(687388),s=e.i(386075),r=e.i(851372),i=e.i(353885),l=e.i(22676),h=e.i(629668),u=e.i(786025),d=e.i(167004),c=e.i(640911),p=e.i(53748),w=e.i(268486),y=e.i(585099),m=e.i(944971),g=e.i(780274),f=t([s,r,l,y,g]);[s,r,l,y,g]=f.then?(await f)():f;let _=globalThis.__botRuns??=new Map,j=globalThis.__botTaskLock??=(0,w.createKeyedLock)(),I=globalThis.__botResumes??=new Map;async function b(e){let t=e.callId?await (0,l.listCallTurns)(e.callId,r.OPENING_TURNS):[],o=(0,r.buildTaskOpening)({bot:e.bot,request:e.request,conversation:t}),a=await (0,g.insertTask)({...e,opening:o});return x(a.id,{bot:e.bot,messages:[{role:"user",content:o}]}),a.id}async function k(e,t){return j(e,async()=>{let o=await (0,g.findTask)(e);o||(0,p.publicError)("No such job.");let a=_.get(e);if(a&&"running"===o.status&&a.note(t))return void c.logger.debug(`task ${e}: interjection queued`);a&&(a.stop.abort(),await a.done),$(e);let n=await (0,g.listThread)(e),{reply:s,as:r}=function(e,t,o){var a;let n,s,r="waiting"===e.status?e.pending:null,l=r?.toolCallId?(a=r.toolCallId,n=new Set(o.flatMap(e=>"tool"===e.role?e.content.flatMap(e=>"tool-result"===e.type?[e.toolCallId]:[]):[])),s=o.findLast(e=>"assistant"===e.role&&"string"!=typeof e.content&&e.content.some(e=>"tool-call"===e.type&&e.toolCallId===a)),(s?.role==="assistant"&&"string"!=typeof s.content?s.content.flatMap(e=>"tool-call"===e.type&&e.toolName===i.TOOL_NAMES.ask_thursday?[e.toolCallId]:[]):[a]).filter(e=>!n.has(e))):[];return l.length?{as:"answer",reply:{role:"tool",content:l.map(e=>({type:"tool-result",toolCallId:e,toolName:i.TOOL_NAMES.ask_thursday,output:{type:"text",value:t}}))}}:{as:"running"===e.status?"interruption":"waiting"===e.status?"answer":"follow-up",reply:{role:"user",content:t}}}(o,t,n);c.logger.debug(`task ${e}: ${r}`),await (0,g.upsertMessage)(e,await (0,g.lastSeq)(e)+1,{bot:null,parent:null,...s}),await (0,g.updateTask)(e,{status:"running",outcome:null,pending:null,seen:!1,endedAt:null}),x(e,{bot:o.bot,messages:(0,y.resumeThread)([...n,s],await (0,g.listBorrowedTails)(e))})})}async function T(e){return j(e,async()=>{let t=await (0,g.findTask)(e);t||(0,p.publicError)("No such job."),t.endedAt&&(0,p.publicError)("That job has already ended."),$(e),_.get(e)?.stop.abort(),await (0,g.updateTask)(e,{status:"failed",outcome:"Cancelled.",pending:null,seen:!0,endedAt:new Date}),(0,u.closeJobShell)(e)})}function $(e){clearTimeout(I.get(e)),I.delete(e)}async function v(e){a.presence.watching&&await j(e,async()=>{let t=await (0,g.findTask)(e);if(!t||"waiting"!==t.status||!t.pending?.auto||_.has(e))return;c.logger.debug(`task ${e}: picking back up`);let o=await (0,g.listThread)(e);await (0,g.updateTask)(e,{status:"running",outcome:null,pending:null,seen:!1,endedAt:null}),x(e,{bot:t.bot,messages:(0,y.resumeThread)(o,await (0,g.listBorrowedTails)(e))})})}async function N(e,t){let o=await (0,g.countStopsSinceSpoken)(e),a=o<n.BOT_RUN.autoResumes,s=n.BOT_RUN.retryAfterMs,r=a&&t.retry?s[Math.min(o,s.length-1)]:0;await O(e,`${t.why} ${B}`).catch(t=>c.logger.warn(`task ${e}: stop not written`,t)),await S(e,{status:"waiting",outcome:a?`${t.why} ${r?`It tries again in ${C(r)}.`:"It picks back up by itself."}`:`${t.why} It has stopped ${o+1} times in a row, so it waits for you. Everything it had done is still here.`,pending:{toolCallId:null,options:[m.TASK_CONTINUE],...a?{auto:!0,retryAt:Date.now()+r}:{}},...t.budget?{contextBudget:t.budget}:{},seen:!1,endedAt:null}),a&&($(e),I.set(e,setTimeout(()=>{I.delete(e),v(e).catch(t=>c.logger.error(`task ${e}: resume`,t))},Math.max(0,r))))}globalThis.__botPausing??={current:Promise.resolve()};let B="Anything that was under way — a command, a page loading, a download — may not have finished: check before relying on it, then carry on.",C=e=>e<6e4?`${Math.round(e/1e3)} seconds`:`${Math.round(e/6e4)} minutes`;async function O(e,t){await (0,g.upsertMessage)(e,await (0,g.lastSeq)(e)+1,{bot:null,parent:null,role:"user",content:t,note:!0})}async function S(e,t){for(let o of[1e3,3e3,null])try{await (0,g.updateTask)(e,t);return}catch(t){if(null===o)throw t;c.logger.warn(`task ${e}: ending not written, trying again`,t),await new Promise(e=>setTimeout(e,o))}}function x(e,t){let o=new AbortController,a=()=>{},n=new Promise(e=>{a=e}),s=[];_.set(e,{stop:o,done:n,note:t=>!!_.has(e)&&(s.push(t),!0)}),A(e,t,o.signal,s).catch(t=>{c.logger.error(`task ${e}`,t)}).finally(a)}class P{taskId;seq;steps;closed;constructor(e,t){this.taskId=e,this.steps=new Map,this.closed=!1,this.seq=t}close(){this.closed=!0}async note(e){await (0,g.upsertMessage)(this.taskId,++this.seq,{bot:null,parent:null,role:"user",content:e,note:!0})}step(e){let t=`${e.bot} ${e.parent??""}`,o=this.steps.get(t);return o||(o={assistant:null,tool:null,parts:{assistant:[],tool:[]}},this.steps.set(t,o)),o}write(e,t,o,a={}){let n={bot:t.bot,parent:t.parent,role:o.role,content:o.content,compact:a.compact??!1,note:a.note??!1};return(0,g.upsertMessage)(this.taskId,e,n)}async on(e){if(this.closed)return;let t=this.step(e);switch(e.type){case"text":return t.assistant??=++this.seq,t.parts.assistant.push({type:"text",text:e.text}),this.write(t.assistant,e,{role:"assistant",content:t.parts.assistant});case"tool":return t.assistant??=++this.seq,t.parts.assistant.push({type:"tool-call",toolCallId:e.id,toolName:e.name,input:e.input}),this.write(t.assistant,e,{role:"assistant",content:t.parts.assistant});case"tool-result":return t.assistant??=++this.seq,t.tool??=++this.seq,t.parts.tool.push({type:"tool-result",toolCallId:e.id,toolName:e.name,output:e.error?{type:"error-text",value:String(e.output)}:"string"==typeof e.output?{type:"text",value:e.output}:{type:"json",value:e.output}}),this.write(t.tool,e,{role:"tool",content:t.parts.tool});case"step":{let o=[t.assistant,t.tool];this.steps.delete(`${e.bot} ${e.parent??""}`);let a=new Set;for(let[t,n]of e.messages.entries()){let s=o[t]??++this.seq;a.add(s),await this.write(s,e,n)}let n=o.filter(e=>null!==e&&!a.has(e));n.length&&await (0,g.deleteMessages)(this.taskId,n);return}case"compact":return this.write(++this.seq,e,{role:"user",content:e.text},{compact:!0,note:!0});case"interjection":return this.write(++this.seq,e,{role:"user",content:e.text});default:return}}}async function A(e,t,o,r){let i=new P(e,await (0,g.lastSeq)(e)),l=null,d=null;try{await (0,y.runBot)(t,{signal:o,taskId:e,notes:()=>r.splice(0),emit:async t=>{await i.on(t),"step"===t.type&&await (0,g.addTaskUsage)(e,t.usage,t.parent?null:{tokens:t.usage.input,budget:t.budget}),("compact"===t.type||"answered"===t.type)&&await (0,g.addTaskUsage)(e,t.usage),t.parent||("waiting"===t.type?l={status:"waiting",outcome:t.question,pending:{toolCallId:t.id,options:t.options}}:"answer"===t.type?l=t.stopped?{status:"waiting",outcome:t.text,pending:{toolCallId:null,options:[m.TASK_CONTINUE]}}:{status:"done",outcome:t.text,pending:null}:"error"===t.type&&(d={message:t.message,failure:t.failure,budget:t.budget},l={status:"failed",outcome:E(t.message),pending:null}))}})}catch(e){d={message:(0,s.modelErrorToString)(e),failure:(0,s.modelFailureOf)(e)},l={status:"failed",outcome:E(d.message),pending:null}}finally{i.close(),_.delete(e)}if(o.aborted)return;let p=l??{status:"failed",outcome:"Stopped without handing anything back.",pending:null},w=d&&"fatal"!==d.failure?d:null;try{w?await N(e,{why:"overflow"===w.failure?`The model refused the context as too long (${w.message}); it is compacted before going on.`:`The model call failed (${w.message}).`,retry:"transient"===w.failure,budget:w.budget}):("failed"===p.status&&await i.note(`The run stopped here: ${d?.message??p.outcome}`).catch(t=>c.logger.warn(`task ${e}: break not written`,t)),await S(e,{...p,seen:!1,endedAt:"waiting"===p.status?null:new Date}))}catch(t){c.logger.error(`task ${e}: could not record how it ended`,t);return}w||"waiting"===p.status?(0,u.pruneJobFiles)():(0,u.closeHiddenBrowser)(e);let f=await (0,g.findTask)(e);if(f){if(r.length){let t=r.splice(0).join("\n\n");c.logger.debug(`task ${e}: interjection after the run ended — resuming`),k(e,t).catch(t=>{c.logger.error(`task ${e}: late interjection`,t)});return}if(!w&&(await M(f.label,p),"done"===p.status)){var b;let t,o=(b=p.outcome,(t=(0,h.pathsIn)(b)).find(e=>e.startsWith(`${n.PATHS.artifacts}/`))??t[0]??null);o&&a.appEvents.emit({type:"artifact",taskId:e,label:f.label,path:o})}}}function E(e){return`The run broke: ${e}
119
+ Check what they did before relying on it, then finish the part yourself or hand them what is left.`:"No result: the run was stopped before this call returned. Check what it did before relying on it."}(e,t)}}]))}return n.length&&a.push({role:"tool",content:n}),a},"runBot",0,b]),o()}catch(e){o(e)}},!1),39803,e=>e.a(async(t,o)=>{try{var a=e.i(380690),n=e.i(687388),s=e.i(386075),r=e.i(851372),i=e.i(353885),l=e.i(22676),u=e.i(629668),h=e.i(786025),d=e.i(167004),c=e.i(640911),p=e.i(53748),w=e.i(268486),y=e.i(585099),m=e.i(944971),f=e.i(780274),g=t([s,r,l,y,f]);[s,r,l,y,f]=g.then?(await g)():g;let _=globalThis.__botRuns??=new Map,j=globalThis.__botTaskLock??=(0,w.createKeyedLock)(),I=globalThis.__botResumes??=new Map;async function b(e){let{from:t,...o}=e,a=o.callId?await (0,l.listCallTurns)(o.callId,r.OPENING_TURNS):[],n=(0,r.buildTaskOpening)({bot:o.bot,request:o.request,conversation:a,from:t}),s=await (0,f.insertTask)({...o,opening:n});return x(s.id,{bot:o.bot,messages:[{role:"user",content:n}]}),s.id}async function k(e,t,o){let a=o?(0,m.tagSpeaker)(o,t):t;return j(e,async()=>{let t=await (0,f.findTask)(e);t||(0,p.publicError)("No such job.");let o=_.get(e);if(o&&"running"===t.status&&o.note(a))return void c.logger.debug(`task ${e}: interjection queued`);o&&(o.stop.abort(),await o.done),$(e);let n=await (0,f.listThread)(e),{reply:s,as:r}=function(e,t,o){var a;let n,s,r="waiting"===e.status?e.pending:null,l=r?.toolCallId?(a=r.toolCallId,n=new Set(o.flatMap(e=>"tool"===e.role?e.content.flatMap(e=>"tool-result"===e.type?[e.toolCallId]:[]):[])),s=o.findLast(e=>"assistant"===e.role&&"string"!=typeof e.content&&e.content.some(e=>"tool-call"===e.type&&e.toolCallId===a)),(s?.role==="assistant"&&"string"!=typeof s.content?s.content.flatMap(e=>"tool-call"===e.type&&e.toolName===i.TOOL_NAMES.ask_thursday?[e.toolCallId]:[]):[a]).filter(e=>!n.has(e))):[];return l.length?{as:"answer",reply:{role:"tool",content:l.map(e=>({type:"tool-result",toolCallId:e,toolName:i.TOOL_NAMES.ask_thursday,output:{type:"text",value:t}}))}}:{as:"running"===e.status?"interruption":"waiting"===e.status?"answer":"follow-up",reply:{role:"user",content:t}}}(t,a,n);c.logger.debug(`task ${e}: ${r}`),await (0,f.upsertMessage)(e,await (0,f.lastSeq)(e)+1,{bot:null,parent:null,...s}),await (0,f.updateTask)(e,{status:"running",outcome:null,pending:null,seen:!1,endedAt:null}),x(e,{bot:t.bot,messages:(0,y.resumeThread)([...n,s],await (0,f.listBorrowedTails)(e))})})}async function T(e){return j(e,async()=>{let t=await (0,f.findTask)(e);t||(0,p.publicError)("No such job."),t.endedAt&&(0,p.publicError)("That job has already ended."),$(e),_.get(e)?.stop.abort(),await (0,f.updateTask)(e,{status:"failed",outcome:"Cancelled.",pending:null,seen:!0,endedAt:new Date}),(0,h.closeJobShell)(e)})}function $(e){clearTimeout(I.get(e)),I.delete(e)}async function v(e){a.presence.watching&&await j(e,async()=>{let t=await (0,f.findTask)(e);if(!t||"waiting"!==t.status||!t.pending?.auto||_.has(e))return;c.logger.debug(`task ${e}: picking back up`);let o=await (0,f.listThread)(e);await (0,f.updateTask)(e,{status:"running",outcome:null,pending:null,seen:!1,endedAt:null}),x(e,{bot:t.bot,messages:(0,y.resumeThread)(o,await (0,f.listBorrowedTails)(e))})})}async function N(e,t){let o=await (0,f.countStopsSinceSpoken)(e),a=o<n.BOT_RUN.autoResumes,s=n.BOT_RUN.retryAfterMs,r=a&&t.retry?s[Math.min(o,s.length-1)]:0;await O(e,(0,f.stopNote)(t.why)).catch(t=>c.logger.warn(`task ${e}: stop not written`,t)),await S(e,{status:"waiting",outcome:a?`${t.why} ${r?`It tries again in ${C(r)}.`:"It picks back up by itself."}`:`${t.why} It has stopped ${o+1} times in a row, so it waits for you. Everything it had done is still here.`,pending:{toolCallId:null,options:[m.TASK_CONTINUE],...a?{auto:!0,retryAt:Date.now()+r}:{}},...t.budget?{contextBudget:t.budget}:{},seen:!1,endedAt:null}),a&&($(e),I.set(e,setTimeout(()=>{I.delete(e),v(e).catch(t=>c.logger.error(`task ${e}: resume`,t))},Math.max(0,r))))}globalThis.__botPausing??={current:Promise.resolve()};let C=e=>e<6e4?`${Math.round(e/1e3)} seconds`:`${Math.round(e/6e4)} minutes`;async function O(e,t){await (0,f.upsertMessage)(e,await (0,f.lastSeq)(e)+1,{bot:null,parent:null,role:"user",content:t,note:!0})}async function S(e,t){for(let o of[1e3,3e3,null])try{await (0,f.updateTask)(e,t);return}catch(t){if(null===o)throw t;c.logger.warn(`task ${e}: ending not written, trying again`,t),await new Promise(e=>setTimeout(e,o))}}function x(e,t){let o=new AbortController,a=()=>{},n=new Promise(e=>{a=e}),s=[];_.set(e,{stop:o,done:n,note:t=>!!_.has(e)&&(s.push(t),!0)}),M(e,t,o.signal,s).catch(t=>{c.logger.error(`task ${e}`,t)}).finally(a)}class B{taskId;seq;steps;closed;constructor(e,t){this.taskId=e,this.steps=new Map,this.closed=!1,this.seq=t}close(){this.closed=!0}async note(e){await (0,f.upsertMessage)(this.taskId,++this.seq,{bot:null,parent:null,role:"user",content:e,note:!0})}step(e){let t=`${e.bot} ${e.parent??""}`,o=this.steps.get(t);return o||(o={assistant:null,tool:null,parts:{assistant:[],tool:[]}},this.steps.set(t,o)),o}write(e,t,o,a={}){let n={bot:t.bot,parent:t.parent,role:o.role,content:o.content,compact:a.compact??!1,note:a.note??!1};return(0,f.upsertMessage)(this.taskId,e,n)}async on(e){if(this.closed)return;let t=this.step(e);switch(e.type){case"text":return t.assistant??=++this.seq,t.parts.assistant.push({type:"text",text:e.text}),this.write(t.assistant,e,{role:"assistant",content:t.parts.assistant});case"tool":return t.assistant??=++this.seq,t.parts.assistant.push({type:"tool-call",toolCallId:e.id,toolName:e.name,input:e.input}),this.write(t.assistant,e,{role:"assistant",content:t.parts.assistant});case"tool-result":return t.assistant??=++this.seq,t.tool??=++this.seq,t.parts.tool.push({type:"tool-result",toolCallId:e.id,toolName:e.name,output:e.error?{type:"error-text",value:String(e.output)}:"string"==typeof e.output?{type:"text",value:e.output}:{type:"json",value:e.output}}),this.write(t.tool,e,{role:"tool",content:t.parts.tool});case"step":{let o=[t.assistant,t.tool];this.steps.delete(`${e.bot} ${e.parent??""}`);let a=new Set;for(let[t,n]of e.messages.entries()){let s=o[t]??++this.seq;a.add(s),await this.write(s,e,n)}let n=o.filter(e=>null!==e&&!a.has(e));n.length&&await (0,f.deleteMessages)(this.taskId,n);return}case"compact":return this.write(++this.seq,e,{role:"user",content:e.text},{compact:!0,note:!0});case"interjection":return this.write(++this.seq,e,{role:"user",content:e.text});default:return}}}async function M(e,t,o,r){let i=new B(e,await (0,f.lastSeq)(e)),l=null,d=null;try{await (0,y.runBot)(t,{signal:o,taskId:e,notes:()=>r.splice(0),emit:async t=>{await i.on(t),"step"===t.type&&await (0,f.addTaskUsage)(e,t.usage,t.parent?null:{tokens:t.usage.input,budget:t.budget}),("compact"===t.type||"answered"===t.type)&&await (0,f.addTaskUsage)(e,t.usage),t.parent||("waiting"===t.type?l={status:"waiting",outcome:t.question,pending:{toolCallId:t.id,options:t.options}}:"answer"===t.type?l=t.stopped?{status:"waiting",outcome:t.text,pending:{toolCallId:null,options:[m.TASK_CONTINUE]}}:{status:"done",outcome:t.text,pending:null}:"error"===t.type&&(d={message:t.message,failure:t.failure,budget:t.budget},l={status:"failed",outcome:A(t.message),pending:null}))}})}catch(e){d={message:(0,s.modelErrorToString)(e),failure:(0,s.modelFailureOf)(e)},l={status:"failed",outcome:A(d.message),pending:null}}finally{i.close(),_.delete(e)}if(o.aborted)return;let p=l??{status:"failed",outcome:"Stopped without handing anything back.",pending:null},w=d&&"fatal"!==d.failure?d:null;try{w?await N(e,{why:"overflow"===w.failure?`The model refused the context as too long (${w.message}); it is compacted before going on.`:`The model call failed (${w.message}).`,retry:"transient"===w.failure,budget:w.budget}):("failed"===p.status&&await i.note(`The run stopped here: ${d?.message??p.outcome}`).catch(t=>c.logger.warn(`task ${e}: break not written`,t)),await S(e,{...p,seen:!1,endedAt:"waiting"===p.status?null:new Date}))}catch(t){c.logger.error(`task ${e}: could not record how it ended`,t);return}w||"waiting"===p.status?(0,h.pruneJobFiles)():(0,h.closeHiddenBrowser)(e);let g=await (0,f.findTask)(e);if(g){if(r.length){let t=r.splice(0).join("\n\n");c.logger.debug(`task ${e}: interjection after the run ended — resuming`),k(e,t).catch(t=>{c.logger.error(`task ${e}: late interjection`,t)});return}if(!w&&(await E(g.label,p),"done"===p.status)){var b;let t,o=(b=p.outcome,(t=(0,u.pathsIn)(b)).find(e=>e.startsWith(`${n.PATHS.artifacts}/`))??t[0]??null);o&&a.appEvents.emit({type:"artifact",taskId:e,label:g.label,path:o})}}}function A(e){return`The run broke: ${e}
116
120
 
117
- Everything it had done is still here — answer to pick it back up.`}async function M(e,t){if(0!==a.appEventStream.watchers&&await (0,l.isAnyCallLive)())return;let o="waiting"===t.status?`${e} — needs you`:e;(0,d.desktopNotify)(o,t.outcome)}e.s(["answerTask",0,k,"cancelTask",0,T,"startTask",0,b]),o()}catch(e){o(e)}},!1),167004,e=>{"use strict";var t=e.i(874533),o=e.i(687388);let a=`on run argv
121
+ Everything it had done is still here — answer to pick it back up.`}async function E(e,t){if(0!==a.appEventStream.watchers&&await (0,l.isAnyCallLive)())return;let o="waiting"===t.status?`${e} — needs you`:e;(0,d.desktopNotify)(o,t.outcome)}e.s(["answerTask",0,k,"cancelTask",0,T,"startTask",0,b]),o()}catch(e){o(e)}},!1),167004,e=>{"use strict";var t=e.i(874533),o=e.i(687388);let a=`on run argv
118
122
  display notification (item 2 of argv) with title (item 1 of argv)
119
123
  end run`,n=`
120
124
  $ErrorActionPreference = 'Stop'