@astralyn/pi 1.4.5 → 1.4.7

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 (324) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/bundle/chunks/chunk-FODCTZXW.js +230 -0
  3. package/dist/bundle/chunks/{chunk-I5S7H7GA.js → chunk-FYKNSJG6.js} +1 -1
  4. package/dist/bundle/chunks/{chunk-AXFWZIHH.js → chunk-MG5XDTXV.js} +1 -1
  5. package/dist/bundle/chunks/{chunk-ALHAFUHP.js → chunk-PU2IWWXV.js} +1 -1
  6. package/dist/bundle/chunks/{chunk-5M3YJ54Z.js → chunk-RO2VH6UZ.js} +1 -1
  7. package/dist/bundle/chunks/chunk-YJTSOLP2.js +1499 -0
  8. package/dist/bundle/chunks/{cli-FH77R7JR.js → cli-MEL7SGJD.js} +1 -1
  9. package/dist/bundle/chunks/{execute-GMFGC27P.js → execute-4CWRNHPO.js} +1 -1
  10. package/dist/bundle/chunks/{runtime-R5CMHJ5P.js → runtime-R3X67XMR.js} +1 -1
  11. package/dist/bundle/chunks/{virtual-modules-6FUV7ZDV.js → virtual-modules-PKEOKGYI.js} +1 -1
  12. package/dist/bundle/cli.js +1 -1
  13. package/dist/bundle/index.js +1 -1
  14. package/dist/bundle/rpc-entry.js +1 -1
  15. package/dist/core/agent-session.d.ts +0 -3
  16. package/dist/core/agent-session.d.ts.map +1 -1
  17. package/dist/core/agent-session.js +0 -4
  18. package/dist/core/agent-session.js.map +1 -1
  19. package/dist/core/extensions/index.d.ts +1 -1
  20. package/dist/core/extensions/index.d.ts.map +1 -1
  21. package/dist/core/extensions/index.js.map +1 -1
  22. package/dist/core/isolated-session.d.ts +23 -0
  23. package/dist/core/isolated-session.d.ts.map +1 -0
  24. package/dist/core/isolated-session.js +55 -0
  25. package/dist/core/isolated-session.js.map +1 -0
  26. package/dist/core/package-manager.d.ts +7 -1
  27. package/dist/core/package-manager.d.ts.map +1 -1
  28. package/dist/core/package-manager.js +72 -1
  29. package/dist/core/package-manager.js.map +1 -1
  30. package/dist/core/resource-loader.d.ts +1 -0
  31. package/dist/core/resource-loader.d.ts.map +1 -1
  32. package/dist/core/resource-loader.js +23 -7
  33. package/dist/core/resource-loader.js.map +1 -1
  34. package/dist/core/settings-manager.d.ts +4 -2
  35. package/dist/core/settings-manager.d.ts.map +1 -1
  36. package/dist/core/settings-manager.js +11 -0
  37. package/dist/core/settings-manager.js.map +1 -1
  38. package/dist/core/settings-schema.d.ts +7 -0
  39. package/dist/core/settings-schema.d.ts.map +1 -1
  40. package/dist/core/settings-schema.js +6 -0
  41. package/dist/core/settings-schema.js.map +1 -1
  42. package/dist/core/skills.d.ts +10 -0
  43. package/dist/core/skills.d.ts.map +1 -1
  44. package/dist/core/skills.js +23 -0
  45. package/dist/core/skills.js.map +1 -1
  46. package/dist/core/tasks/codec.d.ts +12 -0
  47. package/dist/core/tasks/codec.d.ts.map +1 -0
  48. package/dist/core/tasks/codec.js +139 -0
  49. package/dist/core/tasks/codec.js.map +1 -0
  50. package/dist/core/tasks/delivery.d.ts +11 -4
  51. package/dist/core/tasks/delivery.d.ts.map +1 -1
  52. package/dist/core/tasks/delivery.js +9 -9
  53. package/dist/core/tasks/delivery.js.map +1 -1
  54. package/dist/core/tasks/execution.d.ts +71 -0
  55. package/dist/core/tasks/execution.d.ts.map +1 -0
  56. package/dist/core/tasks/execution.js +292 -0
  57. package/dist/core/tasks/execution.js.map +1 -0
  58. package/dist/core/tasks/format.d.ts +0 -2
  59. package/dist/core/tasks/format.d.ts.map +1 -1
  60. package/dist/core/tasks/format.js +1 -16
  61. package/dist/core/tasks/format.js.map +1 -1
  62. package/dist/core/tasks/limits.d.ts +12 -1
  63. package/dist/core/tasks/limits.d.ts.map +1 -1
  64. package/dist/core/tasks/limits.js +20 -1
  65. package/dist/core/tasks/limits.js.map +1 -1
  66. package/dist/core/tasks/output.d.ts +17 -17
  67. package/dist/core/tasks/output.d.ts.map +1 -1
  68. package/dist/core/tasks/output.js +72 -69
  69. package/dist/core/tasks/output.js.map +1 -1
  70. package/dist/core/tasks/presentation.d.ts +14 -5
  71. package/dist/core/tasks/presentation.d.ts.map +1 -1
  72. package/dist/core/tasks/presentation.js +56 -185
  73. package/dist/core/tasks/presentation.js.map +1 -1
  74. package/dist/core/tasks/record.d.ts +45 -0
  75. package/dist/core/tasks/record.d.ts.map +1 -0
  76. package/dist/core/tasks/record.js +80 -0
  77. package/dist/core/tasks/record.js.map +1 -0
  78. package/dist/core/tasks/runtime.d.ts +22 -22
  79. package/dist/core/tasks/runtime.d.ts.map +1 -1
  80. package/dist/core/tasks/runtime.js +170 -343
  81. package/dist/core/tasks/runtime.js.map +1 -1
  82. package/dist/core/tasks/scheduler.d.ts +16 -0
  83. package/dist/core/tasks/scheduler.d.ts.map +1 -0
  84. package/dist/core/tasks/scheduler.js +42 -0
  85. package/dist/core/tasks/scheduler.js.map +1 -0
  86. package/dist/core/tasks/session.d.ts +1 -1
  87. package/dist/core/tasks/session.d.ts.map +1 -1
  88. package/dist/core/tasks/session.js +22 -35
  89. package/dist/core/tasks/session.js.map +1 -1
  90. package/dist/core/tasks/store.d.ts +18 -25
  91. package/dist/core/tasks/store.d.ts.map +1 -1
  92. package/dist/core/tasks/store.js +45 -43
  93. package/dist/core/tasks/store.js.map +1 -1
  94. package/dist/core/tasks/types.d.ts +159 -70
  95. package/dist/core/tasks/types.d.ts.map +1 -1
  96. package/dist/core/tasks/types.js +3 -9
  97. package/dist/core/tasks/types.js.map +1 -1
  98. package/dist/core/tools/shell-execution.d.ts +8 -7
  99. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  100. package/dist/core/tools/shell-execution.js +19 -27
  101. package/dist/core/tools/shell-execution.js.map +1 -1
  102. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  103. package/dist/core/tools/shell-tool.js +42 -47
  104. package/dist/core/tools/shell-tool.js.map +1 -1
  105. package/dist/core/usage-totals.d.ts +4 -3
  106. package/dist/core/usage-totals.d.ts.map +1 -1
  107. package/dist/core/usage-totals.js +32 -8
  108. package/dist/core/usage-totals.js.map +1 -1
  109. package/dist/extensions/agent/activity.d.ts +4 -4
  110. package/dist/extensions/agent/activity.d.ts.map +1 -1
  111. package/dist/extensions/agent/activity.js +15 -24
  112. package/dist/extensions/agent/activity.js.map +1 -1
  113. package/dist/extensions/agent/index.d.ts +2 -11
  114. package/dist/extensions/agent/index.d.ts.map +1 -1
  115. package/dist/extensions/agent/index.js +3 -88
  116. package/dist/extensions/agent/index.js.map +1 -1
  117. package/dist/extensions/agent/progress.d.ts +31 -0
  118. package/dist/extensions/agent/progress.d.ts.map +1 -0
  119. package/dist/extensions/agent/progress.js +135 -0
  120. package/dist/extensions/agent/progress.js.map +1 -0
  121. package/dist/extensions/agent/render.d.ts.map +1 -1
  122. package/dist/extensions/agent/render.js +8 -17
  123. package/dist/extensions/agent/render.js.map +1 -1
  124. package/dist/extensions/agent/report.d.ts +9 -0
  125. package/dist/extensions/agent/report.d.ts.map +1 -0
  126. package/dist/extensions/agent/report.js +40 -0
  127. package/dist/extensions/agent/report.js.map +1 -0
  128. package/dist/extensions/agent/settings-panel.d.ts +43 -0
  129. package/dist/extensions/agent/settings-panel.d.ts.map +1 -0
  130. package/dist/extensions/agent/settings-panel.js +125 -0
  131. package/dist/extensions/agent/settings-panel.js.map +1 -0
  132. package/dist/extensions/agent/settings.d.ts +1 -1
  133. package/dist/extensions/agent/settings.d.ts.map +1 -1
  134. package/dist/extensions/agent/settings.js +101 -83
  135. package/dist/extensions/agent/settings.js.map +1 -1
  136. package/dist/extensions/agent/tool.d.ts +13 -0
  137. package/dist/extensions/agent/tool.d.ts.map +1 -0
  138. package/dist/extensions/agent/tool.js +88 -0
  139. package/dist/extensions/agent/tool.js.map +1 -0
  140. package/dist/extensions/agent/types.d.ts +19 -21
  141. package/dist/extensions/agent/types.d.ts.map +1 -1
  142. package/dist/extensions/agent/types.js +2 -10
  143. package/dist/extensions/agent/types.js.map +1 -1
  144. package/dist/extensions/agent/worker.d.ts +16 -0
  145. package/dist/extensions/agent/worker.d.ts.map +1 -0
  146. package/dist/extensions/agent/worker.js +66 -0
  147. package/dist/extensions/agent/worker.js.map +1 -0
  148. package/dist/extensions/btw/agent.d.ts +1 -1
  149. package/dist/extensions/btw/agent.d.ts.map +1 -1
  150. package/dist/extensions/btw/agent.js +3 -20
  151. package/dist/extensions/btw/agent.js.map +1 -1
  152. package/dist/extensions/cached-compaction/index.d.ts.map +1 -1
  153. package/dist/extensions/cached-compaction/index.js +3 -22
  154. package/dist/extensions/cached-compaction/index.js.map +1 -1
  155. package/dist/extensions/cached-compaction/render.d.ts +1 -0
  156. package/dist/extensions/cached-compaction/render.d.ts.map +1 -1
  157. package/dist/extensions/cached-compaction/render.js +42 -14
  158. package/dist/extensions/cached-compaction/render.js.map +1 -1
  159. package/dist/extensions/deepwiki/client.d.ts.map +1 -1
  160. package/dist/extensions/deepwiki/client.js +6 -78
  161. package/dist/extensions/deepwiki/client.js.map +1 -1
  162. package/dist/extensions/deepwiki/transport.d.ts +3 -0
  163. package/dist/extensions/deepwiki/transport.d.ts.map +1 -0
  164. package/dist/extensions/deepwiki/transport.js +96 -0
  165. package/dist/extensions/deepwiki/transport.js.map +1 -0
  166. package/dist/extensions/provider/ui/builtin-data.d.ts +3 -3
  167. package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -1
  168. package/dist/extensions/provider/ui/builtin-data.js.map +1 -1
  169. package/dist/extensions/provider/ui/compat.d.ts +3 -3
  170. package/dist/extensions/provider/ui/compat.d.ts.map +1 -1
  171. package/dist/extensions/provider/ui/compat.js.map +1 -1
  172. package/dist/extensions/provider/ui/controls.d.ts +2 -2
  173. package/dist/extensions/provider/ui/controls.d.ts.map +1 -1
  174. package/dist/extensions/provider/ui/controls.js.map +1 -1
  175. package/dist/extensions/provider/ui/dialogs.d.ts +3 -3
  176. package/dist/extensions/provider/ui/dialogs.d.ts.map +1 -1
  177. package/dist/extensions/provider/ui/dialogs.js.map +1 -1
  178. package/dist/extensions/provider/ui/dictionary.d.ts +2 -2
  179. package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -1
  180. package/dist/extensions/provider/ui/dictionary.js.map +1 -1
  181. package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
  182. package/dist/extensions/provider/ui/editor.js +1 -3
  183. package/dist/extensions/provider/ui/editor.js.map +1 -1
  184. package/dist/extensions/provider/ui/fetch-models.d.ts +2 -2
  185. package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -1
  186. package/dist/extensions/provider/ui/fetch-models.js.map +1 -1
  187. package/dist/extensions/provider/ui/model-fields.d.ts +2 -2
  188. package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -1
  189. package/dist/extensions/provider/ui/model-fields.js.map +1 -1
  190. package/dist/extensions/provider/ui/model-options.d.ts +6 -6
  191. package/dist/extensions/provider/ui/model-options.d.ts.map +1 -1
  192. package/dist/extensions/provider/ui/model-options.js.map +1 -1
  193. package/dist/extensions/provider/ui/pane.d.ts +21 -12
  194. package/dist/extensions/provider/ui/pane.d.ts.map +1 -1
  195. package/dist/extensions/provider/ui/pane.js.map +1 -1
  196. package/dist/extensions/provider/ui/provider-fields.d.ts +3 -3
  197. package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -1
  198. package/dist/extensions/provider/ui/provider-fields.js.map +1 -1
  199. package/dist/extensions/provider/ui/thinking-map.d.ts +2 -2
  200. package/dist/extensions/provider/ui/thinking-map.d.ts.map +1 -1
  201. package/dist/extensions/provider/ui/thinking-map.js.map +1 -1
  202. package/dist/extensions/run-summary/format.js +1 -1
  203. package/dist/extensions/run-summary/format.js.map +1 -1
  204. package/dist/extensions/statusline/usage.d.ts.map +1 -1
  205. package/dist/extensions/statusline/usage.js +2 -6
  206. package/dist/extensions/statusline/usage.js.map +1 -1
  207. package/dist/extensions/tasks/tool/actions.d.ts +1 -1
  208. package/dist/extensions/tasks/tool/actions.d.ts.map +1 -1
  209. package/dist/extensions/tasks/tool/actions.js +50 -115
  210. package/dist/extensions/tasks/tool/actions.js.map +1 -1
  211. package/dist/extensions/tasks/tool/constants.d.ts +1 -6
  212. package/dist/extensions/tasks/tool/constants.d.ts.map +1 -1
  213. package/dist/extensions/tasks/tool/constants.js +1 -6
  214. package/dist/extensions/tasks/tool/constants.js.map +1 -1
  215. package/dist/extensions/tasks/tool/schema.d.ts +0 -3
  216. package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
  217. package/dist/extensions/tasks/tool/schema.js +5 -14
  218. package/dist/extensions/tasks/tool/schema.js.map +1 -1
  219. package/dist/extensions/tasks/tool/types.d.ts +2 -8
  220. package/dist/extensions/tasks/tool/types.d.ts.map +1 -1
  221. package/dist/extensions/tasks/tool/types.js +0 -2
  222. package/dist/extensions/tasks/tool/types.js.map +1 -1
  223. package/dist/extensions/tasks/tool.d.ts.map +1 -1
  224. package/dist/extensions/tasks/tool.js +2 -2
  225. package/dist/extensions/tasks/tool.js.map +1 -1
  226. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
  227. package/dist/extensions/tasks/ui/completion-render.js +46 -47
  228. package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
  229. package/dist/extensions/tasks/ui/inspector.d.ts +5 -3
  230. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  231. package/dist/extensions/tasks/ui/inspector.js +18 -6
  232. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  233. package/dist/extensions/tasks/ui/layout.d.ts +7 -7
  234. package/dist/extensions/tasks/ui/layout.d.ts.map +1 -1
  235. package/dist/extensions/tasks/ui/layout.js +118 -84
  236. package/dist/extensions/tasks/ui/layout.js.map +1 -1
  237. package/dist/extensions/tasks/ui/list.d.ts.map +1 -1
  238. package/dist/extensions/tasks/ui/list.js +45 -31
  239. package/dist/extensions/tasks/ui/list.js.map +1 -1
  240. package/dist/extensions/tasks/ui/manager.d.ts +16 -7
  241. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
  242. package/dist/extensions/tasks/ui/manager.js +167 -129
  243. package/dist/extensions/tasks/ui/manager.js.map +1 -1
  244. package/dist/extensions/tasks/ui/model.d.ts +29 -0
  245. package/dist/extensions/tasks/ui/model.d.ts.map +1 -1
  246. package/dist/extensions/tasks/ui/model.js +16 -1
  247. package/dist/extensions/tasks/ui/model.js.map +1 -1
  248. package/dist/extensions/tasks/ui/render.d.ts +1 -1
  249. package/dist/extensions/tasks/ui/render.d.ts.map +1 -1
  250. package/dist/extensions/tasks/ui/render.js +12 -9
  251. package/dist/extensions/tasks/ui/render.js.map +1 -1
  252. package/dist/extensions/tasks/ui/status.d.ts +15 -0
  253. package/dist/extensions/tasks/ui/status.d.ts.map +1 -0
  254. package/dist/extensions/tasks/ui/status.js +16 -0
  255. package/dist/extensions/tasks/ui/status.js.map +1 -0
  256. package/dist/extensions/tasks/ui/tree.js +1 -1
  257. package/dist/extensions/tasks/ui/tree.js.map +1 -1
  258. package/dist/extensions/tasks/ui/views.d.ts +10 -5
  259. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  260. package/dist/extensions/tasks/ui/views.js +61 -36
  261. package/dist/extensions/tasks/ui/views.js.map +1 -1
  262. package/dist/index.d.ts +2 -1
  263. package/dist/index.d.ts.map +1 -1
  264. package/dist/index.js.map +1 -1
  265. package/dist/modes/interactive/components/config-selector.d.ts +14 -1
  266. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  267. package/dist/modes/interactive/components/config-selector.js +258 -7
  268. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  269. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  270. package/dist/modes/interactive/components/keybinding-hints.js +2 -1
  271. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  272. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  273. package/dist/modes/interactive/components/model-selector.js +7 -4
  274. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  275. package/dist/modes/interactive/components/status-marker.d.ts +2 -1
  276. package/dist/modes/interactive/components/status-marker.d.ts.map +1 -1
  277. package/dist/modes/interactive/components/status-marker.js +0 -1
  278. package/dist/modes/interactive/components/status-marker.js.map +1 -1
  279. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  280. package/dist/modes/interactive/components/thinking-selector.js +10 -3
  281. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  282. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  283. package/dist/modes/interactive/interactive-mode.js +7 -1
  284. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  285. package/dist/utils/duration.d.ts +3 -0
  286. package/dist/utils/duration.d.ts.map +1 -0
  287. package/dist/utils/duration.js +17 -0
  288. package/dist/utils/duration.js.map +1 -0
  289. package/dist/utils/number.d.ts +3 -0
  290. package/dist/utils/number.d.ts.map +1 -0
  291. package/dist/utils/number.js +5 -0
  292. package/dist/utils/number.js.map +1 -0
  293. package/docs/bundled/extensions/agent.md +14 -12
  294. package/docs/bundled/extensions/cached-compaction.md +13 -4
  295. package/docs/bundled/extensions/deepwiki.md +3 -1
  296. package/docs/bundled/extensions/statusline.md +1 -1
  297. package/docs/bundled/tasks.md +15 -14
  298. package/docs/extensions.md +26 -10
  299. package/docs/packages.md +5 -3
  300. package/docs/sdk.md +3 -3
  301. package/docs/session-format.md +28 -24
  302. package/docs/settings.md +11 -0
  303. package/docs/skills.md +23 -0
  304. package/npm-shrinkwrap.json +2 -2
  305. package/package.json +1 -1
  306. package/schemas/settings.schema.json +36 -0
  307. package/dist/bundle/chunks/chunk-FSJ45CRP.js +0 -229
  308. package/dist/bundle/chunks/chunk-W3FIUMGM.js +0 -1501
  309. package/dist/core/tasks/history.d.ts +0 -4
  310. package/dist/core/tasks/history.d.ts.map +0 -1
  311. package/dist/core/tasks/history.js +0 -131
  312. package/dist/core/tasks/history.js.map +0 -1
  313. package/dist/extensions/agent/runner.d.ts +0 -24
  314. package/dist/extensions/agent/runner.d.ts.map +0 -1
  315. package/dist/extensions/agent/runner.js +0 -274
  316. package/dist/extensions/agent/runner.js.map +0 -1
  317. package/dist/extensions/deepwiki/http.d.ts +0 -13
  318. package/dist/extensions/deepwiki/http.d.ts.map +0 -1
  319. package/dist/extensions/deepwiki/http.js +0 -88
  320. package/dist/extensions/deepwiki/http.js.map +0 -1
  321. package/dist/extensions/tasks/ui/task-view.d.ts +0 -13
  322. package/dist/extensions/tasks/ui/task-view.d.ts.map +0 -1
  323. package/dist/extensions/tasks/ui/task-view.js +0 -20
  324. package/dist/extensions/tasks/ui/task-view.js.map +0 -1
@@ -1,5 +1,24 @@
1
- /** Shared observation-window limits; execution timeouts are configured separately by each executor. */
1
+ import { finiteLimit } from "../../utils/number.js";
2
+ import { boundReadBytes } from "./output.js";
3
+ /**
4
+ * Shared observation-window limits, the one definition used by the runtime and the tasks tool.
5
+ * Execution timeouts are configured separately by each executor.
6
+ */
2
7
  export const TASKS_WAIT_DEFAULT_MS = 20_000;
3
8
  export const TASKS_WAIT_MIN_MS = 1_000;
4
9
  export const TASKS_WAIT_MAX_MS = 10 * 60_000;
10
+ /** Floor for a model-requested read slice; the default and ceiling are TASK_READ_BYTES and TASK_RESULT_BYTES. */
11
+ export const TASKS_READ_MIN_BYTES = 256;
12
+ /** The wait window the runtime honours: any finite value up to the ceiling, including 0. */
13
+ export function boundWaitMs(waitMs) {
14
+ return finiteLimit(waitMs, TASKS_WAIT_DEFAULT_MS, TASKS_WAIT_MAX_MS);
15
+ }
16
+ /** The wait window a tool call runs, which the pending-call renderer also shows. */
17
+ export function clampWaitMs(waitMs) {
18
+ return Math.max(TASKS_WAIT_MIN_MS, boundWaitMs(waitMs));
19
+ }
20
+ /** The read size a tool call runs. */
21
+ export function clampReadBytes(bytes) {
22
+ return Math.max(TASKS_READ_MIN_BYTES, boundReadBytes(bytes));
23
+ }
5
24
  //# sourceMappingURL=limits.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../../src/core/tasks/limits.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AACvC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,MAAM,CAAC","sourcesContent":["/** Shared observation-window limits; execution timeouts are configured separately by each executor. */\nexport const TASKS_WAIT_DEFAULT_MS = 20_000;\nexport const TASKS_WAIT_MIN_MS = 1_000;\nexport const TASKS_WAIT_MAX_MS = 10 * 60_000;\n"]}
1
+ {"version":3,"file":"limits.js","sourceRoot":"","sources":["../../../src/core/tasks/limits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAC5C,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AACvC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,MAAM,CAAC;AAC7C,iHAAiH;AACjH,MAAM,CAAC,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAExC,4FAA4F;AAC5F,MAAM,UAAU,WAAW,CAAC,MAA0B;IACrD,OAAO,WAAW,CAAC,MAAM,EAAE,qBAAqB,EAAE,iBAAiB,CAAC,CAAC;AACtE,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,WAAW,CAAC,MAA0B;IACrD,OAAO,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,cAAc,CAAC,KAAyB;IACvD,OAAO,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import { finiteLimit } from \"../../utils/number.ts\";\nimport { boundReadBytes } from \"./output.ts\";\n\n/**\n * Shared observation-window limits, the one definition used by the runtime and the tasks tool.\n * Execution timeouts are configured separately by each executor.\n */\nexport const TASKS_WAIT_DEFAULT_MS = 20_000;\nexport const TASKS_WAIT_MIN_MS = 1_000;\nexport const TASKS_WAIT_MAX_MS = 10 * 60_000;\n/** Floor for a model-requested read slice; the default and ceiling are TASK_READ_BYTES and TASK_RESULT_BYTES. */\nexport const TASKS_READ_MIN_BYTES = 256;\n\n/** The wait window the runtime honours: any finite value up to the ceiling, including 0. */\nexport function boundWaitMs(waitMs: number | undefined): number {\n\treturn finiteLimit(waitMs, TASKS_WAIT_DEFAULT_MS, TASKS_WAIT_MAX_MS);\n}\n\n/** The wait window a tool call runs, which the pending-call renderer also shows. */\nexport function clampWaitMs(waitMs: number | undefined): number {\n\treturn Math.max(TASKS_WAIT_MIN_MS, boundWaitMs(waitMs));\n}\n\n/** The read size a tool call runs. */\nexport function clampReadBytes(bytes: number | undefined): number {\n\treturn Math.max(TASKS_READ_MIN_BYTES, boundReadBytes(bytes));\n}\n"]}
@@ -1,22 +1,30 @@
1
1
  import type { AgentToolResult } from "@earendil-works/pi-agent-core";
2
- import type { TaskSnapshot } from "./types.ts";
2
+ import type { TaskFact, TaskInput, TaskReadOptions, TaskText } from "./types.ts";
3
3
  export declare const TASK_RESULT_BYTES: number;
4
4
  export declare const TASK_DETAILS_BYTES: number;
5
5
  export declare const TASK_READ_BYTES: number;
6
- export declare const TASK_INFO_BYTES: number;
6
+ export declare const TASK_INPUT_BYTES: number;
7
7
  /** Task title budget, independent of notification wording and rendering. */
8
8
  export declare const TASK_TITLE_BYTES = 1024;
9
- export declare function finiteLimit(value: number | undefined, fallback: number, ceiling: number): number;
9
+ export declare const TASK_LABEL_BYTES = 256;
10
+ export declare const TASK_FACTS = 16;
11
+ export declare const TASK_FACT_BYTES = 1024;
12
+ export declare const TASK_ERROR_BYTES = 4096;
13
+ export declare const TASK_PATH_BYTES = 8192;
14
+ /** A bounded, printable message for any thrown value. */
15
+ export declare function errorText(error: unknown, fallback?: string): string;
16
+ export declare function boundReadBytes(bytes: number | undefined): number;
10
17
  export declare function boundText(text: string, bytes?: number): string;
18
+ export declare function boundTaskText(text: string, bytes?: number): TaskText;
19
+ export declare function boundInput(input: TaskInput): TaskInput;
20
+ export declare function boundFacts(facts: readonly TaskFact[]): TaskFact[];
11
21
  /** The end of a bounded text, codepoint aligned: a command's outcome is at its end. */
12
22
  export declare function boundTail(text: string, bytes: number): {
13
23
  text: string;
14
24
  truncated: boolean;
15
25
  };
16
- /** Keep valid structured details intact or omit them, never truncate serialized JSON. */
17
- export declare function boundedResult(result: AgentToolResult<unknown>): AgentToolResult<unknown>;
18
- /** Store the bounded public part of a result; private details never enter task history. */
19
- export declare function retainResult(task: TaskSnapshot, result: AgentToolResult<unknown>, truncated?: boolean): void;
26
+ /** The bounded model-readable text of a result; images and private details never enter task state. */
27
+ export declare function resultText(result: AgentToolResult<unknown>): TaskText;
20
28
  export interface OutputSlice {
21
29
  text: string;
22
30
  totalBytes: number;
@@ -24,14 +32,6 @@ export interface OutputSlice {
24
32
  fromByte: number;
25
33
  }
26
34
  /** Positioned, bounded reads only. The executor owns the path and its cleanup. */
27
- export declare function readOutputSlice(path: string, options?: {
28
- mode?: "head" | "tail";
29
- bytes?: number;
30
- sinceBytes?: number;
31
- }): Promise<OutputSlice>;
32
- export declare function sliceText(text: string, options?: {
33
- mode?: "head" | "tail";
34
- bytes?: number;
35
- sinceBytes?: number;
36
- }): OutputSlice;
35
+ export declare function readOutputSlice(path: string, options?: TaskReadOptions): Promise<OutputSlice>;
36
+ export declare function sliceText(text: string, options?: TaskReadOptions): OutputSlice;
37
37
  //# sourceMappingURL=output.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,eAAO,MAAM,iBAAiB,QAAY,CAAC;AAC3C,eAAO,MAAM,kBAAkB,QAAa,CAAC;AAC7C,eAAO,MAAM,eAAe,QAAW,CAAC;AACxC,eAAO,MAAM,eAAe,QAAY,CAAC;AACzC,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAErC,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEhG;AAmBD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAoB,GAAG,MAAM,CAMzE;AAED,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAI3F;AAED,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC,CAwBxF;AAED,2FAA2F;AAC3F,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,SAAS,UAAQ,GAAG,IAAI,CAU1G;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,kFAAkF;AAClF,wBAAsB,eAAe,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3E,OAAO,CAAC,WAAW,CAAC,CA2BtB;AAED,wBAAgB,SAAS,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GAC3E,WAAW,CAkBb"}
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjF,eAAO,MAAM,iBAAiB,QAAY,CAAC;AAC3C,eAAO,MAAM,kBAAkB,QAAa,CAAC;AAC7C,eAAO,MAAM,eAAe,QAAW,CAAC;AACxC,eAAO,MAAM,gBAAgB,QAAY,CAAC;AAC1C,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,eAAe,OAAO,CAAC;AACpC,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,eAAe,OAAO,CAAC;AAEpC,yDAAyD;AACzD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,SAA8C,GAAG,MAAM,CAMxG;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEhE;AAmBD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAoB,GAAG,MAAM,CAMzE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAoB,GAAG,QAAQ,CAG/E;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAQtD;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAIjE;AAED,uFAAuF;AACvF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAI3F;AAED,sGAAsG;AACtG,wBAAgB,UAAU,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,QAAQ,CAgBrE;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAuBD,kFAAkF;AAClF,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CAavG;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,WAAW,CAKlF"}
@@ -1,12 +1,27 @@
1
1
  import { open } from "node:fs/promises";
2
+ import { finiteLimit } from "../../utils/number.js";
2
3
  export const TASK_RESULT_BYTES = 48 * 1024;
3
4
  export const TASK_DETAILS_BYTES = 120 * 1024;
4
5
  export const TASK_READ_BYTES = 8 * 1024;
5
- export const TASK_INFO_BYTES = 24 * 1024;
6
+ export const TASK_INPUT_BYTES = 24 * 1024;
6
7
  /** Task title budget, independent of notification wording and rendering. */
7
8
  export const TASK_TITLE_BYTES = 1024;
8
- export function finiteLimit(value, fallback, ceiling) {
9
- return value === undefined || !Number.isFinite(value) ? fallback : Math.max(0, Math.min(ceiling, Math.floor(value)));
9
+ export const TASK_LABEL_BYTES = 256;
10
+ export const TASK_FACTS = 16;
11
+ export const TASK_FACT_BYTES = 1024;
12
+ export const TASK_ERROR_BYTES = 4096;
13
+ export const TASK_PATH_BYTES = 8192;
14
+ /** A bounded, printable message for any thrown value. */
15
+ export function errorText(error, fallback = "Task execution failed (unprintable error)") {
16
+ try {
17
+ return boundText(error instanceof Error ? error.message : String(error), TASK_ERROR_BYTES);
18
+ }
19
+ catch {
20
+ return fallback;
21
+ }
22
+ }
23
+ export function boundReadBytes(bytes) {
24
+ return finiteLimit(bytes, TASK_READ_BYTES, TASK_RESULT_BYTES);
10
25
  }
11
26
  /** Both ends are codepoint aligned, including a head read ending inside a character. */
12
27
  function alignedSlice(buffer, start, end) {
@@ -35,6 +50,24 @@ export function boundText(text, bytes = TASK_RESULT_BYTES) {
35
50
  const buffer = Buffer.from(prefix);
36
51
  return alignedSlice(buffer, 0, Math.min(limit, buffer.length)).toString("utf8");
37
52
  }
53
+ export function boundTaskText(text, bytes = TASK_RESULT_BYTES) {
54
+ const bounded = boundText(text, bytes);
55
+ return { text: bounded, truncated: bounded !== text };
56
+ }
57
+ export function boundInput(input) {
58
+ const text = boundTaskText(input.text, TASK_INPUT_BYTES);
59
+ return {
60
+ label: boundText(input.label, TASK_LABEL_BYTES),
61
+ text: text.text,
62
+ truncated: input.truncated || text.truncated,
63
+ ...(input.language ? { language: boundText(input.language, 64) } : {}),
64
+ };
65
+ }
66
+ export function boundFacts(facts) {
67
+ return facts
68
+ .slice(0, TASK_FACTS)
69
+ .map(([label, value]) => [boundText(label, TASK_LABEL_BYTES), boundText(value, TASK_FACT_BYTES)]);
70
+ }
38
71
  /** The end of a bounded text, codepoint aligned: a command's outcome is at its end. */
39
72
  export function boundTail(text, bytes) {
40
73
  const buffer = Buffer.from(text);
@@ -42,72 +75,54 @@ export function boundTail(text, bytes) {
42
75
  return { text, truncated: false };
43
76
  return { text: alignedSlice(buffer, buffer.length - bytes, buffer.length).toString("utf8"), truncated: true };
44
77
  }
45
- /** Keep valid structured details intact or omit them, never truncate serialized JSON. */
46
- export function boundedResult(result) {
78
+ /** The bounded model-readable text of a result; images and private details never enter task state. */
79
+ export function resultText(result) {
47
80
  let remaining = TASK_RESULT_BYTES;
48
- const content = [];
81
+ const parts = [];
82
+ let truncated = false;
49
83
  for (const block of result.content) {
50
- if (remaining <= 0)
84
+ if (remaining <= 0) {
85
+ truncated = true;
51
86
  break;
52
- const text = boundText(block.type === "text" ? block.text : "[Image omitted from background history]", remaining);
53
- content.push({ type: "text", text });
54
- remaining -= Math.max(1, Buffer.byteLength(text));
87
+ }
88
+ const source = block.type === "text" ? block.text : "[Image omitted from task output]";
89
+ const text = boundText(source, remaining);
90
+ if (block.type !== "text" || text !== source)
91
+ truncated = true;
92
+ parts.push(text);
93
+ remaining -= Math.max(1, Buffer.byteLength(text) + 1);
55
94
  }
56
- let details;
57
- try {
58
- let budget = TASK_DETAILS_BYTES;
59
- const json = JSON.stringify(result.details, (key, value) => {
60
- // Stop visiting an oversized structure before constructing an unbounded JSON string.
61
- budget -= Buffer.byteLength(key) + 3;
62
- budget -= typeof value === "string" ? Buffer.byteLength(value) + 2 : 8;
63
- if (budget < 0)
64
- throw new Error("Background details exceed the storage budget");
65
- return value;
66
- });
67
- if (json !== undefined && Buffer.byteLength(json) <= TASK_DETAILS_BYTES)
68
- details = JSON.parse(json);
69
- }
70
- catch {
71
- // Runtime handles and cyclic details cannot enter a serializable snapshot.
72
- }
73
- return { content, details };
95
+ return { text: boundText(parts.join("\n")), truncated };
96
+ }
97
+ /**
98
+ * The byte window a read covers in an output of `size` bytes. `floor` is the first byte the
99
+ * caller has not seen yet; anything before it never counts as truncated.
100
+ */
101
+ function readWindow(size, options) {
102
+ const bytes = boundReadBytes(options.bytes);
103
+ const since = finiteLimit(options.sinceBytes, 0, Number.MAX_SAFE_INTEGER);
104
+ const floor = since > size ? 0 : since;
105
+ const start = options.sinceBytes !== undefined
106
+ ? Math.max(floor, size - bytes)
107
+ : options.mode === "head"
108
+ ? 0
109
+ : Math.max(0, size - bytes);
110
+ return { start, length: Math.min(bytes, size - start), floor };
74
111
  }
75
- /** Store the bounded public part of a result; private details never enter task history. */
76
- export function retainResult(task, result, truncated = false) {
77
- const bounded = boundedResult({ content: result.content, details: undefined });
78
- task.result = bounded;
79
- task.resultTruncated =
80
- truncated ||
81
- bounded.content.length !== result.content.length ||
82
- bounded.content.some((block, index) => {
83
- const original = result.content[index];
84
- return original?.type !== "text" || block.type !== "text" || block.text !== original.text;
85
- });
112
+ function outputSlice(size, floor, slice, fromByte) {
113
+ return { text: slice.toString("utf8"), totalBytes: size, truncated: slice.length < size - floor, fromByte };
86
114
  }
87
115
  /** Positioned, bounded reads only. The executor owns the path and its cleanup. */
88
116
  export async function readOutputSlice(path, options = {}) {
89
- const bytes = finiteLimit(options.bytes, TASK_READ_BYTES, TASK_RESULT_BYTES);
90
117
  const file = await open(path, "r");
91
118
  try {
92
119
  const { size } = await file.stat();
93
- const since = finiteLimit(options.sinceBytes, 0, Number.MAX_SAFE_INTEGER);
94
- const floor = since > size ? 0 : since;
95
- const start = options.sinceBytes !== undefined
96
- ? Math.max(floor, size - bytes)
97
- : options.mode === "head"
98
- ? 0
99
- : Math.max(0, size - bytes);
100
- const length = Math.min(bytes, size - start);
120
+ const { start, length, floor } = readWindow(size, options);
101
121
  // One extra byte lets alignment distinguish a complete last codepoint.
102
122
  const buffer = Buffer.alloc(Math.min(length + 1, size - start));
103
123
  const { bytesRead } = await file.read(buffer, 0, buffer.length, start);
104
124
  const slice = alignedSlice(buffer.subarray(0, bytesRead), 0, Math.min(length, bytesRead));
105
- return {
106
- text: slice.toString("utf8"),
107
- totalBytes: size,
108
- truncated: options.sinceBytes !== undefined ? start > floor || slice.length < length : slice.length < size,
109
- fromByte: start + slice.byteOffset - buffer.byteOffset,
110
- };
125
+ return outputSlice(size, floor, slice, start + slice.byteOffset - buffer.byteOffset);
111
126
  }
112
127
  finally {
113
128
  await file.close();
@@ -115,20 +130,8 @@ export async function readOutputSlice(path, options = {}) {
115
130
  }
116
131
  export function sliceText(text, options = {}) {
117
132
  const buffer = Buffer.from(text);
118
- const bytes = finiteLimit(options.bytes, TASK_READ_BYTES, TASK_RESULT_BYTES);
119
- const since = finiteLimit(options.sinceBytes, 0, Number.MAX_SAFE_INTEGER);
120
- const floor = since > buffer.length ? 0 : since;
121
- const start = options.sinceBytes !== undefined
122
- ? Math.max(floor, buffer.length - bytes)
123
- : options.mode === "head"
124
- ? 0
125
- : Math.max(0, buffer.length - bytes);
126
- const slice = alignedSlice(buffer, start, Math.min(buffer.length, start + bytes));
127
- return {
128
- text: slice.toString("utf8"),
129
- totalBytes: buffer.length,
130
- truncated: slice.length < buffer.length - floor,
131
- fromByte: slice.byteOffset - buffer.byteOffset,
132
- };
133
+ const { start, length, floor } = readWindow(buffer.length, options);
134
+ const slice = alignedSlice(buffer, start, start + length);
135
+ return outputSlice(buffer.length, floor, slice, slice.byteOffset - buffer.byteOffset);
133
136
  }
134
137
  //# sourceMappingURL=output.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../../../src/core/tasks/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAIxC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,CAAC;AAC3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,GAAG,IAAI,CAAC;AAC7C,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,CAAC;AACxC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,CAAC;AACzC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC,MAAM,UAAU,WAAW,CAAC,KAAyB,EAAE,QAAgB,EAAE,OAAe;IACvF,OAAO,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtH,CAAC;AAED,wFAAwF;AACxF,SAAS,YAAY,CAAC,MAAc,EAAE,KAAa,EAAE,GAAW;IAC/D,OAAO,KAAK,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAE,GAAG,IAAI,CAAC,KAAK,IAAI;QAAE,KAAK,EAAE,CAAC;IAChE,IAAI,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QACzB,OAAO,GAAG,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,GAAG,CAAE,GAAG,IAAI,CAAC,KAAK,IAAI;YAAE,GAAG,EAAE,CAAC;IAC7D,CAAC;IACD,8EAA8E;IAC9E,IAAI,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;IACnB,OAAO,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,CAAE,GAAG,IAAI,CAAC,KAAK,IAAI;QAAE,IAAI,EAAE,CAAC;IAChE,IAAI,IAAI,IAAI,KAAK,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzE,IAAI,GAAG,GAAG,IAAI,GAAG,KAAK;YAAE,GAAG,GAAG,IAAI,CAAC;IACpC,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,KAAK,GAAG,iBAAiB;IAChE,iEAAiE;IACjE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnC,OAAO,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACjF,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,KAAa;IACpD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,MAAM,CAAC,MAAM,IAAI,KAAK;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9D,OAAO,EAAE,IAAI,EAAE,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC/G,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,aAAa,CAAC,MAAgC;IAC7D,IAAI,SAAS,GAAG,iBAAiB,CAAC;IAClC,MAAM,OAAO,GAAwC,EAAE,CAAC;IACxD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,IAAI,SAAS,IAAI,CAAC;YAAE,MAAM;QAC1B,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,yCAAyC,EAAE,SAAS,CAAC,CAAC;QAClH,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACJ,IAAI,MAAM,GAAG,kBAAkB,CAAC;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,KAAc,EAAE,EAAE;YACnE,qFAAqF;YACrF,MAAM,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACrC,MAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACvE,IAAI,MAAM,GAAG,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAChF,OAAO,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QACH,IAAI,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,kBAAkB;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrG,CAAC;IAAC,MAAM,CAAC;QACR,2EAA2E;IAC5E,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,YAAY,CAAC,IAAkB,EAAE,MAAgC,EAAE,SAAS,GAAG,KAAK;IACnG,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;IAC/E,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;IACtB,IAAI,CAAC,eAAe;QACnB,SAAS;YACT,OAAO,CAAC,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC,OAAO,CAAC,MAAM;YAChD,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACvC,OAAO,QAAQ,EAAE,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC;YAC3F,CAAC,CAAC,CAAC;AACL,CAAC;AASD,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,eAAe,CACpC,IAAY,EACZ,UAA2E,EAAE;IAE7E,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC;IAC7E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACnC,IAAI,CAAC;QACJ,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAC1E,MAAM,KAAK,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACvC,MAAM,KAAK,GACV,OAAO,CAAC,UAAU,KAAK,SAAS;YAC/B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,KAAK,CAAC;YAC/B,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM;gBACxB,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,KAAK,CAAC,CAAC;QAC7C,uEAAuE;QACvE,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC;QAChE,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACvE,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;QAC1F,OAAO;YACN,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC5B,UAAU,EAAE,IAAI;YAChB,SAAS,EAAE,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI;YAC1G,QAAQ,EAAE,KAAK,GAAG,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU;SACtD,CAAC;IACH,CAAC;YAAS,CAAC;QACV,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;AACF,CAAC;AAED,MAAM,UAAU,SAAS,CACxB,IAAY,EACZ,UAA2E,EAAE;IAE7E,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAChD,MAAM,KAAK,GACV,OAAO,CAAC,UAAU,KAAK,SAAS;QAC/B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;QACxC,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM;YACxB,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;IAClF,OAAO;QACN,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC5B,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,SAAS,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,KAAK;QAC/C,QAAQ,EAAE,KAAK,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU;KAC9C,CAAC;AACH,CAAC","sourcesContent":["import { open } from \"node:fs/promises\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { TaskSnapshot } 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_INFO_BYTES = 24 * 1024;\n/** Task title budget, independent of notification wording and rendering. */\nexport const TASK_TITLE_BYTES = 1024;\n\nexport function finiteLimit(value: number | undefined, fallback: number, ceiling: number): number {\n\treturn value === undefined || !Number.isFinite(value) ? fallback : Math.max(0, Math.min(ceiling, Math.floor(value)));\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\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/** Keep valid structured details intact or omit them, never truncate serialized JSON. */\nexport function boundedResult(result: AgentToolResult<unknown>): AgentToolResult<unknown> {\n\tlet remaining = TASK_RESULT_BYTES;\n\tconst content: AgentToolResult<unknown>[\"content\"] = [];\n\tfor (const block of result.content) {\n\t\tif (remaining <= 0) break;\n\t\tconst text = boundText(block.type === \"text\" ? block.text : \"[Image omitted from background history]\", remaining);\n\t\tcontent.push({ type: \"text\", text });\n\t\tremaining -= Math.max(1, Buffer.byteLength(text));\n\t}\n\tlet details: unknown;\n\ttry {\n\t\tlet budget = TASK_DETAILS_BYTES;\n\t\tconst json = JSON.stringify(result.details, (key, value: unknown) => {\n\t\t\t// Stop visiting an oversized structure before constructing an unbounded JSON string.\n\t\t\tbudget -= Buffer.byteLength(key) + 3;\n\t\t\tbudget -= typeof value === \"string\" ? Buffer.byteLength(value) + 2 : 8;\n\t\t\tif (budget < 0) throw new Error(\"Background details exceed the storage budget\");\n\t\t\treturn value;\n\t\t});\n\t\tif (json !== undefined && Buffer.byteLength(json) <= TASK_DETAILS_BYTES) details = JSON.parse(json);\n\t} catch {\n\t\t// Runtime handles and cyclic details cannot enter a serializable snapshot.\n\t}\n\treturn { content, details };\n}\n\n/** Store the bounded public part of a result; private details never enter task history. */\nexport function retainResult(task: TaskSnapshot, result: AgentToolResult<unknown>, truncated = false): void {\n\tconst bounded = boundedResult({ content: result.content, details: undefined });\n\ttask.result = bounded;\n\ttask.resultTruncated =\n\t\ttruncated ||\n\t\tbounded.content.length !== result.content.length ||\n\t\tbounded.content.some((block, index) => {\n\t\t\tconst original = result.content[index];\n\t\t\treturn original?.type !== \"text\" || block.type !== \"text\" || block.text !== original.text;\n\t\t});\n}\n\nexport interface OutputSlice {\n\ttext: string;\n\ttotalBytes: number;\n\ttruncated: boolean;\n\tfromByte: number;\n}\n\n/** Positioned, bounded reads only. The executor owns the path and its cleanup. */\nexport async function readOutputSlice(\n\tpath: string,\n\toptions: { mode?: \"head\" | \"tail\"; bytes?: number; sinceBytes?: number } = {},\n): Promise<OutputSlice> {\n\tconst bytes = finiteLimit(options.bytes, TASK_READ_BYTES, TASK_RESULT_BYTES);\n\tconst file = await open(path, \"r\");\n\ttry {\n\t\tconst { size } = await file.stat();\n\t\tconst since = finiteLimit(options.sinceBytes, 0, Number.MAX_SAFE_INTEGER);\n\t\tconst floor = since > size ? 0 : since;\n\t\tconst start =\n\t\t\toptions.sinceBytes !== undefined\n\t\t\t\t? Math.max(floor, size - bytes)\n\t\t\t\t: options.mode === \"head\"\n\t\t\t\t\t? 0\n\t\t\t\t\t: Math.max(0, size - bytes);\n\t\tconst length = Math.min(bytes, size - start);\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 {\n\t\t\ttext: slice.toString(\"utf8\"),\n\t\t\ttotalBytes: size,\n\t\t\ttruncated: options.sinceBytes !== undefined ? start > floor || slice.length < length : slice.length < size,\n\t\t\tfromByte: start + slice.byteOffset - buffer.byteOffset,\n\t\t};\n\t} finally {\n\t\tawait file.close();\n\t}\n}\n\nexport function sliceText(\n\ttext: string,\n\toptions: { mode?: \"head\" | \"tail\"; bytes?: number; sinceBytes?: number } = {},\n): OutputSlice {\n\tconst buffer = Buffer.from(text);\n\tconst bytes = finiteLimit(options.bytes, TASK_READ_BYTES, TASK_RESULT_BYTES);\n\tconst since = finiteLimit(options.sinceBytes, 0, Number.MAX_SAFE_INTEGER);\n\tconst floor = since > buffer.length ? 0 : since;\n\tconst start =\n\t\toptions.sinceBytes !== undefined\n\t\t\t? Math.max(floor, buffer.length - bytes)\n\t\t\t: options.mode === \"head\"\n\t\t\t\t? 0\n\t\t\t\t: Math.max(0, buffer.length - bytes);\n\tconst slice = alignedSlice(buffer, start, Math.min(buffer.length, start + bytes));\n\treturn {\n\t\ttext: slice.toString(\"utf8\"),\n\t\ttotalBytes: buffer.length,\n\t\ttruncated: slice.length < buffer.length - floor,\n\t\tfromByte: slice.byteOffset - buffer.byteOffset,\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 { TaskFact, TaskInput, 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}\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; anything before it 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.sinceBytes !== undefined\n\t\t\t? Math.max(floor, size - bytes)\n\t\t\t: options.mode === \"head\"\n\t\t\t\t? 0\n\t\t\t\t: Math.max(0, size - bytes);\n\treturn { start, length: Math.min(bytes, size - start), floor };\n}\n\nfunction outputSlice(size: number, floor: number, slice: Buffer, fromByte: number): OutputSlice {\n\treturn { text: slice.toString(\"utf8\"), totalBytes: size, truncated: slice.length < size - floor, fromByte };\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(size, floor, slice, start + slice.byteOffset - buffer.byteOffset);\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(buffer.length, floor, slice, slice.byteOffset - buffer.byteOffset);\n}\n"]}
@@ -1,7 +1,16 @@
1
1
  import type { CustomMessage } from "../messages.ts";
2
- import type { TaskCompletionSnapshot, TaskSnapshot } from "./types.ts";
3
- /** Only this format is understood. Invalid/older details receive the renderer's bounded plain-text fallback. */
4
- export declare function readTaskCompletion(value: unknown): TaskCompletionSnapshot | undefined;
5
- export declare function taskCompletionSnapshot(task: TaskSnapshot): TaskCompletionSnapshot;
6
- export declare function taskCompletionMessage(task: TaskSnapshot): CustomMessage<TaskCompletionSnapshot>;
2
+ import { TASK_SNAPSHOT_VERSION } from "./codec.ts";
3
+ import type { TaskSnapshot } from "./types.ts";
4
+ export interface TaskCompletionDetails {
5
+ version: typeof TASK_SNAPSHOT_VERSION;
6
+ task: TaskSnapshot;
7
+ }
8
+ /**
9
+ * The model-facing text of a settled background task. A report reaches the model as its
10
+ * foreground result would have; a log contributes only its tail to the automatic turn.
11
+ */
12
+ export declare function projectForModel(task: TaskSnapshot): string;
13
+ /** A self-contained replay snapshot within the details budget; human-only display stays in the session record. */
14
+ export declare function taskCompletionDetails(task: TaskSnapshot): TaskCompletionDetails;
15
+ export declare function taskCompletionMessage(task: TaskSnapshot): CustomMessage<TaskCompletionDetails>;
7
16
  //# sourceMappingURL=presentation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"presentation.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/presentation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,OAAO,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAgC,MAAM,YAAY,CAAC;AA4ErG,gHAAgH;AAChH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,sBAAsB,GAAG,SAAS,CA+DrF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,YAAY,GAAG,sBAAsB,CAyBjF;AA4DD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC,sBAAsB,CAAC,CAU/F"}
1
+ {"version":3,"file":"presentation.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/presentation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAwB,MAAM,YAAY,CAAC;AASrE,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,OAAO,qBAAqB,CAAC;IACtC,IAAI,EAAE,YAAY,CAAC;CACnB;AAyCD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAkB1D;AAOD,kHAAkH;AAClH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,qBAAqB,CAgB/E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC,qBAAqB,CAAC,CAS9F"}