@astralyn/pi 1.4.4 → 1.4.6
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 +34 -0
- package/README.md +1 -0
- package/dist/bundle/chunks/chunk-5M3YJ54Z.js +82 -0
- package/dist/bundle/chunks/chunk-6QGV3IWD.js +6 -0
- package/dist/bundle/chunks/chunk-ALHAFUHP.js +7 -0
- package/dist/bundle/chunks/chunk-AXFWZIHH.js +4 -0
- package/dist/bundle/chunks/chunk-EYKC6ESU.js +2 -0
- package/dist/bundle/chunks/chunk-KDO6L76C.js +230 -0
- package/dist/bundle/chunks/chunk-RBTJBQWX.js +1500 -0
- package/dist/bundle/chunks/chunk-RLNMABLM.js +9 -0
- package/dist/bundle/chunks/cli-FH77R7JR.js +51 -0
- package/dist/bundle/chunks/execute-5ZQUS52M.js +505 -0
- package/dist/bundle/chunks/runtime-R5CMHJ5P.js +2 -0
- package/dist/bundle/chunks/virtual-modules-KCQU7LOC.js +2 -0
- 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.map +1 -1
- package/dist/core/agent-session.js +2 -0
- 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/extensions/runner.d.ts +2 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +18 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +6 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/isolated-session.d.ts +23 -0
- package/dist/core/isolated-session.d.ts.map +1 -0
- package/dist/core/isolated-session.js +55 -0
- package/dist/core/isolated-session.js.map +1 -0
- package/dist/core/model-config.d.ts +1 -3
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +1 -3
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/settings-manager.d.ts +4 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +38 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-schema.d.ts +1 -0
- package/dist/core/settings-schema.d.ts.map +1 -1
- package/dist/core/settings-schema.js +3 -0
- package/dist/core/settings-schema.js.map +1 -1
- package/dist/core/tasks/codec.d.ts +12 -0
- package/dist/core/tasks/codec.d.ts.map +1 -0
- package/dist/core/tasks/codec.js +139 -0
- package/dist/core/tasks/codec.js.map +1 -0
- package/dist/core/tasks/execution.d.ts +64 -0
- package/dist/core/tasks/execution.d.ts.map +1 -0
- package/dist/core/tasks/execution.js +272 -0
- package/dist/core/tasks/execution.js.map +1 -0
- package/dist/core/tasks/output.d.ts +12 -5
- package/dist/core/tasks/output.d.ts.map +1 -1
- package/dist/core/tasks/output.js +38 -37
- package/dist/core/tasks/output.js.map +1 -1
- package/dist/core/tasks/presentation.d.ts +14 -5
- package/dist/core/tasks/presentation.d.ts.map +1 -1
- package/dist/core/tasks/presentation.js +56 -185
- package/dist/core/tasks/presentation.js.map +1 -1
- package/dist/core/tasks/runtime.d.ts +9 -9
- package/dist/core/tasks/runtime.d.ts.map +1 -1
- package/dist/core/tasks/runtime.js +63 -252
- package/dist/core/tasks/runtime.js.map +1 -1
- package/dist/core/tasks/scheduler.d.ts +16 -0
- package/dist/core/tasks/scheduler.d.ts.map +1 -0
- package/dist/core/tasks/scheduler.js +42 -0
- package/dist/core/tasks/scheduler.js.map +1 -0
- package/dist/core/tasks/session.d.ts +1 -0
- package/dist/core/tasks/session.d.ts.map +1 -1
- package/dist/core/tasks/session.js +15 -27
- package/dist/core/tasks/session.js.map +1 -1
- package/dist/core/tasks/store.js +4 -4
- package/dist/core/tasks/store.js.map +1 -1
- package/dist/core/tasks/types.d.ts +63 -49
- package/dist/core/tasks/types.d.ts.map +1 -1
- package/dist/core/tasks/types.js +3 -9
- package/dist/core/tasks/types.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +6 -4
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +34 -14
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/shell-execution.js +4 -4
- 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 +23 -30
- package/dist/core/tools/shell-tool.js.map +1 -1
- package/dist/core/usage-totals.d.ts +1 -3
- package/dist/core/usage-totals.d.ts.map +1 -1
- package/dist/core/usage-totals.js +17 -8
- package/dist/core/usage-totals.js.map +1 -1
- package/dist/extensions/agent/activity.d.ts +13 -0
- package/dist/extensions/agent/activity.d.ts.map +1 -0
- package/dist/extensions/agent/activity.js +75 -0
- package/dist/extensions/agent/activity.js.map +1 -0
- package/dist/extensions/agent/index.d.ts +4 -0
- package/dist/extensions/agent/index.d.ts.map +1 -0
- package/dist/extensions/agent/index.js +11 -0
- package/dist/extensions/agent/index.js.map +1 -0
- package/dist/extensions/agent/progress.d.ts +31 -0
- package/dist/extensions/agent/progress.d.ts.map +1 -0
- package/dist/extensions/agent/progress.js +145 -0
- package/dist/extensions/agent/progress.js.map +1 -0
- package/dist/extensions/agent/render.d.ts +6 -0
- package/dist/extensions/agent/render.d.ts.map +1 -0
- package/dist/extensions/agent/render.js +120 -0
- package/dist/extensions/agent/render.js.map +1 -0
- package/dist/extensions/agent/report.d.ts +9 -0
- package/dist/extensions/agent/report.d.ts.map +1 -0
- package/dist/extensions/agent/report.js +40 -0
- package/dist/extensions/agent/report.js.map +1 -0
- package/dist/extensions/agent/settings-panel.d.ts +43 -0
- package/dist/extensions/agent/settings-panel.d.ts.map +1 -0
- package/dist/extensions/agent/settings-panel.js +125 -0
- package/dist/extensions/agent/settings-panel.js.map +1 -0
- package/dist/extensions/agent/settings.d.ts +15 -0
- package/dist/extensions/agent/settings.d.ts.map +1 -0
- package/dist/extensions/agent/settings.js +201 -0
- package/dist/extensions/agent/settings.js.map +1 -0
- package/dist/extensions/agent/tool.d.ts +13 -0
- package/dist/extensions/agent/tool.d.ts.map +1 -0
- package/dist/extensions/agent/tool.js +84 -0
- package/dist/extensions/agent/tool.js.map +1 -0
- package/dist/extensions/agent/types.d.ts +43 -0
- package/dist/extensions/agent/types.d.ts.map +1 -0
- package/dist/extensions/agent/types.js +6 -0
- package/dist/extensions/agent/types.js.map +1 -0
- package/dist/extensions/agent/worker.d.ts +16 -0
- package/dist/extensions/agent/worker.d.ts.map +1 -0
- package/dist/extensions/agent/worker.js +68 -0
- package/dist/extensions/agent/worker.js.map +1 -0
- package/dist/extensions/codemode/execute.js +1 -1
- package/dist/extensions/codemode/execute.js.map +1 -1
- package/dist/extensions/codemode/execute.lazy.d.ts +2 -2
- package/dist/extensions/codemode/execute.lazy.d.ts.map +1 -1
- package/dist/extensions/codemode/execute.lazy.js +2 -2
- package/dist/extensions/codemode/execute.lazy.js.map +1 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +2 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/mcp/cli.lazy.d.ts +2 -2
- package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -1
- package/dist/extensions/mcp/cli.lazy.js +2 -2
- package/dist/extensions/mcp/cli.lazy.js.map +1 -1
- package/dist/extensions/mcp/index.d.ts.map +1 -1
- package/dist/extensions/mcp/index.js +2 -2
- package/dist/extensions/mcp/index.js.map +1 -1
- package/dist/extensions/mcp/runtime.lazy.d.ts +2 -2
- package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -1
- package/dist/extensions/mcp/runtime.lazy.js +2 -2
- package/dist/extensions/mcp/runtime.lazy.js.map +1 -1
- package/dist/extensions/provider/compat-fields.js +1 -1
- package/dist/extensions/provider/compat-fields.js.map +1 -1
- package/dist/extensions/tasks/tool/actions.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/actions.js +1 -9
- package/dist/extensions/tasks/tool/actions.js.map +1 -1
- package/dist/extensions/tasks/tool/schema.js +1 -1
- package/dist/extensions/tasks/tool/schema.js.map +1 -1
- package/dist/extensions/tasks/tool/types.d.ts +2 -8
- package/dist/extensions/tasks/tool/types.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/types.js +0 -2
- package/dist/extensions/tasks/tool/types.js.map +1 -1
- package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/completion-render.js +27 -26
- package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
- package/dist/extensions/tasks/ui/inspector.d.ts +5 -3
- package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/inspector.js +18 -6
- package/dist/extensions/tasks/ui/inspector.js.map +1 -1
- package/dist/extensions/tasks/ui/layout.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/layout.js +111 -75
- 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 +43 -28
- package/dist/extensions/tasks/ui/list.js.map +1 -1
- package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/manager.js +8 -2
- package/dist/extensions/tasks/ui/manager.js.map +1 -1
- package/dist/extensions/tasks/ui/model.d.ts +4 -0
- package/dist/extensions/tasks/ui/model.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/model.js +12 -1
- package/dist/extensions/tasks/ui/model.js.map +1 -1
- package/dist/extensions/tasks/ui/render.js +3 -4
- package/dist/extensions/tasks/ui/render.js.map +1 -1
- package/dist/extensions/tasks/ui/task-view.d.ts +0 -5
- package/dist/extensions/tasks/ui/task-view.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/task-view.js +0 -7
- package/dist/extensions/tasks/ui/task-view.js.map +1 -1
- package/dist/extensions/tasks/ui/tree.js +1 -1
- package/dist/extensions/tasks/ui/tree.js.map +1 -1
- package/dist/extensions/tasks/ui/views.d.ts +10 -6
- package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/views.js +64 -28
- package/dist/extensions/tasks/ui/views.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
- package/dist/modes/interactive/components/keybinding-hints.js +2 -1
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +7 -4
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +10 -3
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/docs/bundled/README.md +1 -0
- package/docs/bundled/extensions/agent.md +68 -0
- package/docs/bundled/extensions/statusline.md +1 -1
- package/docs/bundled/tasks.md +15 -14
- package/docs/docs.json +4 -0
- package/docs/extensions.md +33 -6
- package/docs/sdk.md +2 -2
- package/docs/session-format.md +27 -23
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/schemas/settings.schema.json +12 -0
- package/dist/bundle/chunks/chunk-SBVVM3NV.js +0 -2361
- package/dist/bundle/chunks/chunk-VGSZTBVJ.js +0 -2
- package/dist/bundle/chunks/virtual-modules-ETYFHSUG.js +0 -2
- package/dist/core/tasks/history.d.ts +0 -4
- package/dist/core/tasks/history.d.ts.map +0 -1
- package/dist/core/tasks/history.js +0 -121
- package/dist/core/tasks/history.js.map +0 -1
- package/dist/extensions/codemode/search.d.ts +0 -33
- package/dist/extensions/codemode/search.d.ts.map +0 -1
- package/dist/extensions/codemode/search.js +0 -117
- package/dist/extensions/codemode/search.js.map +0 -1
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { boundFacts, boundTaskText, boundText, resultText, TASK_ERROR_BYTES, TASK_PATH_BYTES } from "./output.js";
|
|
2
|
+
import { changed, snapshotOf } from "./store.js";
|
|
3
|
+
export function errorText(error) {
|
|
4
|
+
try {
|
|
5
|
+
return boundText(error instanceof Error ? error.message : String(error), TASK_ERROR_BYTES);
|
|
6
|
+
}
|
|
7
|
+
catch {
|
|
8
|
+
return "Task execution failed (unprintable error)";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function prependText(text, result) {
|
|
12
|
+
return {
|
|
13
|
+
text: boundText(result?.text ? `${text}\n${result.text}` : text),
|
|
14
|
+
truncated: result?.truncated ?? false,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Terminal rows replace launch rows with the same label and append new ones. */
|
|
18
|
+
function mergeFacts(base = [], terminal) {
|
|
19
|
+
const labels = new Set(terminal.map(([label]) => label));
|
|
20
|
+
return boundFacts([...base.filter(([label]) => !labels.has(label)), ...terminal]);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* One live task: its caller, controller, parent link and executor callbacks.
|
|
24
|
+
*
|
|
25
|
+
* A caller may be handed off to the background whenever no executor preflight is in
|
|
26
|
+
* progress: before `run` starts (queued) or after the executor calls `accept()`.
|
|
27
|
+
*/
|
|
28
|
+
export class Execution {
|
|
29
|
+
constructor(host, record, execution) {
|
|
30
|
+
this.controller = new AbortController();
|
|
31
|
+
this.modeListeners = new Set();
|
|
32
|
+
this.releaseParentSignal = () => { };
|
|
33
|
+
this.started = false;
|
|
34
|
+
this.accepted = false;
|
|
35
|
+
this.handedOff = false;
|
|
36
|
+
this.host = host;
|
|
37
|
+
this.record = record;
|
|
38
|
+
this.run = execution.run;
|
|
39
|
+
this.concurrency = execution.concurrency;
|
|
40
|
+
this.detachRequested = execution.background ?? false;
|
|
41
|
+
this.onUpdate = execution.background ? undefined : execution.onUpdate;
|
|
42
|
+
this.caller = new Promise((resolve, reject) => {
|
|
43
|
+
this.resolveCaller = resolve;
|
|
44
|
+
this.rejectCaller = reject;
|
|
45
|
+
});
|
|
46
|
+
this.done = new Promise((resolve) => {
|
|
47
|
+
this.resolveDone = resolve;
|
|
48
|
+
});
|
|
49
|
+
const parent = execution.signal;
|
|
50
|
+
if (parent) {
|
|
51
|
+
const abort = () => {
|
|
52
|
+
if (!this.detachRequested || !this.handoffAllowed)
|
|
53
|
+
this.cancel();
|
|
54
|
+
};
|
|
55
|
+
parent.addEventListener("abort", abort, { once: true });
|
|
56
|
+
this.releaseParentSignal = () => parent.removeEventListener("abort", abort);
|
|
57
|
+
}
|
|
58
|
+
const task = record.task;
|
|
59
|
+
this.control = {
|
|
60
|
+
id: task.id,
|
|
61
|
+
signal: this.controller.signal,
|
|
62
|
+
get mode() {
|
|
63
|
+
return task.mode;
|
|
64
|
+
},
|
|
65
|
+
onModeChange: (listener) => this.onModeChange(listener),
|
|
66
|
+
accept: () => this.accept(),
|
|
67
|
+
publish: (update) => this.publish(update),
|
|
68
|
+
attachOutput: (path, cleanup) => this.attachOutput(path, cleanup),
|
|
69
|
+
cancel: () => {
|
|
70
|
+
this.cancel();
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
get task() {
|
|
75
|
+
return this.record.task;
|
|
76
|
+
}
|
|
77
|
+
get aborted() {
|
|
78
|
+
return this.controller.signal.aborted;
|
|
79
|
+
}
|
|
80
|
+
/** Executor preflight never races a handoff; queued work has not begun any. */
|
|
81
|
+
get handoffAllowed() {
|
|
82
|
+
return !this.started || this.accepted;
|
|
83
|
+
}
|
|
84
|
+
/** Waiting for a concurrency slot: registered, but `run` has not started. */
|
|
85
|
+
get queued() {
|
|
86
|
+
return !this.started && !this.record.settled;
|
|
87
|
+
}
|
|
88
|
+
get detachable() {
|
|
89
|
+
return !this.record.settled && !this.detachRequested && !this.aborted;
|
|
90
|
+
}
|
|
91
|
+
/** Stop forwarding to the launching tool call: parent cancellation and progress no longer reach it. */
|
|
92
|
+
releaseParent() {
|
|
93
|
+
this.releaseParentSignal();
|
|
94
|
+
this.releaseParentSignal = () => { };
|
|
95
|
+
this.onUpdate = undefined;
|
|
96
|
+
}
|
|
97
|
+
start() {
|
|
98
|
+
if (this.started || this.record.settled)
|
|
99
|
+
return;
|
|
100
|
+
if (this.host.closed) {
|
|
101
|
+
this.cancel();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.started = true;
|
|
105
|
+
this.task.status = "running";
|
|
106
|
+
changed(this.record);
|
|
107
|
+
// The rejection handler is installed immediately, including for synchronous preflight throws.
|
|
108
|
+
try {
|
|
109
|
+
void Promise.resolve(this.run(this.control)).then((completion) => this.finish(completion), (error) => this.finish(undefined, error));
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
this.finish(undefined, error);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
handoff() {
|
|
116
|
+
if (!this.handoffAllowed ||
|
|
117
|
+
!this.detachRequested ||
|
|
118
|
+
this.record.settled ||
|
|
119
|
+
this.handedOff ||
|
|
120
|
+
this.host.closed ||
|
|
121
|
+
!this.record.visible ||
|
|
122
|
+
this.aborted)
|
|
123
|
+
return;
|
|
124
|
+
this.handedOff = true;
|
|
125
|
+
this.task.mode = "background";
|
|
126
|
+
changed(this.record);
|
|
127
|
+
this.releaseParent();
|
|
128
|
+
this.resolveCaller({ kind: "background", task: snapshotOf(this.record) });
|
|
129
|
+
this.host.emit();
|
|
130
|
+
}
|
|
131
|
+
requestDetach() {
|
|
132
|
+
this.detachRequested = true;
|
|
133
|
+
this.task.mode = "background";
|
|
134
|
+
changed(this.record);
|
|
135
|
+
if (this.accepted)
|
|
136
|
+
this.releaseParent();
|
|
137
|
+
}
|
|
138
|
+
completeDetach() {
|
|
139
|
+
this.handoff();
|
|
140
|
+
for (const listener of this.modeListeners) {
|
|
141
|
+
try {
|
|
142
|
+
listener(this.task.mode);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
/* Executors own their diagnostics. */
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
cancel() {
|
|
150
|
+
if (this.record.settled || this.aborted)
|
|
151
|
+
return false;
|
|
152
|
+
this.task.status = "stopping";
|
|
153
|
+
changed(this.record);
|
|
154
|
+
this.controller.abort();
|
|
155
|
+
if (!this.started)
|
|
156
|
+
this.finish(undefined, new Error("Task cancelled before it started."));
|
|
157
|
+
this.host.emit();
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
onModeChange(listener) {
|
|
161
|
+
if (this.record.settled || this.host.closed)
|
|
162
|
+
return () => { };
|
|
163
|
+
this.modeListeners.add(listener);
|
|
164
|
+
return () => {
|
|
165
|
+
this.modeListeners.delete(listener);
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
accept() {
|
|
169
|
+
if (this.record.settled || this.accepted || this.host.closed || this.aborted)
|
|
170
|
+
return;
|
|
171
|
+
this.accepted = true;
|
|
172
|
+
if (this.detachRequested)
|
|
173
|
+
this.releaseParent();
|
|
174
|
+
// Let an already available final result win over a handoff.
|
|
175
|
+
queueMicrotask(() => queueMicrotask(() => this.handoff()));
|
|
176
|
+
this.host.emit();
|
|
177
|
+
}
|
|
178
|
+
publish(update) {
|
|
179
|
+
if (this.record.settled || this.host.closed)
|
|
180
|
+
return;
|
|
181
|
+
this.task.result = resultText(update.result);
|
|
182
|
+
if (update.display !== undefined)
|
|
183
|
+
this.task.display = boundTaskText(update.display);
|
|
184
|
+
changed(this.record);
|
|
185
|
+
if (update.usage !== undefined)
|
|
186
|
+
this.usage = structuredClone(update.usage);
|
|
187
|
+
if (!this.detachRequested && !this.handedOff) {
|
|
188
|
+
try {
|
|
189
|
+
this.onUpdate?.(update.result);
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
/* UI observers cannot stop execution. */
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
this.host.emit();
|
|
196
|
+
}
|
|
197
|
+
attachOutput(path, cleanup) {
|
|
198
|
+
if (this.record.settled) {
|
|
199
|
+
if (cleanup)
|
|
200
|
+
throw new Error("Task execution has settled");
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (this.record.cleanup)
|
|
204
|
+
throw new Error("Managed output is already registered");
|
|
205
|
+
// Never truncate a real filesystem path into a different path.
|
|
206
|
+
if (Buffer.byteLength(path) > TASK_PATH_BYTES)
|
|
207
|
+
throw new Error("Task output path is too large");
|
|
208
|
+
this.record.cleanup = cleanup;
|
|
209
|
+
this.task.outputPath = path;
|
|
210
|
+
changed(this.record);
|
|
211
|
+
this.host.emit();
|
|
212
|
+
}
|
|
213
|
+
finish(completion, error) {
|
|
214
|
+
const record = this.record;
|
|
215
|
+
const task = this.task;
|
|
216
|
+
if (record.settled)
|
|
217
|
+
return;
|
|
218
|
+
record.settled = true;
|
|
219
|
+
this.modeListeners.clear();
|
|
220
|
+
this.releaseParent();
|
|
221
|
+
task.endedAt = Date.now();
|
|
222
|
+
const status = completion
|
|
223
|
+
? (completion.status ?? (this.aborted ? "cancelled" : "completed"))
|
|
224
|
+
: this.aborted
|
|
225
|
+
? "cancelled"
|
|
226
|
+
: "failed";
|
|
227
|
+
task.status = status;
|
|
228
|
+
if (completion) {
|
|
229
|
+
task.result = resultText(completion.result);
|
|
230
|
+
if (completion.display !== undefined)
|
|
231
|
+
task.display = boundTaskText(completion.display);
|
|
232
|
+
if (completion.error !== undefined)
|
|
233
|
+
task.error = boundText(completion.error, TASK_ERROR_BYTES);
|
|
234
|
+
if (completion.facts)
|
|
235
|
+
task.facts = mergeFacts(task.facts, completion.facts);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
task.error = errorText(error);
|
|
239
|
+
task.result = prependText(task.error, task.result);
|
|
240
|
+
}
|
|
241
|
+
changed(record);
|
|
242
|
+
let warning;
|
|
243
|
+
try {
|
|
244
|
+
this.host.settle(snapshotOf(record), completion?.usage ?? completion?.result.usage ?? this.usage);
|
|
245
|
+
}
|
|
246
|
+
catch (accountingError) {
|
|
247
|
+
warning = `Usage settlement failed: ${errorText(accountingError)}`;
|
|
248
|
+
task.error = boundText([task.error, warning].filter(Boolean).join("\n"), 2 * TASK_ERROR_BYTES);
|
|
249
|
+
task.result = prependText(warning, task.result);
|
|
250
|
+
changed(record);
|
|
251
|
+
}
|
|
252
|
+
this.usage = undefined;
|
|
253
|
+
// Delivery becomes eligible only after settlement is persisted.
|
|
254
|
+
record.delivery = this.handedOff ? "pending" : "delivered";
|
|
255
|
+
if (!this.handedOff) {
|
|
256
|
+
if (!completion)
|
|
257
|
+
this.rejectCaller(error);
|
|
258
|
+
else {
|
|
259
|
+
// The task ledger owns usage; a tool result never carries it a second time.
|
|
260
|
+
const { usage: _usage, ...result } = completion.result;
|
|
261
|
+
if (warning)
|
|
262
|
+
result.content = [{ type: "text", text: warning }, ...result.content];
|
|
263
|
+
this.resolveCaller({ kind: "result", result, status, error: task.error });
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
for (const waiter of [...record.waiters])
|
|
267
|
+
waiter();
|
|
268
|
+
this.resolveDone();
|
|
269
|
+
this.host.released(this);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
//# sourceMappingURL=execution.js.map
|
|
@@ -0,0 +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,21 +1,28 @@
|
|
|
1
1
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
2
|
-
import type {
|
|
2
|
+
import type { TaskFact, TaskInput, 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_INPUT_BYTES: number;
|
|
6
7
|
/** Task title budget, independent of notification wording and rendering. */
|
|
7
8
|
export declare const TASK_TITLE_BYTES = 1024;
|
|
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;
|
|
8
14
|
export declare function finiteLimit(value: number | undefined, fallback: number, ceiling: number): number;
|
|
9
15
|
export declare function boundText(text: string, bytes?: number): string;
|
|
16
|
+
export declare function boundTaskText(text: string, bytes?: number): TaskText;
|
|
17
|
+
export declare function boundInput(input: TaskInput): TaskInput;
|
|
18
|
+
export declare function boundFacts(facts: readonly TaskFact[]): TaskFact[];
|
|
10
19
|
/** The end of a bounded text, codepoint aligned: a command's outcome is at its end. */
|
|
11
20
|
export declare function boundTail(text: string, bytes: number): {
|
|
12
21
|
text: string;
|
|
13
22
|
truncated: boolean;
|
|
14
23
|
};
|
|
15
|
-
/**
|
|
16
|
-
export declare function
|
|
17
|
-
/** Store the bounded public part of a result; private details never enter task history. */
|
|
18
|
-
export declare function retainResult(task: TaskSnapshot, result: AgentToolResult<unknown>, truncated?: boolean): void;
|
|
24
|
+
/** The bounded model-readable text of a result; images and private details never enter task state. */
|
|
25
|
+
export declare function resultText(result: AgentToolResult<unknown>): TaskText;
|
|
19
26
|
export interface OutputSlice {
|
|
20
27
|
text: string;
|
|
21
28
|
totalBytes: number;
|
|
@@ -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,
|
|
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,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhE,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,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,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;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"}
|
|
@@ -2,8 +2,14 @@ import { open } from "node:fs/promises";
|
|
|
2
2
|
export const TASK_RESULT_BYTES = 48 * 1024;
|
|
3
3
|
export const TASK_DETAILS_BYTES = 120 * 1024;
|
|
4
4
|
export const TASK_READ_BYTES = 8 * 1024;
|
|
5
|
+
export const TASK_INPUT_BYTES = 24 * 1024;
|
|
5
6
|
/** Task title budget, independent of notification wording and rendering. */
|
|
6
7
|
export const TASK_TITLE_BYTES = 1024;
|
|
8
|
+
export const TASK_LABEL_BYTES = 256;
|
|
9
|
+
export const TASK_FACTS = 16;
|
|
10
|
+
export const TASK_FACT_BYTES = 1024;
|
|
11
|
+
export const TASK_ERROR_BYTES = 4096;
|
|
12
|
+
export const TASK_PATH_BYTES = 8192;
|
|
7
13
|
export function finiteLimit(value, fallback, ceiling) {
|
|
8
14
|
return value === undefined || !Number.isFinite(value) ? fallback : Math.max(0, Math.min(ceiling, Math.floor(value)));
|
|
9
15
|
}
|
|
@@ -34,6 +40,24 @@ export function boundText(text, bytes = TASK_RESULT_BYTES) {
|
|
|
34
40
|
const buffer = Buffer.from(prefix);
|
|
35
41
|
return alignedSlice(buffer, 0, Math.min(limit, buffer.length)).toString("utf8");
|
|
36
42
|
}
|
|
43
|
+
export function boundTaskText(text, bytes = TASK_RESULT_BYTES) {
|
|
44
|
+
const bounded = boundText(text, bytes);
|
|
45
|
+
return { text: bounded, truncated: bounded !== text };
|
|
46
|
+
}
|
|
47
|
+
export function boundInput(input) {
|
|
48
|
+
const text = boundTaskText(input.text, TASK_INPUT_BYTES);
|
|
49
|
+
return {
|
|
50
|
+
label: boundText(input.label, TASK_LABEL_BYTES),
|
|
51
|
+
text: text.text,
|
|
52
|
+
truncated: input.truncated || text.truncated,
|
|
53
|
+
...(input.language ? { language: boundText(input.language, 64) } : {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export function boundFacts(facts) {
|
|
57
|
+
return facts
|
|
58
|
+
.slice(0, TASK_FACTS)
|
|
59
|
+
.map(([label, value]) => [boundText(label, TASK_LABEL_BYTES), boundText(value, TASK_FACT_BYTES)]);
|
|
60
|
+
}
|
|
37
61
|
/** The end of a bounded text, codepoint aligned: a command's outcome is at its end. */
|
|
38
62
|
export function boundTail(text, bytes) {
|
|
39
63
|
const buffer = Buffer.from(text);
|
|
@@ -41,47 +65,24 @@ export function boundTail(text, bytes) {
|
|
|
41
65
|
return { text, truncated: false };
|
|
42
66
|
return { text: alignedSlice(buffer, buffer.length - bytes, buffer.length).toString("utf8"), truncated: true };
|
|
43
67
|
}
|
|
44
|
-
/**
|
|
45
|
-
export function
|
|
68
|
+
/** The bounded model-readable text of a result; images and private details never enter task state. */
|
|
69
|
+
export function resultText(result) {
|
|
46
70
|
let remaining = TASK_RESULT_BYTES;
|
|
47
|
-
const
|
|
71
|
+
const parts = [];
|
|
72
|
+
let truncated = false;
|
|
48
73
|
for (const block of result.content) {
|
|
49
|
-
if (remaining <= 0)
|
|
74
|
+
if (remaining <= 0) {
|
|
75
|
+
truncated = true;
|
|
50
76
|
break;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
77
|
+
}
|
|
78
|
+
const source = block.type === "text" ? block.text : "[Image omitted from task output]";
|
|
79
|
+
const text = boundText(source, remaining);
|
|
80
|
+
if (block.type !== "text" || text !== source)
|
|
81
|
+
truncated = true;
|
|
82
|
+
parts.push(text);
|
|
83
|
+
remaining -= Math.max(1, Buffer.byteLength(text) + 1);
|
|
54
84
|
}
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
let budget = TASK_DETAILS_BYTES;
|
|
58
|
-
const json = JSON.stringify(result.details, (key, value) => {
|
|
59
|
-
// Stop visiting an oversized structure before constructing an unbounded JSON string.
|
|
60
|
-
budget -= Buffer.byteLength(key) + 3;
|
|
61
|
-
budget -= typeof value === "string" ? Buffer.byteLength(value) + 2 : 8;
|
|
62
|
-
if (budget < 0)
|
|
63
|
-
throw new Error("Background details exceed the storage budget");
|
|
64
|
-
return value;
|
|
65
|
-
});
|
|
66
|
-
if (json !== undefined && Buffer.byteLength(json) <= TASK_DETAILS_BYTES)
|
|
67
|
-
details = JSON.parse(json);
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
// Runtime handles and cyclic details cannot enter a serializable snapshot.
|
|
71
|
-
}
|
|
72
|
-
return { content, details };
|
|
73
|
-
}
|
|
74
|
-
/** Store the bounded public part of a result; private details never enter task history. */
|
|
75
|
-
export function retainResult(task, result, truncated = false) {
|
|
76
|
-
const bounded = boundedResult({ content: result.content, details: undefined });
|
|
77
|
-
task.result = bounded;
|
|
78
|
-
task.resultTruncated =
|
|
79
|
-
truncated ||
|
|
80
|
-
bounded.content.length !== result.content.length ||
|
|
81
|
-
bounded.content.some((block, index) => {
|
|
82
|
-
const original = result.content[index];
|
|
83
|
-
return original?.type !== "text" || block.type !== "text" || block.text !== original.text;
|
|
84
|
-
});
|
|
85
|
+
return { text: boundText(parts.join("\n")), truncated };
|
|
85
86
|
}
|
|
86
87
|
/** Positioned, bounded reads only. The executor owns the path and its cleanup. */
|
|
87
88
|
export async function readOutputSlice(path, options = {}) {
|
|
@@ -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 { 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;\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 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,7 +1,16 @@
|
|
|
1
1
|
import type { CustomMessage } from "../messages.ts";
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
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;
|
|
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"}
|