@astralyn/pi 1.4.6 → 1.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/bundle/chunks/{chunk-EYKC6ESU.js → chunk-5VIOGR76.js} +1 -1
- package/dist/bundle/chunks/{chunk-KDO6L76C.js → chunk-FODCTZXW.js} +4 -4
- package/dist/bundle/chunks/{chunk-RBTJBQWX.js → chunk-I2COK45I.js} +136 -137
- package/dist/bundle/chunks/{chunk-AXFWZIHH.js → chunk-MG5XDTXV.js} +1 -1
- package/dist/bundle/chunks/{chunk-ALHAFUHP.js → chunk-PU2IWWXV.js} +1 -1
- package/dist/bundle/chunks/{chunk-5M3YJ54Z.js → chunk-RO2VH6UZ.js} +1 -1
- package/dist/bundle/chunks/{cli-FH77R7JR.js → cli-MEL7SGJD.js} +1 -1
- package/dist/bundle/chunks/{execute-5ZQUS52M.js → execute-4CWRNHPO.js} +1 -1
- package/dist/bundle/chunks/{runtime-R5CMHJ5P.js → runtime-R3X67XMR.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-KCQU7LOC.js → virtual-modules-BBLD7YLS.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/agent-session.d.ts +0 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +0 -4
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/package-manager.d.ts +3 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +10 -0
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/resource-loader.d.ts +2 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +17 -4
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +4 -2
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +11 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-schema.d.ts +7 -0
- package/dist/core/settings-schema.d.ts.map +1 -1
- package/dist/core/settings-schema.js +6 -0
- package/dist/core/settings-schema.js.map +1 -1
- package/dist/core/skill-invocation.d.ts +46 -0
- package/dist/core/skill-invocation.d.ts.map +1 -0
- package/dist/core/skill-invocation.js +128 -0
- package/dist/core/skill-invocation.js.map +1 -0
- package/dist/core/skills.d.ts +10 -0
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +23 -0
- package/dist/core/skills.js.map +1 -1
- package/dist/core/tasks/delivery.d.ts +11 -4
- package/dist/core/tasks/delivery.d.ts.map +1 -1
- package/dist/core/tasks/delivery.js +9 -9
- package/dist/core/tasks/delivery.js.map +1 -1
- package/dist/core/tasks/execution.d.ts +10 -3
- package/dist/core/tasks/execution.d.ts.map +1 -1
- package/dist/core/tasks/execution.js +72 -52
- package/dist/core/tasks/execution.js.map +1 -1
- package/dist/core/tasks/format.d.ts +0 -2
- package/dist/core/tasks/format.d.ts.map +1 -1
- package/dist/core/tasks/format.js +1 -16
- package/dist/core/tasks/format.js.map +1 -1
- package/dist/core/tasks/limits.d.ts +12 -1
- package/dist/core/tasks/limits.d.ts.map +1 -1
- package/dist/core/tasks/limits.js +20 -1
- package/dist/core/tasks/limits.js.map +1 -1
- package/dist/core/tasks/output.d.ts +6 -12
- package/dist/core/tasks/output.d.ts.map +1 -1
- package/dist/core/tasks/output.js +35 -32
- package/dist/core/tasks/output.js.map +1 -1
- package/dist/core/tasks/record.d.ts +45 -0
- package/dist/core/tasks/record.d.ts.map +1 -0
- package/dist/core/tasks/record.js +80 -0
- package/dist/core/tasks/record.js.map +1 -0
- package/dist/core/tasks/runtime.d.ts +14 -14
- package/dist/core/tasks/runtime.d.ts.map +1 -1
- package/dist/core/tasks/runtime.js +111 -93
- package/dist/core/tasks/runtime.js.map +1 -1
- package/dist/core/tasks/session.d.ts +0 -1
- package/dist/core/tasks/session.d.ts.map +1 -1
- package/dist/core/tasks/session.js +7 -8
- package/dist/core/tasks/session.js.map +1 -1
- package/dist/core/tasks/store.d.ts +18 -25
- package/dist/core/tasks/store.d.ts.map +1 -1
- package/dist/core/tasks/store.js +42 -40
- package/dist/core/tasks/store.js.map +1 -1
- package/dist/core/tasks/types.d.ts +96 -17
- package/dist/core/tasks/types.d.ts.map +1 -1
- package/dist/core/tasks/types.js.map +1 -1
- package/dist/core/tools/shell-execution.d.ts +8 -7
- package/dist/core/tools/shell-execution.d.ts.map +1 -1
- package/dist/core/tools/shell-execution.js +18 -26
- package/dist/core/tools/shell-execution.js.map +1 -1
- package/dist/core/tools/shell-tool.d.ts.map +1 -1
- package/dist/core/tools/shell-tool.js +31 -29
- package/dist/core/tools/shell-tool.js.map +1 -1
- package/dist/core/usage-totals.d.ts +3 -0
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js +15 -0
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/extensions/agent/progress.d.ts.map +1 -1
- package/dist/extensions/agent/progress.js +1 -11
- package/dist/extensions/agent/progress.js.map +1 -1
- package/dist/extensions/agent/settings-host.d.ts +33 -0
- package/dist/extensions/agent/settings-host.d.ts.map +1 -0
- package/dist/extensions/agent/settings-host.js +75 -0
- package/dist/extensions/agent/settings-host.js.map +1 -0
- package/dist/extensions/agent/settings.d.ts.map +1 -1
- package/dist/extensions/agent/settings.js +18 -7
- package/dist/extensions/agent/settings.js.map +1 -1
- package/dist/extensions/agent/tool.d.ts.map +1 -1
- package/dist/extensions/agent/tool.js +9 -5
- package/dist/extensions/agent/tool.js.map +1 -1
- package/dist/extensions/agent/worker.d.ts.map +1 -1
- package/dist/extensions/agent/worker.js +3 -5
- package/dist/extensions/agent/worker.js.map +1 -1
- package/dist/extensions/btw/agent.d.ts +1 -1
- package/dist/extensions/btw/agent.d.ts.map +1 -1
- package/dist/extensions/btw/agent.js +3 -20
- package/dist/extensions/btw/agent.js.map +1 -1
- package/dist/extensions/cached-compaction/index.d.ts.map +1 -1
- package/dist/extensions/cached-compaction/index.js +3 -22
- package/dist/extensions/cached-compaction/index.js.map +1 -1
- package/dist/extensions/cached-compaction/render.d.ts +1 -0
- package/dist/extensions/cached-compaction/render.d.ts.map +1 -1
- package/dist/extensions/cached-compaction/render.js +42 -14
- package/dist/extensions/cached-compaction/render.js.map +1 -1
- package/dist/extensions/deepwiki/client.d.ts.map +1 -1
- package/dist/extensions/deepwiki/client.js +6 -78
- package/dist/extensions/deepwiki/client.js.map +1 -1
- package/dist/extensions/deepwiki/transport.d.ts +3 -0
- package/dist/extensions/deepwiki/transport.d.ts.map +1 -0
- package/dist/extensions/deepwiki/transport.js +96 -0
- package/dist/extensions/deepwiki/transport.js.map +1 -0
- package/dist/extensions/provider/ui/builtin-data.d.ts +3 -3
- package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -1
- package/dist/extensions/provider/ui/builtin-data.js.map +1 -1
- package/dist/extensions/provider/ui/compat.d.ts +3 -3
- package/dist/extensions/provider/ui/compat.d.ts.map +1 -1
- package/dist/extensions/provider/ui/compat.js.map +1 -1
- package/dist/extensions/provider/ui/controls.d.ts +2 -2
- package/dist/extensions/provider/ui/controls.d.ts.map +1 -1
- package/dist/extensions/provider/ui/controls.js.map +1 -1
- package/dist/extensions/provider/ui/dialogs.d.ts +3 -3
- package/dist/extensions/provider/ui/dialogs.d.ts.map +1 -1
- package/dist/extensions/provider/ui/dialogs.js.map +1 -1
- package/dist/extensions/provider/ui/dictionary.d.ts +2 -2
- package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -1
- package/dist/extensions/provider/ui/dictionary.js.map +1 -1
- package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
- package/dist/extensions/provider/ui/editor.js +1 -3
- package/dist/extensions/provider/ui/editor.js.map +1 -1
- package/dist/extensions/provider/ui/fetch-models.d.ts +2 -2
- package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -1
- package/dist/extensions/provider/ui/fetch-models.js.map +1 -1
- package/dist/extensions/provider/ui/model-fields.d.ts +2 -2
- package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -1
- package/dist/extensions/provider/ui/model-fields.js.map +1 -1
- package/dist/extensions/provider/ui/model-options.d.ts +6 -6
- package/dist/extensions/provider/ui/model-options.d.ts.map +1 -1
- package/dist/extensions/provider/ui/model-options.js.map +1 -1
- package/dist/extensions/provider/ui/pane.d.ts +21 -12
- package/dist/extensions/provider/ui/pane.d.ts.map +1 -1
- package/dist/extensions/provider/ui/pane.js.map +1 -1
- package/dist/extensions/provider/ui/provider-fields.d.ts +3 -3
- package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -1
- package/dist/extensions/provider/ui/provider-fields.js.map +1 -1
- package/dist/extensions/provider/ui/thinking-map.d.ts +2 -2
- package/dist/extensions/provider/ui/thinking-map.d.ts.map +1 -1
- package/dist/extensions/provider/ui/thinking-map.js.map +1 -1
- package/dist/extensions/run-summary/format.js +1 -1
- package/dist/extensions/run-summary/format.js.map +1 -1
- package/dist/extensions/statusline/usage.d.ts.map +1 -1
- package/dist/extensions/statusline/usage.js +2 -6
- package/dist/extensions/statusline/usage.js.map +1 -1
- package/dist/extensions/tasks/tool/actions.d.ts +1 -1
- package/dist/extensions/tasks/tool/actions.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/actions.js +49 -106
- package/dist/extensions/tasks/tool/actions.js.map +1 -1
- package/dist/extensions/tasks/tool/constants.d.ts +1 -6
- package/dist/extensions/tasks/tool/constants.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/constants.js +1 -6
- package/dist/extensions/tasks/tool/constants.js.map +1 -1
- package/dist/extensions/tasks/tool/schema.d.ts +0 -3
- package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/schema.js +4 -13
- package/dist/extensions/tasks/tool/schema.js.map +1 -1
- package/dist/extensions/tasks/tool.d.ts.map +1 -1
- package/dist/extensions/tasks/tool.js +2 -2
- package/dist/extensions/tasks/tool.js.map +1 -1
- package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/completion-render.js +31 -33
- package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
- package/dist/extensions/tasks/ui/layout.d.ts +7 -7
- package/dist/extensions/tasks/ui/layout.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/layout.js +17 -19
- package/dist/extensions/tasks/ui/layout.js.map +1 -1
- package/dist/extensions/tasks/ui/list.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/list.js +2 -3
- package/dist/extensions/tasks/ui/list.js.map +1 -1
- package/dist/extensions/tasks/ui/manager.d.ts +16 -7
- package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/manager.js +163 -131
- package/dist/extensions/tasks/ui/manager.js.map +1 -1
- package/dist/extensions/tasks/ui/model.d.ts +25 -0
- package/dist/extensions/tasks/ui/model.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/model.js +4 -0
- package/dist/extensions/tasks/ui/model.js.map +1 -1
- package/dist/extensions/tasks/ui/render.d.ts +1 -1
- package/dist/extensions/tasks/ui/render.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/render.js +11 -7
- package/dist/extensions/tasks/ui/render.js.map +1 -1
- package/dist/extensions/tasks/ui/status.d.ts +15 -0
- package/dist/extensions/tasks/ui/status.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/status.js +16 -0
- package/dist/extensions/tasks/ui/status.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts +17 -2
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +199 -18
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/status-marker.d.ts +2 -1
- package/dist/modes/interactive/components/status-marker.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-marker.js +0 -1
- package/dist/modes/interactive/components/status-marker.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +7 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/utils/duration.d.ts +3 -0
- package/dist/utils/duration.d.ts.map +1 -0
- package/dist/utils/duration.js +17 -0
- package/dist/utils/duration.js.map +1 -0
- package/dist/utils/number.d.ts +3 -0
- package/dist/utils/number.d.ts.map +1 -0
- package/dist/utils/number.js +5 -0
- package/dist/utils/number.js.map +1 -0
- package/docs/bundled/extensions/agent.md +3 -3
- package/docs/bundled/extensions/cached-compaction.md +13 -4
- package/docs/bundled/extensions/deepwiki.md +3 -1
- package/docs/extensions.md +5 -5
- package/docs/packages.md +5 -3
- package/docs/sdk.md +1 -1
- package/docs/session-format.md +1 -1
- package/docs/settings.md +11 -0
- package/docs/skills.md +23 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/schemas/settings.schema.json +36 -0
- package/dist/extensions/deepwiki/http.d.ts +0 -13
- package/dist/extensions/deepwiki/http.d.ts.map +0 -1
- package/dist/extensions/deepwiki/http.js +0 -88
- package/dist/extensions/deepwiki/http.js.map +0 -1
- package/dist/extensions/tasks/ui/task-view.d.ts +0 -8
- package/dist/extensions/tasks/ui/task-view.d.ts.map +0 -1
- package/dist/extensions/tasks/ui/task-view.js +0 -13
- package/dist/extensions/tasks/ui/task-view.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../../src/core/tasks/execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport { boundFacts, boundTaskText, boundText, resultText, TASK_ERROR_BYTES, TASK_PATH_BYTES } from \"./output.ts\";\nimport { changed, snapshotOf, type TaskRecord } from \"./store.ts\";\nimport type {\n\tTaskCompletion,\n\tTaskControl,\n\tTaskExecution,\n\tTaskFact,\n\tTaskMode,\n\tTaskSnapshot,\n\tTaskTerminalStatus,\n\tTaskText,\n\tTaskToolOutcome,\n\tTaskUpdate,\n} from \"./types.ts\";\n\n/** The runtime services one execution needs; it never reaches into the runtime itself. */\nexport interface ExecutionHost {\n\treadonly closed: boolean;\n\temit(): void;\n\t/** Synchronous persistence before terminal observers or notifications. */\n\tsettle(task: TaskSnapshot, usage: Usage | undefined): void;\n\t/** The execution settled and holds no slot, parent listener or caller any more. */\n\treleased(execution: Execution<unknown>): void;\n}\n\nexport function errorText(error: unknown): string {\n\ttry {\n\t\treturn boundText(error instanceof Error ? error.message : String(error), TASK_ERROR_BYTES);\n\t} catch {\n\t\treturn \"Task execution failed (unprintable error)\";\n\t}\n}\n\nfunction prependText(text: string, result: TaskText | undefined): TaskText {\n\treturn {\n\t\ttext: boundText(result?.text ? `${text}\\n${result.text}` : text),\n\t\ttruncated: result?.truncated ?? false,\n\t};\n}\n\n/** Terminal rows replace launch rows with the same label and append new ones. */\nfunction mergeFacts(base: readonly TaskFact[] = [], terminal: readonly TaskFact[]): TaskFact[] {\n\tconst labels = new Set(terminal.map(([label]) => label));\n\treturn boundFacts([...base.filter(([label]) => !labels.has(label)), ...terminal]);\n}\n\n/**\n * One live task: its caller, controller, parent link and executor callbacks.\n *\n * A caller may be handed off to the background whenever no executor preflight is in\n * progress: before `run` starts (queued) or after the executor calls `accept()`.\n */\nexport class Execution<T> {\n\treadonly record: TaskRecord;\n\treadonly concurrency?: { key: string; limit: number };\n\treadonly caller: Promise<TaskToolOutcome<T>>;\n\treadonly done: Promise<void>;\n\treadonly control: TaskControl<T>;\n\tprivate readonly host: ExecutionHost;\n\tprivate readonly run: TaskExecution<T>[\"run\"];\n\tprivate readonly controller = new AbortController();\n\tprivate readonly modeListeners = new Set<(mode: TaskMode) => void>();\n\tprivate resolveCaller!: (outcome: TaskToolOutcome<T>) => void;\n\tprivate rejectCaller!: (error: unknown) => void;\n\tprivate resolveDone!: () => void;\n\tprivate onUpdate?: (result: AgentToolResult<T>) => void;\n\tprivate releaseParentSignal: () => void = () => {};\n\tprivate usage?: Usage;\n\tprivate started = false;\n\tprivate accepted = false;\n\tprivate handedOff = false;\n\tprivate detachRequested: boolean;\n\n\tconstructor(host: ExecutionHost, record: TaskRecord, execution: TaskExecution<T>) {\n\t\tthis.host = host;\n\t\tthis.record = record;\n\t\tthis.run = execution.run;\n\t\tthis.concurrency = execution.concurrency;\n\t\tthis.detachRequested = execution.background ?? false;\n\t\tthis.onUpdate = execution.background ? undefined : execution.onUpdate;\n\t\tthis.caller = new Promise<TaskToolOutcome<T>>((resolve, reject) => {\n\t\t\tthis.resolveCaller = resolve;\n\t\t\tthis.rejectCaller = reject;\n\t\t});\n\t\tthis.done = new Promise<void>((resolve) => {\n\t\t\tthis.resolveDone = resolve;\n\t\t});\n\t\tconst parent = execution.signal;\n\t\tif (parent) {\n\t\t\tconst abort = () => {\n\t\t\t\tif (!this.detachRequested || !this.handoffAllowed) this.cancel();\n\t\t\t};\n\t\t\tparent.addEventListener(\"abort\", abort, { once: true });\n\t\t\tthis.releaseParentSignal = () => parent.removeEventListener(\"abort\", abort);\n\t\t}\n\t\tconst task = record.task;\n\t\tthis.control = {\n\t\t\tid: task.id,\n\t\t\tsignal: this.controller.signal,\n\t\t\tget mode() {\n\t\t\t\treturn task.mode;\n\t\t\t},\n\t\t\tonModeChange: (listener) => this.onModeChange(listener),\n\t\t\taccept: () => this.accept(),\n\t\t\tpublish: (update) => this.publish(update),\n\t\t\tattachOutput: (path, cleanup) => this.attachOutput(path, cleanup),\n\t\t\tcancel: () => {\n\t\t\t\tthis.cancel();\n\t\t\t},\n\t\t};\n\t}\n\n\tget task(): TaskSnapshot {\n\t\treturn this.record.task;\n\t}\n\n\tget aborted(): boolean {\n\t\treturn this.controller.signal.aborted;\n\t}\n\n\t/** Executor preflight never races a handoff; queued work has not begun any. */\n\tprivate get handoffAllowed(): boolean {\n\t\treturn !this.started || this.accepted;\n\t}\n\n\t/** Waiting for a concurrency slot: registered, but `run` has not started. */\n\tget queued(): boolean {\n\t\treturn !this.started && !this.record.settled;\n\t}\n\n\tget detachable(): boolean {\n\t\treturn !this.record.settled && !this.detachRequested && !this.aborted;\n\t}\n\n\t/** Stop forwarding to the launching tool call: parent cancellation and progress no longer reach it. */\n\treleaseParent(): void {\n\t\tthis.releaseParentSignal();\n\t\tthis.releaseParentSignal = () => {};\n\t\tthis.onUpdate = undefined;\n\t}\n\n\tstart(): void {\n\t\tif (this.started || this.record.settled) return;\n\t\tif (this.host.closed) {\n\t\t\tthis.cancel();\n\t\t\treturn;\n\t\t}\n\t\tthis.started = true;\n\t\tthis.task.status = \"running\";\n\t\tchanged(this.record);\n\t\t// The rejection handler is installed immediately, including for synchronous preflight throws.\n\t\ttry {\n\t\t\tvoid Promise.resolve(this.run(this.control)).then(\n\t\t\t\t(completion) => this.finish(completion),\n\t\t\t\t(error: unknown) => this.finish(undefined, error),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.finish(undefined, error);\n\t\t}\n\t}\n\n\thandoff(): void {\n\t\tif (\n\t\t\t!this.handoffAllowed ||\n\t\t\t!this.detachRequested ||\n\t\t\tthis.record.settled ||\n\t\t\tthis.handedOff ||\n\t\t\tthis.host.closed ||\n\t\t\t!this.record.visible ||\n\t\t\tthis.aborted\n\t\t)\n\t\t\treturn;\n\t\tthis.handedOff = true;\n\t\tthis.task.mode = \"background\";\n\t\tchanged(this.record);\n\t\tthis.releaseParent();\n\t\tthis.resolveCaller({ kind: \"background\", task: snapshotOf(this.record) });\n\t\tthis.host.emit();\n\t}\n\n\trequestDetach(): void {\n\t\tthis.detachRequested = true;\n\t\tthis.task.mode = \"background\";\n\t\tchanged(this.record);\n\t\tif (this.accepted) this.releaseParent();\n\t}\n\n\tcompleteDetach(): void {\n\t\tthis.handoff();\n\t\tfor (const listener of this.modeListeners) {\n\t\t\ttry {\n\t\t\t\tlistener(this.task.mode);\n\t\t\t} catch {\n\t\t\t\t/* Executors own their diagnostics. */\n\t\t\t}\n\t\t}\n\t}\n\n\tcancel(): boolean {\n\t\tif (this.record.settled || this.aborted) return false;\n\t\tthis.task.status = \"stopping\";\n\t\tchanged(this.record);\n\t\tthis.controller.abort();\n\t\tif (!this.started) this.finish(undefined, new Error(\"Task cancelled before it started.\"));\n\t\tthis.host.emit();\n\t\treturn true;\n\t}\n\n\tprivate onModeChange(listener: (mode: TaskMode) => void): () => void {\n\t\tif (this.record.settled || this.host.closed) return () => {};\n\t\tthis.modeListeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.modeListeners.delete(listener);\n\t\t};\n\t}\n\n\tprivate accept(): void {\n\t\tif (this.record.settled || this.accepted || this.host.closed || this.aborted) return;\n\t\tthis.accepted = true;\n\t\tif (this.detachRequested) this.releaseParent();\n\t\t// Let an already available final result win over a handoff.\n\t\tqueueMicrotask(() => queueMicrotask(() => this.handoff()));\n\t\tthis.host.emit();\n\t}\n\n\tprivate publish(update: TaskUpdate<T>): void {\n\t\tif (this.record.settled || this.host.closed) return;\n\t\tthis.task.result = resultText(update.result);\n\t\tif (update.display !== undefined) this.task.display = boundTaskText(update.display);\n\t\tchanged(this.record);\n\t\tif (update.usage !== undefined) this.usage = structuredClone(update.usage);\n\t\tif (!this.detachRequested && !this.handedOff) {\n\t\t\ttry {\n\t\t\t\tthis.onUpdate?.(update.result);\n\t\t\t} catch {\n\t\t\t\t/* UI observers cannot stop execution. */\n\t\t\t}\n\t\t}\n\t\tthis.host.emit();\n\t}\n\n\tprivate attachOutput(path: string, cleanup?: () => void | Promise<void>): void {\n\t\tif (this.record.settled) {\n\t\t\tif (cleanup) throw new Error(\"Task execution has settled\");\n\t\t\treturn;\n\t\t}\n\t\tif (this.record.cleanup) throw new Error(\"Managed output is already registered\");\n\t\t// Never truncate a real filesystem path into a different path.\n\t\tif (Buffer.byteLength(path) > TASK_PATH_BYTES) throw new Error(\"Task output path is too large\");\n\t\tthis.record.cleanup = cleanup;\n\t\tthis.task.outputPath = path;\n\t\tchanged(this.record);\n\t\tthis.host.emit();\n\t}\n\n\tprivate finish(completion: TaskCompletion<T> | undefined, error?: unknown): void {\n\t\tconst record = this.record;\n\t\tconst task = this.task;\n\t\tif (record.settled) return;\n\t\trecord.settled = true;\n\t\tthis.modeListeners.clear();\n\t\tthis.releaseParent();\n\t\ttask.endedAt = Date.now();\n\t\tconst status: TaskTerminalStatus = completion\n\t\t\t? (completion.status ?? (this.aborted ? \"cancelled\" : \"completed\"))\n\t\t\t: this.aborted\n\t\t\t\t? \"cancelled\"\n\t\t\t\t: \"failed\";\n\t\ttask.status = status;\n\t\tif (completion) {\n\t\t\ttask.result = resultText(completion.result);\n\t\t\tif (completion.display !== undefined) task.display = boundTaskText(completion.display);\n\t\t\tif (completion.error !== undefined) task.error = boundText(completion.error, TASK_ERROR_BYTES);\n\t\t\tif (completion.facts) task.facts = mergeFacts(task.facts, completion.facts);\n\t\t} else {\n\t\t\ttask.error = errorText(error);\n\t\t\ttask.result = prependText(task.error, task.result);\n\t\t}\n\t\tchanged(record);\n\t\tlet warning: string | undefined;\n\t\ttry {\n\t\t\tthis.host.settle(snapshotOf(record), completion?.usage ?? completion?.result.usage ?? this.usage);\n\t\t} catch (accountingError) {\n\t\t\twarning = `Usage settlement failed: ${errorText(accountingError)}`;\n\t\t\ttask.error = boundText([task.error, warning].filter(Boolean).join(\"\\n\"), 2 * TASK_ERROR_BYTES);\n\t\t\ttask.result = prependText(warning, task.result);\n\t\t\tchanged(record);\n\t\t}\n\t\tthis.usage = undefined;\n\t\t// Delivery becomes eligible only after settlement is persisted.\n\t\trecord.delivery = this.handedOff ? \"pending\" : \"delivered\";\n\t\tif (!this.handedOff) {\n\t\t\tif (!completion) this.rejectCaller(error);\n\t\t\telse {\n\t\t\t\t// The task ledger owns usage; a tool result never carries it a second time.\n\t\t\t\tconst { usage: _usage, ...result } = completion.result;\n\t\t\t\tif (warning) result.content = [{ type: \"text\", text: warning }, ...result.content];\n\t\t\t\tthis.resolveCaller({ kind: \"result\", result, status, error: task.error });\n\t\t\t}\n\t\t}\n\t\tfor (const waiter of [...record.waiters]) waiter();\n\t\tthis.resolveDone();\n\t\tthis.host.released(this as Execution<unknown>);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../../src/core/tasks/execution.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport {\n\tboundFacts,\n\tboundTaskText,\n\tboundText,\n\terrorText,\n\tresultText,\n\tTASK_ERROR_BYTES,\n\tTASK_PATH_BYTES,\n} from \"./output.ts\";\nimport type { TaskRecord } from \"./record.ts\";\nimport type {\n\tTaskCompletion,\n\tTaskControl,\n\tTaskExecution,\n\tTaskFact,\n\tTaskMode,\n\tTaskSnapshot,\n\tTaskTerminalStatus,\n\tTaskText,\n\tTaskToolOutcome,\n\tTaskUpdate,\n} from \"./types.ts\";\n\n/** The runtime services one execution needs; it never reaches into the runtime itself. */\nexport interface ExecutionHost {\n\treadonly closed: boolean;\n\temit(): void;\n\t/** Synchronous persistence before terminal observers or notifications. */\n\tsettle(task: TaskSnapshot, usage: Usage | undefined): void;\n\t/** The execution settled and holds no slot, parent listener or caller any more. */\n\treleased(execution: Execution<unknown>): void;\n}\n\nfunction prependText(text: string, result: TaskText | undefined): TaskText {\n\treturn {\n\t\ttext: boundText(result?.text ? `${text}\\n${result.text}` : text),\n\t\ttruncated: result?.truncated ?? false,\n\t};\n}\n\n/** Terminal rows replace launch rows with the same label and append new ones. */\nfunction mergeFacts(base: readonly TaskFact[] = [], terminal: readonly TaskFact[]): TaskFact[] {\n\tconst labels = new Set(terminal.map(([label]) => label));\n\treturn boundFacts([...base.filter(([label]) => !labels.has(label)), ...terminal]);\n}\n\n/**\n * One live task: its caller, controller, parent link and executor callbacks.\n *\n * A caller may be handed off to the background whenever no executor preflight is in\n * progress: before `run` starts (queued) or after the executor calls `accept()`.\n */\nexport class Execution<T> {\n\treadonly record: TaskRecord;\n\treadonly concurrency?: { key: string; limit: number };\n\treadonly caller: Promise<TaskToolOutcome<T>>;\n\treadonly done: Promise<void>;\n\treadonly control: TaskControl<T>;\n\tprivate readonly host: ExecutionHost;\n\tprivate readonly run: TaskExecution<T>[\"run\"];\n\tprivate readonly controller = new AbortController();\n\tprivate readonly modeListeners = new Set<(mode: TaskMode) => void>();\n\tprivate resolveCaller!: (outcome: TaskToolOutcome<T>) => void;\n\tprivate rejectCaller!: (error: unknown) => void;\n\tprivate resolveDone!: () => void;\n\tprivate onUpdate?: (result: AgentToolResult<T>) => void;\n\tprivate releaseParentSignal: () => void = () => {};\n\tprivate usage?: Usage;\n\tprivate started = false;\n\tprivate accepted = false;\n\tprivate handedOff = false;\n\tprivate detachRequested: boolean;\n\t/** The executor's `run` promise once started. */\n\tprivate running?: Promise<TaskCompletion<T>>;\n\n\tconstructor(host: ExecutionHost, record: TaskRecord, execution: TaskExecution<T>) {\n\t\tthis.host = host;\n\t\tthis.record = record;\n\t\tthis.run = execution.run;\n\t\tthis.concurrency = execution.concurrency;\n\t\tthis.detachRequested = execution.background ?? false;\n\t\tthis.onUpdate = execution.background ? undefined : execution.onUpdate;\n\t\tthis.caller = new Promise<TaskToolOutcome<T>>((resolve, reject) => {\n\t\t\tthis.resolveCaller = resolve;\n\t\t\tthis.rejectCaller = reject;\n\t\t});\n\t\tthis.done = new Promise<void>((resolve) => {\n\t\t\tthis.resolveDone = resolve;\n\t\t});\n\t\tconst parent = execution.signal;\n\t\tif (parent) {\n\t\t\tconst abort = () => {\n\t\t\t\tif (!this.detachRequested || !this.handoffAllowed) this.cancel();\n\t\t\t};\n\t\t\tparent.addEventListener(\"abort\", abort, { once: true });\n\t\t\tthis.releaseParentSignal = () => parent.removeEventListener(\"abort\", abort);\n\t\t}\n\t\tconst task = record.task;\n\t\tthis.control = {\n\t\t\tid: task.id,\n\t\t\tsignal: this.controller.signal,\n\t\t\tget mode() {\n\t\t\t\treturn task.mode;\n\t\t\t},\n\t\t\tonModeChange: (listener) => this.onModeChange(listener),\n\t\t\taccept: () => this.accept(),\n\t\t\tpublish: (update) => this.publish(update),\n\t\t\tattachOutput: (path, cleanup) => this.attachOutput(path, cleanup),\n\t\t\tcancel: () => {\n\t\t\t\tthis.cancel();\n\t\t\t},\n\t\t};\n\t}\n\n\tget task(): Readonly<TaskSnapshot> {\n\t\treturn this.record.task;\n\t}\n\n\tget aborted(): boolean {\n\t\treturn this.controller.signal.aborted;\n\t}\n\n\t/** Executor preflight never races a handoff; queued work has not begun any. */\n\tprivate get handoffAllowed(): boolean {\n\t\treturn !this.started || this.accepted;\n\t}\n\n\t/** Waiting for a concurrency slot: registered, but `run` has not started. */\n\tget queued(): boolean {\n\t\treturn !this.started && !this.record.settled;\n\t}\n\n\tget detachable(): boolean {\n\t\treturn !this.record.settled && !this.detachRequested && !this.aborted;\n\t}\n\n\t/** Stop forwarding to the launching tool call: parent cancellation and progress no longer reach it. */\n\treleaseParent(): void {\n\t\tthis.releaseParentSignal();\n\t\tthis.releaseParentSignal = () => {};\n\t\tthis.onUpdate = undefined;\n\t}\n\n\tstart(): void {\n\t\tif (this.started || this.record.settled) return;\n\t\tif (this.host.closed) {\n\t\t\tthis.cancel();\n\t\t\treturn;\n\t\t}\n\t\tthis.started = true;\n\t\tthis.record.update((task) => {\n\t\t\ttask.status = \"running\";\n\t\t});\n\t\t// The rejection handler is installed immediately, including for synchronous preflight throws.\n\t\ttry {\n\t\t\tthis.running = Promise.resolve(this.run(this.control));\n\t\t\tvoid this.running.then(\n\t\t\t\t(completion) => this.finish(completion),\n\t\t\t\t(error: unknown) => this.finish(undefined, error),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthis.finish(undefined, error);\n\t\t}\n\t}\n\n\thandoff(): void {\n\t\tif (\n\t\t\t!this.handoffAllowed ||\n\t\t\t!this.detachRequested ||\n\t\t\tthis.record.settled ||\n\t\t\tthis.handedOff ||\n\t\t\tthis.host.closed ||\n\t\t\t!this.record.visible ||\n\t\t\tthis.aborted\n\t\t)\n\t\t\treturn;\n\t\tthis.handedOff = true;\n\t\tthis.record.update((task) => {\n\t\t\ttask.mode = \"background\";\n\t\t});\n\t\tthis.releaseParent();\n\t\tthis.resolveCaller({ kind: \"background\", task: this.record.snapshot() });\n\t\tthis.host.emit();\n\t}\n\n\trequestDetach(): void {\n\t\tthis.detachRequested = true;\n\t\tthis.record.update((task) => {\n\t\t\ttask.mode = \"background\";\n\t\t});\n\t\tif (this.accepted) this.releaseParent();\n\t}\n\n\tcompleteDetach(): void {\n\t\tthis.handoff();\n\t\tfor (const listener of this.modeListeners) {\n\t\t\ttry {\n\t\t\t\tlistener(this.task.mode);\n\t\t\t} catch {\n\t\t\t\t/* Executors own their diagnostics. */\n\t\t\t}\n\t\t}\n\t}\n\n\tcancel(): boolean {\n\t\tif (this.record.settled || this.aborted) return false;\n\t\tthis.record.update((task) => {\n\t\t\ttask.status = \"stopping\";\n\t\t});\n\t\tthis.controller.abort();\n\t\tif (!this.started) this.finish(undefined, new Error(\"Task cancelled before it started.\"));\n\t\tthis.host.emit();\n\t\treturn true;\n\t}\n\n\tprivate onModeChange(listener: (mode: TaskMode) => void): () => void {\n\t\tif (this.record.settled || this.host.closed) return () => {};\n\t\tthis.modeListeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.modeListeners.delete(listener);\n\t\t};\n\t}\n\n\tprivate accept(): void {\n\t\tif (this.record.settled || this.accepted || this.host.closed || this.aborted) return;\n\t\tthis.accepted = true;\n\t\tif (this.detachRequested) this.releaseParent();\n\t\t// An already available final result wins over a handoff, so decide only once the\n\t\t// executor's own synchronous code has yielded.\n\t\tqueueMicrotask(() => this.handoffIfRunning());\n\t\tthis.host.emit();\n\t}\n\n\t/**\n\t * Hand off unless `run` has already settled. A reaction on an already settled promise is\n\t * queued at once, ahead of the pending-check below whatever the promise's chain depth, so\n\t * the outcome never depends on how `start()` chains its own handlers.\n\t */\n\tprivate handoffIfRunning(): void {\n\t\tlet settled = false;\n\t\tconst markSettled = () => {\n\t\t\tsettled = true;\n\t\t};\n\t\tthis.running?.then(markSettled, markSettled);\n\t\tvoid Promise.resolve().then(() => {\n\t\t\tif (!settled) this.handoff();\n\t\t});\n\t}\n\n\tprivate publish(update: TaskUpdate<T>): void {\n\t\tif (this.record.settled || this.host.closed) return;\n\t\tthis.record.update((task) => {\n\t\t\ttask.result = resultText(update.result);\n\t\t\tif (update.display !== undefined) task.display = boundTaskText(update.display);\n\t\t});\n\t\tif (update.usage !== undefined) this.usage = structuredClone(update.usage);\n\t\tif (!this.detachRequested && !this.handedOff) {\n\t\t\ttry {\n\t\t\t\tthis.onUpdate?.(update.result);\n\t\t\t} catch {\n\t\t\t\t/* UI observers cannot stop execution. */\n\t\t\t}\n\t\t}\n\t\tthis.host.emit();\n\t}\n\n\tprivate attachOutput(path: string, cleanup?: () => void | Promise<void>): void {\n\t\tif (this.record.settled) {\n\t\t\tif (cleanup) throw new Error(\"Task execution has settled\");\n\t\t\treturn;\n\t\t}\n\t\tif (this.record.cleanup) throw new Error(\"Managed output is already registered\");\n\t\t// Never truncate a real filesystem path into a different path.\n\t\tif (Buffer.byteLength(path) > TASK_PATH_BYTES) throw new Error(\"Task output path is too large\");\n\t\tthis.record.cleanup = cleanup;\n\t\tthis.record.update((task) => {\n\t\t\ttask.outputPath = path;\n\t\t});\n\t\tthis.host.emit();\n\t}\n\n\tprivate finish(completion: TaskCompletion<T> | undefined, error?: unknown): void {\n\t\tconst record = this.record;\n\t\tif (record.settled) return;\n\t\trecord.settled = true;\n\t\tthis.modeListeners.clear();\n\t\tthis.releaseParent();\n\t\tconst status: TaskTerminalStatus = completion\n\t\t\t? (completion.status ?? (this.aborted ? \"cancelled\" : \"completed\"))\n\t\t\t: this.aborted\n\t\t\t\t? \"cancelled\"\n\t\t\t\t: \"failed\";\n\t\trecord.update((task) => {\n\t\t\ttask.endedAt = Date.now();\n\t\t\ttask.status = status;\n\t\t\tif (completion) {\n\t\t\t\ttask.result = resultText(completion.result);\n\t\t\t\tif (completion.display !== undefined) task.display = boundTaskText(completion.display);\n\t\t\t\tif (completion.error !== undefined) task.error = boundText(completion.error, TASK_ERROR_BYTES);\n\t\t\t\tif (completion.facts) task.facts = mergeFacts(task.facts, completion.facts);\n\t\t\t} else {\n\t\t\t\ttask.error = errorText(error);\n\t\t\t\ttask.result = prependText(task.error, task.result);\n\t\t\t}\n\t\t});\n\t\tlet warning: string | undefined;\n\t\ttry {\n\t\t\tthis.host.settle(record.snapshot(), completion?.usage ?? completion?.result.usage ?? this.usage);\n\t\t} catch (accountingError) {\n\t\t\tconst notice = `Usage settlement failed: ${errorText(accountingError)}`;\n\t\t\twarning = notice;\n\t\t\trecord.update((task) => {\n\t\t\t\ttask.error = boundText([task.error, notice].filter(Boolean).join(\"\\n\"), 2 * TASK_ERROR_BYTES);\n\t\t\t\ttask.result = prependText(notice, task.result);\n\t\t\t});\n\t\t}\n\t\tthis.usage = undefined;\n\t\t// Delivery becomes eligible only after settlement is persisted.\n\t\tif (this.handedOff) record.queueDelivery();\n\t\telse record.acknowledge();\n\t\tif (!this.handedOff) {\n\t\t\tif (!completion) this.rejectCaller(error);\n\t\t\telse {\n\t\t\t\t// The task ledger owns usage; a tool result never carries it a second time.\n\t\t\t\tconst { usage: _usage, ...result } = completion.result;\n\t\t\t\tif (warning) result.content = [{ type: \"text\", text: warning }, ...result.content];\n\t\t\t\tthis.resolveCaller({ kind: \"result\", result, status, error: record.task.error });\n\t\t\t}\n\t\t}\n\t\tfor (const waiter of [...record.waiters]) waiter();\n\t\tthis.resolveDone();\n\t\tthis.host.released(this as Execution<unknown>);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/format.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/format.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,SAAa,GAAG,MAAM,CAEpG"}
|
|
@@ -1,19 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
export function formatDuration(ms) {
|
|
3
|
-
if (ms < 500)
|
|
4
|
-
return "<1s";
|
|
5
|
-
const seconds = Math.round(ms / 1000);
|
|
6
|
-
if (seconds < 60)
|
|
7
|
-
return `${seconds}s`;
|
|
8
|
-
const minutes = Math.floor(seconds / 60);
|
|
9
|
-
if (minutes < 60) {
|
|
10
|
-
const remainder = seconds % 60;
|
|
11
|
-
return remainder === 0 ? `${minutes}m` : `${minutes}m ${remainder}s`;
|
|
12
|
-
}
|
|
13
|
-
const hours = Math.floor(minutes / 60);
|
|
14
|
-
const remainder = minutes % 60;
|
|
15
|
-
return remainder === 0 ? `${hours}h` : `${hours}h ${remainder}m`;
|
|
16
|
-
}
|
|
1
|
+
import { formatDuration } from "../../utils/duration.js";
|
|
17
2
|
export function runtimeLabel(task, now = Date.now()) {
|
|
18
3
|
return formatDuration((task.endedAt ?? now) - task.startedAt);
|
|
19
4
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/core/tasks/format.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/core/tasks/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,UAAU,YAAY,CAAC,IAA6C,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC3F,OAAO,cAAc,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;AAC/D,CAAC","sourcesContent":["import { formatDuration } from \"../../utils/duration.ts\";\n\nexport function runtimeLabel(task: { startedAt: number; endedAt?: number }, now = Date.now()): string {\n\treturn formatDuration((task.endedAt ?? now) - task.startedAt);\n}\n"]}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Shared observation-window limits, the one definition used by the runtime and the tasks tool.
|
|
3
|
+
* Execution timeouts are configured separately by each executor.
|
|
4
|
+
*/
|
|
2
5
|
export declare const TASKS_WAIT_DEFAULT_MS = 20000;
|
|
3
6
|
export declare const TASKS_WAIT_MIN_MS = 1000;
|
|
4
7
|
export declare const TASKS_WAIT_MAX_MS: number;
|
|
8
|
+
/** Floor for a model-requested read slice; the default and ceiling are TASK_READ_BYTES and TASK_RESULT_BYTES. */
|
|
9
|
+
export declare const TASKS_READ_MIN_BYTES = 256;
|
|
10
|
+
/** The wait window the runtime honours: any finite value up to the ceiling, including 0. */
|
|
11
|
+
export declare function boundWaitMs(waitMs: number | undefined): number;
|
|
12
|
+
/** The wait window a tool call runs, which the pending-call renderer also shows. */
|
|
13
|
+
export declare function clampWaitMs(waitMs: number | undefined): number;
|
|
14
|
+
/** The read size a tool call runs. */
|
|
15
|
+
export declare function clampReadBytes(bytes: number | undefined): number;
|
|
5
16
|
//# sourceMappingURL=limits.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/limits.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/limits.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAC5C,eAAO,MAAM,iBAAiB,OAAQ,CAAC;AACvC,eAAO,MAAM,iBAAiB,QAAc,CAAC;AAC7C,iHAAiH;AACjH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,4FAA4F;AAC5F,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE9D;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE9D;AAED,sCAAsC;AACtC,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEhE"}
|
|
@@ -1,5 +1,24 @@
|
|
|
1
|
-
|
|
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,
|
|
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,5 +1,5 @@
|
|
|
1
1
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
2
|
-
import type { TaskFact, TaskInput, TaskText } 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;
|
|
@@ -11,7 +11,9 @@ export declare const TASK_FACTS = 16;
|
|
|
11
11
|
export declare const TASK_FACT_BYTES = 1024;
|
|
12
12
|
export declare const TASK_ERROR_BYTES = 4096;
|
|
13
13
|
export declare const TASK_PATH_BYTES = 8192;
|
|
14
|
-
|
|
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;
|
|
15
17
|
export declare function boundText(text: string, bytes?: number): string;
|
|
16
18
|
export declare function boundTaskText(text: string, bytes?: number): TaskText;
|
|
17
19
|
export declare function boundInput(input: TaskInput): TaskInput;
|
|
@@ -30,14 +32,6 @@ export interface OutputSlice {
|
|
|
30
32
|
fromByte: number;
|
|
31
33
|
}
|
|
32
34
|
/** Positioned, bounded reads only. The executor owns the path and its cleanup. */
|
|
33
|
-
export declare function readOutputSlice(path: string, options?:
|
|
34
|
-
|
|
35
|
-
bytes?: number;
|
|
36
|
-
sinceBytes?: number;
|
|
37
|
-
}): Promise<OutputSlice>;
|
|
38
|
-
export declare function sliceText(text: string, options?: {
|
|
39
|
-
mode?: "head" | "tail";
|
|
40
|
-
bytes?: number;
|
|
41
|
-
sinceBytes?: number;
|
|
42
|
-
}): OutputSlice;
|
|
35
|
+
export declare function readOutputSlice(path: string, options?: TaskReadOptions): Promise<OutputSlice>;
|
|
36
|
+
export declare function sliceText(text: string, options?: TaskReadOptions): OutputSlice;
|
|
43
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;
|
|
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,4 +1,5 @@
|
|
|
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;
|
|
@@ -10,8 +11,17 @@ export const TASK_FACTS = 16;
|
|
|
10
11
|
export const TASK_FACT_BYTES = 1024;
|
|
11
12
|
export const TASK_ERROR_BYTES = 4096;
|
|
12
13
|
export const TASK_PATH_BYTES = 8192;
|
|
13
|
-
|
|
14
|
-
|
|
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);
|
|
15
25
|
}
|
|
16
26
|
/** Both ends are codepoint aligned, including a head read ending inside a character. */
|
|
17
27
|
function alignedSlice(buffer, start, end) {
|
|
@@ -84,30 +94,35 @@ export function resultText(result) {
|
|
|
84
94
|
}
|
|
85
95
|
return { text: boundText(parts.join("\n")), truncated };
|
|
86
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 };
|
|
111
|
+
}
|
|
112
|
+
function outputSlice(size, floor, slice, fromByte) {
|
|
113
|
+
return { text: slice.toString("utf8"), totalBytes: size, truncated: slice.length < size - floor, fromByte };
|
|
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
|
|
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
|
|
119
|
-
const
|
|
120
|
-
|
|
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":"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","sourcesContent":["import { open } from \"node:fs/promises\";\nimport type { AgentToolResult } from \"@earendil-works/pi-agent-core\";\nimport type { TaskFact, TaskInput, 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\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\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/** 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"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { TaskSnapshot } from "./types.ts";
|
|
2
|
+
/**
|
|
3
|
+
* none: running, or answered inline by its tool call; pending: a settled handoff
|
|
4
|
+
* awaiting automatic delivery; claimed: handed to the host; delivered: acknowledged.
|
|
5
|
+
*/
|
|
6
|
+
export type TaskDeliveryState = "none" | "pending" | "claimed" | "delivered";
|
|
7
|
+
/**
|
|
8
|
+
* The runtime's state for one task: its working snapshot, retention counters and delivery
|
|
9
|
+
* state. The working snapshot changes only through `update()`, which also drops the frozen
|
|
10
|
+
* copy that readers share, so a mutation can never leave a stale snapshot behind.
|
|
11
|
+
*/
|
|
12
|
+
export declare class TaskRecord {
|
|
13
|
+
/** Read-only view of the working copy; change it with update(). */
|
|
14
|
+
readonly task: Readonly<TaskSnapshot>;
|
|
15
|
+
settled: boolean;
|
|
16
|
+
/** Whether the launch anchor is on the selected branch. */
|
|
17
|
+
visible: boolean;
|
|
18
|
+
pins: number;
|
|
19
|
+
deliveryHolds: number;
|
|
20
|
+
cleanup?: () => void | Promise<void>;
|
|
21
|
+
readError?: string;
|
|
22
|
+
readonly waiters: Set<() => void>;
|
|
23
|
+
private readonly working;
|
|
24
|
+
private frozen?;
|
|
25
|
+
private state;
|
|
26
|
+
constructor(task: TaskSnapshot);
|
|
27
|
+
/** A terminal record rebuilt from persisted history: nothing is left to run or deliver. */
|
|
28
|
+
static restored(task: TaskSnapshot, readError: string | undefined): TaskRecord;
|
|
29
|
+
update(mutate: (task: TaskSnapshot) => void): void;
|
|
30
|
+
/** Readers share one frozen copy, so polling and status rendering never clone unchanged output. */
|
|
31
|
+
snapshot(): TaskSnapshot;
|
|
32
|
+
get delivery(): TaskDeliveryState;
|
|
33
|
+
/** A settled handoff the host has not yet been told about. */
|
|
34
|
+
queueDelivery(): void;
|
|
35
|
+
/** The result was answered inline, or the host acknowledged its delivery. */
|
|
36
|
+
acknowledge(): void;
|
|
37
|
+
/** Only explicit result-delivery holds and active waits delay an automatic completion. */
|
|
38
|
+
get deliverable(): boolean;
|
|
39
|
+
claim(): boolean;
|
|
40
|
+
/** Return a claimed record to pending after a failed delivery. */
|
|
41
|
+
unclaim(): boolean;
|
|
42
|
+
/** Delivered, unpinned and unwatched: bounded history that retention may evict. */
|
|
43
|
+
get inHistory(): boolean;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../../src/core/tasks/record.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAU7E;;;;GAIG;AACH,qBAAa,UAAU;IACtB,mEAAmE;IACnE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IACtC,OAAO,UAAS;IAChB,2DAA2D;IAC3D,OAAO,UAAQ;IACf,IAAI,SAAK;IACT,aAAa,SAAK;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,OAAO,YAAiB,IAAI,EAAI;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,MAAM,CAAC,CAAe;IAC9B,OAAO,CAAC,KAAK,CAA6B;gBAE9B,IAAI,EAAE,YAAY;IAK9B,2FAA2F;IAC3F,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU;IAQ9E,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,GAAG,IAAI;IAQlD,mGAAmG;IACnG,QAAQ,IAAI,YAAY;IAKxB,IAAI,QAAQ,IAAI,iBAAiB,CAEhC;IAED,8DAA8D;IAC9D,aAAa,IAAI,IAAI;IAIrB,6EAA6E;IAC7E,WAAW,IAAI,IAAI;IAInB,0FAA0F;IAC1F,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,KAAK,IAAI,OAAO;IAMhB,kEAAkE;IAClE,OAAO,IAAI,OAAO;IAMlB,mFAAmF;IACnF,IAAI,SAAS,IAAI,OAAO,CAEvB;CACD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
function freeze(value) {
|
|
2
|
+
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
3
|
+
for (const child of Object.values(value))
|
|
4
|
+
freeze(child);
|
|
5
|
+
Object.freeze(value);
|
|
6
|
+
}
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The runtime's state for one task: its working snapshot, retention counters and delivery
|
|
11
|
+
* state. The working snapshot changes only through `update()`, which also drops the frozen
|
|
12
|
+
* copy that readers share, so a mutation can never leave a stale snapshot behind.
|
|
13
|
+
*/
|
|
14
|
+
export class TaskRecord {
|
|
15
|
+
constructor(task) {
|
|
16
|
+
this.settled = false;
|
|
17
|
+
/** Whether the launch anchor is on the selected branch. */
|
|
18
|
+
this.visible = true;
|
|
19
|
+
this.pins = 0;
|
|
20
|
+
this.deliveryHolds = 0;
|
|
21
|
+
this.waiters = new Set();
|
|
22
|
+
this.state = "none";
|
|
23
|
+
this.working = task;
|
|
24
|
+
this.task = task;
|
|
25
|
+
}
|
|
26
|
+
/** A terminal record rebuilt from persisted history: nothing is left to run or deliver. */
|
|
27
|
+
static restored(task, readError) {
|
|
28
|
+
const record = new TaskRecord(task);
|
|
29
|
+
record.settled = true;
|
|
30
|
+
record.state = "delivered";
|
|
31
|
+
record.readError = readError;
|
|
32
|
+
return record;
|
|
33
|
+
}
|
|
34
|
+
update(mutate) {
|
|
35
|
+
try {
|
|
36
|
+
mutate(this.working);
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
this.frozen = undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Readers share one frozen copy, so polling and status rendering never clone unchanged output. */
|
|
43
|
+
snapshot() {
|
|
44
|
+
this.frozen ??= freeze(structuredClone(this.working));
|
|
45
|
+
return this.frozen;
|
|
46
|
+
}
|
|
47
|
+
get delivery() {
|
|
48
|
+
return this.state;
|
|
49
|
+
}
|
|
50
|
+
/** A settled handoff the host has not yet been told about. */
|
|
51
|
+
queueDelivery() {
|
|
52
|
+
this.state = "pending";
|
|
53
|
+
}
|
|
54
|
+
/** The result was answered inline, or the host acknowledged its delivery. */
|
|
55
|
+
acknowledge() {
|
|
56
|
+
this.state = "delivered";
|
|
57
|
+
}
|
|
58
|
+
/** Only explicit result-delivery holds and active waits delay an automatic completion. */
|
|
59
|
+
get deliverable() {
|
|
60
|
+
return this.visible && this.state === "pending" && this.waiters.size === 0 && this.deliveryHolds === 0;
|
|
61
|
+
}
|
|
62
|
+
claim() {
|
|
63
|
+
if (!this.deliverable)
|
|
64
|
+
return false;
|
|
65
|
+
this.state = "claimed";
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
/** Return a claimed record to pending after a failed delivery. */
|
|
69
|
+
unclaim() {
|
|
70
|
+
if (this.state !== "claimed")
|
|
71
|
+
return false;
|
|
72
|
+
this.state = "pending";
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
/** Delivered, unpinned and unwatched: bounded history that retention may evict. */
|
|
76
|
+
get inHistory() {
|
|
77
|
+
return this.settled && this.state === "delivered" && !this.pins && !this.waiters.size;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.js","sourceRoot":"","sources":["../../../src/core/tasks/record.ts"],"names":[],"mappings":"AAQA,SAAS,MAAM,CAAI,KAAQ;IAC1B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5E,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,UAAU;IAetB,YAAY,IAAkB;QAZ9B,YAAO,GAAG,KAAK,CAAC;QAChB,2DAA2D;QAC3D,YAAO,GAAG,IAAI,CAAC;QACf,SAAI,GAAG,CAAC,CAAC;QACT,kBAAa,GAAG,CAAC,CAAC;QAGT,YAAO,GAAG,IAAI,GAAG,EAAc,CAAC;QAGjC,UAAK,GAAsB,MAAM,CAAC;QAGzC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IAClB,CAAC;IAED,2FAA2F;IAC3F,MAAM,CAAC,QAAQ,CAAC,IAAkB,EAAE,SAA6B;QAChE,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,KAAK,GAAG,WAAW,CAAC;QAC3B,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC;QAC7B,OAAO,MAAM,CAAC;IACf,CAAC;IAED,MAAM,CAAC,MAAoC;QAC1C,IAAI,CAAC;YACJ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACzB,CAAC;IACF,CAAC;IAED,mGAAmG;IACnG,QAAQ;QACP,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,IAAI,QAAQ;QACX,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IAED,8DAA8D;IAC9D,aAAa;QACZ,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IACxB,CAAC;IAED,6EAA6E;IAC7E,WAAW;QACV,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC;IAC1B,CAAC;IAED,0FAA0F;IAC1F,IAAI,WAAW;QACd,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,aAAa,KAAK,CAAC,CAAC;IACxG,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,kEAAkE;IAClE,OAAO;QACN,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAC3C,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,mFAAmF;IACnF,IAAI,SAAS;QACZ,OAAO,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IACvF,CAAC;CACD","sourcesContent":["import type { TaskSnapshot } from \"./types.ts\";\n\n/**\n * none: running, or answered inline by its tool call; pending: a settled handoff\n * awaiting automatic delivery; claimed: handed to the host; delivered: acknowledged.\n */\nexport type TaskDeliveryState = \"none\" | \"pending\" | \"claimed\" | \"delivered\";\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\n/**\n * The runtime's state for one task: its working snapshot, retention counters and delivery\n * state. The working snapshot changes only through `update()`, which also drops the frozen\n * 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\tsettled = false;\n\t/** Whether the launch anchor is on the selected branch. */\n\tvisible = true;\n\tpins = 0;\n\tdeliveryHolds = 0;\n\tcleanup?: () => void | Promise<void>;\n\treadError?: string;\n\treadonly waiters = new Set<() => void>();\n\tprivate readonly working: TaskSnapshot;\n\tprivate frozen?: TaskSnapshot;\n\tprivate state: TaskDeliveryState = \"none\";\n\n\tconstructor(task: TaskSnapshot) {\n\t\tthis.working = task;\n\t\tthis.task = task;\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.settled = true;\n\t\trecord.state = \"delivered\";\n\t\trecord.readError = readError;\n\t\treturn record;\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\tget delivery(): TaskDeliveryState {\n\t\treturn this.state;\n\t}\n\n\t/** A settled handoff the host has not yet been told about. */\n\tqueueDelivery(): void {\n\t\tthis.state = \"pending\";\n\t}\n\n\t/** The result was answered inline, or the host acknowledged its delivery. */\n\tacknowledge(): void {\n\t\tthis.state = \"delivered\";\n\t}\n\n\t/** Only explicit result-delivery holds and active waits delay an automatic completion. */\n\tget deliverable(): boolean {\n\t\treturn this.visible && this.state === \"pending\" && this.waiters.size === 0 && this.deliveryHolds === 0;\n\t}\n\n\tclaim(): boolean {\n\t\tif (!this.deliverable) return false;\n\t\tthis.state = \"claimed\";\n\t\treturn true;\n\t}\n\n\t/** Return a claimed record to pending after a failed delivery. */\n\tunclaim(): boolean {\n\t\tif (this.state !== \"claimed\") return false;\n\t\tthis.state = \"pending\";\n\t\treturn true;\n\t}\n\n\t/** Delivered, unpinned and unwatched: bounded history that retention may evict. */\n\tget inHistory(): boolean {\n\t\treturn this.settled && this.state === \"delivered\" && !this.pins && !this.waiters.size;\n\t}\n}\n"]}
|