@astralyn/pi 1.4.11 → 1.5.1

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 (564) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/dist/bundle/chunks/anthropic-messages-G5ZGBHOH.js +6 -0
  3. package/dist/bundle/chunks/azure-openai-responses-EMPTMYNF.js +2 -0
  4. package/dist/bundle/chunks/bedrock-converse-stream.js +22 -15
  5. package/dist/bundle/chunks/{chunk-TH3QDDPD.js → chunk-3YGNXVKM.js} +1 -1
  6. package/dist/bundle/chunks/chunk-AXX7FFFD.js +2 -0
  7. package/dist/bundle/chunks/chunk-FNGB3ASD.js +2 -0
  8. package/dist/bundle/chunks/chunk-FPALVF3F.js +4 -0
  9. package/dist/bundle/chunks/chunk-H3UF54OB.js +9 -0
  10. package/dist/bundle/chunks/{chunk-NUQMVNKQ.js → chunk-HLVMLRZJ.js} +58 -62
  11. package/dist/bundle/chunks/chunk-IC6JXX2J.js +10 -0
  12. package/dist/bundle/chunks/{chunk-MZJC45TM.js → chunk-J7L6O5XA.js} +3 -3
  13. package/dist/bundle/chunks/{chunk-DLVLAQEG.js → chunk-KBFO53OG.js} +3 -3
  14. package/dist/bundle/chunks/chunk-M3D4ADUT.js +1503 -0
  15. package/dist/bundle/chunks/{chunk-TPVFPFJP.js → chunk-P7VXFB2M.js} +1 -1
  16. package/dist/bundle/chunks/chunk-PSYLMRL6.js +9 -0
  17. package/dist/bundle/chunks/chunk-QNZARXLE.js +82 -0
  18. package/dist/bundle/chunks/chunk-RAIYJ5FC.js +4 -0
  19. package/dist/bundle/chunks/{chunk-OV2VMHBX.js → chunk-SR6EWNPW.js} +1 -1
  20. package/dist/bundle/chunks/chunk-TA3YH2ZI.js +16 -0
  21. package/dist/bundle/chunks/{chunk-24FY4C5S.js → chunk-TRSJS3FM.js} +1 -1
  22. package/dist/bundle/chunks/chunk-ZRI3ICDE.js +2 -0
  23. package/dist/bundle/chunks/{cli-MBFCFGI2.js → cli-LAZQG54B.js} +11 -9
  24. package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-7BKATOEJ.js → cloudflare-workers-ai-system-one-4L2ABUJE.js} +1 -1
  25. package/dist/bundle/chunks/{execute-VLAIP26K.js → execute-SSRW6NGS.js} +1 -1
  26. package/dist/bundle/chunks/github-copilot.js +1 -1
  27. package/dist/bundle/chunks/{google-generative-ai-HTUSU45F.js → google-generative-ai-OOVDGS5W.js} +1 -1
  28. package/dist/bundle/chunks/{google-vertex-AVQV4P76.js → google-vertex-IK5RNG7J.js} +1 -1
  29. package/dist/bundle/chunks/image-resize-worker.js +1 -1
  30. package/dist/bundle/chunks/kimi-coding.js +1 -1
  31. package/dist/bundle/chunks/{llama-cpp-classify-27QYLJZY.js → llama-cpp-classify-XHAVT37C.js} +1 -1
  32. package/dist/bundle/chunks/meta.js +1 -1
  33. package/dist/bundle/chunks/mistral-conversations-Z56KY4OJ.js +5 -0
  34. package/dist/bundle/chunks/{openai-codex-responses-Q25MHDFX.js → openai-codex-responses-5NAH3SK6.js} +1 -1
  35. package/dist/bundle/chunks/openai-completions-S7S6PO3J.js +7 -0
  36. package/dist/bundle/chunks/{openai-decisions-3WYFPGSK.js → openai-decisions-7A36EAHE.js} +1 -1
  37. package/dist/bundle/chunks/{openai-responses-E4BNZIQK.js → openai-responses-ZQRZJKH4.js} +1 -1
  38. package/dist/bundle/chunks/{openrouter-images-CBP3OPOD.js → openrouter-images-X7PX72ON.js} +1 -1
  39. package/dist/bundle/chunks/pi-messages-TXNWPLI4.js +8 -0
  40. package/dist/bundle/chunks/radius.js +1 -1
  41. package/dist/bundle/chunks/{runtime-3RPOJS5T.js → runtime-X3XOMNXQ.js} +1 -1
  42. package/dist/bundle/chunks/{typesafe-system-one-BNICP2LS.js → typesafe-system-one-XJGMSHWL.js} +1 -1
  43. package/dist/bundle/chunks/virtual-modules-NFDW2JKH.js +2 -0
  44. package/dist/bundle/cli.js +1 -1
  45. package/dist/bundle/index.js +1 -1
  46. package/dist/bundle/rpc-entry.js +1 -1
  47. package/dist/cli/args.d.ts.map +1 -1
  48. package/dist/cli/args.js +8 -7
  49. package/dist/cli/args.js.map +1 -1
  50. package/dist/config.d.ts +10 -0
  51. package/dist/config.d.ts.map +1 -1
  52. package/dist/config.js +24 -5
  53. package/dist/config.js.map +1 -1
  54. package/dist/core/agent-session-runtime.d.ts +0 -5
  55. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  56. package/dist/core/agent-session-runtime.js +12 -28
  57. package/dist/core/agent-session-runtime.js.map +1 -1
  58. package/dist/core/agent-session.d.ts +21 -14
  59. package/dist/core/agent-session.d.ts.map +1 -1
  60. package/dist/core/agent-session.js +67 -93
  61. package/dist/core/agent-session.js.map +1 -1
  62. package/dist/core/compaction/branch-summarization.d.ts +4 -2
  63. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  64. package/dist/core/compaction/branch-summarization.js +16 -4
  65. package/dist/core/compaction/branch-summarization.js.map +1 -1
  66. package/dist/core/exec.d.ts +9 -1
  67. package/dist/core/exec.d.ts.map +1 -1
  68. package/dist/core/exec.js +104 -60
  69. package/dist/core/exec.js.map +1 -1
  70. package/dist/core/export-html/template.css +9 -0
  71. package/dist/core/export-html/template.js +165 -45
  72. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  73. package/dist/core/export-html/tool-renderer.js +5 -0
  74. package/dist/core/export-html/tool-renderer.js.map +1 -1
  75. package/dist/core/extensions/index.d.ts +1 -1
  76. package/dist/core/extensions/index.d.ts.map +1 -1
  77. package/dist/core/extensions/index.js.map +1 -1
  78. package/dist/core/extensions/loader.d.ts.map +1 -1
  79. package/dist/core/extensions/loader.js +7 -6
  80. package/dist/core/extensions/loader.js.map +1 -1
  81. package/dist/core/extensions/pi-ai-extension-view.d.ts +19 -0
  82. package/dist/core/extensions/pi-ai-extension-view.d.ts.map +1 -0
  83. package/dist/core/extensions/pi-ai-extension-view.js +22 -0
  84. package/dist/core/extensions/pi-ai-extension-view.js.map +1 -0
  85. package/dist/core/extensions/runner.d.ts +0 -1
  86. package/dist/core/extensions/runner.d.ts.map +1 -1
  87. package/dist/core/extensions/runner.js +7 -12
  88. package/dist/core/extensions/runner.js.map +1 -1
  89. package/dist/core/extensions/types.d.ts +41 -23
  90. package/dist/core/extensions/types.d.ts.map +1 -1
  91. package/dist/core/extensions/types.js.map +1 -1
  92. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  93. package/dist/core/extensions/virtual-modules.js +8 -7
  94. package/dist/core/extensions/virtual-modules.js.map +1 -1
  95. package/dist/core/mcp-servers.d.ts +11 -4
  96. package/dist/core/mcp-servers.d.ts.map +1 -1
  97. package/dist/core/mcp-servers.js +15 -5
  98. package/dist/core/mcp-servers.js.map +1 -1
  99. package/dist/core/model-config.d.ts +1678 -2029
  100. package/dist/core/model-config.d.ts.map +1 -1
  101. package/dist/core/model-config.js +2 -3
  102. package/dist/core/model-config.js.map +1 -1
  103. package/dist/core/model-resolver.d.ts.map +1 -1
  104. package/dist/core/model-resolver.js +16 -10
  105. package/dist/core/model-resolver.js.map +1 -1
  106. package/dist/core/package-manager.d.ts +14 -0
  107. package/dist/core/package-manager.d.ts.map +1 -1
  108. package/dist/core/package-manager.js +160 -46
  109. package/dist/core/package-manager.js.map +1 -1
  110. package/dist/core/pi-ai-schemas.d.ts +163 -0
  111. package/dist/core/pi-ai-schemas.d.ts.map +1 -0
  112. package/dist/core/pi-ai-schemas.js +21 -0
  113. package/dist/core/pi-ai-schemas.js.map +1 -0
  114. package/dist/core/pi-manifest.d.ts +1 -0
  115. package/dist/core/pi-manifest.d.ts.map +1 -1
  116. package/dist/core/pi-manifest.js +4 -0
  117. package/dist/core/pi-manifest.js.map +1 -1
  118. package/dist/core/project-trust.js +1 -1
  119. package/dist/core/project-trust.js.map +1 -1
  120. package/dist/core/quiescence.d.ts +24 -0
  121. package/dist/core/quiescence.d.ts.map +1 -0
  122. package/dist/core/quiescence.js +81 -0
  123. package/dist/core/quiescence.js.map +1 -0
  124. package/dist/core/resource-loader.d.ts +4 -1
  125. package/dist/core/resource-loader.d.ts.map +1 -1
  126. package/dist/core/resource-loader.js +41 -28
  127. package/dist/core/resource-loader.js.map +1 -1
  128. package/dist/core/sdk.d.ts.map +1 -1
  129. package/dist/core/sdk.js +3 -1
  130. package/dist/core/sdk.js.map +1 -1
  131. package/dist/core/session-manager.d.ts +7 -0
  132. package/dist/core/session-manager.d.ts.map +1 -1
  133. package/dist/core/session-manager.js +32 -13
  134. package/dist/core/session-manager.js.map +1 -1
  135. package/dist/core/settings-manager.d.ts +2 -0
  136. package/dist/core/settings-manager.d.ts.map +1 -1
  137. package/dist/core/settings-manager.js +11 -0
  138. package/dist/core/settings-manager.js.map +1 -1
  139. package/dist/core/settings-schema.d.ts +4 -2
  140. package/dist/core/settings-schema.d.ts.map +1 -1
  141. package/dist/core/settings-schema.js +8 -1
  142. package/dist/core/settings-schema.js.map +1 -1
  143. package/dist/core/skills.d.ts.map +1 -1
  144. package/dist/core/skills.js +6 -14
  145. package/dist/core/skills.js.map +1 -1
  146. package/dist/core/slash-command-name.d.ts +6 -0
  147. package/dist/core/slash-command-name.d.ts.map +1 -0
  148. package/dist/core/slash-command-name.js +11 -0
  149. package/dist/core/slash-command-name.js.map +1 -0
  150. package/dist/core/slash-commands.js +2 -2
  151. package/dist/core/slash-commands.js.map +1 -1
  152. package/dist/core/source-info.d.ts +9 -0
  153. package/dist/core/source-info.d.ts.map +1 -1
  154. package/dist/core/source-info.js +13 -0
  155. package/dist/core/source-info.js.map +1 -1
  156. package/dist/core/system-prompt.d.ts.map +1 -1
  157. package/dist/core/system-prompt.js +5 -6
  158. package/dist/core/system-prompt.js.map +1 -1
  159. package/dist/core/tasks/activity.d.ts +14 -0
  160. package/dist/core/tasks/activity.d.ts.map +1 -0
  161. package/dist/core/tasks/activity.js +58 -0
  162. package/dist/core/tasks/activity.js.map +1 -0
  163. package/dist/core/tasks/codec.d.ts +14 -0
  164. package/dist/core/tasks/codec.d.ts.map +1 -1
  165. package/dist/core/tasks/codec.js +57 -4
  166. package/dist/core/tasks/codec.js.map +1 -1
  167. package/dist/core/tasks/execution.d.ts.map +1 -1
  168. package/dist/core/tasks/execution.js +2 -2
  169. package/dist/core/tasks/execution.js.map +1 -1
  170. package/dist/core/tasks/output.d.ts +4 -1
  171. package/dist/core/tasks/output.d.ts.map +1 -1
  172. package/dist/core/tasks/output.js +33 -0
  173. package/dist/core/tasks/output.js.map +1 -1
  174. package/dist/core/tasks/record.d.ts +1 -7
  175. package/dist/core/tasks/record.d.ts.map +1 -1
  176. package/dist/core/tasks/record.js +0 -18
  177. package/dist/core/tasks/record.js.map +1 -1
  178. package/dist/core/tasks/reminder.d.ts +3 -2
  179. package/dist/core/tasks/reminder.d.ts.map +1 -1
  180. package/dist/core/tasks/reminder.js +4 -3
  181. package/dist/core/tasks/reminder.js.map +1 -1
  182. package/dist/core/tasks/runtime.d.ts +0 -2
  183. package/dist/core/tasks/runtime.d.ts.map +1 -1
  184. package/dist/core/tasks/runtime.js +2 -15
  185. package/dist/core/tasks/runtime.js.map +1 -1
  186. package/dist/core/tasks/session.d.ts +9 -2
  187. package/dist/core/tasks/session.d.ts.map +1 -1
  188. package/dist/core/tasks/session.js +23 -9
  189. package/dist/core/tasks/session.js.map +1 -1
  190. package/dist/core/tasks/types.d.ts +20 -20
  191. package/dist/core/tasks/types.d.ts.map +1 -1
  192. package/dist/core/tasks/types.js +1 -1
  193. package/dist/core/tasks/types.js.map +1 -1
  194. package/dist/core/tools/bash.d.ts +8 -7
  195. package/dist/core/tools/bash.d.ts.map +1 -1
  196. package/dist/core/tools/bash.js +6 -5
  197. package/dist/core/tools/bash.js.map +1 -1
  198. package/dist/core/tools/edit.d.ts +3 -3
  199. package/dist/core/tools/edit.d.ts.map +1 -1
  200. package/dist/core/tools/edit.js +2 -4
  201. package/dist/core/tools/edit.js.map +1 -1
  202. package/dist/core/tools/find.d.ts +2 -2
  203. package/dist/core/tools/find.d.ts.map +1 -1
  204. package/dist/core/tools/find.js.map +1 -1
  205. package/dist/core/tools/grep.d.ts +2 -2
  206. package/dist/core/tools/grep.d.ts.map +1 -1
  207. package/dist/core/tools/grep.js +1 -1
  208. package/dist/core/tools/grep.js.map +1 -1
  209. package/dist/core/tools/ls.d.ts +2 -2
  210. package/dist/core/tools/ls.d.ts.map +1 -1
  211. package/dist/core/tools/ls.js.map +1 -1
  212. package/dist/core/tools/powershell.d.ts +1 -5
  213. package/dist/core/tools/powershell.d.ts.map +1 -1
  214. package/dist/core/tools/read.d.ts +2 -2
  215. package/dist/core/tools/read.d.ts.map +1 -1
  216. package/dist/core/tools/read.js.map +1 -1
  217. package/dist/core/tools/render-utils.d.ts +4 -6
  218. package/dist/core/tools/render-utils.d.ts.map +1 -1
  219. package/dist/core/tools/render-utils.js +19 -41
  220. package/dist/core/tools/render-utils.js.map +1 -1
  221. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  222. package/dist/core/tools/renderers/bash.js +3 -25
  223. package/dist/core/tools/renderers/bash.js.map +1 -1
  224. package/dist/core/tools/renderers/write.d.ts.map +1 -1
  225. package/dist/core/tools/renderers/write.js +18 -19
  226. package/dist/core/tools/renderers/write.js.map +1 -1
  227. package/dist/core/tools/shell-execution.d.ts +20 -13
  228. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  229. package/dist/core/tools/shell-execution.js +165 -183
  230. package/dist/core/tools/shell-execution.js.map +1 -1
  231. package/dist/core/tools/shell-tool.d.ts +9 -14
  232. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  233. package/dist/core/tools/shell-tool.js +38 -66
  234. package/dist/core/tools/shell-tool.js.map +1 -1
  235. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -4
  236. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  237. package/dist/core/tools/tool-definition-wrapper.js +2 -3
  238. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  239. package/dist/core/tools/write.d.ts +2 -2
  240. package/dist/core/tools/write.d.ts.map +1 -1
  241. package/dist/core/tools/write.js.map +1 -1
  242. package/dist/core/trust-manager.d.ts.map +1 -1
  243. package/dist/core/trust-manager.js +30 -13
  244. package/dist/core/trust-manager.js.map +1 -1
  245. package/dist/core/usage-totals.d.ts +0 -9
  246. package/dist/core/usage-totals.d.ts.map +1 -1
  247. package/dist/core/usage-totals.js +24 -91
  248. package/dist/core/usage-totals.js.map +1 -1
  249. package/dist/extensions/agent/activity-lines.d.ts +2 -7
  250. package/dist/extensions/agent/activity-lines.d.ts.map +1 -1
  251. package/dist/extensions/agent/activity-lines.js +6 -74
  252. package/dist/extensions/agent/activity-lines.js.map +1 -1
  253. package/dist/extensions/agent/activity.d.ts +0 -21
  254. package/dist/extensions/agent/activity.d.ts.map +1 -1
  255. package/dist/extensions/agent/activity.js +0 -63
  256. package/dist/extensions/agent/activity.js.map +1 -1
  257. package/dist/extensions/agent/progress.d.ts +0 -3
  258. package/dist/extensions/agent/progress.d.ts.map +1 -1
  259. package/dist/extensions/agent/progress.js +11 -10
  260. package/dist/extensions/agent/progress.js.map +1 -1
  261. package/dist/extensions/agent/render.js +1 -1
  262. package/dist/extensions/agent/render.js.map +1 -1
  263. package/dist/extensions/agent/tool.d.ts.map +1 -1
  264. package/dist/extensions/agent/tool.js +0 -6
  265. package/dist/extensions/agent/tool.js.map +1 -1
  266. package/dist/extensions/agent/types.d.ts +3 -11
  267. package/dist/extensions/agent/types.d.ts.map +1 -1
  268. package/dist/extensions/agent/types.js.map +1 -1
  269. package/dist/{core/isolated-session.d.ts → extensions/agent/worker-session.d.ts} +6 -6
  270. package/dist/extensions/agent/worker-session.d.ts.map +1 -0
  271. package/dist/{core/isolated-session.js → extensions/agent/worker-session.js} +9 -9
  272. package/dist/extensions/agent/worker-session.js.map +1 -0
  273. package/dist/extensions/agent/worker.d.ts +0 -3
  274. package/dist/extensions/agent/worker.d.ts.map +1 -1
  275. package/dist/extensions/agent/worker.js +2 -3
  276. package/dist/extensions/agent/worker.js.map +1 -1
  277. package/dist/extensions/btw/agent.d.ts.map +1 -1
  278. package/dist/extensions/btw/agent.js +2 -1
  279. package/dist/extensions/btw/agent.js.map +1 -1
  280. package/dist/extensions/cached-compaction/render.d.ts.map +1 -1
  281. package/dist/extensions/cached-compaction/render.js +3 -3
  282. package/dist/extensions/cached-compaction/render.js.map +1 -1
  283. package/dist/extensions/codemode/renderer.d.ts.map +1 -1
  284. package/dist/extensions/codemode/renderer.js +6 -2
  285. package/dist/extensions/codemode/renderer.js.map +1 -1
  286. package/dist/extensions/codemode/tool.d.ts +2 -1
  287. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  288. package/dist/extensions/codemode/tool.js +33 -8
  289. package/dist/extensions/codemode/tool.js.map +1 -1
  290. package/dist/extensions/deepwiki/schema.d.ts.map +1 -1
  291. package/dist/extensions/deepwiki/schema.js +1 -1
  292. package/dist/extensions/deepwiki/schema.js.map +1 -1
  293. package/dist/extensions/llama/ui.d.ts.map +1 -1
  294. package/dist/extensions/llama/ui.js +16 -4
  295. package/dist/extensions/llama/ui.js.map +1 -1
  296. package/dist/extensions/mcp/cli.d.ts.map +1 -1
  297. package/dist/extensions/mcp/cli.js +34 -8
  298. package/dist/extensions/mcp/cli.js.map +1 -1
  299. package/dist/extensions/mcp/oauth.d.ts +1 -1
  300. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  301. package/dist/extensions/mcp/oauth.js +36 -13
  302. package/dist/extensions/mcp/oauth.js.map +1 -1
  303. package/dist/extensions/mcp/ui.d.ts +1 -0
  304. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  305. package/dist/extensions/mcp/ui.js +33 -24
  306. package/dist/extensions/mcp/ui.js.map +1 -1
  307. package/dist/extensions/run-summary/index.d.ts +1 -1
  308. package/dist/extensions/run-summary/index.d.ts.map +1 -1
  309. package/dist/extensions/run-summary/index.js +11 -23
  310. package/dist/extensions/run-summary/index.js.map +1 -1
  311. package/dist/extensions/statusline/usage.d.ts.map +1 -1
  312. package/dist/extensions/statusline/usage.js +2 -1
  313. package/dist/extensions/statusline/usage.js.map +1 -1
  314. package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
  315. package/dist/extensions/tasks/tool/schema.js +1 -1
  316. package/dist/extensions/tasks/tool/schema.js.map +1 -1
  317. package/dist/extensions/tasks/ui/completion-render.d.ts +5 -1
  318. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
  319. package/dist/extensions/tasks/ui/completion-render.js +25 -70
  320. package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
  321. package/dist/extensions/tasks/ui/inspector.d.ts +1 -1
  322. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  323. package/dist/extensions/tasks/ui/inspector.js +3 -7
  324. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  325. package/dist/extensions/tasks/ui/manager.d.ts +1 -1
  326. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
  327. package/dist/extensions/tasks/ui/manager.js.map +1 -1
  328. package/dist/extensions/tasks/ui/views.d.ts +3 -4
  329. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  330. package/dist/extensions/tasks/ui/views.js +15 -14
  331. package/dist/extensions/tasks/ui/views.js.map +1 -1
  332. package/dist/extensions/tool-presentation/fallback.d.ts.map +1 -0
  333. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/fallback.js +5 -5
  334. package/dist/extensions/tool-presentation/fallback.js.map +1 -0
  335. package/dist/extensions/tool-presentation/index.js +1 -1
  336. package/dist/extensions/tool-presentation/index.js.map +1 -1
  337. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/shell.d.ts +1 -1
  338. package/dist/extensions/tool-presentation/shell.d.ts.map +1 -0
  339. package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/shell.js +3 -3
  340. package/dist/extensions/tool-presentation/shell.js.map +1 -0
  341. package/dist/extensions/tool-search/tool.d.ts +21 -6
  342. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  343. package/dist/extensions/tool-search/tool.js +104 -36
  344. package/dist/extensions/tool-search/tool.js.map +1 -1
  345. package/dist/index.d.ts +3 -3
  346. package/dist/index.d.ts.map +1 -1
  347. package/dist/index.js.map +1 -1
  348. package/dist/main.d.ts.map +1 -1
  349. package/dist/main.js +15 -8
  350. package/dist/main.js.map +1 -1
  351. package/dist/modes/interactive/components/assistant-message.d.ts +5 -3
  352. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  353. package/dist/modes/interactive/components/assistant-message.js +61 -45
  354. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  355. package/dist/modes/interactive/components/config-selector-skills.d.ts +54 -0
  356. package/dist/modes/interactive/components/config-selector-skills.d.ts.map +1 -0
  357. package/dist/modes/interactive/components/config-selector-skills.js +178 -0
  358. package/dist/modes/interactive/components/config-selector-skills.js.map +1 -0
  359. package/dist/modes/interactive/components/config-selector.d.ts +2 -11
  360. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  361. package/dist/modes/interactive/components/config-selector.js +31 -181
  362. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  363. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  364. package/dist/modes/interactive/components/custom-editor.js +7 -0
  365. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  366. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  367. package/dist/modes/interactive/components/custom-entry.js +2 -1
  368. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  369. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  370. package/dist/modes/interactive/components/custom-message.js +2 -1
  371. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  372. package/dist/modes/interactive/components/extension-editor.d.ts +2 -0
  373. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  374. package/dist/modes/interactive/components/extension-editor.js +4 -0
  375. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  376. package/dist/modes/interactive/components/login-dialog.d.ts +5 -0
  377. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  378. package/dist/modes/interactive/components/login-dialog.js +103 -10
  379. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  380. package/dist/modes/interactive/components/markdown-transform.d.ts +2 -1
  381. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
  382. package/dist/modes/interactive/components/markdown-transform.js +3 -2
  383. package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
  384. package/dist/modes/interactive/components/model-selector.d.ts +1 -0
  385. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  386. package/dist/modes/interactive/components/model-selector.js +17 -6
  387. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  388. package/dist/modes/interactive/components/oauth-selector.d.ts +1 -0
  389. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  390. package/dist/modes/interactive/components/oauth-selector.js +13 -4
  391. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  392. package/dist/modes/interactive/components/scoped-models-selector.d.ts +1 -0
  393. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  394. package/dist/modes/interactive/components/scoped-models-selector.js +14 -3
  395. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  396. package/dist/modes/interactive/components/session-selector-search.d.ts +4 -0
  397. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  398. package/dist/modes/interactive/components/session-selector-search.js +86 -22
  399. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  400. package/dist/modes/interactive/components/session-selector.d.ts +2 -1
  401. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  402. package/dist/modes/interactive/components/session-selector.js +15 -23
  403. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  404. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  405. package/dist/modes/interactive/components/settings-submenu.js +2 -0
  406. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  407. package/dist/modes/interactive/components/task-activity-list.d.ts +5 -0
  408. package/dist/modes/interactive/components/task-activity-list.d.ts.map +1 -0
  409. package/dist/modes/interactive/components/task-activity-list.js +68 -0
  410. package/dist/modes/interactive/components/task-activity-list.js.map +1 -0
  411. package/dist/modes/interactive/components/tool-execution.d.ts +7 -0
  412. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  413. package/dist/modes/interactive/components/tool-execution.js +48 -9
  414. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  415. package/dist/modes/interactive/components/tree-selector.d.ts +1 -0
  416. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  417. package/dist/modes/interactive/components/tree-selector.js +5 -6
  418. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  419. package/dist/modes/interactive/components/user-message-selector.d.ts +1 -0
  420. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  421. package/dist/modes/interactive/components/user-message-selector.js +9 -1
  422. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  423. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  424. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  425. package/dist/modes/interactive/components/user-message.js +4 -2
  426. package/dist/modes/interactive/components/user-message.js.map +1 -1
  427. package/dist/modes/interactive/editor-host.d.ts.map +1 -1
  428. package/dist/modes/interactive/editor-host.js +3 -2
  429. package/dist/modes/interactive/editor-host.js.map +1 -1
  430. package/dist/modes/interactive/external-editor.d.ts +1 -0
  431. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  432. package/dist/modes/interactive/external-editor.js +17 -5
  433. package/dist/modes/interactive/external-editor.js.map +1 -1
  434. package/dist/modes/interactive/interactive-mode.d.ts +8 -12
  435. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  436. package/dist/modes/interactive/interactive-mode.js +169 -112
  437. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  438. package/dist/modes/interactive/model-search.d.ts +10 -0
  439. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  440. package/dist/modes/interactive/model-search.js +21 -0
  441. package/dist/modes/interactive/model-search.js.map +1 -1
  442. package/dist/modes/interactive/theme/theme.d.ts +10 -0
  443. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  444. package/dist/modes/interactive/theme/theme.js +30 -23
  445. package/dist/modes/interactive/theme/theme.js.map +1 -1
  446. package/dist/modes/interactive/tool-view/chat.d.ts +2 -2
  447. package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -1
  448. package/dist/modes/interactive/tool-view/chat.js +22 -19
  449. package/dist/modes/interactive/tool-view/chat.js.map +1 -1
  450. package/dist/modes/interactive/transcript-layout.d.ts +2 -0
  451. package/dist/modes/interactive/transcript-layout.d.ts.map +1 -1
  452. package/dist/modes/interactive/transcript-layout.js +5 -2
  453. package/dist/modes/interactive/transcript-layout.js.map +1 -1
  454. package/dist/modes/rpc/rpc-client.d.ts +9 -1
  455. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  456. package/dist/modes/rpc/rpc-client.js +23 -23
  457. package/dist/modes/rpc/rpc-client.js.map +1 -1
  458. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  459. package/dist/modes/rpc/rpc-mode.js +0 -3
  460. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  461. package/dist/package-manager-cli.d.ts.map +1 -1
  462. package/dist/package-manager-cli.js +55 -4
  463. package/dist/package-manager-cli.js.map +1 -1
  464. package/dist/utils/ansi.d.ts.map +1 -1
  465. package/dist/utils/ansi.js +5 -2
  466. package/dist/utils/ansi.js.map +1 -1
  467. package/dist/utils/clipboard-command.d.ts.map +1 -1
  468. package/dist/utils/clipboard-command.js +4 -0
  469. package/dist/utils/clipboard-command.js.map +1 -1
  470. package/dist/utils/git.d.ts +1 -1
  471. package/dist/utils/git.d.ts.map +1 -1
  472. package/dist/utils/git.js.map +1 -1
  473. package/dist/utils/image-resize-core.d.ts.map +1 -1
  474. package/dist/utils/image-resize-core.js +5 -3
  475. package/dist/utils/image-resize-core.js.map +1 -1
  476. package/dist/utils/open-browser.d.ts.map +1 -1
  477. package/dist/utils/open-browser.js +4 -1
  478. package/dist/utils/open-browser.js.map +1 -1
  479. package/dist/utils/paths.d.ts +17 -0
  480. package/dist/utils/paths.d.ts.map +1 -1
  481. package/dist/utils/paths.js +42 -1
  482. package/dist/utils/paths.js.map +1 -1
  483. package/dist/utils/shell.d.ts.map +1 -1
  484. package/dist/utils/shell.js +14 -0
  485. package/dist/utils/shell.js.map +1 -1
  486. package/dist/utils/syntax-highlight.d.ts +5 -0
  487. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  488. package/dist/utils/syntax-highlight.js +7 -0
  489. package/dist/utils/syntax-highlight.js.map +1 -1
  490. package/dist/utils/tools-manager.d.ts.map +1 -1
  491. package/dist/utils/tools-manager.js +30 -35
  492. package/dist/utils/tools-manager.js.map +1 -1
  493. package/dist/utils/usage.d.ts +5 -0
  494. package/dist/utils/usage.d.ts.map +1 -0
  495. package/dist/utils/usage.js +16 -0
  496. package/dist/utils/usage.js.map +1 -0
  497. package/docs/bundled/README.md +1 -1
  498. package/docs/bundled/extensions/agent.md +5 -5
  499. package/docs/bundled/extensions/run-summary.md +4 -4
  500. package/docs/bundled/tasks.md +2 -4
  501. package/docs/bundled/tool-presentation.md +2 -2
  502. package/docs/custom-provider.md +1 -1
  503. package/docs/environment-variables.md +2 -0
  504. package/docs/extensions.md +38 -21
  505. package/docs/keybindings.md +1 -1
  506. package/docs/llama-cpp.md +17 -12
  507. package/docs/mcp.md +6 -4
  508. package/docs/packages.md +26 -1
  509. package/docs/rpc.md +1 -1
  510. package/docs/sdk.md +7 -5
  511. package/docs/session-format.md +2 -2
  512. package/docs/sessions.md +10 -0
  513. package/docs/settings.md +5 -4
  514. package/docs/terminal-setup.md +2 -2
  515. package/docs/tmux.md +6 -0
  516. package/docs/tui.md +12 -7
  517. package/docs/usage.md +19 -9
  518. package/docs/windows.md +29 -0
  519. package/examples/extensions/README.md +2 -1
  520. package/examples/extensions/custom-provider-anthropic/index.ts +27 -31
  521. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  522. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  523. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  524. package/examples/extensions/debug-provider.ts +2 -2
  525. package/examples/extensions/gondolin/package-lock.json +19 -29
  526. package/examples/extensions/gondolin/package.json +2 -2
  527. package/examples/extensions/preset.ts +2 -0
  528. package/examples/extensions/reload-runtime.ts +17 -5
  529. package/examples/extensions/tools.ts +2 -0
  530. package/examples/extensions/with-deps/package-lock.json +2 -2
  531. package/examples/extensions/with-deps/package.json +1 -1
  532. package/package.json +9 -9
  533. package/schemas/models.schema.json +36 -36
  534. package/schemas/settings.schema.json +17 -0
  535. package/dist/bundle/chunks/anthropic-messages-HWL6AS7T.js +0 -6
  536. package/dist/bundle/chunks/azure-openai-responses-4YYPDYV5.js +0 -2
  537. package/dist/bundle/chunks/chunk-6JS2SOFO.js +0 -11
  538. package/dist/bundle/chunks/chunk-ANCZPKX7.js +0 -2
  539. package/dist/bundle/chunks/chunk-FEZ5RM2B.js +0 -2
  540. package/dist/bundle/chunks/chunk-LPF7HQ3S.js +0 -4
  541. package/dist/bundle/chunks/chunk-MMNIHCU7.js +0 -2
  542. package/dist/bundle/chunks/chunk-PUU43PDV.js +0 -1484
  543. package/dist/bundle/chunks/chunk-R267VV5T.js +0 -82
  544. package/dist/bundle/chunks/chunk-RVKT7OUB.js +0 -9
  545. package/dist/bundle/chunks/chunk-SA2AQYEI.js +0 -7
  546. package/dist/bundle/chunks/chunk-ZAIGBRV5.js +0 -16
  547. package/dist/bundle/chunks/mistral-conversations-V2JJTMJ5.js +0 -5
  548. package/dist/bundle/chunks/openai-completions-TXZXILJR.js +0 -7
  549. package/dist/bundle/chunks/pi-messages-LBJQ4NGP.js +0 -8
  550. package/dist/bundle/chunks/virtual-modules-63XNTSVN.js +0 -2
  551. package/dist/core/isolated-session.d.ts.map +0 -1
  552. package/dist/core/isolated-session.js.map +0 -1
  553. package/dist/modes/interactive/tool-view/fallback.d.ts.map +0 -1
  554. package/dist/modes/interactive/tool-view/fallback.js.map +0 -1
  555. package/dist/modes/interactive/tool-view/shell.d.ts.map +0 -1
  556. package/dist/modes/interactive/tool-view/shell.js.map +0 -1
  557. package/dist/utils/path-identity.d.ts +0 -12
  558. package/dist/utils/path-identity.d.ts.map +0 -1
  559. package/dist/utils/path-identity.js +0 -63
  560. package/dist/utils/path-identity.js.map +0 -1
  561. package/examples/extensions/sandbox/index.ts +0 -321
  562. package/examples/extensions/sandbox/package-lock.json +0 -92
  563. package/examples/extensions/sandbox/package.json +0 -19
  564. /package/dist/{modes/interactive/tool-view → extensions/tool-presentation}/fallback.d.ts +0 -0
@@ -9,6 +9,7 @@ export const TASK_TITLE_BYTES = 1024;
9
9
  export const TASK_LABEL_BYTES = 256;
10
10
  export const TASK_FACTS = 16;
11
11
  export const TASK_FACT_BYTES = 1024;
12
+ export const TASK_ACTIVITIES = 50;
12
13
  export const TASK_ERROR_BYTES = 4096;
13
14
  export const TASK_PATH_BYTES = 8192;
14
15
  /** A bounded, printable message for any thrown value. */
@@ -54,6 +55,38 @@ export function boundTaskText(text, bytes = TASK_RESULT_BYTES) {
54
55
  const bounded = boundText(text, bytes);
55
56
  return { text: bounded, truncated: bounded !== text };
56
57
  }
58
+ function activityTime(value) {
59
+ return value !== undefined && Number.isFinite(value) && value >= 0 ? value : undefined;
60
+ }
61
+ function boundActivity(activity) {
62
+ const target = activity.target === undefined ? undefined : boundText(activity.target, TASK_FACT_BYTES);
63
+ const error = activity.error === undefined ? undefined : boundText(activity.error, TASK_FACT_BYTES);
64
+ const startedAt = activityTime(activity.startedAt);
65
+ const durationMs = activityTime(activity.durationMs);
66
+ return {
67
+ name: boundText(activity.name, TASK_LABEL_BYTES),
68
+ status: activity.status,
69
+ ...(target === undefined ? {} : { target }),
70
+ ...(startedAt === undefined ? {} : { startedAt }),
71
+ ...(durationMs === undefined ? {} : { durationMs }),
72
+ ...(error === undefined ? {} : { error }),
73
+ };
74
+ }
75
+ /** Keep live display structured data bounded and detached; its plain text remains the portable fallback. */
76
+ export function boundTaskDisplay(display) {
77
+ if (typeof display === "string")
78
+ return boundTaskText(display);
79
+ const text = boundTaskText(display.text);
80
+ const activities = display.activities?.slice(-TASK_ACTIVITIES).map(boundActivity);
81
+ const omitted = display.activities ? display.activities.length - (activities?.length ?? 0) : 0;
82
+ const earlierActivities = finiteLimit((display.earlierActivities ?? 0) + omitted, 0, Number.MAX_SAFE_INTEGER);
83
+ return {
84
+ ...text,
85
+ truncated: display.truncated || text.truncated,
86
+ ...(activities ? { activities } : {}),
87
+ ...(display.earlierActivities !== undefined || omitted ? { earlierActivities } : {}),
88
+ };
89
+ }
57
90
  export function boundInput(input) {
58
91
  const text = boundTaskText(input.text, TASK_INPUT_BYTES);
59
92
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/core/tasks/output.ts"],"names":[],"mappings":"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","sourcesContent":["import { open } from \"node:fs/promises\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { finiteLimit } from \"../../utils/number.ts\";\nimport type { TaskFact, TaskInput, TaskRead, TaskReadOptions, TaskText } from \"./types.ts\";\n\nexport const TASK_RESULT_BYTES = 48 * 1024;\nexport const TASK_DETAILS_BYTES = 120 * 1024;\nexport const TASK_READ_BYTES = 8 * 1024;\nexport const TASK_INPUT_BYTES = 24 * 1024;\n/** Task title budget, independent of notification wording and rendering. */\nexport const TASK_TITLE_BYTES = 1024;\nexport const TASK_LABEL_BYTES = 256;\nexport const TASK_FACTS = 16;\nexport const TASK_FACT_BYTES = 1024;\nexport const TASK_ERROR_BYTES = 4096;\nexport const TASK_PATH_BYTES = 8192;\n\n/** A bounded, printable message for any thrown value. */\nexport function errorText(error: unknown, fallback = \"Task execution failed (unprintable error)\"): string {\n\ttry {\n\t\treturn boundText(error instanceof Error ? error.message : String(error), TASK_ERROR_BYTES);\n\t} catch {\n\t\treturn fallback;\n\t}\n}\n\nexport function boundReadBytes(bytes: number | undefined): number {\n\treturn finiteLimit(bytes, TASK_READ_BYTES, TASK_RESULT_BYTES);\n}\n\n/** Both ends are codepoint aligned, including a head read ending inside a character. */\nfunction alignedSlice(buffer: Buffer, start: number, end: number): Buffer {\n\twhile (start < end && (buffer[start]! & 0xc0) === 0x80) start++;\n\tif (end < buffer.length) {\n\t\twhile (end > start && (buffer[end]! & 0xc0) === 0x80) end--;\n\t}\n\t// A concurrently written file can itself end in an incomplete UTF-8 sequence.\n\tlet lead = end - 1;\n\twhile (lead >= start && (buffer[lead]! & 0xc0) === 0x80) lead--;\n\tif (lead >= start) {\n\t\tconst byte = buffer[lead]!;\n\t\tconst width = byte >= 0xf0 ? 4 : byte >= 0xe0 ? 3 : byte >= 0xc0 ? 2 : 1;\n\t\tif (end - lead < width) end = lead;\n\t}\n\treturn buffer.subarray(start, end);\n}\n\nexport function boundText(text: string, bytes = TASK_RESULT_BYTES): string {\n\t// Avoid allocating a buffer proportional to an unbounded source.\n\tconst limit = finiteLimit(bytes, TASK_RESULT_BYTES, TASK_RESULT_BYTES);\n\tconst prefix = text.slice(0, limit + 1);\n\tconst buffer = Buffer.from(prefix);\n\treturn alignedSlice(buffer, 0, Math.min(limit, buffer.length)).toString(\"utf8\");\n}\n\nexport function boundTaskText(text: string, bytes = TASK_RESULT_BYTES): TaskText {\n\tconst bounded = boundText(text, bytes);\n\treturn { text: bounded, truncated: bounded !== text };\n}\n\nexport function boundInput(input: TaskInput): TaskInput {\n\tconst text = boundTaskText(input.text, TASK_INPUT_BYTES);\n\treturn {\n\t\tlabel: boundText(input.label, TASK_LABEL_BYTES),\n\t\ttext: text.text,\n\t\ttruncated: input.truncated || text.truncated,\n\t\t...(input.language ? { language: boundText(input.language, 64) } : {}),\n\t};\n}\n\nexport function boundFacts(facts: readonly TaskFact[]): TaskFact[] {\n\treturn facts\n\t\t.slice(0, TASK_FACTS)\n\t\t.map(([label, value]): TaskFact => [boundText(label, TASK_LABEL_BYTES), boundText(value, TASK_FACT_BYTES)]);\n}\n\n/** The end of a bounded text, codepoint aligned: a command's outcome is at its end. */\nexport function boundTail(text: string, bytes: number): { text: string; truncated: boolean } {\n\tconst buffer = Buffer.from(text);\n\tif (buffer.length <= bytes) return { text, truncated: false };\n\treturn { text: alignedSlice(buffer, buffer.length - bytes, buffer.length).toString(\"utf8\"), truncated: true };\n}\n\n/** The bounded model-readable text of a result; images and private details never enter task state. */\nexport function resultText(result: AgentToolResult<unknown>): TaskText {\n\tlet remaining = TASK_RESULT_BYTES;\n\tconst parts: string[] = [];\n\tlet truncated = false;\n\tfor (const block of result.content) {\n\t\tif (remaining <= 0) {\n\t\t\ttruncated = true;\n\t\t\tbreak;\n\t\t}\n\t\tconst source = block.type === \"text\" ? block.text : \"[Image omitted from task output]\";\n\t\tconst text = boundText(source, remaining);\n\t\tif (block.type !== \"text\" || text !== source) truncated = true;\n\t\tparts.push(text);\n\t\tremaining -= Math.max(1, Buffer.byteLength(text) + 1);\n\t}\n\treturn { text: boundText(parts.join(\"\\n\")), truncated };\n}\n\nexport interface OutputSlice {\n\ttext: string;\n\ttotalBytes: number;\n\ttruncated: boolean;\n\tfromByte: number;\n\t/** Raw source-byte end, independent of UTF-8 decoding or replacement characters. */\n\tendByte: number;\n}\n\n/** Raw source-byte range; decoding invalid UTF-8 must never move the continuation offset. */\nexport function taskReadRange(slice: Pick<TaskRead, \"text\" | \"fromByte\" | \"endByte\">): { from: number; to: number } {\n\tconst from = slice.fromByte ?? 0;\n\treturn { from, to: slice.endByte ?? from + Buffer.byteLength(slice.text) };\n}\n\nexport function taskReadBytes(slice: Pick<TaskRead, \"text\" | \"fromByte\" | \"endByte\">): number {\n\tconst { from, to } = taskReadRange(slice);\n\treturn to - from;\n}\n\n/**\n * The byte window a read covers in an output of `size` bytes. `floor` is the first byte the\n * caller has not seen yet. A head read continues forward from it; a tail read keeps the newest\n * unread window. Anything before the floor never counts as truncated.\n */\nfunction readWindow(size: number, options: TaskReadOptions): { start: number; length: number; floor: number } {\n\tconst bytes = boundReadBytes(options.bytes);\n\tconst since = finiteLimit(options.sinceBytes, 0, Number.MAX_SAFE_INTEGER);\n\tconst floor = since > size ? 0 : since;\n\tconst start =\n\t\toptions.mode === \"head\" ? (options.sinceBytes !== undefined ? floor : 0) : Math.max(floor, size - bytes);\n\treturn { start, length: Math.min(bytes, size - start), floor };\n}\n\nfunction outputSlice(size: number, slice: Buffer, fromByte: number, earlierTruncated: boolean): OutputSlice {\n\tconst endByte = fromByte + slice.byteLength;\n\treturn {\n\t\ttext: slice.toString(\"utf8\"),\n\t\ttotalBytes: size,\n\t\ttruncated: earlierTruncated || endByte < size,\n\t\tfromByte,\n\t\tendByte,\n\t};\n}\n\n/** Positioned, bounded reads only. The executor owns the path and its cleanup. */\nexport async function readOutputSlice(path: string, options: TaskReadOptions = {}): Promise<OutputSlice> {\n\tconst file = await open(path, \"r\");\n\ttry {\n\t\tconst { size } = await file.stat();\n\t\tconst { start, length, floor } = readWindow(size, options);\n\t\t// One extra byte lets alignment distinguish a complete last codepoint.\n\t\tconst buffer = Buffer.alloc(Math.min(length + 1, size - start));\n\t\tconst { bytesRead } = await file.read(buffer, 0, buffer.length, start);\n\t\tconst slice = alignedSlice(buffer.subarray(0, bytesRead), 0, Math.min(length, bytesRead));\n\t\treturn outputSlice(\n\t\t\tsize,\n\t\t\tslice,\n\t\t\tstart + slice.byteOffset - buffer.byteOffset,\n\t\t\toptions.mode !== \"head\" && start > floor,\n\t\t);\n\t} finally {\n\t\tawait file.close();\n\t}\n}\n\nexport function sliceText(text: string, options: TaskReadOptions = {}): OutputSlice {\n\tconst buffer = Buffer.from(text);\n\tconst { start, length, floor } = readWindow(buffer.length, options);\n\tconst slice = alignedSlice(buffer, start, start + length);\n\treturn outputSlice(\n\t\tbuffer.length,\n\t\tslice,\n\t\tslice.byteOffset - buffer.byteOffset,\n\t\toptions.mode !== \"head\" && start > floor,\n\t);\n}\n"]}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/core/tasks/output.ts"],"names":[],"mappings":"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","sourcesContent":["import { open } from \"node:fs/promises\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { finiteLimit } from \"../../utils/number.ts\";\nimport type { TaskActivity, TaskDisplay, TaskFact, TaskInput, TaskRead, TaskReadOptions, TaskText } from \"./types.ts\";\n\nexport const TASK_RESULT_BYTES = 48 * 1024;\nexport const TASK_DETAILS_BYTES = 120 * 1024;\nexport const TASK_READ_BYTES = 8 * 1024;\nexport const TASK_INPUT_BYTES = 24 * 1024;\n/** Task title budget, independent of notification wording and rendering. */\nexport const TASK_TITLE_BYTES = 1024;\nexport const TASK_LABEL_BYTES = 256;\nexport const TASK_FACTS = 16;\nexport const TASK_FACT_BYTES = 1024;\nexport const TASK_ACTIVITIES = 50;\nexport const TASK_ERROR_BYTES = 4096;\nexport const TASK_PATH_BYTES = 8192;\n\n/** A bounded, printable message for any thrown value. */\nexport function errorText(error: unknown, fallback = \"Task execution failed (unprintable error)\"): string {\n\ttry {\n\t\treturn boundText(error instanceof Error ? error.message : String(error), TASK_ERROR_BYTES);\n\t} catch {\n\t\treturn fallback;\n\t}\n}\n\nexport function boundReadBytes(bytes: number | undefined): number {\n\treturn finiteLimit(bytes, TASK_READ_BYTES, TASK_RESULT_BYTES);\n}\n\n/** Both ends are codepoint aligned, including a head read ending inside a character. */\nfunction alignedSlice(buffer: Buffer, start: number, end: number): Buffer {\n\twhile (start < end && (buffer[start]! & 0xc0) === 0x80) start++;\n\tif (end < buffer.length) {\n\t\twhile (end > start && (buffer[end]! & 0xc0) === 0x80) end--;\n\t}\n\t// A concurrently written file can itself end in an incomplete UTF-8 sequence.\n\tlet lead = end - 1;\n\twhile (lead >= start && (buffer[lead]! & 0xc0) === 0x80) lead--;\n\tif (lead >= start) {\n\t\tconst byte = buffer[lead]!;\n\t\tconst width = byte >= 0xf0 ? 4 : byte >= 0xe0 ? 3 : byte >= 0xc0 ? 2 : 1;\n\t\tif (end - lead < width) end = lead;\n\t}\n\treturn buffer.subarray(start, end);\n}\n\nexport function boundText(text: string, bytes = TASK_RESULT_BYTES): string {\n\t// Avoid allocating a buffer proportional to an unbounded source.\n\tconst limit = finiteLimit(bytes, TASK_RESULT_BYTES, TASK_RESULT_BYTES);\n\tconst prefix = text.slice(0, limit + 1);\n\tconst buffer = Buffer.from(prefix);\n\treturn alignedSlice(buffer, 0, Math.min(limit, buffer.length)).toString(\"utf8\");\n}\n\nexport function boundTaskText(text: string, bytes = TASK_RESULT_BYTES): TaskText {\n\tconst bounded = boundText(text, bytes);\n\treturn { text: bounded, truncated: bounded !== text };\n}\n\nfunction activityTime(value: number | undefined): number | undefined {\n\treturn value !== undefined && Number.isFinite(value) && value >= 0 ? value : undefined;\n}\n\nfunction boundActivity(activity: TaskActivity): TaskActivity {\n\tconst target = activity.target === undefined ? undefined : boundText(activity.target, TASK_FACT_BYTES);\n\tconst error = activity.error === undefined ? undefined : boundText(activity.error, TASK_FACT_BYTES);\n\tconst startedAt = activityTime(activity.startedAt);\n\tconst durationMs = activityTime(activity.durationMs);\n\treturn {\n\t\tname: boundText(activity.name, TASK_LABEL_BYTES),\n\t\tstatus: activity.status,\n\t\t...(target === undefined ? {} : { target }),\n\t\t...(startedAt === undefined ? {} : { startedAt }),\n\t\t...(durationMs === undefined ? {} : { durationMs }),\n\t\t...(error === undefined ? {} : { error }),\n\t};\n}\n\n/** Keep live display structured data bounded and detached; its plain text remains the portable fallback. */\nexport function boundTaskDisplay(display: string | TaskDisplay): TaskDisplay {\n\tif (typeof display === \"string\") return boundTaskText(display);\n\tconst text = boundTaskText(display.text);\n\tconst activities = display.activities?.slice(-TASK_ACTIVITIES).map(boundActivity);\n\tconst omitted = display.activities ? display.activities.length - (activities?.length ?? 0) : 0;\n\tconst earlierActivities = finiteLimit((display.earlierActivities ?? 0) + omitted, 0, Number.MAX_SAFE_INTEGER);\n\treturn {\n\t\t...text,\n\t\ttruncated: display.truncated || text.truncated,\n\t\t...(activities ? { activities } : {}),\n\t\t...(display.earlierActivities !== undefined || omitted ? { earlierActivities } : {}),\n\t};\n}\n\nexport function boundInput(input: TaskInput): TaskInput {\n\tconst text = boundTaskText(input.text, TASK_INPUT_BYTES);\n\treturn {\n\t\tlabel: boundText(input.label, TASK_LABEL_BYTES),\n\t\ttext: text.text,\n\t\ttruncated: input.truncated || text.truncated,\n\t\t...(input.language ? { language: boundText(input.language, 64) } : {}),\n\t};\n}\n\nexport function boundFacts(facts: readonly TaskFact[]): TaskFact[] {\n\treturn facts\n\t\t.slice(0, TASK_FACTS)\n\t\t.map(([label, value]): TaskFact => [boundText(label, TASK_LABEL_BYTES), boundText(value, TASK_FACT_BYTES)]);\n}\n\n/** The end of a bounded text, codepoint aligned: a command's outcome is at its end. */\nexport function boundTail(text: string, bytes: number): { text: string; truncated: boolean } {\n\tconst buffer = Buffer.from(text);\n\tif (buffer.length <= bytes) return { text, truncated: false };\n\treturn { text: alignedSlice(buffer, buffer.length - bytes, buffer.length).toString(\"utf8\"), truncated: true };\n}\n\n/** The bounded model-readable text of a result; images and private details never enter task state. */\nexport function resultText(result: AgentToolResult<unknown>): TaskText {\n\tlet remaining = TASK_RESULT_BYTES;\n\tconst parts: string[] = [];\n\tlet truncated = false;\n\tfor (const block of result.content) {\n\t\tif (remaining <= 0) {\n\t\t\ttruncated = true;\n\t\t\tbreak;\n\t\t}\n\t\tconst source = block.type === \"text\" ? block.text : \"[Image omitted from task output]\";\n\t\tconst text = boundText(source, remaining);\n\t\tif (block.type !== \"text\" || text !== source) truncated = true;\n\t\tparts.push(text);\n\t\tremaining -= Math.max(1, Buffer.byteLength(text) + 1);\n\t}\n\treturn { text: boundText(parts.join(\"\\n\")), truncated };\n}\n\nexport interface OutputSlice {\n\ttext: string;\n\ttotalBytes: number;\n\ttruncated: boolean;\n\tfromByte: number;\n\t/** Raw source-byte end, independent of UTF-8 decoding or replacement characters. */\n\tendByte: number;\n}\n\n/** Raw source-byte range; decoding invalid UTF-8 must never move the continuation offset. */\nexport function taskReadRange(slice: Pick<TaskRead, \"text\" | \"fromByte\" | \"endByte\">): { from: number; to: number } {\n\tconst from = slice.fromByte ?? 0;\n\treturn { from, to: slice.endByte ?? from + Buffer.byteLength(slice.text) };\n}\n\nexport function taskReadBytes(slice: Pick<TaskRead, \"text\" | \"fromByte\" | \"endByte\">): number {\n\tconst { from, to } = taskReadRange(slice);\n\treturn to - from;\n}\n\n/**\n * The byte window a read covers in an output of `size` bytes. `floor` is the first byte the\n * caller has not seen yet. A head read continues forward from it; a tail read keeps the newest\n * unread window. Anything before the floor never counts as truncated.\n */\nfunction readWindow(size: number, options: TaskReadOptions): { start: number; length: number; floor: number } {\n\tconst bytes = boundReadBytes(options.bytes);\n\tconst since = finiteLimit(options.sinceBytes, 0, Number.MAX_SAFE_INTEGER);\n\tconst floor = since > size ? 0 : since;\n\tconst start =\n\t\toptions.mode === \"head\" ? (options.sinceBytes !== undefined ? floor : 0) : Math.max(floor, size - bytes);\n\treturn { start, length: Math.min(bytes, size - start), floor };\n}\n\nfunction outputSlice(size: number, slice: Buffer, fromByte: number, earlierTruncated: boolean): OutputSlice {\n\tconst endByte = fromByte + slice.byteLength;\n\treturn {\n\t\ttext: slice.toString(\"utf8\"),\n\t\ttotalBytes: size,\n\t\ttruncated: earlierTruncated || endByte < size,\n\t\tfromByte,\n\t\tendByte,\n\t};\n}\n\n/** Positioned, bounded reads only. The executor owns the path and its cleanup. */\nexport async function readOutputSlice(path: string, options: TaskReadOptions = {}): Promise<OutputSlice> {\n\tconst file = await open(path, \"r\");\n\ttry {\n\t\tconst { size } = await file.stat();\n\t\tconst { start, length, floor } = readWindow(size, options);\n\t\t// One extra byte lets alignment distinguish a complete last codepoint.\n\t\tconst buffer = Buffer.alloc(Math.min(length + 1, size - start));\n\t\tconst { bytesRead } = await file.read(buffer, 0, buffer.length, start);\n\t\tconst slice = alignedSlice(buffer.subarray(0, bytesRead), 0, Math.min(length, bytesRead));\n\t\treturn outputSlice(\n\t\t\tsize,\n\t\t\tslice,\n\t\t\tstart + slice.byteOffset - buffer.byteOffset,\n\t\t\toptions.mode !== \"head\" && start > floor,\n\t\t);\n\t} finally {\n\t\tawait file.close();\n\t}\n}\n\nexport function sliceText(text: string, options: TaskReadOptions = {}): OutputSlice {\n\tconst buffer = Buffer.from(text);\n\tconst { start, length, floor } = readWindow(buffer.length, options);\n\tconst slice = alignedSlice(buffer, start, start + length);\n\treturn outputSlice(\n\t\tbuffer.length,\n\t\tslice,\n\t\tslice.byteOffset - buffer.byteOffset,\n\t\toptions.mode !== \"head\" && start > floor,\n\t);\n}\n"]}
@@ -1,5 +1,4 @@
1
- import type { Theme } from "../../modes/interactive/theme/theme.ts";
2
- import { type TaskPresenter, type TaskSnapshot } from "./types.ts";
1
+ import { type TaskSnapshot } from "./types.ts";
3
2
  export declare const EXPIRED_OUTPUT = "Output has expired: the managed log was released; showing the stored result.";
4
3
  type OutputCleanup = () => void | Promise<void>;
5
4
  /**
@@ -21,16 +20,11 @@ export declare class TaskRecord {
21
20
  private pins;
22
21
  private cleanup?;
23
22
  private expiredReason?;
24
- private presenter?;
25
23
  constructor(task: TaskSnapshot);
26
24
  /** A terminal record rebuilt from persisted history: nothing is left to run or deliver. */
27
25
  static restored(task: TaskSnapshot, readError: string | undefined): TaskRecord;
28
26
  /** Terminal: nothing is left to run. Derived from the status so it can never disagree with it. */
29
27
  get settled(): boolean;
30
- /** The executor's live Output renderer; held in memory for a running task only. */
31
- setPresenter(presenter: TaskPresenter | undefined): void;
32
- /** Live Output while running; `undefined` once settled, without a presenter, or if the presenter throws. */
33
- present(width: number, theme: Theme): string[] | undefined;
34
28
  /** Called once, after the terminal snapshot is final. */
35
29
  settle(): void;
36
30
  update(mutate: (task: TaskSnapshot) => void): void;
@@ -1 +1 @@
1
- {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/record.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,EAAkB,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAEnF,eAAO,MAAM,cAAc,iFAAiF,CAAC;AAU7G,KAAK,aAAa,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhD;;;;;;GAMG;AACH,qBAAa,UAAU;IACtB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IACtC,yFAAyF;IACzF,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,MAAM,CAAC,CAAe;IAC9B,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,OAAO,CAAC,CAAgB;IAChC,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAgB;gBAEtB,IAAI,EAAE,YAAY;IAQ9B,2FAA2F;IAC3F,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU;IAO9E,kGAAkG;IAClG,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,mFAAmF;IACnF,YAAY,CAAC,SAAS,EAAE,aAAa,GAAG,SAAS,GAAG,IAAI;IAIxD,4GAA4G;IAC5G,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,EAAE,GAAG,SAAS;IAW1D,yDAAyD;IACzD,MAAM,IAAI,IAAI;IAKd,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAQlD,mGAAmG;IACnG,QAAQ,IAAI,YAAY;IAKxB,2DAA2D;IAC3D,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,6FAA6F;IAC7F,GAAG,IAAI,MAAM,IAAI;IAUjB,sEAAsE;IACtE,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,kFAAkF;IAClF,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED,gGAAgG;IAChG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI;IAQzD;;;OAGG;IACH,YAAY,IAAI,aAAa,GAAG,SAAS;CAUzC"}
1
+ {"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/record.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/D,eAAO,MAAM,cAAc,iFAAiF,CAAC;AAU7G,KAAK,aAAa,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEhD;;;;;;GAMG;AACH,qBAAa,UAAU;IACtB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IACtC,yFAAyF;IACzF,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,MAAM,CAAC,CAAe;IAC9B,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,OAAO,CAAC,CAAgB;IAChC,OAAO,CAAC,aAAa,CAAC,CAAS;gBAEnB,IAAI,EAAE,YAAY;IAQ9B,2FAA2F;IAC3F,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU;IAO9E,kGAAkG;IAClG,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,yDAAyD;IACzD,MAAM,IAAI,IAAI;IAId,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAQlD,mGAAmG;IACnG,QAAQ,IAAI,YAAY;IAKxB,2DAA2D;IAC3D,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,6FAA6F;IAC7F,GAAG,IAAI,MAAM,IAAI;IAUjB,sEAAsE;IACtE,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,kFAAkF;IAClF,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED,gGAAgG;IAChG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,IAAI;IAQzD;;;OAGG;IACH,YAAY,IAAI,aAAa,GAAG,SAAS;CAUzC"}
@@ -36,26 +36,8 @@ export class TaskRecord {
36
36
  get settled() {
37
37
  return isTaskTerminal(this.working.status);
38
38
  }
39
- /** The executor's live Output renderer; held in memory for a running task only. */
40
- setPresenter(presenter) {
41
- this.presenter = presenter;
42
- }
43
- /** Live Output while running; `undefined` once settled, without a presenter, or if the presenter throws. */
44
- present(width, theme) {
45
- if (this.settled || !this.presenter)
46
- return undefined;
47
- try {
48
- const lines = this.presenter(width, theme);
49
- return Array.isArray(lines) ? lines : undefined;
50
- }
51
- catch {
52
- // An executor bug must not break the panel; it falls back to the default view.
53
- return undefined;
54
- }
55
- }
56
39
  /** Called once, after the terminal snapshot is final. */
57
40
  settle() {
58
- this.presenter = undefined;
59
41
  this.resolveSettlement();
60
42
  }
61
43
  update(mutate) {
@@ -1 +1 @@
1
- {"version":3,"file":"record.js","sourceRoot":"","sources":["../../../src/core/tasks/record.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { isTaskTerminal, type TaskPresenter, type TaskSnapshot } from \"./types.ts\";\n\nexport const EXPIRED_OUTPUT = \"Output has expired: the managed log was released; showing the stored result.\";\n\nfunction freeze<T>(value: T): T {\n\tif (value !== null && typeof value === \"object\" && !Object.isFrozen(value)) {\n\t\tfor (const child of Object.values(value)) freeze(child);\n\t\tObject.freeze(value);\n\t}\n\treturn value;\n}\n\ntype OutputCleanup = () => void | Promise<void>;\n\n/**\n * The runtime's state for one task: its working snapshot, whether it is on the selected branch,\n * the pins that keep it retained, and the managed output it owns. Whether a completion reached\n * the model is a session concern held outside the runtime as a pin. Every lifecycle fact changes\n * through a named method here; the working snapshot changes only through `update()`, which also\n * drops the frozen copy that readers share, so a mutation can never leave a stale snapshot behind.\n */\nexport class TaskRecord {\n\t/** Read-only view of the working copy; change it with update(). */\n\treadonly task: Readonly<TaskSnapshot>;\n\t/** Settles once the task is terminal and its final snapshot is stored. Never rejects. */\n\treadonly settlement: Promise<void>;\n\tprivate readonly working: TaskSnapshot;\n\tprivate frozen?: TaskSnapshot;\n\tprivate resolveSettlement!: () => void;\n\tprivate onBranch = true;\n\tprivate pins = 0;\n\tprivate cleanup?: OutputCleanup;\n\tprivate expiredReason?: string;\n\tprivate presenter?: TaskPresenter;\n\n\tconstructor(task: TaskSnapshot) {\n\t\tthis.working = task;\n\t\tthis.task = task;\n\t\tthis.settlement = new Promise<void>((resolve) => {\n\t\t\tthis.resolveSettlement = resolve;\n\t\t});\n\t}\n\n\t/** A terminal record rebuilt from persisted history: nothing is left to run or deliver. */\n\tstatic restored(task: TaskSnapshot, readError: string | undefined): TaskRecord {\n\t\tconst record = new TaskRecord(task);\n\t\trecord.expiredReason = readError;\n\t\trecord.settle();\n\t\treturn record;\n\t}\n\n\t/** Terminal: nothing is left to run. Derived from the status so it can never disagree with it. */\n\tget settled(): boolean {\n\t\treturn isTaskTerminal(this.working.status);\n\t}\n\n\t/** The executor's live Output renderer; held in memory for a running task only. */\n\tsetPresenter(presenter: TaskPresenter | undefined): void {\n\t\tthis.presenter = presenter;\n\t}\n\n\t/** Live Output while running; `undefined` once settled, without a presenter, or if the presenter throws. */\n\tpresent(width: number, theme: Theme): string[] | undefined {\n\t\tif (this.settled || !this.presenter) return undefined;\n\t\ttry {\n\t\t\tconst lines = this.presenter(width, theme);\n\t\t\treturn Array.isArray(lines) ? lines : undefined;\n\t\t} catch {\n\t\t\t// An executor bug must not break the panel; it falls back to the default view.\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/** Called once, after the terminal snapshot is final. */\n\tsettle(): void {\n\t\tthis.presenter = undefined;\n\t\tthis.resolveSettlement();\n\t}\n\n\tupdate(mutate: (task: TaskSnapshot) => void): void {\n\t\ttry {\n\t\t\tmutate(this.working);\n\t\t} finally {\n\t\t\tthis.frozen = undefined;\n\t\t}\n\t}\n\n\t/** Readers share one frozen copy, so polling and status rendering never clone unchanged output. */\n\tsnapshot(): TaskSnapshot {\n\t\tthis.frozen ??= freeze(structuredClone(this.working));\n\t\treturn this.frozen;\n\t}\n\n\t/** Whether the launch anchor is on the selected branch. */\n\tget visible(): boolean {\n\t\treturn this.onBranch;\n\t}\n\n\tsetVisible(visible: boolean): void {\n\t\tthis.onBranch = visible;\n\t}\n\n\t/** Keep the record, and its output, retained until the returned release runs. Idempotent. */\n\tpin(): () => void {\n\t\tthis.pins++;\n\t\tlet released = false;\n\t\treturn () => {\n\t\t\tif (released) return;\n\t\t\treleased = true;\n\t\t\tthis.pins--;\n\t\t};\n\t}\n\n\t/** Settled and unpinned: bounded history that retention may evict. */\n\tget inHistory(): boolean {\n\t\treturn this.settled && this.pins === 0;\n\t}\n\n\t/** Why the output could not be read from a log: it expired, or was never kept. */\n\tget readError(): string | undefined {\n\t\treturn this.expiredReason;\n\t}\n\n\t/** Register the one output file this task owns; `cleanup` deletes it when retention lets go. */\n\tattachOutput(path: string, cleanup?: OutputCleanup): void {\n\t\tif (this.cleanup) throw new Error(\"Managed output is already registered\");\n\t\tthis.cleanup = cleanup;\n\t\tthis.update((task) => {\n\t\t\ttask.outputPath = path;\n\t\t});\n\t}\n\n\t/**\n\t * Release the managed output once nothing retains it. Returns the owner's cleanup to run, if\n\t * any; the snapshot keeps its final bounded text, so an expired file is never needed again.\n\t */\n\texpireOutput(): OutputCleanup | undefined {\n\t\tif (!this.settled || this.pins > 0 || !this.cleanup) return undefined;\n\t\tconst cleanup = this.cleanup;\n\t\tthis.cleanup = undefined;\n\t\tthis.update((task) => {\n\t\t\ttask.outputPath = undefined;\n\t\t});\n\t\tthis.expiredReason = EXPIRED_OUTPUT;\n\t\treturn cleanup;\n\t}\n}\n"]}
1
+ {"version":3,"file":"record.js","sourceRoot":"","sources":["../../../src/core/tasks/record.ts"],"names":[],"mappings":"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","sourcesContent":["import { isTaskTerminal, type TaskSnapshot } from \"./types.ts\";\n\nexport const EXPIRED_OUTPUT = \"Output has expired: the managed log was released; showing the stored result.\";\n\nfunction freeze<T>(value: T): T {\n\tif (value !== null && typeof value === \"object\" && !Object.isFrozen(value)) {\n\t\tfor (const child of Object.values(value)) freeze(child);\n\t\tObject.freeze(value);\n\t}\n\treturn value;\n}\n\ntype OutputCleanup = () => void | Promise<void>;\n\n/**\n * The runtime's state for one task: its working snapshot, whether it is on the selected branch,\n * the pins that keep it retained, and the managed output it owns. Whether a completion reached\n * the model is a session concern held outside the runtime as a pin. Every lifecycle fact changes\n * through a named method here; the working snapshot changes only through `update()`, which also\n * drops the frozen copy that readers share, so a mutation can never leave a stale snapshot behind.\n */\nexport class TaskRecord {\n\t/** Read-only view of the working copy; change it with update(). */\n\treadonly task: Readonly<TaskSnapshot>;\n\t/** Settles once the task is terminal and its final snapshot is stored. Never rejects. */\n\treadonly settlement: Promise<void>;\n\tprivate readonly working: TaskSnapshot;\n\tprivate frozen?: TaskSnapshot;\n\tprivate resolveSettlement!: () => void;\n\tprivate onBranch = true;\n\tprivate pins = 0;\n\tprivate cleanup?: OutputCleanup;\n\tprivate expiredReason?: string;\n\n\tconstructor(task: TaskSnapshot) {\n\t\tthis.working = task;\n\t\tthis.task = task;\n\t\tthis.settlement = new Promise<void>((resolve) => {\n\t\t\tthis.resolveSettlement = resolve;\n\t\t});\n\t}\n\n\t/** A terminal record rebuilt from persisted history: nothing is left to run or deliver. */\n\tstatic restored(task: TaskSnapshot, readError: string | undefined): TaskRecord {\n\t\tconst record = new TaskRecord(task);\n\t\trecord.expiredReason = readError;\n\t\trecord.settle();\n\t\treturn record;\n\t}\n\n\t/** Terminal: nothing is left to run. Derived from the status so it can never disagree with it. */\n\tget settled(): boolean {\n\t\treturn isTaskTerminal(this.working.status);\n\t}\n\n\t/** Called once, after the terminal snapshot is final. */\n\tsettle(): void {\n\t\tthis.resolveSettlement();\n\t}\n\n\tupdate(mutate: (task: TaskSnapshot) => void): void {\n\t\ttry {\n\t\t\tmutate(this.working);\n\t\t} finally {\n\t\t\tthis.frozen = undefined;\n\t\t}\n\t}\n\n\t/** Readers share one frozen copy, so polling and status rendering never clone unchanged output. */\n\tsnapshot(): TaskSnapshot {\n\t\tthis.frozen ??= freeze(structuredClone(this.working));\n\t\treturn this.frozen;\n\t}\n\n\t/** Whether the launch anchor is on the selected branch. */\n\tget visible(): boolean {\n\t\treturn this.onBranch;\n\t}\n\n\tsetVisible(visible: boolean): void {\n\t\tthis.onBranch = visible;\n\t}\n\n\t/** Keep the record, and its output, retained until the returned release runs. Idempotent. */\n\tpin(): () => void {\n\t\tthis.pins++;\n\t\tlet released = false;\n\t\treturn () => {\n\t\t\tif (released) return;\n\t\t\treleased = true;\n\t\t\tthis.pins--;\n\t\t};\n\t}\n\n\t/** Settled and unpinned: bounded history that retention may evict. */\n\tget inHistory(): boolean {\n\t\treturn this.settled && this.pins === 0;\n\t}\n\n\t/** Why the output could not be read from a log: it expired, or was never kept. */\n\tget readError(): string | undefined {\n\t\treturn this.expiredReason;\n\t}\n\n\t/** Register the one output file this task owns; `cleanup` deletes it when retention lets go. */\n\tattachOutput(path: string, cleanup?: OutputCleanup): void {\n\t\tif (this.cleanup) throw new Error(\"Managed output is already registered\");\n\t\tthis.cleanup = cleanup;\n\t\tthis.update((task) => {\n\t\t\ttask.outputPath = path;\n\t\t});\n\t}\n\n\t/**\n\t * Release the managed output once nothing retains it. Returns the owner's cleanup to run, if\n\t * any; the snapshot keeps its final bounded text, so an expired file is never needed again.\n\t */\n\texpireOutput(): OutputCleanup | undefined {\n\t\tif (!this.settled || this.pins > 0 || !this.cleanup) return undefined;\n\t\tconst cleanup = this.cleanup;\n\t\tthis.cleanup = undefined;\n\t\tthis.update((task) => {\n\t\t\ttask.outputPath = undefined;\n\t\t});\n\t\tthis.expiredReason = EXPIRED_OUTPUT;\n\t\treturn cleanup;\n\t}\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { AgentMessage } from "@earendil-works/pi-agent-core";
2
- import type { TaskRuntime } from "./runtime.ts";
2
+ import { type TaskSnapshot } from "./types.ts";
3
3
  /**
4
4
  * A one-shot, request-local reminder after compaction. It is never persisted and
5
5
  * creates no turn. Failed requests keep it eligible; an assistant response consumes it.
@@ -8,7 +8,8 @@ export declare class TaskContextReminder {
8
8
  private pending;
9
9
  private projected;
10
10
  compacted(): void;
11
- project(service: TaskRuntime, messages: AgentMessage[]): AgentMessage[];
11
+ /** `runningBackground` is read only while a reminder is pending. */
12
+ project(messages: AgentMessage[], runningBackground: () => TaskSnapshot[]): AgentMessage[];
12
13
  assistantCompleted(): void;
13
14
  reset(): void;
14
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reminder.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/reminder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAQhD;;;GAGG;AACH,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAE1B,SAAS,IAAI,IAAI;IAKjB,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE;IAyBvE,kBAAkB,IAAI,IAAI;IAI1B,KAAK,IAAI,IAAI;CAIb"}
1
+ {"version":3,"file":"reminder.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/reminder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAOhE;;;GAGG;AACH,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAE1B,SAAS,IAAI,IAAI;IAKjB,oEAAoE;IACpE,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,iBAAiB,EAAE,MAAM,YAAY,EAAE,GAAG,YAAY,EAAE;IAyB1F,kBAAkB,IAAI,IAAI;IAI1B,KAAK,IAAI,IAAI;CAIb"}
@@ -1,5 +1,5 @@
1
1
  import { boundText } from "./output.js";
2
- import { isTaskTerminal, TASKS_TOOL_NAME } from "./types.js";
2
+ import { TASKS_TOOL_NAME } from "./types.js";
3
3
  function taskLine(task) {
4
4
  const title = boundText(task.title.replace(/\s+/gu, " ").trim(), 240);
5
5
  return boundText(`${task.id} ${task.kind} ${task.status} ${title}`, 1024);
@@ -17,10 +17,11 @@ export class TaskContextReminder {
17
17
  this.pending = true;
18
18
  this.projected = false;
19
19
  }
20
- project(service, messages) {
20
+ /** `runningBackground` is read only while a reminder is pending. */
21
+ project(messages, runningBackground) {
21
22
  if (!this.pending)
22
23
  return messages;
23
- const tasks = service.list().filter((task) => task.mode === "background" && !isTaskTerminal(task.status));
24
+ const tasks = runningBackground();
24
25
  if (tasks.length === 0) {
25
26
  this.reset();
26
27
  return messages;
@@ -1 +1 @@
1
- {"version":3,"file":"reminder.js","sourceRoot":"","sources":["../../../src/core/tasks/reminder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAqB,MAAM,YAAY,CAAC;AAEhF,SAAS,QAAQ,CAAC,IAAkB;IACnC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;IACtE,OAAO,SAAS,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IAAhC;QACS,YAAO,GAAG,KAAK,CAAC;QAChB,cAAS,GAAG,KAAK,CAAC;IAwC3B,CAAC;IAtCA,SAAS;QACR,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,OAAoB,EAAE,QAAwB;QACrD,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,QAAQ,CAAC;QACnC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1G,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO,QAAQ,CAAC;QACjB,CAAC;QACD,MAAM,QAAQ,GAAiB;YAC9B,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE;gBACR;oBACC,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;wBACL,0FAA0F;wBAC1F,OAAO,eAAe,uGAAuG;wBAC7H,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;qBACtB,CAAC,IAAI,CAAC,IAAI,CAAC;iBACZ;aACD;YACD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACrB,CAAC;QACF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,OAAO,CAAC,GAAG,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,kBAAkB;QACjB,IAAI,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACxB,CAAC;CACD","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport { boundText } from \"./output.ts\";\nimport type { TaskRuntime } from \"./runtime.ts\";\nimport { isTaskTerminal, TASKS_TOOL_NAME, type TaskSnapshot } from \"./types.ts\";\n\nfunction taskLine(task: TaskSnapshot): string {\n\tconst title = boundText(task.title.replace(/\\s+/gu, \" \").trim(), 240);\n\treturn boundText(`${task.id} ${task.kind} ${task.status} ${title}`, 1024);\n}\n\n/**\n * A one-shot, request-local reminder after compaction. It is never persisted and\n * creates no turn. Failed requests keep it eligible; an assistant response consumes it.\n */\nexport class TaskContextReminder {\n\tprivate pending = false;\n\tprivate projected = false;\n\n\tcompacted(): void {\n\t\tthis.pending = true;\n\t\tthis.projected = false;\n\t}\n\n\tproject(service: TaskRuntime, messages: AgentMessage[]): AgentMessage[] {\n\t\tif (!this.pending) return messages;\n\t\tconst tasks = service.list().filter((task) => task.mode === \"background\" && !isTaskTerminal(task.status));\n\t\tif (tasks.length === 0) {\n\t\t\tthis.reset();\n\t\t\treturn messages;\n\t\t}\n\t\tconst reminder: AgentMessage = {\n\t\t\trole: \"user\",\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: [\n\t\t\t\t\t\t\"Context was compacted. These background tasks are still active; do not start duplicates.\",\n\t\t\t\t\t\t`Use ${TASKS_TOOL_NAME} list/read/kill to inspect or stop them. Each completion wakes you automatically; do not wait for it.`,\n\t\t\t\t\t\t...tasks.map(taskLine),\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t},\n\t\t\t],\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\t\tthis.projected = true;\n\t\treturn [...messages, reminder];\n\t}\n\n\tassistantCompleted(): void {\n\t\tif (this.projected) this.reset();\n\t}\n\n\treset(): void {\n\t\tthis.pending = false;\n\t\tthis.projected = false;\n\t}\n}\n"]}
1
+ {"version":3,"file":"reminder.js","sourceRoot":"","sources":["../../../src/core/tasks/reminder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAqB,MAAM,YAAY,CAAC;AAEhE,SAAS,QAAQ,CAAC,IAAkB;IACnC,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC;IACtE,OAAO,SAAS,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;AAC3E,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IAAhC;QACS,YAAO,GAAG,KAAK,CAAC;QAChB,cAAS,GAAG,KAAK,CAAC;IAyC3B,CAAC;IAvCA,SAAS;QACR,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,oEAAoE;IACpE,OAAO,CAAC,QAAwB,EAAE,iBAAuC;QACxE,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,QAAQ,CAAC;QACnC,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO,QAAQ,CAAC;QACjB,CAAC;QACD,MAAM,QAAQ,GAAiB;YAC9B,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE;gBACR;oBACC,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;wBACL,0FAA0F;wBAC1F,OAAO,eAAe,uGAAuG;wBAC7H,GAAG,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;qBACtB,CAAC,IAAI,CAAC,IAAI,CAAC;iBACZ;aACD;YACD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACrB,CAAC;QACF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,OAAO,CAAC,GAAG,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,kBAAkB;QACjB,IAAI,IAAI,CAAC,SAAS;YAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IAClC,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACxB,CAAC;CACD","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport { boundText } from \"./output.ts\";\nimport { TASKS_TOOL_NAME, type TaskSnapshot } from \"./types.ts\";\n\nfunction taskLine(task: TaskSnapshot): string {\n\tconst title = boundText(task.title.replace(/\\s+/gu, \" \").trim(), 240);\n\treturn boundText(`${task.id} ${task.kind} ${task.status} ${title}`, 1024);\n}\n\n/**\n * A one-shot, request-local reminder after compaction. It is never persisted and\n * creates no turn. Failed requests keep it eligible; an assistant response consumes it.\n */\nexport class TaskContextReminder {\n\tprivate pending = false;\n\tprivate projected = false;\n\n\tcompacted(): void {\n\t\tthis.pending = true;\n\t\tthis.projected = false;\n\t}\n\n\t/** `runningBackground` is read only while a reminder is pending. */\n\tproject(messages: AgentMessage[], runningBackground: () => TaskSnapshot[]): AgentMessage[] {\n\t\tif (!this.pending) return messages;\n\t\tconst tasks = runningBackground();\n\t\tif (tasks.length === 0) {\n\t\t\tthis.reset();\n\t\t\treturn messages;\n\t\t}\n\t\tconst reminder: AgentMessage = {\n\t\t\trole: \"user\",\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: [\n\t\t\t\t\t\t\"Context was compacted. These background tasks are still active; do not start duplicates.\",\n\t\t\t\t\t\t`Use ${TASKS_TOOL_NAME} list/read/kill to inspect or stop them. Each completion wakes you automatically; do not wait for it.`,\n\t\t\t\t\t\t...tasks.map(taskLine),\n\t\t\t\t\t].join(\"\\n\"),\n\t\t\t\t},\n\t\t\t],\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\t\tthis.projected = true;\n\t\treturn [...messages, reminder];\n\t}\n\n\tassistantCompleted(): void {\n\t\tif (this.projected) this.reset();\n\t}\n\n\treset(): void {\n\t\tthis.pending = false;\n\t\tthis.projected = false;\n\t}\n}\n"]}
@@ -1,5 +1,4 @@
1
1
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
2
- import type { Theme } from "../../modes/interactive/theme/theme.ts";
3
2
  import { type TaskExecution, type TaskRead, type TaskReadOptions, type TaskRuntimeOptions, type TaskSnapshot, type TasksContext, type TaskToolOutcome } from "./types.ts";
4
3
  /** Session-local supervision. Executors own their processes, items and output files. */
5
4
  export declare class TaskRuntime implements TasksContext {
@@ -48,7 +47,6 @@ export declare class TaskRuntime implements TasksContext {
48
47
  private lookup;
49
48
  get(id: string): TaskSnapshot;
50
49
  read(id: string, options?: TaskReadOptions): Promise<TaskRead>;
51
- presentOutput(id: string, width: number, theme: Theme): string[] | undefined;
52
50
  private resultText;
53
51
  kill(id: string): boolean;
54
52
  private cancel;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/runtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAiBrE,OAAO,EAIN,KAAK,aAAa,EAElB,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,MAAM,YAAY,CAAC;AAEpB,wFAAwF;AACxF,qBAAa,WAAY,YAAW,YAAY;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyC;IACpE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgB;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,iBAAiB,CAAU;IACnC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,kBAAuB;IAwB5C,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,OAAO,IAAI,kBAAkB,CAAC,SAAS,CAAC,CAE3C;IAED;;;;;;OAMG;IACH,cAAc,CACb,OAAO,EAAE,SAAS,OAAO,EAAE,EAC3B,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,GACpE,IAAI;IAIP,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAKlC,8GAA8G;IAC9G,OAAO,IAAI,IAAI;IAIf,oGAAoG;IACpG,OAAO,KAAK,gBAAgB,GAE3B;IAED;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,UAAU;IAMZ,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IA6C1E,OAAO,CAAC,UAAU;IAIlB,gBAAgB,IAAI,MAAM;IAW1B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK9B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAQ3B,kEAAkE;IAClE,OAAO,CAAC,SAAS;IAOjB,IAAI,IAAI,YAAY,EAAE;IAItB,OAAO,CAAC,MAAM;IAad,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY;IAIvB,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAuBxE,OAAO,CAAC,UAAU;IAIlB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIzB,OAAO,CAAC,MAAM;IAId,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAQ3C,yFAAyF;IACzF,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,IAAI;IAI9B,OAAO,CAAC,GAAG;IAQX,KAAK,IAAI,IAAI;IAYP,QAAQ,CAAC,OAAO,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C,mFAAmF;IACnF,mBAAmB,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,YAAY,EAAE;IAOnE;;;OAGG;IACG,mBAAmB,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAW1D,KAAK;IAgBnB,OAAO,CAAC,IAAI;CAWZ"}
@@ -53,7 +53,7 @@ export class TaskRuntime {
53
53
  this.store.restoreHistory(records, toolResults);
54
54
  }
55
55
  get enabled() {
56
- return this.configuredEnabled && !this.closed && this.options.backgroundAllowed !== false;
56
+ return this.configuredEnabled && !this.closed;
57
57
  }
58
58
  setEnabled(enabled) {
59
59
  this.configuredEnabled = enabled;
@@ -79,13 +79,11 @@ export class TaskRuntime {
79
79
  }
80
80
  async execute(execution) {
81
81
  // Admission and registration happen synchronously, before invoking user code or awaiting anything.
82
- if (execution.background && this.options.backgroundAllowed === false)
83
- throw new Error(TASK_BACKGROUND_REJECTION);
84
82
  if (this.closed)
85
83
  throw new Error("Task service is closed");
86
84
  if (execution.background) {
87
85
  if (!this.enabled)
88
- throw new Error("Background execution is not available in this host");
86
+ throw new Error(TASK_BACKGROUND_REJECTION);
89
87
  if (!this.admitsBackground)
90
88
  throw new Error(TASK_MANAGEMENT_REJECTION);
91
89
  if (this.backgroundActive() >= this.maxBackground)
@@ -119,7 +117,6 @@ export class TaskRuntime {
119
117
  startedAt: Date.now(),
120
118
  };
121
119
  const record = new TaskRecord(task);
122
- record.setPresenter(execution.present);
123
120
  const active = new Execution(this.host, record, execution);
124
121
  this.store.add(record);
125
122
  this.executions.set(task.id, active);
@@ -206,16 +203,6 @@ export class TaskRuntime {
206
203
  release();
207
204
  }
208
205
  }
209
- presentOutput(id, width, theme) {
210
- let record;
211
- try {
212
- record = this.lookup(id);
213
- }
214
- catch {
215
- return undefined;
216
- }
217
- return record.present(width, theme);
218
- }
219
206
  resultText(task) {
220
207
  return task.result?.text || task.error || "No output yet.";
221
208
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/core/tasks/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { finiteLimit } from \"../../utils/number.ts\";\nimport { Execution, type ExecutionHost } from \"./execution.ts\";\nimport { defaultReadMode } from \"./limits.ts\";\nimport {\n\tboundFacts,\n\tboundInput,\n\tboundText,\n\terrorText,\n\treadOutputSlice,\n\tsliceText,\n\tTASK_LABEL_BYTES,\n\tTASK_TITLE_BYTES,\n} from \"./output.ts\";\nimport { TaskRecord } from \"./record.ts\";\nimport { TaskScheduler } from \"./scheduler.ts\";\nimport { TaskStore } from \"./store.ts\";\nimport {\n\tTASK_BACKGROUND_REJECTION,\n\tTASK_KIND_PATTERN,\n\tTASK_MANAGEMENT_REJECTION,\n\ttype TaskExecution,\n\tTaskLookupError,\n\ttype TaskRead,\n\ttype TaskReadOptions,\n\ttype TaskRuntimeOptions,\n\ttype TaskSnapshot,\n\ttype TasksContext,\n\ttype TaskToolOutcome,\n} from \"./types.ts\";\n\n/** Session-local supervision. Executors own their processes, items and output files. */\nexport class TaskRuntime implements TasksContext {\n\tprivate readonly store: TaskStore;\n\tprivate readonly executions = new Map<string, Execution<unknown>>();\n\tprivate readonly scheduler = new TaskScheduler();\n\tprivate readonly listeners = new Set<() => void>();\n\tprivate readonly host: ExecutionHost;\n\tprivate readonly maxBackground: number;\n\tprivate readonly maxHistory: number;\n\tprivate readonly maxRetained: number;\n\tprivate readonly options: TaskRuntimeOptions;\n\tprivate configuredEnabled: boolean;\n\tprivate _closed = false;\n\n\tconstructor(options: TaskRuntimeOptions = {}) {\n\t\tthis.options = options;\n\t\tthis.configuredEnabled = options.enabled ?? false;\n\t\tthis.maxBackground = Math.max(1, finiteLimit(options.maxBackground, 8, 128));\n\t\tthis.maxHistory = finiteLimit(options.maxHistory, 32, 1024);\n\t\t// Separate foreground and background histories, plus the protected-record allowance.\n\t\tthis.maxRetained = this.maxBackground + 2 * Math.max(1, this.maxHistory) + this.maxHistory;\n\t\tthis.store = new TaskStore(this.maxHistory, this.maxRetained, () => this.closed, options.onCleanupError);\n\t\tconst runtime = this;\n\t\tthis.host = {\n\t\t\tget closed() {\n\t\t\t\treturn runtime.closed;\n\t\t\t},\n\t\t\temit: () => this.emit(),\n\t\t\tsettle: (task, usage) => this.options.onSettled?.(task, usage),\n\t\t\treleased: (execution) => {\n\t\t\t\tthis.executions.delete(execution.task.id);\n\t\t\t\tthis.scheduler.release(execution);\n\t\t\t\tthis.store.trim();\n\t\t\t\tthis.emit();\n\t\t\t},\n\t\t};\n\t}\n\n\tget closed(): boolean {\n\t\treturn this._closed;\n\t}\n\n\tget session(): TaskRuntimeOptions[\"session\"] {\n\t\treturn this.options.session;\n\t}\n\n\t/**\n\t * Rehydrate terminal snapshots only, newest endedAt in each history (later input wins\n\t * ties). Existing runtime records win ID collisions. No execution, accounting,\n\t * notification, or deletion ownership is restored. Foreground records take their output\n\t * from the branch's tool results. The host supplies the current branch; closed services\n\t * ignore restoration.\n\t */\n\trestoreHistory(\n\t\trecords: readonly unknown[],\n\t\ttoolResults?: ReadonlyMap<string, AgentToolResult<unknown>[\"content\"]>,\n\t): void {\n\t\tthis.store.restoreHistory(records, toolResults);\n\t}\n\n\tget enabled(): boolean {\n\t\treturn this.configuredEnabled && !this.closed && this.options.backgroundAllowed !== false;\n\t}\n\n\tsetEnabled(enabled: boolean): void {\n\t\tthis.configuredEnabled = enabled;\n\t\tthis.emit();\n\t}\n\n\t/** Tell subscribers that something the runtime reads from its host changed, such as `canManageBackground`. */\n\trefresh(): void {\n\t\tthis.emit();\n\t}\n\n\t/** Whether new work may move to or start in the background: enabled, and the host can manage it. */\n\tprivate get admitsBackground(): boolean {\n\t\treturn this.enabled && (this.options.canManageBackground?.() ?? true);\n\t}\n\n\t/**\n\t * Foreground work is bounded by its caller; only background work holds a slot, including work\n\t * whose caller is still waiting for the executor to accept (a detaching task).\n\t */\n\tprivate backgroundActive(): number {\n\t\treturn [...this.executions.values()].filter((execution) => execution.holdsBackgroundSlot).length;\n\t}\n\n\tprivate limitError(): Error {\n\t\treturn new Error(\n\t\t\t`Background task limit reached (${this.maxBackground}); stop or wait for a background task, or run in the foreground.`,\n\t\t);\n\t}\n\n\tasync execute<T>(execution: TaskExecution<T>): Promise<TaskToolOutcome<T>> {\n\t\t// Admission and registration happen synchronously, before invoking user code or awaiting anything.\n\t\tif (execution.background && this.options.backgroundAllowed === false) throw new Error(TASK_BACKGROUND_REJECTION);\n\t\tif (this.closed) throw new Error(\"Task service is closed\");\n\t\tif (execution.background) {\n\t\t\tif (!this.enabled) throw new Error(\"Background execution is not available in this host\");\n\t\t\tif (!this.admitsBackground) throw new Error(TASK_MANAGEMENT_REJECTION);\n\t\t\tif (this.backgroundActive() >= this.maxBackground) throw this.limitError();\n\t\t\tif (this.store.retainedCount() >= this.maxRetained) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Task history retention limit reached; deliver pending notifications or release task pins and delivery leases\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (execution.signal?.aborted) throw execution.signal.reason ?? new Error(\"Execution aborted\");\n\t\tif (!TASK_KIND_PATTERN.test(execution.kind)) throw new Error(\"Invalid task source\");\n\t\tconst concurrency = execution.concurrency;\n\t\tif (concurrency && (!concurrency.key || !Number.isSafeInteger(concurrency.limit) || concurrency.limit < 1))\n\t\t\tthrow new Error(\"Invalid task concurrency\");\n\t\tconst anchorId = this.options.anchor?.() ?? null;\n\t\tif (anchorId !== null && Buffer.byteLength(anchorId) > 8192) throw new Error(\"Task branch anchor is too large\");\n\t\tconst task: TaskSnapshot = {\n\t\t\tid: `${execution.kind}-${randomUUID()}`,\n\t\t\tkind: execution.kind,\n\t\t\tlabel: boundText(execution.label ?? execution.kind, TASK_LABEL_BYTES),\n\t\t\ttitle: boundText(execution.title, TASK_TITLE_BYTES),\n\t\t\toutput: execution.output ?? \"log\",\n\t\t\t...(execution.input ? { input: boundInput(execution.input) } : {}),\n\t\t\t...(execution.facts?.length ? { facts: boundFacts(execution.facts) } : {}),\n\t\t\ttoolCallId: boundText(execution.toolCallId, 512),\n\t\t\tanchorId,\n\t\t\tmode: \"foreground\",\n\t\t\tstatus: \"queued\",\n\t\t\tstartedAt: Date.now(),\n\t\t};\n\t\tconst record = new TaskRecord(task);\n\t\trecord.setPresenter(execution.present);\n\t\tconst active = new Execution(this.host, record, execution);\n\t\tthis.store.add(record);\n\t\tthis.executions.set(task.id, active as Execution<unknown>);\n\t\tthis.scheduler.schedule(active);\n\t\t// Queued background work returns at once; started work hands off after its own accept().\n\t\tactive.handOffIfQueued();\n\t\tthis.emit();\n\t\treturn active.caller;\n\t}\n\n\tprivate detachable(record: TaskRecord): boolean {\n\t\treturn this.executions.get(record.task.id)?.detachable ?? false;\n\t}\n\n\tdetachForeground(): number {\n\t\tif (!this.admitsBackground) return 0;\n\t\tconst eligible = [...this.executions.values()]\n\t\t\t.filter((execution) => execution.detachable)\n\t\t\t.sort((left, right) => left.task.startedAt - right.task.startedAt);\n\t\tif (!eligible.length) return 0;\n\t\tconst free = this.maxBackground - this.backgroundActive();\n\t\tif (free <= 0) throw this.limitError();\n\t\treturn this.detachAll(eligible.slice(0, free));\n\t}\n\n\tcanDetach(id: string): boolean {\n\t\tconst record = this.lookup(id);\n\t\treturn this.admitsBackground && this.backgroundActive() < this.maxBackground && this.detachable(record);\n\t}\n\n\tdetach(id: string): boolean {\n\t\tconst record = this.lookup(id);\n\t\tif (!this.admitsBackground || !this.detachable(record)) return false;\n\t\tif (this.backgroundActive() >= this.maxBackground) throw this.limitError();\n\t\tthis.detachAll([this.executions.get(record.task.id)!]);\n\t\treturn true;\n\t}\n\n\t/** Every placement changes before any listener hears about it. */\n\tprivate detachAll(executions: Execution<unknown>[]): number {\n\t\tconst notifications = executions.map((execution) => execution.detach());\n\t\tfor (const notify of notifications) notify();\n\t\tthis.emit();\n\t\treturn executions.length;\n\t}\n\n\tlist(): TaskSnapshot[] {\n\t\treturn this.store.visible().map((record) => record.snapshot());\n\t}\n\n\tprivate lookup(id: string): TaskRecord {\n\t\tconst exact = this.store.get(id);\n\t\tif (exact) return exact;\n\t\tconst matches = this.store.match(id);\n\t\tif (!id || matches.length !== 1) {\n\t\t\tthrow new TaskLookupError(\n\t\t\t\tmatches.length > 1 ? \"ambiguous\" : \"unknown\",\n\t\t\t\tmatches.map((record) => record.snapshot()),\n\t\t\t);\n\t\t}\n\t\treturn matches[0]!;\n\t}\n\n\tget(id: string): TaskSnapshot {\n\t\treturn this.lookup(id).snapshot();\n\t}\n\n\tasync read(id: string, options: TaskReadOptions = {}): Promise<TaskRead> {\n\t\tconst record = this.lookup(id);\n\t\tconst release = this.retain(record.task.id);\n\t\ttry {\n\t\t\tconst task = record.snapshot();\n\t\t\tconst window = { ...options, mode: options.mode ?? defaultReadMode(task) };\n\t\t\tif (task.outputPath) {\n\t\t\t\ttry {\n\t\t\t\t\treturn { task, ...(await readOutputSlice(task.outputPath, window)) };\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttask,\n\t\t\t\t\t\treadError: boundText(`Output could not be read: ${errorText(error)}`, 4096),\n\t\t\t\t\t\t...sliceText(this.resultText(task), window),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { task, readError: record.readError, ...sliceText(this.resultText(task), window) };\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t}\n\n\tpresentOutput(id: string, width: number, theme: Theme): string[] | undefined {\n\t\tlet record: TaskRecord;\n\t\ttry {\n\t\t\trecord = this.lookup(id);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn record.present(width, theme);\n\t}\n\n\tprivate resultText(task: TaskSnapshot): string {\n\t\treturn task.result?.text || task.error || \"No output yet.\";\n\t}\n\n\tkill(id: string): boolean {\n\t\treturn this.cancel(this.lookup(id));\n\t}\n\n\tprivate cancel(record: TaskRecord): boolean {\n\t\treturn this.executions.get(record.task.id)?.cancel() ?? false;\n\t}\n\n\tsubscribe(listener: () => void): () => void {\n\t\tif (this.closed) return () => {};\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\t/** Retention protects snapshots and logs only; completion delivery never waits on it. */\n\tretain(id: string): () => void {\n\t\treturn this.pin(this.lookup(id));\n\t}\n\n\tprivate pin(record: TaskRecord): () => void {\n\t\tconst release = record.pin();\n\t\treturn () => {\n\t\t\trelease();\n\t\t\tthis.store.trim();\n\t\t};\n\t}\n\n\tclose(): void {\n\t\tif (this.closed) return;\n\t\tthis._closed = true;\n\t\tthis.listeners.clear();\n\t\tfor (const record of this.store.all()) {\n\t\t\tthis.executions.get(record.task.id)?.releaseParent();\n\t\t\tthis.cancel(record);\n\t\t}\n\t\tthis.options.onClosed?.();\n\t\tthis.store.trim();\n\t}\n\n\tasync shutdown(graceMs = 2000): Promise<void> {\n\t\tthis.close();\n\t\tawait this.drain(this.store.all(), graceMs);\n\t}\n\n\t/** Running tasks whose launch anchor is outside the branch made of `ancestors`. */\n\tactiveOutsideBranch(ancestors: ReadonlySet<string>): TaskSnapshot[] {\n\t\treturn this.store\n\t\t\t.unsettled()\n\t\t\t.filter((record) => record.task.anchorId !== null && !ancestors.has(record.task.anchorId))\n\t\t\t.map((record) => record.snapshot());\n\t}\n\n\t/**\n\t * Hidden results stay pending: returning to their branch delivers them again.\n\t * Restored history is already delivered.\n\t */\n\tasync cancelOutsideBranch(ancestors: ReadonlySet<string>): Promise<void> {\n\t\tconst records = this.store.all();\n\t\tfor (const record of records)\n\t\t\trecord.setVisible(record.task.anchorId === null || ancestors.has(record.task.anchorId));\n\t\tconst outside = records.filter((record) => !record.visible);\n\t\tfor (const record of outside) this.cancel(record);\n\t\tthis.store.trim();\n\t\tthis.emit();\n\t\tawait this.drain(outside, 2000);\n\t}\n\n\tprivate async drain(records: TaskRecord[], graceMs: number): Promise<void> {\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\ttry {\n\t\t\tawait Promise.race([\n\t\t\t\tPromise.all(records.map((record) => this.executions.get(record.task.id)?.done)).then(() =>\n\t\t\t\t\tthis.store.cleanupsDone(),\n\t\t\t\t),\n\t\t\t\tnew Promise<void>((resolve) => {\n\t\t\t\t\ttimer = setTimeout(resolve, finiteLimit(graceMs, 2000, 60_000));\n\t\t\t\t}),\n\t\t\t]);\n\t\t} finally {\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t}\n\t}\n\n\tprivate emit(): void {\n\t\tif (this.closed) return;\n\t\tfor (const listener of [...this.listeners]) {\n\t\t\tif (this.closed) break;\n\t\t\ttry {\n\t\t\t\tlistener();\n\t\t\t} catch {\n\t\t\t\t/* Observers do not own execution or delivery. */\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../../src/core/tasks/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport { finiteLimit } from \"../../utils/number.ts\";\nimport { Execution, type ExecutionHost } from \"./execution.ts\";\nimport { defaultReadMode } from \"./limits.ts\";\nimport {\n\tboundFacts,\n\tboundInput,\n\tboundText,\n\terrorText,\n\treadOutputSlice,\n\tsliceText,\n\tTASK_LABEL_BYTES,\n\tTASK_TITLE_BYTES,\n} from \"./output.ts\";\nimport { TaskRecord } from \"./record.ts\";\nimport { TaskScheduler } from \"./scheduler.ts\";\nimport { TaskStore } from \"./store.ts\";\nimport {\n\tTASK_BACKGROUND_REJECTION,\n\tTASK_KIND_PATTERN,\n\tTASK_MANAGEMENT_REJECTION,\n\ttype TaskExecution,\n\tTaskLookupError,\n\ttype TaskRead,\n\ttype TaskReadOptions,\n\ttype TaskRuntimeOptions,\n\ttype TaskSnapshot,\n\ttype TasksContext,\n\ttype TaskToolOutcome,\n} from \"./types.ts\";\n\n/** Session-local supervision. Executors own their processes, items and output files. */\nexport class TaskRuntime implements TasksContext {\n\tprivate readonly store: TaskStore;\n\tprivate readonly executions = new Map<string, Execution<unknown>>();\n\tprivate readonly scheduler = new TaskScheduler();\n\tprivate readonly listeners = new Set<() => void>();\n\tprivate readonly host: ExecutionHost;\n\tprivate readonly maxBackground: number;\n\tprivate readonly maxHistory: number;\n\tprivate readonly maxRetained: number;\n\tprivate readonly options: TaskRuntimeOptions;\n\tprivate configuredEnabled: boolean;\n\tprivate _closed = false;\n\n\tconstructor(options: TaskRuntimeOptions = {}) {\n\t\tthis.options = options;\n\t\tthis.configuredEnabled = options.enabled ?? false;\n\t\tthis.maxBackground = Math.max(1, finiteLimit(options.maxBackground, 8, 128));\n\t\tthis.maxHistory = finiteLimit(options.maxHistory, 32, 1024);\n\t\t// Separate foreground and background histories, plus the protected-record allowance.\n\t\tthis.maxRetained = this.maxBackground + 2 * Math.max(1, this.maxHistory) + this.maxHistory;\n\t\tthis.store = new TaskStore(this.maxHistory, this.maxRetained, () => this.closed, options.onCleanupError);\n\t\tconst runtime = this;\n\t\tthis.host = {\n\t\t\tget closed() {\n\t\t\t\treturn runtime.closed;\n\t\t\t},\n\t\t\temit: () => this.emit(),\n\t\t\tsettle: (task, usage) => this.options.onSettled?.(task, usage),\n\t\t\treleased: (execution) => {\n\t\t\t\tthis.executions.delete(execution.task.id);\n\t\t\t\tthis.scheduler.release(execution);\n\t\t\t\tthis.store.trim();\n\t\t\t\tthis.emit();\n\t\t\t},\n\t\t};\n\t}\n\n\tget closed(): boolean {\n\t\treturn this._closed;\n\t}\n\n\tget session(): TaskRuntimeOptions[\"session\"] {\n\t\treturn this.options.session;\n\t}\n\n\t/**\n\t * Rehydrate terminal snapshots only, newest endedAt in each history (later input wins\n\t * ties). Existing runtime records win ID collisions. No execution, accounting,\n\t * notification, or deletion ownership is restored. Foreground records take their output\n\t * from the branch's tool results. The host supplies the current branch; closed services\n\t * ignore restoration.\n\t */\n\trestoreHistory(\n\t\trecords: readonly unknown[],\n\t\ttoolResults?: ReadonlyMap<string, AgentToolResult<unknown>[\"content\"]>,\n\t): void {\n\t\tthis.store.restoreHistory(records, toolResults);\n\t}\n\n\tget enabled(): boolean {\n\t\treturn this.configuredEnabled && !this.closed;\n\t}\n\n\tsetEnabled(enabled: boolean): void {\n\t\tthis.configuredEnabled = enabled;\n\t\tthis.emit();\n\t}\n\n\t/** Tell subscribers that something the runtime reads from its host changed, such as `canManageBackground`. */\n\trefresh(): void {\n\t\tthis.emit();\n\t}\n\n\t/** Whether new work may move to or start in the background: enabled, and the host can manage it. */\n\tprivate get admitsBackground(): boolean {\n\t\treturn this.enabled && (this.options.canManageBackground?.() ?? true);\n\t}\n\n\t/**\n\t * Foreground work is bounded by its caller; only background work holds a slot, including work\n\t * whose caller is still waiting for the executor to accept (a detaching task).\n\t */\n\tprivate backgroundActive(): number {\n\t\treturn [...this.executions.values()].filter((execution) => execution.holdsBackgroundSlot).length;\n\t}\n\n\tprivate limitError(): Error {\n\t\treturn new Error(\n\t\t\t`Background task limit reached (${this.maxBackground}); stop or wait for a background task, or run in the foreground.`,\n\t\t);\n\t}\n\n\tasync execute<T>(execution: TaskExecution<T>): Promise<TaskToolOutcome<T>> {\n\t\t// Admission and registration happen synchronously, before invoking user code or awaiting anything.\n\t\tif (this.closed) throw new Error(\"Task service is closed\");\n\t\tif (execution.background) {\n\t\t\tif (!this.enabled) throw new Error(TASK_BACKGROUND_REJECTION);\n\t\t\tif (!this.admitsBackground) throw new Error(TASK_MANAGEMENT_REJECTION);\n\t\t\tif (this.backgroundActive() >= this.maxBackground) throw this.limitError();\n\t\t\tif (this.store.retainedCount() >= this.maxRetained) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Task history retention limit reached; deliver pending notifications or release task pins and delivery leases\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (execution.signal?.aborted) throw execution.signal.reason ?? new Error(\"Execution aborted\");\n\t\tif (!TASK_KIND_PATTERN.test(execution.kind)) throw new Error(\"Invalid task source\");\n\t\tconst concurrency = execution.concurrency;\n\t\tif (concurrency && (!concurrency.key || !Number.isSafeInteger(concurrency.limit) || concurrency.limit < 1))\n\t\t\tthrow new Error(\"Invalid task concurrency\");\n\t\tconst anchorId = this.options.anchor?.() ?? null;\n\t\tif (anchorId !== null && Buffer.byteLength(anchorId) > 8192) throw new Error(\"Task branch anchor is too large\");\n\t\tconst task: TaskSnapshot = {\n\t\t\tid: `${execution.kind}-${randomUUID()}`,\n\t\t\tkind: execution.kind,\n\t\t\tlabel: boundText(execution.label ?? execution.kind, TASK_LABEL_BYTES),\n\t\t\ttitle: boundText(execution.title, TASK_TITLE_BYTES),\n\t\t\toutput: execution.output ?? \"log\",\n\t\t\t...(execution.input ? { input: boundInput(execution.input) } : {}),\n\t\t\t...(execution.facts?.length ? { facts: boundFacts(execution.facts) } : {}),\n\t\t\ttoolCallId: boundText(execution.toolCallId, 512),\n\t\t\tanchorId,\n\t\t\tmode: \"foreground\",\n\t\t\tstatus: \"queued\",\n\t\t\tstartedAt: Date.now(),\n\t\t};\n\t\tconst record = new TaskRecord(task);\n\t\tconst active = new Execution(this.host, record, execution);\n\t\tthis.store.add(record);\n\t\tthis.executions.set(task.id, active as Execution<unknown>);\n\t\tthis.scheduler.schedule(active);\n\t\t// Queued background work returns at once; started work hands off after its own accept().\n\t\tactive.handOffIfQueued();\n\t\tthis.emit();\n\t\treturn active.caller;\n\t}\n\n\tprivate detachable(record: TaskRecord): boolean {\n\t\treturn this.executions.get(record.task.id)?.detachable ?? false;\n\t}\n\n\tdetachForeground(): number {\n\t\tif (!this.admitsBackground) return 0;\n\t\tconst eligible = [...this.executions.values()]\n\t\t\t.filter((execution) => execution.detachable)\n\t\t\t.sort((left, right) => left.task.startedAt - right.task.startedAt);\n\t\tif (!eligible.length) return 0;\n\t\tconst free = this.maxBackground - this.backgroundActive();\n\t\tif (free <= 0) throw this.limitError();\n\t\treturn this.detachAll(eligible.slice(0, free));\n\t}\n\n\tcanDetach(id: string): boolean {\n\t\tconst record = this.lookup(id);\n\t\treturn this.admitsBackground && this.backgroundActive() < this.maxBackground && this.detachable(record);\n\t}\n\n\tdetach(id: string): boolean {\n\t\tconst record = this.lookup(id);\n\t\tif (!this.admitsBackground || !this.detachable(record)) return false;\n\t\tif (this.backgroundActive() >= this.maxBackground) throw this.limitError();\n\t\tthis.detachAll([this.executions.get(record.task.id)!]);\n\t\treturn true;\n\t}\n\n\t/** Every placement changes before any listener hears about it. */\n\tprivate detachAll(executions: Execution<unknown>[]): number {\n\t\tconst notifications = executions.map((execution) => execution.detach());\n\t\tfor (const notify of notifications) notify();\n\t\tthis.emit();\n\t\treturn executions.length;\n\t}\n\n\tlist(): TaskSnapshot[] {\n\t\treturn this.store.visible().map((record) => record.snapshot());\n\t}\n\n\tprivate lookup(id: string): TaskRecord {\n\t\tconst exact = this.store.get(id);\n\t\tif (exact) return exact;\n\t\tconst matches = this.store.match(id);\n\t\tif (!id || matches.length !== 1) {\n\t\t\tthrow new TaskLookupError(\n\t\t\t\tmatches.length > 1 ? \"ambiguous\" : \"unknown\",\n\t\t\t\tmatches.map((record) => record.snapshot()),\n\t\t\t);\n\t\t}\n\t\treturn matches[0]!;\n\t}\n\n\tget(id: string): TaskSnapshot {\n\t\treturn this.lookup(id).snapshot();\n\t}\n\n\tasync read(id: string, options: TaskReadOptions = {}): Promise<TaskRead> {\n\t\tconst record = this.lookup(id);\n\t\tconst release = this.retain(record.task.id);\n\t\ttry {\n\t\t\tconst task = record.snapshot();\n\t\t\tconst window = { ...options, mode: options.mode ?? defaultReadMode(task) };\n\t\t\tif (task.outputPath) {\n\t\t\t\ttry {\n\t\t\t\t\treturn { task, ...(await readOutputSlice(task.outputPath, window)) };\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttask,\n\t\t\t\t\t\treadError: boundText(`Output could not be read: ${errorText(error)}`, 4096),\n\t\t\t\t\t\t...sliceText(this.resultText(task), window),\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { task, readError: record.readError, ...sliceText(this.resultText(task), window) };\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t}\n\n\tprivate resultText(task: TaskSnapshot): string {\n\t\treturn task.result?.text || task.error || \"No output yet.\";\n\t}\n\n\tkill(id: string): boolean {\n\t\treturn this.cancel(this.lookup(id));\n\t}\n\n\tprivate cancel(record: TaskRecord): boolean {\n\t\treturn this.executions.get(record.task.id)?.cancel() ?? false;\n\t}\n\n\tsubscribe(listener: () => void): () => void {\n\t\tif (this.closed) return () => {};\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\t/** Retention protects snapshots and logs only; completion delivery never waits on it. */\n\tretain(id: string): () => void {\n\t\treturn this.pin(this.lookup(id));\n\t}\n\n\tprivate pin(record: TaskRecord): () => void {\n\t\tconst release = record.pin();\n\t\treturn () => {\n\t\t\trelease();\n\t\t\tthis.store.trim();\n\t\t};\n\t}\n\n\tclose(): void {\n\t\tif (this.closed) return;\n\t\tthis._closed = true;\n\t\tthis.listeners.clear();\n\t\tfor (const record of this.store.all()) {\n\t\t\tthis.executions.get(record.task.id)?.releaseParent();\n\t\t\tthis.cancel(record);\n\t\t}\n\t\tthis.options.onClosed?.();\n\t\tthis.store.trim();\n\t}\n\n\tasync shutdown(graceMs = 2000): Promise<void> {\n\t\tthis.close();\n\t\tawait this.drain(this.store.all(), graceMs);\n\t}\n\n\t/** Running tasks whose launch anchor is outside the branch made of `ancestors`. */\n\tactiveOutsideBranch(ancestors: ReadonlySet<string>): TaskSnapshot[] {\n\t\treturn this.store\n\t\t\t.unsettled()\n\t\t\t.filter((record) => record.task.anchorId !== null && !ancestors.has(record.task.anchorId))\n\t\t\t.map((record) => record.snapshot());\n\t}\n\n\t/**\n\t * Hidden results stay pending: returning to their branch delivers them again.\n\t * Restored history is already delivered.\n\t */\n\tasync cancelOutsideBranch(ancestors: ReadonlySet<string>): Promise<void> {\n\t\tconst records = this.store.all();\n\t\tfor (const record of records)\n\t\t\trecord.setVisible(record.task.anchorId === null || ancestors.has(record.task.anchorId));\n\t\tconst outside = records.filter((record) => !record.visible);\n\t\tfor (const record of outside) this.cancel(record);\n\t\tthis.store.trim();\n\t\tthis.emit();\n\t\tawait this.drain(outside, 2000);\n\t}\n\n\tprivate async drain(records: TaskRecord[], graceMs: number): Promise<void> {\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\ttry {\n\t\t\tawait Promise.race([\n\t\t\t\tPromise.all(records.map((record) => this.executions.get(record.task.id)?.done)).then(() =>\n\t\t\t\t\tthis.store.cleanupsDone(),\n\t\t\t\t),\n\t\t\t\tnew Promise<void>((resolve) => {\n\t\t\t\t\ttimer = setTimeout(resolve, finiteLimit(graceMs, 2000, 60_000));\n\t\t\t\t}),\n\t\t\t]);\n\t\t} finally {\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t}\n\t}\n\n\tprivate emit(): void {\n\t\tif (this.closed) return;\n\t\tfor (const listener of [...this.listeners]) {\n\t\t\tif (this.closed) break;\n\t\t\ttry {\n\t\t\t\tlistener();\n\t\t\t} catch {\n\t\t\t\t/* Observers do not own execution or delivery. */\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { AgentMessage } from "@earendil-works/pi-agent-core";
1
+ import type { AgentEvent, AgentMessage } from "@earendil-works/pi-agent-core";
2
2
  import type { Usage } from "@earendil-works/pi-ai/compat";
3
3
  import type { CustomMessage } from "../messages.ts";
4
4
  import { type SessionEntry, type SessionManager } from "../session-manager.ts";
@@ -7,6 +7,7 @@ import { TaskRuntime } from "./runtime.ts";
7
7
  import { type TaskSnapshot } from "./types.ts";
8
8
  interface TaskSessionOptions {
9
9
  manager: SessionManager;
10
+ /** Host capability ceiling: false keeps background execution off, whatever the bindings ask for. */
10
11
  backgroundAllowed?: boolean;
11
12
  /** The main session owns input queues, preflight and idle state. */
12
13
  canDeliver(): boolean;
@@ -47,12 +48,18 @@ export declare class TaskSession {
47
48
  private changed;
48
49
  /** Handed-off tasks of the current runtime that have not settled. */
49
50
  runningBackground(): TaskSnapshot[];
51
+ /**
52
+ * No unsettled background task and no completion that could be delivered now. Consulted while
53
+ * the main session is idle, where an undeliverable completion waits for the next input.
54
+ */
55
+ isQuiet(): boolean;
50
56
  get service(): TaskRuntime;
57
+ /** Follow the main agent: delivery tracks its completion message, the context reminder its finished replies. */
58
+ observe(event: AgentEvent): void;
51
59
  /** The active tools changed: availability of background detaching may have too. */
52
60
  toolsChanged(): void;
53
61
  noteCompaction(): void;
54
62
  projectContextReminder(messages: AgentMessage[]): AgentMessage[];
55
- noteAssistantCompleted(): void;
56
63
  get quarantinedSettlements(): readonly QuarantinedTaskSettlement[];
57
64
  setEnabled(enabled: boolean): void;
58
65
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/session.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,7 @@ import { appendFileSync, mkdirSync } from "node:fs";
2
2
  import { dirname } from "node:path";
3
3
  import { getTasksLateSidecarPath } from "../session-manager.js";
4
4
  import { truncateHead } from "../tools/truncate.js";
5
- import { getTaskUsageRecord } from "../usage-totals.js";
6
- import { TASK_RECORD_TYPE, TASK_SNAPSHOT_VERSION } from "./codec.js";
5
+ import { readTaskUsage, TASK_RECORD_TYPE, TASK_SNAPSHOT_VERSION } from "./codec.js";
7
6
  import { TaskDelivery } from "./delivery.js";
8
7
  import { TaskContextReminder } from "./reminder.js";
9
8
  import { TaskRuntime } from "./runtime.js";
@@ -55,9 +54,28 @@ export class TaskSession {
55
54
  return [];
56
55
  return service.list().filter((task) => task.mode === "background" && !isTaskTerminal(task.status));
57
56
  }
57
+ /**
58
+ * No unsettled background task and no completion that could be delivered now. Consulted while
59
+ * the main session is idle, where an undeliverable completion waits for the next input.
60
+ */
61
+ isQuiet() {
62
+ return (this.runningBackground().length === 0 && !(this.options.canDeliver() && this.delivery.hasDeliverableWork()));
63
+ }
58
64
  get service() {
59
65
  return this._service;
60
66
  }
67
+ /** Follow the main agent: delivery tracks its completion message, the context reminder its finished replies. */
68
+ observe(event) {
69
+ if (event.type === "message_start")
70
+ this.delivery.messageStarted(event.message);
71
+ else if (event.type === "agent_end")
72
+ this.delivery.agentEnded();
73
+ else if (event.type === "message_end" &&
74
+ event.message.role === "assistant" &&
75
+ event.message.stopReason !== "error" &&
76
+ event.message.stopReason !== "aborted")
77
+ this.contextReminder.assistantCompleted();
78
+ }
61
79
  /** The active tools changed: availability of background detaching may have too. */
62
80
  toolsChanged() {
63
81
  this.service.refresh();
@@ -66,10 +84,7 @@ export class TaskSession {
66
84
  this.contextReminder.compacted();
67
85
  }
68
86
  projectContextReminder(messages) {
69
- return this.contextReminder.project(this.service, messages);
70
- }
71
- noteAssistantCompleted() {
72
- this.contextReminder.assistantCompleted();
87
+ return this.contextReminder.project(messages, () => this.runningBackground());
73
88
  }
74
89
  get quarantinedSettlements() {
75
90
  return structuredClone(this.quarantine);
@@ -119,13 +134,12 @@ export class TaskSession {
119
134
  this.delivery.acknowledge(taskId);
120
135
  }
121
136
  createService() {
122
- const { manager, backgroundAllowed } = this.options;
137
+ const { manager } = this.options;
123
138
  const generation = ++this.generation;
124
139
  const sessionId = manager.getSessionId();
125
140
  const sessionFile = manager.getSessionFile();
126
141
  const service = new TaskRuntime({
127
142
  enabled: this.enabled,
128
- backgroundAllowed,
129
143
  canManageBackground: () => this.options.managementActive?.() ?? true,
130
144
  session: {
131
145
  stoppedByTreeNavigation: (targetId) => this.stoppedByTreeNavigation(targetId, service),
@@ -192,7 +206,7 @@ export class TaskSession {
192
206
  /** One entry per settlement: the bounded terminal snapshot and its first usage settlement. */
193
207
  persistSettlement(task, usage) {
194
208
  const manager = this.options.manager;
195
- const accounted = usage && manager.getEntries().some((entry) => getTaskUsageRecord(entry)?.taskId === task.id);
209
+ const accounted = usage && manager.getEntries().some((entry) => readTaskUsage(entry)?.taskId === task.id);
196
210
  // A foreground result is the tool result the transcript already saves; restoration reads it from there.
197
211
  const { result: _result, ...metadata } = task;
198
212
  const saved = task.mode === "foreground" ? metadata : task;