@astralyn/pi 1.4.9 → 1.4.11
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 +69 -0
- package/dist/bundle/chunks/{chunk-BAGHIP5J.js → chunk-NUQMVNKQ.js} +3 -3
- package/dist/bundle/chunks/{chunk-3PKXUKTB.js → chunk-PUU43PDV.js} +121 -136
- package/dist/bundle/chunks/{chunk-F66AY3WR.js → chunk-TH3QDDPD.js} +1 -1
- package/dist/bundle/chunks/{execute-P22VMM2H.js → execute-VLAIP26K.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-VKMBQTR2.js → virtual-modules-63XNTSVN.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 +34 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +99 -5
- 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/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +14 -7
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/isolated-session.d.ts +7 -2
- package/dist/core/isolated-session.d.ts.map +1 -1
- package/dist/core/isolated-session.js +7 -3
- package/dist/core/isolated-session.js.map +1 -1
- package/dist/core/session-manager.d.ts +17 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +29 -0
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/tasks/delivery.d.ts +31 -12
- package/dist/core/tasks/delivery.d.ts.map +1 -1
- package/dist/core/tasks/delivery.js +97 -36
- package/dist/core/tasks/delivery.js.map +1 -1
- package/dist/core/tasks/execution.d.ts +27 -14
- package/dist/core/tasks/execution.d.ts.map +1 -1
- package/dist/core/tasks/execution.js +90 -86
- package/dist/core/tasks/execution.js.map +1 -1
- package/dist/core/tasks/limits.d.ts +7 -11
- package/dist/core/tasks/limits.d.ts.map +1 -1
- package/dist/core/tasks/limits.js +8 -16
- package/dist/core/tasks/limits.js.map +1 -1
- package/dist/core/tasks/output.d.ts +9 -1
- package/dist/core/tasks/output.d.ts.map +1 -1
- package/dist/core/tasks/output.js +23 -10
- package/dist/core/tasks/output.js.map +1 -1
- package/dist/core/tasks/presentation.d.ts +1 -1
- package/dist/core/tasks/presentation.d.ts.map +1 -1
- package/dist/core/tasks/presentation.js +6 -4
- package/dist/core/tasks/presentation.js.map +1 -1
- package/dist/core/tasks/record.d.ts +41 -29
- package/dist/core/tasks/record.d.ts.map +1 -1
- package/dist/core/tasks/record.js +82 -37
- package/dist/core/tasks/record.js.map +1 -1
- package/dist/core/tasks/reminder.js +2 -2
- package/dist/core/tasks/reminder.js.map +1 -1
- package/dist/core/tasks/runtime.d.ts +15 -23
- package/dist/core/tasks/runtime.d.ts.map +1 -1
- package/dist/core/tasks/runtime.js +50 -178
- package/dist/core/tasks/runtime.js.map +1 -1
- package/dist/core/tasks/scheduler.d.ts +3 -1
- package/dist/core/tasks/scheduler.d.ts.map +1 -1
- package/dist/core/tasks/scheduler.js +16 -12
- package/dist/core/tasks/scheduler.js.map +1 -1
- package/dist/core/tasks/session.d.ts +24 -6
- package/dist/core/tasks/session.d.ts.map +1 -1
- package/dist/core/tasks/session.js +70 -22
- package/dist/core/tasks/session.js.map +1 -1
- package/dist/core/tasks/store.d.ts +17 -4
- package/dist/core/tasks/store.d.ts.map +1 -1
- package/dist/core/tasks/store.js +45 -48
- package/dist/core/tasks/store.js.map +1 -1
- package/dist/core/tasks/types.d.ts +64 -93
- package/dist/core/tasks/types.d.ts.map +1 -1
- package/dist/core/tasks/types.js +7 -0
- package/dist/core/tasks/types.js.map +1 -1
- package/dist/core/tools/shell-execution.d.ts.map +1 -1
- package/dist/core/tools/shell-execution.js +2 -1
- 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 +20 -13
- package/dist/core/tools/shell-tool.js.map +1 -1
- package/dist/extensions/agent/activity-lines.d.ts +10 -0
- package/dist/extensions/agent/activity-lines.d.ts.map +1 -0
- package/dist/extensions/agent/activity-lines.js +76 -0
- package/dist/extensions/agent/activity-lines.js.map +1 -0
- package/dist/extensions/agent/activity.d.ts +25 -4
- package/dist/extensions/agent/activity.d.ts.map +1 -1
- package/dist/extensions/agent/activity.js +76 -21
- package/dist/extensions/agent/activity.js.map +1 -1
- package/dist/extensions/agent/artifacts.d.ts +15 -0
- package/dist/extensions/agent/artifacts.d.ts.map +1 -0
- package/dist/extensions/agent/artifacts.js +44 -0
- package/dist/extensions/agent/artifacts.js.map +1 -0
- package/dist/extensions/agent/progress.d.ts +30 -4
- package/dist/extensions/agent/progress.d.ts.map +1 -1
- package/dist/extensions/agent/progress.js +84 -11
- package/dist/extensions/agent/progress.js.map +1 -1
- package/dist/extensions/agent/render.d.ts.map +1 -1
- package/dist/extensions/agent/render.js +8 -24
- package/dist/extensions/agent/render.js.map +1 -1
- package/dist/extensions/agent/report.d.ts +11 -3
- package/dist/extensions/agent/report.d.ts.map +1 -1
- package/dist/extensions/agent/report.js +32 -7
- package/dist/extensions/agent/report.js.map +1 -1
- package/dist/extensions/agent/tool.d.ts.map +1 -1
- package/dist/extensions/agent/tool.js +20 -5
- package/dist/extensions/agent/tool.js.map +1 -1
- package/dist/extensions/agent/types.d.ts +2 -0
- package/dist/extensions/agent/types.d.ts.map +1 -1
- package/dist/extensions/agent/types.js.map +1 -1
- package/dist/extensions/agent/worker.d.ts +7 -0
- package/dist/extensions/agent/worker.d.ts.map +1 -1
- package/dist/extensions/agent/worker.js +9 -3
- package/dist/extensions/agent/worker.js.map +1 -1
- package/dist/extensions/cached-compaction/summary.d.ts +1 -1
- package/dist/extensions/cached-compaction/summary.d.ts.map +1 -1
- package/dist/extensions/cached-compaction/summary.js +13 -16
- package/dist/extensions/cached-compaction/summary.js.map +1 -1
- package/dist/extensions/search/index.d.ts.map +1 -1
- package/dist/extensions/search/index.js +6 -7
- package/dist/extensions/search/index.js.map +1 -1
- package/dist/extensions/tasks/tool/actions.d.ts +1 -2
- package/dist/extensions/tasks/tool/actions.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/actions.js +12 -80
- package/dist/extensions/tasks/tool/actions.js.map +1 -1
- package/dist/extensions/tasks/tool/constants.d.ts +1 -3
- package/dist/extensions/tasks/tool/constants.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/constants.js +1 -3
- package/dist/extensions/tasks/tool/constants.js.map +1 -1
- package/dist/extensions/tasks/tool/schema.d.ts +2 -3
- package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/schema.js +10 -18
- package/dist/extensions/tasks/tool/schema.js.map +1 -1
- package/dist/extensions/tasks/tool/types.d.ts +1 -17
- package/dist/extensions/tasks/tool/types.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/types.js.map +1 -1
- package/dist/extensions/tasks/tool.d.ts +1 -2
- package/dist/extensions/tasks/tool.d.ts.map +1 -1
- package/dist/extensions/tasks/tool.js +5 -6
- 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 +2 -2
- package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
- package/dist/extensions/tasks/ui/footer.d.ts +37 -0
- package/dist/extensions/tasks/ui/footer.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/footer.js +129 -0
- package/dist/extensions/tasks/ui/footer.js.map +1 -0
- package/dist/extensions/tasks/ui/frame.d.ts +36 -0
- package/dist/extensions/tasks/ui/frame.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/frame.js +33 -0
- package/dist/extensions/tasks/ui/frame.js.map +1 -0
- package/dist/extensions/tasks/ui/help.d.ts +6 -0
- package/dist/extensions/tasks/ui/help.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/help.js +53 -0
- package/dist/extensions/tasks/ui/help.js.map +1 -0
- package/dist/extensions/tasks/ui/inspector.d.ts +4 -3
- package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/inspector.js +25 -6
- package/dist/extensions/tasks/ui/inspector.js.map +1 -1
- package/dist/extensions/tasks/ui/layout.d.ts +15 -18
- package/dist/extensions/tasks/ui/layout.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/layout.js +162 -255
- package/dist/extensions/tasks/ui/layout.js.map +1 -1
- package/dist/extensions/tasks/ui/list.d.ts +3 -1
- package/dist/extensions/tasks/ui/list.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/list.js +19 -14
- package/dist/extensions/tasks/ui/list.js.map +1 -1
- package/dist/extensions/tasks/ui/manager.d.ts +17 -5
- package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/manager.js +147 -90
- package/dist/extensions/tasks/ui/manager.js.map +1 -1
- package/dist/extensions/tasks/ui/model.d.ts +32 -5
- package/dist/extensions/tasks/ui/model.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/model.js +7 -7
- package/dist/extensions/tasks/ui/model.js.map +1 -1
- package/dist/extensions/tasks/ui/panes.d.ts +40 -0
- package/dist/extensions/tasks/ui/panes.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/panes.js +144 -0
- package/dist/extensions/tasks/ui/panes.js.map +1 -0
- package/dist/extensions/tasks/ui/render.d.ts +2 -16
- package/dist/extensions/tasks/ui/render.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/render.js +13 -85
- package/dist/extensions/tasks/ui/render.js.map +1 -1
- package/dist/extensions/tasks/ui/viewport.d.ts +12 -4
- package/dist/extensions/tasks/ui/viewport.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/viewport.js +23 -7
- package/dist/extensions/tasks/ui/viewport.js.map +1 -1
- package/dist/extensions/tasks/ui/views.d.ts +12 -6
- package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/views.js +39 -32
- package/dist/extensions/tasks/ui/views.js.map +1 -1
- 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/session-selector.d.ts +11 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +43 -17
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +38 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +11 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +48 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +2 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/bundled/extensions/agent.md +39 -7
- package/docs/bundled/extensions/statusline.md +1 -1
- package/docs/bundled/tasks.md +28 -37
- package/docs/bundled/tool-presentation.md +1 -1
- package/docs/extensions.md +15 -13
- package/docs/json.md +3 -0
- package/docs/models-configuration.md +1 -1
- package/docs/models.md +7 -85
- package/docs/rpc.md +14 -0
- package/docs/sdk.md +12 -2
- package/docs/session-format.md +11 -5
- package/docs/sessions.md +1 -1
- package/docs/usage.md +2 -0
- package/package.json +3 -4
- package/dist/modes/interactive/tool-view/tool-execution.d.ts +0 -14
- package/dist/modes/interactive/tool-view/tool-execution.d.ts.map +0 -1
- package/dist/modes/interactive/tool-view/tool-execution.js +0 -13
- package/dist/modes/interactive/tool-view/tool-execution.js.map +0 -1
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/exy.png +0 -0
- package/npm-shrinkwrap.json +0 -4207
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { TASK_FACT_BYTES } from "../../core/tasks/output.js";
|
|
2
|
+
import { resolveToCwd } from "../../core/tools/path-utils.js";
|
|
1
3
|
import { combineUsage, emptyUsage } from "../../core/usage-totals.js";
|
|
2
|
-
import { activitiesText, activityTarget, clipText, compactArguments } from "./activity.js";
|
|
4
|
+
import { activitiesText, activityTarget, clipText, compactArguments, relativeToCwd } from "./activity.js";
|
|
5
|
+
import { activityLines } from "./activity-lines.js";
|
|
6
|
+
import { fitList, savedTranscript } from "./artifacts.js";
|
|
3
7
|
import { AGENT_MAX_ACTIVITIES } from "./types.js";
|
|
4
8
|
function assistantText(message) {
|
|
5
9
|
if (message.role !== "assistant")
|
|
@@ -25,17 +29,33 @@ function toolErrorText(result) {
|
|
|
25
29
|
.join("\n");
|
|
26
30
|
return clipText(text || "Tool call failed.", 1000);
|
|
27
31
|
}
|
|
32
|
+
/** Tools whose successful calls change the named file. */
|
|
33
|
+
const EDIT_TOOLS = new Set(["edit", "write"]);
|
|
34
|
+
/** The model-facing Edited line stays this small, whatever the Agent changed. */
|
|
35
|
+
const EDITED_LINE_BYTES = 1024;
|
|
36
|
+
const EDITED_LINE_PREFIX = "Edited (edit/write): ";
|
|
28
37
|
/**
|
|
29
38
|
* One worker session translated into task progress: a one-line status for the model,
|
|
30
39
|
* tool activity for humans, and cumulative usage for the ledger.
|
|
31
40
|
*/
|
|
32
41
|
export class AgentProgress {
|
|
33
|
-
constructor(control) {
|
|
42
|
+
constructor(control, cwd) {
|
|
34
43
|
this.activities = [];
|
|
35
44
|
this.counted = new WeakSet();
|
|
36
45
|
this.calls = 0;
|
|
46
|
+
this.failedCalls = 0;
|
|
47
|
+
/** The file key of each in-flight edit/write call, by tool call id. */
|
|
48
|
+
this.pendingEdits = new Map();
|
|
49
|
+
/**
|
|
50
|
+
* Files named by edit/write calls in the order their first call started, so parallel calls give a
|
|
51
|
+
* stable order; only files with a successful call count as edited. Never trimmed with the activity list.
|
|
52
|
+
*/
|
|
53
|
+
this.attempts = new Map();
|
|
37
54
|
this.usage = emptyUsage();
|
|
55
|
+
/** What the model-facing status line names; it keeps the path as the Agent wrote it. */
|
|
56
|
+
this.latest = "";
|
|
38
57
|
this.control = control;
|
|
58
|
+
this.cwd = cwd;
|
|
39
59
|
}
|
|
40
60
|
handle(event) {
|
|
41
61
|
switch (event.type) {
|
|
@@ -54,17 +74,28 @@ export class AgentProgress {
|
|
|
54
74
|
return;
|
|
55
75
|
case "tool_execution_start":
|
|
56
76
|
this.calls++;
|
|
77
|
+
if (EDIT_TOOLS.has(event.toolName))
|
|
78
|
+
this.trackEditStart(event.toolCallId, event.args);
|
|
79
|
+
this.latest = [event.toolName, activityTarget(event.toolName, event.args)].filter(Boolean).join(" ");
|
|
57
80
|
this.activities.push({
|
|
58
81
|
id: event.toolCallId,
|
|
59
82
|
name: event.toolName,
|
|
60
83
|
args: compactArguments(event.args),
|
|
61
|
-
target: activityTarget(event.toolName, event.args),
|
|
84
|
+
target: activityTarget(event.toolName, event.args, this.cwd),
|
|
62
85
|
status: "running",
|
|
86
|
+
startedAt: Date.now(),
|
|
63
87
|
});
|
|
64
88
|
if (this.activities.length > AGENT_MAX_ACTIVITIES)
|
|
65
89
|
this.activities.shift();
|
|
66
90
|
break;
|
|
67
91
|
case "tool_execution_end": {
|
|
92
|
+
const key = this.pendingEdits.get(event.toolCallId);
|
|
93
|
+
this.pendingEdits.delete(event.toolCallId);
|
|
94
|
+
const attempt = key === undefined ? undefined : this.attempts.get(key);
|
|
95
|
+
if (attempt && !event.isError)
|
|
96
|
+
attempt.changed = true;
|
|
97
|
+
if (event.isError && !this.control.signal.aborted)
|
|
98
|
+
this.failedCalls++;
|
|
68
99
|
const activity = this.activities.findLast((item) => item.id === event.toolCallId);
|
|
69
100
|
if (!activity)
|
|
70
101
|
return;
|
|
@@ -94,6 +125,12 @@ export class AgentProgress {
|
|
|
94
125
|
usage: this.usage,
|
|
95
126
|
});
|
|
96
127
|
}
|
|
128
|
+
/** The themed live tool-call list for /tasks Output; `undefined` before the first call, so the default view shows. */
|
|
129
|
+
present(width, theme) {
|
|
130
|
+
if (!this.activities.length)
|
|
131
|
+
return undefined;
|
|
132
|
+
return activityLines(this.activities, this.calls - this.activities.length, width, theme);
|
|
133
|
+
}
|
|
97
134
|
/** Classify a finished run from its last assistant message. */
|
|
98
135
|
outcome() {
|
|
99
136
|
const last = this.last;
|
|
@@ -106,30 +143,66 @@ export class AgentProgress {
|
|
|
106
143
|
};
|
|
107
144
|
return { status: "completed" };
|
|
108
145
|
}
|
|
109
|
-
|
|
146
|
+
/** The settled Agent's Details rows: call counts, files changed, and where the full report and transcript live. */
|
|
147
|
+
facts(report, artifacts) {
|
|
148
|
+
const calls = `${this.calls}${this.failedCalls ? ` · ${this.failedCalls} failed` : ""}`;
|
|
149
|
+
const facts = [["Tool calls", calls]];
|
|
150
|
+
const edited = this.editedFiles();
|
|
151
|
+
if (edited.length)
|
|
152
|
+
facts.push(["Edited", fitList(edited, TASK_FACT_BYTES)]);
|
|
153
|
+
if (report.reportPath)
|
|
154
|
+
facts.push(["Report", report.reportPath]);
|
|
155
|
+
const transcript = savedTranscript(artifacts);
|
|
156
|
+
if (transcript)
|
|
157
|
+
facts.push(["Transcript", transcript]);
|
|
158
|
+
return facts;
|
|
159
|
+
}
|
|
160
|
+
/** Settle with the bounded report, then the Edited line, so truncation can never cut it. */
|
|
161
|
+
complete(status, error, report, artifacts) {
|
|
162
|
+
const edited = this.editedFiles();
|
|
163
|
+
const line = edited.length
|
|
164
|
+
? `\n\n${EDITED_LINE_PREFIX}${fitList(edited, EDITED_LINE_BYTES - EDITED_LINE_PREFIX.length)}`
|
|
165
|
+
: "";
|
|
110
166
|
return {
|
|
111
167
|
status,
|
|
112
168
|
error,
|
|
113
169
|
usage: this.usage,
|
|
114
|
-
|
|
170
|
+
facts: this.facts(report, artifacts),
|
|
115
171
|
result: {
|
|
116
|
-
content: [{ type: "text", text: report }],
|
|
172
|
+
content: [{ type: "text", text: report.text + line }],
|
|
117
173
|
details: { version: 2, state: status, taskId: this.control.id, ...(error ? { error } : {}) },
|
|
118
174
|
...(status === "completed" ? {} : { isError: true }),
|
|
119
175
|
},
|
|
120
176
|
};
|
|
121
177
|
}
|
|
178
|
+
/** Display paths of the files a successful edit/write call changed, each once. */
|
|
179
|
+
editedFiles() {
|
|
180
|
+
return [...this.attempts.values()].filter((attempt) => attempt.changed).map((attempt) => attempt.display);
|
|
181
|
+
}
|
|
182
|
+
trackEditStart(id, args) {
|
|
183
|
+
const path = args?.path;
|
|
184
|
+
if (typeof path !== "string" || !path.trim())
|
|
185
|
+
return;
|
|
186
|
+
const resolved = this.cwd ? resolveToCwd(path, this.cwd) : path;
|
|
187
|
+
// One key per file, however the Agent spelled its path.
|
|
188
|
+
const key = process.platform === "win32" ? resolved.toLowerCase() : resolved;
|
|
189
|
+
if (!this.attempts.has(key))
|
|
190
|
+
this.attempts.set(key, { display: relativeToCwd(resolved, this.cwd), changed: false });
|
|
191
|
+
this.pendingEdits.set(id, key);
|
|
192
|
+
}
|
|
122
193
|
/** Model-readable progress: the report is the contract, so intermediate text never leaves the worker. */
|
|
123
194
|
status() {
|
|
124
|
-
|
|
125
|
-
if (!latest)
|
|
195
|
+
if (!this.latest)
|
|
126
196
|
return "Agent running; no tool calls yet.";
|
|
127
197
|
const calls = `${this.calls} tool ${this.calls === 1 ? "call" : "calls"}`;
|
|
128
|
-
return `Agent running · ${calls} · latest: ${
|
|
198
|
+
return `Agent running · ${calls} · latest: ${this.latest}`;
|
|
129
199
|
}
|
|
130
|
-
/**
|
|
200
|
+
/**
|
|
201
|
+
* Human-only live Output: the compact tool-call list, never sent to the model. A settled Agent
|
|
202
|
+
* publishes no display, so /tasks then shows its report.
|
|
203
|
+
*/
|
|
131
204
|
display() {
|
|
132
|
-
return this.activities.length ?
|
|
205
|
+
return this.activities.length ? activitiesText(this.activities, this.calls - this.activities.length) : "";
|
|
133
206
|
}
|
|
134
207
|
}
|
|
135
208
|
//# sourceMappingURL=progress.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../../src/extensions/agent/progress.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport type { TaskCompletion, TaskControl, TaskTerminalStatus } from \"../../core/tasks/types.ts\";\nimport { combineUsage, emptyUsage } from \"../../core/usage-totals.ts\";\nimport { activitiesText, activityTarget, clipText, compactArguments } from \"./activity.ts\";\nimport { AGENT_MAX_ACTIVITIES, type AgentActivity, type AgentToolDetails } from \"./types.ts\";\n\ntype AssistantMessage = Extract<AgentMessage, { role: \"assistant\" }>;\n\nfunction assistantText(message: AgentMessage): string {\n\tif (message.role !== \"assistant\") return \"\";\n\treturn message.content\n\t\t.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\\n\");\n}\n\nexport function finalAssistantText(messages: readonly AgentMessage[]): string {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst text = assistantText(messages[index]!);\n\t\tif (text.trim()) return text;\n\t}\n\treturn \"\";\n}\n\nfunction toolErrorText(result: unknown): string {\n\tconst content = (result as { content?: Array<{ type: string; text?: string }> }).content;\n\tconst text = content\n\t\t?.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text ?? \"\")\n\t\t.join(\"\\n\");\n\treturn clipText(text || \"Tool call failed.\", 1000);\n}\n\n/**\n * One worker session translated into task progress: a one-line status for the model,\n * tool activity for humans, and cumulative usage for the ledger.\n */\nexport class AgentProgress {\n\tprivate readonly control: TaskControl<AgentToolDetails>;\n\tprivate readonly activities: AgentActivity[] = [];\n\tprivate readonly counted = new WeakSet<AgentMessage>();\n\tprivate calls = 0;\n\tprivate usage: Usage = emptyUsage();\n\tprivate last?: AssistantMessage;\n\n\tconstructor(control: TaskControl<AgentToolDetails>) {\n\t\tthis.control = control;\n\t}\n\n\thandle(event: AgentSessionEvent): void {\n\t\tswitch (event.type) {\n\t\t\tcase \"message_end\":\n\t\t\t\tif (event.message.role !== \"assistant\") return;\n\t\t\t\tthis.last = event.message;\n\t\t\t\tif (!this.counted.has(event.message)) {\n\t\t\t\t\tthis.counted.add(event.message);\n\t\t\t\t\tthis.usage = combineUsage(this.usage, event.message.usage);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase \"compaction_end\":\n\t\t\t\tif (event.result?.usage) this.usage = combineUsage(this.usage, event.result.usage);\n\t\t\t\treturn;\n\t\t\tcase \"tool_execution_start\":\n\t\t\t\tthis.calls++;\n\t\t\t\tthis.activities.push({\n\t\t\t\t\tid: event.toolCallId,\n\t\t\t\t\tname: event.toolName,\n\t\t\t\t\targs: compactArguments(event.args),\n\t\t\t\t\ttarget: activityTarget(event.toolName, event.args),\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t});\n\t\t\t\tif (this.activities.length > AGENT_MAX_ACTIVITIES) this.activities.shift();\n\t\t\t\tbreak;\n\t\t\tcase \"tool_execution_end\": {\n\t\t\t\tconst activity = this.activities.findLast((item) => item.id === event.toolCallId);\n\t\t\t\tif (!activity) return;\n\t\t\t\tactivity.status = this.control.signal.aborted ? \"cancelled\" : event.isError ? \"error\" : \"ok\";\n\t\t\t\tactivity.durationMs = event.durationMs;\n\t\t\t\tif (event.isError) activity.error = toolErrorText(event.result);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\t\tthis.publish();\n\t}\n\n\tpublish(): void {\n\t\tthis.control.publish({\n\t\t\tresult: {\n\t\t\t\tcontent: [{ type: \"text\", text: this.status() }],\n\t\t\t\tdetails: {\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tstate: \"running\",\n\t\t\t\t\ttaskId: this.control.id,\n\t\t\t\t\tactivities: structuredClone(this.activities),\n\t\t\t\t},\n\t\t\t},\n\t\t\tdisplay: this.display(),\n\t\t\tusage: this.usage,\n\t\t});\n\t}\n\n\t/** Classify a finished run from its last assistant message. */\n\toutcome(): { status: TaskTerminalStatus; error?: string } {\n\t\tconst last = this.last;\n\t\tif (this.control.signal.aborted || last?.stopReason === \"aborted\")\n\t\t\treturn { status: \"cancelled\", error: \"Agent cancelled.\" };\n\t\tif (!last || last.stopReason === \"error\" || last.stopReason === \"length\")\n\t\t\treturn {\n\t\t\t\tstatus: \"failed\",\n\t\t\t\terror: clipText(last?.errorMessage || \"Agent ended without a complete report.\", 4096),\n\t\t\t};\n\t\treturn { status: \"completed\" };\n\t}\n\n\tcomplete(status: TaskTerminalStatus, error: string | undefined, report: string): TaskCompletion<AgentToolDetails> {\n\t\treturn {\n\t\t\tstatus,\n\t\t\terror,\n\t\t\tusage: this.usage,\n\t\t\tdisplay: this.display(),\n\t\t\tresult: {\n\t\t\t\tcontent: [{ type: \"text\", text: report }],\n\t\t\t\tdetails: { version: 2, state: status, taskId: this.control.id, ...(error ? { error } : {}) },\n\t\t\t\t...(status === \"completed\" ? {} : { isError: true }),\n\t\t\t},\n\t\t};\n\t}\n\n\t/** Model-readable progress: the report is the contract, so intermediate text never leaves the worker. */\n\tprivate status(): string {\n\t\tconst latest = this.activities.at(-1);\n\t\tif (!latest) return \"Agent running; no tool calls yet.\";\n\t\tconst calls = `${this.calls} tool ${this.calls === 1 ? \"call\" : \"calls\"}`;\n\t\treturn `Agent running · ${calls} · latest: ${latest.name}${latest.target ? ` ${latest.target}` : \"\"}`;\n\t}\n\n\t/** Human-only Output: compact tool calls, never sent to the model. */\n\tprivate display(): string {\n\t\treturn this.activities.length ? `Tool calls\\n${activitiesText(this.activities)}` : \"\";\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../../src/extensions/agent/progress.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { Usage } from \"@earendil-works/pi-ai/compat\";\nimport type { AgentSessionEvent } from \"../../core/agent-session.ts\";\nimport { TASK_FACT_BYTES } from \"../../core/tasks/output.ts\";\nimport type { TaskCompletion, TaskControl, TaskFact, TaskTerminalStatus } from \"../../core/tasks/types.ts\";\nimport { resolveToCwd } from \"../../core/tools/path-utils.ts\";\nimport { combineUsage, emptyUsage } from \"../../core/usage-totals.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { activitiesText, activityTarget, clipText, compactArguments, relativeToCwd } from \"./activity.ts\";\nimport { activityLines } from \"./activity-lines.ts\";\nimport { type AgentArtifacts, fitList, savedTranscript } from \"./artifacts.ts\";\nimport type { FinalReport } from \"./report.ts\";\nimport { AGENT_MAX_ACTIVITIES, type AgentActivity, type AgentToolDetails } from \"./types.ts\";\n\ntype AssistantMessage = Extract<AgentMessage, { role: \"assistant\" }>;\n\nfunction assistantText(message: AgentMessage): string {\n\tif (message.role !== \"assistant\") return \"\";\n\treturn message.content\n\t\t.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\\n\");\n}\n\nexport function finalAssistantText(messages: readonly AgentMessage[]): string {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst text = assistantText(messages[index]!);\n\t\tif (text.trim()) return text;\n\t}\n\treturn \"\";\n}\n\nfunction toolErrorText(result: unknown): string {\n\tconst content = (result as { content?: Array<{ type: string; text?: string }> }).content;\n\tconst text = content\n\t\t?.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text ?? \"\")\n\t\t.join(\"\\n\");\n\treturn clipText(text || \"Tool call failed.\", 1000);\n}\n\n/** Tools whose successful calls change the named file. */\nconst EDIT_TOOLS = new Set([\"edit\", \"write\"]);\n/** The model-facing Edited line stays this small, whatever the Agent changed. */\nconst EDITED_LINE_BYTES = 1024;\nconst EDITED_LINE_PREFIX = \"Edited (edit/write): \";\n\n/**\n * One worker session translated into task progress: a one-line status for the model,\n * tool activity for humans, and cumulative usage for the ledger.\n */\nexport class AgentProgress {\n\tprivate readonly control: TaskControl<AgentToolDetails>;\n\tprivate readonly activities: AgentActivity[] = [];\n\tprivate readonly counted = new WeakSet<AgentMessage>();\n\tprivate calls = 0;\n\tprivate failedCalls = 0;\n\t/** The file key of each in-flight edit/write call, by tool call id. */\n\tprivate readonly pendingEdits = new Map<string, string>();\n\t/**\n\t * Files named by edit/write calls in the order their first call started, so parallel calls give a\n\t * stable order; only files with a successful call count as edited. Never trimmed with the activity list.\n\t */\n\tprivate readonly attempts = new Map<string, { display: string; changed: boolean }>();\n\tprivate usage: Usage = emptyUsage();\n\tprivate last?: AssistantMessage;\n\t/** What the model-facing status line names; it keeps the path as the Agent wrote it. */\n\tprivate latest = \"\";\n\t/** The Agent's working directory, used to show paths inside it relative. */\n\tprivate readonly cwd?: string;\n\n\tconstructor(control: TaskControl<AgentToolDetails>, cwd?: string) {\n\t\tthis.control = control;\n\t\tthis.cwd = cwd;\n\t}\n\n\thandle(event: AgentSessionEvent): void {\n\t\tswitch (event.type) {\n\t\t\tcase \"message_end\":\n\t\t\t\tif (event.message.role !== \"assistant\") return;\n\t\t\t\tthis.last = event.message;\n\t\t\t\tif (!this.counted.has(event.message)) {\n\t\t\t\t\tthis.counted.add(event.message);\n\t\t\t\t\tthis.usage = combineUsage(this.usage, event.message.usage);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase \"compaction_end\":\n\t\t\t\tif (event.result?.usage) this.usage = combineUsage(this.usage, event.result.usage);\n\t\t\t\treturn;\n\t\t\tcase \"tool_execution_start\":\n\t\t\t\tthis.calls++;\n\t\t\t\tif (EDIT_TOOLS.has(event.toolName)) this.trackEditStart(event.toolCallId, event.args);\n\t\t\t\tthis.latest = [event.toolName, activityTarget(event.toolName, event.args)].filter(Boolean).join(\" \");\n\t\t\t\tthis.activities.push({\n\t\t\t\t\tid: event.toolCallId,\n\t\t\t\t\tname: event.toolName,\n\t\t\t\t\targs: compactArguments(event.args),\n\t\t\t\t\ttarget: activityTarget(event.toolName, event.args, this.cwd),\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\tstartedAt: Date.now(),\n\t\t\t\t});\n\t\t\t\tif (this.activities.length > AGENT_MAX_ACTIVITIES) this.activities.shift();\n\t\t\t\tbreak;\n\t\t\tcase \"tool_execution_end\": {\n\t\t\t\tconst key = this.pendingEdits.get(event.toolCallId);\n\t\t\t\tthis.pendingEdits.delete(event.toolCallId);\n\t\t\t\tconst attempt = key === undefined ? undefined : this.attempts.get(key);\n\t\t\t\tif (attempt && !event.isError) attempt.changed = true;\n\t\t\t\tif (event.isError && !this.control.signal.aborted) this.failedCalls++;\n\t\t\t\tconst activity = this.activities.findLast((item) => item.id === event.toolCallId);\n\t\t\t\tif (!activity) return;\n\t\t\t\tactivity.status = this.control.signal.aborted ? \"cancelled\" : event.isError ? \"error\" : \"ok\";\n\t\t\t\tactivity.durationMs = event.durationMs;\n\t\t\t\tif (event.isError) activity.error = toolErrorText(event.result);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\t\tthis.publish();\n\t}\n\n\tpublish(): void {\n\t\tthis.control.publish({\n\t\t\tresult: {\n\t\t\t\tcontent: [{ type: \"text\", text: this.status() }],\n\t\t\t\tdetails: {\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tstate: \"running\",\n\t\t\t\t\ttaskId: this.control.id,\n\t\t\t\t\tactivities: structuredClone(this.activities),\n\t\t\t\t},\n\t\t\t},\n\t\t\tdisplay: this.display(),\n\t\t\tusage: this.usage,\n\t\t});\n\t}\n\n\t/** The themed live tool-call list for /tasks Output; `undefined` before the first call, so the default view shows. */\n\tpresent(width: number, theme: Theme): string[] | undefined {\n\t\tif (!this.activities.length) return undefined;\n\t\treturn activityLines(this.activities, this.calls - this.activities.length, width, theme);\n\t}\n\n\t/** Classify a finished run from its last assistant message. */\n\toutcome(): { status: TaskTerminalStatus; error?: string } {\n\t\tconst last = this.last;\n\t\tif (this.control.signal.aborted || last?.stopReason === \"aborted\")\n\t\t\treturn { status: \"cancelled\", error: \"Agent cancelled.\" };\n\t\tif (!last || last.stopReason === \"error\" || last.stopReason === \"length\")\n\t\t\treturn {\n\t\t\t\tstatus: \"failed\",\n\t\t\t\terror: clipText(last?.errorMessage || \"Agent ended without a complete report.\", 4096),\n\t\t\t};\n\t\treturn { status: \"completed\" };\n\t}\n\n\t/** The settled Agent's Details rows: call counts, files changed, and where the full report and transcript live. */\n\tfacts(report: FinalReport, artifacts?: AgentArtifacts): TaskFact[] {\n\t\tconst calls = `${this.calls}${this.failedCalls ? ` · ${this.failedCalls} failed` : \"\"}`;\n\t\tconst facts: TaskFact[] = [[\"Tool calls\", calls]];\n\t\tconst edited = this.editedFiles();\n\t\tif (edited.length) facts.push([\"Edited\", fitList(edited, TASK_FACT_BYTES)]);\n\t\tif (report.reportPath) facts.push([\"Report\", report.reportPath]);\n\t\tconst transcript = savedTranscript(artifacts);\n\t\tif (transcript) facts.push([\"Transcript\", transcript]);\n\t\treturn facts;\n\t}\n\n\t/** Settle with the bounded report, then the Edited line, so truncation can never cut it. */\n\tcomplete(\n\t\tstatus: TaskTerminalStatus,\n\t\terror: string | undefined,\n\t\treport: FinalReport,\n\t\tartifacts?: AgentArtifacts,\n\t): TaskCompletion<AgentToolDetails> {\n\t\tconst edited = this.editedFiles();\n\t\tconst line = edited.length\n\t\t\t? `\\n\\n${EDITED_LINE_PREFIX}${fitList(edited, EDITED_LINE_BYTES - EDITED_LINE_PREFIX.length)}`\n\t\t\t: \"\";\n\t\treturn {\n\t\t\tstatus,\n\t\t\terror,\n\t\t\tusage: this.usage,\n\t\t\tfacts: this.facts(report, artifacts),\n\t\t\tresult: {\n\t\t\t\tcontent: [{ type: \"text\", text: report.text + line }],\n\t\t\t\tdetails: { version: 2, state: status, taskId: this.control.id, ...(error ? { error } : {}) },\n\t\t\t\t...(status === \"completed\" ? {} : { isError: true }),\n\t\t\t},\n\t\t};\n\t}\n\n\t/** Display paths of the files a successful edit/write call changed, each once. */\n\tprivate editedFiles(): string[] {\n\t\treturn [...this.attempts.values()].filter((attempt) => attempt.changed).map((attempt) => attempt.display);\n\t}\n\n\tprivate trackEditStart(id: string, args: unknown): void {\n\t\tconst path = (args as { path?: unknown } | null)?.path;\n\t\tif (typeof path !== \"string\" || !path.trim()) return;\n\t\tconst resolved = this.cwd ? resolveToCwd(path, this.cwd) : path;\n\t\t// One key per file, however the Agent spelled its path.\n\t\tconst key = process.platform === \"win32\" ? resolved.toLowerCase() : resolved;\n\t\tif (!this.attempts.has(key))\n\t\t\tthis.attempts.set(key, { display: relativeToCwd(resolved, this.cwd), changed: false });\n\t\tthis.pendingEdits.set(id, key);\n\t}\n\n\t/** Model-readable progress: the report is the contract, so intermediate text never leaves the worker. */\n\tprivate status(): string {\n\t\tif (!this.latest) return \"Agent running; no tool calls yet.\";\n\t\tconst calls = `${this.calls} tool ${this.calls === 1 ? \"call\" : \"calls\"}`;\n\t\treturn `Agent running · ${calls} · latest: ${this.latest}`;\n\t}\n\n\t/**\n\t * Human-only live Output: the compact tool-call list, never sent to the model. A settled Agent\n\t * publishes no display, so /tasks then shows its report.\n\t */\n\tprivate display(): string {\n\t\treturn this.activities.length ? activitiesText(this.activities, this.calls - this.activities.length) : \"\";\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,cAAc,EAAqB,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,cAAc,EAAqB,MAAM,gCAAgC,CAAC;AAKzG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInD,KAAK,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC;AA2F1G,eAAO,MAAM,cAAc,EAAE,aA6B5B,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { Container,
|
|
1
|
+
import { Container, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
2
2
|
import { getTextOutput, startToolTimer, toolTimerText } from "../../core/tools/render-utils.js";
|
|
3
|
-
import {
|
|
3
|
+
import { clipText, targetOf } from "./activity.js";
|
|
4
|
+
import { activityLines } from "./activity-lines.js";
|
|
4
5
|
const EXPANDED_ACTIVITIES = 5;
|
|
5
6
|
class AgentCallComponent {
|
|
6
7
|
constructor(theme) {
|
|
@@ -37,26 +38,6 @@ class AgentCallComponent {
|
|
|
37
38
|
}
|
|
38
39
|
invalidate() { }
|
|
39
40
|
}
|
|
40
|
-
function activityColor(status) {
|
|
41
|
-
switch (status) {
|
|
42
|
-
case "running":
|
|
43
|
-
return "warning";
|
|
44
|
-
case "ok":
|
|
45
|
-
return "success";
|
|
46
|
-
case "error":
|
|
47
|
-
return "error";
|
|
48
|
-
case "cancelled":
|
|
49
|
-
return "muted";
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
function renderActivity(activity, theme) {
|
|
53
|
-
const target = targetOf(activity);
|
|
54
|
-
const duration = formatActivityDuration(activity.durationMs);
|
|
55
|
-
return [
|
|
56
|
-
`${theme.fg(activityColor(activity.status), activityGlyph(activity.status))} ${theme.fg("toolTitle", activity.name)}${target ? theme.fg("muted", ` ${target}`) : ""}`,
|
|
57
|
-
...(duration ? [theme.fg("dim", duration)] : []),
|
|
58
|
-
].join(theme.fg("dim", " · "));
|
|
59
|
-
}
|
|
60
41
|
function detailsOf(result) {
|
|
61
42
|
const details = result?.details;
|
|
62
43
|
return details?.version === 2 && typeof details.state === "string" ? details : undefined;
|
|
@@ -112,8 +93,11 @@ export const agentRenderers = {
|
|
|
112
93
|
// Only live progress carries activities; settled rows stay one line.
|
|
113
94
|
if (details?.state !== "running" || !options.expanded)
|
|
114
95
|
return component;
|
|
115
|
-
|
|
116
|
-
|
|
96
|
+
const shown = details.activities.slice(-EXPANDED_ACTIVITIES);
|
|
97
|
+
component.addChild({
|
|
98
|
+
render: (width) => activityLines(shown, 0, width, theme),
|
|
99
|
+
invalidate() { },
|
|
100
|
+
});
|
|
117
101
|
return component;
|
|
118
102
|
},
|
|
119
103
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/extensions/agent/render.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, Container, TruncatedText, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { AgentToolResult, ToolDefinition, ToolRenderContext } from \"../../core/extensions/types.ts\";\nimport { getTextOutput, startToolTimer, toolTimerText } from \"../../core/tools/render-utils.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { activityGlyph, clipText, formatActivityDuration, targetOf } from \"./activity.ts\";\nimport type { AgentActivity, AgentToolDetails } from \"./types.ts\";\n\nconst EXPANDED_ACTIVITIES = 5;\n\ntype AgentRenderer = Required<Pick<ToolDefinition<any, AgentToolDetails>, \"renderCall\" | \"renderResult\">>;\n\ninterface StatusParts {\n\tdiagnostic?: string;\n\tduration?: string;\n\ttasks?: string;\n}\n\nclass AgentCallComponent implements Component {\n\tprivate title = \"\";\n\tprivate parts: StatusParts = {};\n\tprivate theme: Theme;\n\n\tconstructor(theme: Theme) {\n\t\tthis.theme = theme;\n\t}\n\n\tupdate(theme: Theme, title: string, parts: StatusParts): void {\n\t\tthis.theme = theme;\n\t\tthis.title = singleLine(title, 160);\n\t\tthis.parts = parts;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width <= 0) return [];\n\t\tconst heading = this.theme.fg(\"toolTitle\", this.theme.bold(\"Agent\"));\n\t\tconst available = width - visibleWidth(heading) - 1;\n\t\tif (available <= 0) return [truncateToWidth(heading, width, \"\")];\n\n\t\t// Tasks access and time are fixed; diagnostics take precedence over the task label.\n\t\tconst { diagnostic, duration, tasks } = this.parts;\n\t\tconst fullSuffix = [duration, tasks].filter(Boolean).join(\" · \");\n\t\tconst suffix = truncateToWidth(\n\t\t\tvisibleWidth(fullSuffix) <= available ? fullSuffix : (tasks ?? duration ?? \"\"),\n\t\t\tavailable,\n\t\t\t\"…\",\n\t\t);\n\t\tconst contentWidth = Math.max(0, available - visibleWidth(suffix) - (suffix ? 3 : 0));\n\t\tconst shownDiagnostic = truncateToWidth(diagnostic ?? \"\", contentWidth, \"…\");\n\t\tconst titleWidth = Math.max(0, contentWidth - visibleWidth(shownDiagnostic) - (shownDiagnostic ? 3 : 0));\n\t\tconst title = truncateToWidth(this.title, titleWidth, \"…\");\n\t\tconst parts = [\n\t\t\ttitle ? this.theme.fg(\"muted\", title) : undefined,\n\t\t\tshownDiagnostic ? this.theme.fg(\"dim\", shownDiagnostic) : undefined,\n\t\t\tsuffix ? this.theme.fg(\"dim\", suffix) : undefined,\n\t\t].filter(Boolean);\n\t\treturn [heading + (parts.length ? ` ${parts.join(this.theme.fg(\"dim\", \" · \"))}` : \"\")];\n\t}\n\n\tinvalidate(): void {}\n}\n\nfunction activityColor(status: AgentActivity[\"status\"]): \"warning\" | \"success\" | \"error\" | \"muted\" {\n\tswitch (status) {\n\t\tcase \"running\":\n\t\t\treturn \"warning\";\n\t\tcase \"ok\":\n\t\t\treturn \"success\";\n\t\tcase \"error\":\n\t\t\treturn \"error\";\n\t\tcase \"cancelled\":\n\t\t\treturn \"muted\";\n\t}\n}\n\nfunction renderActivity(activity: AgentActivity, theme: Theme): string {\n\tconst target = targetOf(activity);\n\tconst duration = formatActivityDuration(activity.durationMs);\n\treturn [\n\t\t`${theme.fg(activityColor(activity.status), activityGlyph(activity.status))} ${theme.fg(\"toolTitle\", activity.name)}${target ? theme.fg(\"muted\", ` ${target}`) : \"\"}`,\n\t\t...(duration ? [theme.fg(\"dim\", duration)] : []),\n\t].join(theme.fg(\"dim\", \" · \"));\n}\n\nfunction detailsOf(result: AgentToolResult<AgentToolDetails> | undefined): AgentToolDetails | undefined {\n\tconst details = result?.details;\n\treturn details?.version === 2 && typeof details.state === \"string\" ? details : undefined;\n}\n\nfunction singleLine(text: string, bytes = 120): string {\n\treturn clipText(text.replace(/\\s+/gu, \" \").trim(), bytes);\n}\n\nfunction errorOf(result: AgentToolResult<AgentToolDetails> | undefined, details: AgentToolDetails | undefined): string {\n\tif (details && \"error\" in details && details.error) return singleLine(details.error, 240);\n\tconst output = result ? getTextOutput(result, false).trim() : \"\";\n\tconst marker = output.lastIndexOf(\"Error:\");\n\treturn singleLine(marker >= 0 ? output.slice(marker + 6) : output.split(\"\\n\")[0] || \"Failed\", 240);\n}\n\nfunction statusParts(\n\tcontext: ToolRenderContext<any, any, AgentToolDetails>,\n\tdetails: AgentToolDetails | undefined,\n): StatusParts {\n\tconst status = details?.state;\n\tif (status === \"background\") {\n\t\ttoolTimerText(context, false);\n\t\treturn { diagnostic: \"Background\", tasks: \"/tasks\" };\n\t}\n\tconst timer = toolTimerText(context, context.isPartial);\n\tconst duration = timer?.replace(/^(?:Took|Elapsed) /, \"\");\n\tconst tasks = details?.taskId ? \"/tasks\" : undefined;\n\tif (context.isPartial || status === \"running\") {\n\t\tconst latest = details?.state === \"running\" ? details.activities.at(-1) : undefined;\n\t\tconst activity = latest ? `${latest.name}${targetOf(latest) ? ` ${targetOf(latest)}` : \"\"}` : \"Starting…\";\n\t\treturn { diagnostic: context.expanded ? undefined : activity, duration };\n\t}\n\tif (status === \"cancelled\") return { diagnostic: \"Cancelled\", duration, tasks };\n\tif (status === \"failed\" || status === \"timeout\" || context.isError)\n\t\treturn { diagnostic: errorOf(context.result, details), duration, tasks };\n\treturn { duration, tasks };\n}\n\nexport const agentRenderers: AgentRenderer = {\n\trenderCall(args, theme, context) {\n\t\tstartToolTimer(context);\n\t\tconst input = args as { description?: unknown; prompt?: unknown };\n\t\tconst title =\n\t\t\ttypeof input.description === \"string\" && input.description.trim()\n\t\t\t\t? input.description\n\t\t\t\t: typeof input.prompt === \"string\"\n\t\t\t\t\t? input.prompt\n\t\t\t\t\t: \"Delegated task\";\n\t\tconst parts = statusParts(context, detailsOf(context.result));\n\t\tconst component =\n\t\t\tcontext.lastComponent instanceof AgentCallComponent ? context.lastComponent : new AgentCallComponent(theme);\n\t\tcomponent.update(theme, title, parts);\n\t\treturn component;\n\t},\n\trenderResult(result, options, theme, context) {\n\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\tcomponent.clear();\n\t\tconst details = detailsOf(result);\n\t\t// Only live progress carries activities; settled rows stay one line.\n\t\tif (details?.state !== \"running\" || !options.expanded) return component;\n\t\tfor (const activity of details.activities.slice(-EXPANDED_ACTIVITIES))\n\t\t\tcomponent.addChild(new TruncatedText(renderActivity(activity, theme), 0, 0));\n\t\treturn component;\n\t},\n};\n"]}
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/extensions/agent/render.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Component, Container, truncateToWidth, visibleWidth } from \"@earendil-works/pi-tui\";\nimport type { AgentToolResult, ToolDefinition, ToolRenderContext } from \"../../core/extensions/types.ts\";\nimport { getTextOutput, startToolTimer, toolTimerText } from \"../../core/tools/render-utils.ts\";\nimport type { Theme } from \"../../modes/interactive/theme/theme.ts\";\nimport { clipText, targetOf } from \"./activity.ts\";\nimport { activityLines } from \"./activity-lines.ts\";\nimport type { AgentToolDetails } from \"./types.ts\";\n\nconst EXPANDED_ACTIVITIES = 5;\n\ntype AgentRenderer = Required<Pick<ToolDefinition<any, AgentToolDetails>, \"renderCall\" | \"renderResult\">>;\n\ninterface StatusParts {\n\tdiagnostic?: string;\n\tduration?: string;\n\ttasks?: string;\n}\n\nclass AgentCallComponent implements Component {\n\tprivate title = \"\";\n\tprivate parts: StatusParts = {};\n\tprivate theme: Theme;\n\n\tconstructor(theme: Theme) {\n\t\tthis.theme = theme;\n\t}\n\n\tupdate(theme: Theme, title: string, parts: StatusParts): void {\n\t\tthis.theme = theme;\n\t\tthis.title = singleLine(title, 160);\n\t\tthis.parts = parts;\n\t}\n\n\trender(width: number): string[] {\n\t\tif (width <= 0) return [];\n\t\tconst heading = this.theme.fg(\"toolTitle\", this.theme.bold(\"Agent\"));\n\t\tconst available = width - visibleWidth(heading) - 1;\n\t\tif (available <= 0) return [truncateToWidth(heading, width, \"\")];\n\n\t\t// Tasks access and time are fixed; diagnostics take precedence over the task label.\n\t\tconst { diagnostic, duration, tasks } = this.parts;\n\t\tconst fullSuffix = [duration, tasks].filter(Boolean).join(\" · \");\n\t\tconst suffix = truncateToWidth(\n\t\t\tvisibleWidth(fullSuffix) <= available ? fullSuffix : (tasks ?? duration ?? \"\"),\n\t\t\tavailable,\n\t\t\t\"…\",\n\t\t);\n\t\tconst contentWidth = Math.max(0, available - visibleWidth(suffix) - (suffix ? 3 : 0));\n\t\tconst shownDiagnostic = truncateToWidth(diagnostic ?? \"\", contentWidth, \"…\");\n\t\tconst titleWidth = Math.max(0, contentWidth - visibleWidth(shownDiagnostic) - (shownDiagnostic ? 3 : 0));\n\t\tconst title = truncateToWidth(this.title, titleWidth, \"…\");\n\t\tconst parts = [\n\t\t\ttitle ? this.theme.fg(\"muted\", title) : undefined,\n\t\t\tshownDiagnostic ? this.theme.fg(\"dim\", shownDiagnostic) : undefined,\n\t\t\tsuffix ? this.theme.fg(\"dim\", suffix) : undefined,\n\t\t].filter(Boolean);\n\t\treturn [heading + (parts.length ? ` ${parts.join(this.theme.fg(\"dim\", \" · \"))}` : \"\")];\n\t}\n\n\tinvalidate(): void {}\n}\n\nfunction detailsOf(result: AgentToolResult<AgentToolDetails> | undefined): AgentToolDetails | undefined {\n\tconst details = result?.details;\n\treturn details?.version === 2 && typeof details.state === \"string\" ? details : undefined;\n}\n\nfunction singleLine(text: string, bytes = 120): string {\n\treturn clipText(text.replace(/\\s+/gu, \" \").trim(), bytes);\n}\n\nfunction errorOf(result: AgentToolResult<AgentToolDetails> | undefined, details: AgentToolDetails | undefined): string {\n\tif (details && \"error\" in details && details.error) return singleLine(details.error, 240);\n\tconst output = result ? getTextOutput(result, false).trim() : \"\";\n\tconst marker = output.lastIndexOf(\"Error:\");\n\treturn singleLine(marker >= 0 ? output.slice(marker + 6) : output.split(\"\\n\")[0] || \"Failed\", 240);\n}\n\nfunction statusParts(\n\tcontext: ToolRenderContext<any, any, AgentToolDetails>,\n\tdetails: AgentToolDetails | undefined,\n): StatusParts {\n\tconst status = details?.state;\n\tif (status === \"background\") {\n\t\ttoolTimerText(context, false);\n\t\treturn { diagnostic: \"Background\", tasks: \"/tasks\" };\n\t}\n\tconst timer = toolTimerText(context, context.isPartial);\n\tconst duration = timer?.replace(/^(?:Took|Elapsed) /, \"\");\n\tconst tasks = details?.taskId ? \"/tasks\" : undefined;\n\tif (context.isPartial || status === \"running\") {\n\t\tconst latest = details?.state === \"running\" ? details.activities.at(-1) : undefined;\n\t\tconst activity = latest ? `${latest.name}${targetOf(latest) ? ` ${targetOf(latest)}` : \"\"}` : \"Starting…\";\n\t\treturn { diagnostic: context.expanded ? undefined : activity, duration };\n\t}\n\tif (status === \"cancelled\") return { diagnostic: \"Cancelled\", duration, tasks };\n\tif (status === \"failed\" || status === \"timeout\" || context.isError)\n\t\treturn { diagnostic: errorOf(context.result, details), duration, tasks };\n\treturn { duration, tasks };\n}\n\nexport const agentRenderers: AgentRenderer = {\n\trenderCall(args, theme, context) {\n\t\tstartToolTimer(context);\n\t\tconst input = args as { description?: unknown; prompt?: unknown };\n\t\tconst title =\n\t\t\ttypeof input.description === \"string\" && input.description.trim()\n\t\t\t\t? input.description\n\t\t\t\t: typeof input.prompt === \"string\"\n\t\t\t\t\t? input.prompt\n\t\t\t\t\t: \"Delegated task\";\n\t\tconst parts = statusParts(context, detailsOf(context.result));\n\t\tconst component =\n\t\t\tcontext.lastComponent instanceof AgentCallComponent ? context.lastComponent : new AgentCallComponent(theme);\n\t\tcomponent.update(theme, title, parts);\n\t\treturn component;\n\t},\n\trenderResult(result, options, theme, context) {\n\t\tconst component = (context.lastComponent as Container | undefined) ?? new Container();\n\t\tcomponent.clear();\n\t\tconst details = detailsOf(result);\n\t\t// Only live progress carries activities; settled rows stay one line.\n\t\tif (details?.state !== \"running\" || !options.expanded) return component;\n\t\tconst shown = details.activities.slice(-EXPANDED_ACTIVITIES);\n\t\tcomponent.addChild({\n\t\t\trender: (width) => activityLines(shown, 0, width, theme),\n\t\t\tinvalidate() {},\n\t\t});\n\t\treturn component;\n\t},\n};\n"]}
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import type { TaskControl } from "../../core/tasks/types.ts";
|
|
2
|
+
import type { AgentArtifacts } from "./artifacts.ts";
|
|
2
3
|
import { type AgentToolDetails } from "./types.ts";
|
|
4
|
+
export interface FinalReport {
|
|
5
|
+
/** The model-facing text, within AGENT_REPORT_BYTES. */
|
|
6
|
+
text: string;
|
|
7
|
+
/** The persistent file holding the complete report, when one was written. */
|
|
8
|
+
reportPath?: string;
|
|
9
|
+
}
|
|
3
10
|
export declare function boundedReport(text: string, fullOutputPath?: string): string;
|
|
4
11
|
/**
|
|
5
|
-
* The model-facing report.
|
|
6
|
-
*
|
|
12
|
+
* The model-facing report. With session artifacts the complete report is always saved there and an
|
|
13
|
+
* oversized one names that file. Without them, an oversized report keeps its beginning and names a
|
|
14
|
+
* managed temporary Markdown file, which the task owns and cleans up.
|
|
7
15
|
*/
|
|
8
|
-
export declare function finalReport(control: TaskControl<AgentToolDetails>, report: string, error: string | undefined): Promise<
|
|
16
|
+
export declare function finalReport(control: TaskControl<AgentToolDetails>, report: string, error: string | undefined, artifacts?: AgentArtifacts): Promise<FinalReport>;
|
|
9
17
|
//# sourceMappingURL=report.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/report.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/report.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAKvE,MAAM,WAAW,WAAW;IAC3B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAM3E;AA6BD;;;;GAIG;AACH,wBAAsB,WAAW,CAChC,OAAO,EAAE,WAAW,CAAC,gBAAgB,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,SAAS,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,WAAW,CAAC,CAetB"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { unlink } from "node:fs/promises";
|
|
1
|
+
import { unlink, writeFile } from "node:fs/promises";
|
|
2
2
|
import { boundText } from "../../core/tasks/output.js";
|
|
3
3
|
import { writeOutputFile } from "../../utils/output-files.js";
|
|
4
4
|
import { AGENT_REPORT_BYTES } from "./types.js";
|
|
5
|
+
/** Reports can carry private data, so only the user may read the file. */
|
|
6
|
+
const REPORT_FILE_MODE = 0o600;
|
|
5
7
|
export function boundedReport(text, fullOutputPath) {
|
|
6
8
|
if (Buffer.byteLength(text) <= AGENT_REPORT_BYTES)
|
|
7
9
|
return text;
|
|
@@ -16,25 +18,48 @@ async function removeOutputFile(path) {
|
|
|
16
18
|
throw error;
|
|
17
19
|
});
|
|
18
20
|
}
|
|
21
|
+
/** Write the complete report beside the session; an oversized one stays readable through `tasks read` and is never retired. */
|
|
22
|
+
async function persistReport(control, artifacts, text) {
|
|
23
|
+
try {
|
|
24
|
+
await writeFile(artifacts.reportPath, text, { mode: REPORT_FILE_MODE });
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
if (Buffer.byteLength(text) <= AGENT_REPORT_BYTES)
|
|
30
|
+
return { text, reportPath: artifacts.reportPath };
|
|
31
|
+
try {
|
|
32
|
+
// No cleanup: the report belongs to the session, not to Tasks retention.
|
|
33
|
+
control.attachOutput(artifacts.reportPath);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
/* The notice below still names the file; only `tasks read` loses it. */
|
|
37
|
+
}
|
|
38
|
+
return { text: boundedReport(text, artifacts.reportPath), reportPath: artifacts.reportPath };
|
|
39
|
+
}
|
|
19
40
|
/**
|
|
20
|
-
* The model-facing report.
|
|
21
|
-
*
|
|
41
|
+
* The model-facing report. With session artifacts the complete report is always saved there and an
|
|
42
|
+
* oversized one names that file. Without them, an oversized report keeps its beginning and names a
|
|
43
|
+
* managed temporary Markdown file, which the task owns and cleans up.
|
|
22
44
|
*/
|
|
23
|
-
export async function finalReport(control, report, error) {
|
|
45
|
+
export async function finalReport(control, report, error, artifacts) {
|
|
24
46
|
const text = !report ? (error ?? "No report returned.") : error ? `${report}\n\nError: ${error}` : report;
|
|
47
|
+
const persisted = artifacts && (await persistReport(control, artifacts, text));
|
|
48
|
+
if (persisted)
|
|
49
|
+
return persisted;
|
|
25
50
|
if (Buffer.byteLength(text) <= AGENT_REPORT_BYTES)
|
|
26
|
-
return text;
|
|
51
|
+
return { text };
|
|
27
52
|
let path;
|
|
28
53
|
try {
|
|
29
54
|
path = await writeOutputFile("pi-agent", ".md", text);
|
|
30
55
|
const saved = path;
|
|
31
56
|
control.attachOutput(saved, () => removeOutputFile(saved));
|
|
32
|
-
return boundedReport(text, saved);
|
|
57
|
+
return { text: boundedReport(text, saved) };
|
|
33
58
|
}
|
|
34
59
|
catch {
|
|
35
60
|
if (path)
|
|
36
61
|
await removeOutputFile(path).catch(() => { });
|
|
37
|
-
return boundedReport(text);
|
|
62
|
+
return { text: boundedReport(text) };
|
|
38
63
|
}
|
|
39
64
|
}
|
|
40
65
|
//# sourceMappingURL=report.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/extensions/agent/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/extensions/agent/report.ts"],"names":[],"mappings":"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","sourcesContent":["import { unlink, writeFile } from \"node:fs/promises\";\nimport { boundText } from \"../../core/tasks/output.ts\";\nimport type { TaskControl } from \"../../core/tasks/types.ts\";\nimport { writeOutputFile } from \"../../utils/output-files.ts\";\nimport type { AgentArtifacts } from \"./artifacts.ts\";\nimport { AGENT_REPORT_BYTES, type AgentToolDetails } from \"./types.ts\";\n\n/** Reports can carry private data, so only the user may read the file. */\nconst REPORT_FILE_MODE = 0o600;\n\nexport interface FinalReport {\n\t/** The model-facing text, within AGENT_REPORT_BYTES. */\n\ttext: string;\n\t/** The persistent file holding the complete report, when one was written. */\n\treportPath?: string;\n}\n\nexport function boundedReport(text: string, fullOutputPath?: string): string {\n\tif (Buffer.byteLength(text) <= AGENT_REPORT_BYTES) return text;\n\tconst notice = fullOutputPath\n\t\t? `\\n\\n[Agent output truncated. Full output: ${fullOutputPath}]`\n\t\t: \"\\n\\n[Agent output truncated. Full output unavailable.]\";\n\treturn boundText(text, AGENT_REPORT_BYTES - Buffer.byteLength(notice)) + notice;\n}\n\nasync function removeOutputFile(path: string): Promise<void> {\n\tawait unlink(path).catch((error: NodeJS.ErrnoException) => {\n\t\tif (error.code !== \"ENOENT\") throw error;\n\t});\n}\n\n/** Write the complete report beside the session; an oversized one stays readable through `tasks read` and is never retired. */\nasync function persistReport(\n\tcontrol: TaskControl<AgentToolDetails>,\n\tartifacts: AgentArtifacts,\n\ttext: string,\n): Promise<FinalReport | undefined> {\n\ttry {\n\t\tawait writeFile(artifacts.reportPath, text, { mode: REPORT_FILE_MODE });\n\t} catch {\n\t\treturn undefined;\n\t}\n\tif (Buffer.byteLength(text) <= AGENT_REPORT_BYTES) return { text, reportPath: artifacts.reportPath };\n\ttry {\n\t\t// No cleanup: the report belongs to the session, not to Tasks retention.\n\t\tcontrol.attachOutput(artifacts.reportPath);\n\t} catch {\n\t\t/* The notice below still names the file; only `tasks read` loses it. */\n\t}\n\treturn { text: boundedReport(text, artifacts.reportPath), reportPath: artifacts.reportPath };\n}\n\n/**\n * The model-facing report. With session artifacts the complete report is always saved there and an\n * oversized one names that file. Without them, an oversized report keeps its beginning and names a\n * managed temporary Markdown file, which the task owns and cleans up.\n */\nexport async function finalReport(\n\tcontrol: TaskControl<AgentToolDetails>,\n\treport: string,\n\terror: string | undefined,\n\tartifacts?: AgentArtifacts,\n): Promise<FinalReport> {\n\tconst text = !report ? (error ?? \"No report returned.\") : error ? `${report}\\n\\nError: ${error}` : report;\n\tconst persisted = artifacts && (await persistReport(control, artifacts, text));\n\tif (persisted) return persisted;\n\tif (Buffer.byteLength(text) <= AGENT_REPORT_BYTES) return { text };\n\tlet path: string | undefined;\n\ttry {\n\t\tpath = await writeOutputFile(\"pi-agent\", \".md\", text);\n\t\tconst saved = path;\n\t\tcontrol.attachOutput(saved, () => removeOutputFile(saved));\n\t\treturn { text: boundedReport(text, saved) };\n\t} catch {\n\t\tif (path) await removeOutputFile(path).catch(() => {});\n\t\treturn { text: boundedReport(text) };\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAOtF,OAAO,EAAyC,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG1F,QAAA,MAAM,WAAW;;;;EAkBhB,CAAC;AAmBF,wBAAgB,eAAe,CAC9B,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACpC,cAAc,CAAC,OAAO,WAAW,EAAE,gBAAgB,CAAC,CAmEtD"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
2
|
import { defineTool } from "../../core/extensions/types.js";
|
|
3
|
+
import { TASKS_TOOL_NAME } from "../../core/tasks/types.js";
|
|
3
4
|
import { clipText } from "./activity.js";
|
|
4
5
|
import { agentRenderers } from "./render.js";
|
|
5
6
|
import { resolveAgentConfiguration } from "./settings.js";
|
|
@@ -11,7 +12,9 @@ const agentSchema = Type.Object({
|
|
|
11
12
|
description: "Complete, self-contained task briefing: goal, relevant context and paths, constraints, whether to edit or only investigate, and expected verification and report. The Agent cannot see this conversation.",
|
|
12
13
|
}),
|
|
13
14
|
description: Type.Optional(Type.String({ description: "Short (3–5 word) task label for the transcript and Tasks panel" })),
|
|
14
|
-
background: Type.Optional(Type.Boolean({
|
|
15
|
+
background: Type.Optional(Type.Boolean({
|
|
16
|
+
description: "Only when you have independent work to do while it runs: return a task ID now; the report wakes you when it finishes",
|
|
17
|
+
})),
|
|
15
18
|
}, { additionalProperties: false });
|
|
16
19
|
/** The model-facing handoff: who moved the Agent, whether it waits for a slot, and how to follow it. */
|
|
17
20
|
function handoffResult(task, byUser) {
|
|
@@ -23,7 +26,7 @@ function handoffResult(task, byUser) {
|
|
|
23
26
|
content: [
|
|
24
27
|
{
|
|
25
28
|
type: "text",
|
|
26
|
-
text: `${moved}${queued}
|
|
29
|
+
text: `${moved}${queued} When it finishes, its report wakes you automatically, even after your turn ends. Do not wait for it or poll it: continue independent work, or end your turn and tell the user it is running. Use ${TASKS_TOOL_NAME} kill only to stop it.`,
|
|
27
30
|
},
|
|
28
31
|
],
|
|
29
32
|
details: { version: 2, state: "background", taskId: task.id, byUser },
|
|
@@ -34,13 +37,14 @@ export function createAgentTool(options = {}) {
|
|
|
34
37
|
return defineTool({
|
|
35
38
|
name: "Agent",
|
|
36
39
|
label: "Agent",
|
|
37
|
-
description: "Run one self-contained task in a fresh Agent session and get back only its final report. Use Agent when separate context or parallel execution clearly helps; handle known-path reads and small edits directly. The Agent cannot see this conversation, but shares your working directory and applicable project instructions, with read, bash, edit, and write. Foreground returns the report; background returns a task ID and
|
|
40
|
+
description: "Run one self-contained task in a fresh Agent session and get back only its final report. Use Agent when separate context or parallel execution clearly helps; handle known-path reads and small edits directly. The Agent cannot see this conversation, but shares your working directory and applicable project instructions, with read, bash, edit, and write. Foreground returns the report; background returns a task ID, and the report notifies you when it finishes.",
|
|
38
41
|
promptSnippet: "Delegate a self-contained task and receive only its final report",
|
|
39
42
|
promptGuidelines: [
|
|
40
43
|
"Use Agent primarily for independent research, verification, or well-specified, self-contained implementation when separate context or parallel execution clearly helps. Keep design and substantial coding in the main session; handle known-path reads and small edits directly. “Multiple angles” or “be thorough” alone does not justify an Agent.",
|
|
41
44
|
"Give Agent a self-contained briefing: the goal and why it matters, prior findings or ruled-out options, relevant paths and constraints, whether to investigate or edit, and expected verification. For open investigations, hand over the question rather than a fragile step-by-step procedure; state any report-length limit.",
|
|
42
45
|
"Keep ownership of synthesis when using Agent—never delegate understanding. For edits, supply your conclusions, target behavior, relevant files, and acceptance checks rather than “based on your findings, fix it.” Verify actual edits and test evidence before calling the work done.",
|
|
43
|
-
"Run parallel Agents only on independent work; concurrent writers must not touch the same files or shared state. Do not duplicate delegated work
|
|
46
|
+
"Run parallel Agents only on independent work; concurrent writers must not touch the same files or shared state. Do not duplicate delegated work.",
|
|
47
|
+
"Use background only when you have independent work to do while the Agent runs. Never wait for or poll a background Agent: once you run out of independent work, end your turn, and its report wakes you automatically.",
|
|
44
48
|
"An Agent report is not automatically presented to the user. Relay the important outcome, verification result, and remaining risks concisely.",
|
|
45
49
|
],
|
|
46
50
|
parameters: agentSchema,
|
|
@@ -53,6 +57,11 @@ export function createAgentTool(options = {}) {
|
|
|
53
57
|
const auth = await ctx.modelRuntime.getAuth(model, { signal });
|
|
54
58
|
if (!auth)
|
|
55
59
|
throw new Error(`No authentication for Agent model ${model.provider}/${model.id}`);
|
|
60
|
+
// Captured now: a background Agent may outlive the session that launched it.
|
|
61
|
+
const sessionArtifactDir = ctx.sessionManager.getArtifactDir();
|
|
62
|
+
const parentSession = ctx.sessionManager.getSessionFile();
|
|
63
|
+
// The live view reads the run's own progress, which exists only once the run starts.
|
|
64
|
+
let progress;
|
|
56
65
|
const outcome = await ctx.tasks.execute({
|
|
57
66
|
kind: "agent",
|
|
58
67
|
label: "Agent",
|
|
@@ -69,6 +78,7 @@ export function createAgentTool(options = {}) {
|
|
|
69
78
|
background: params.background,
|
|
70
79
|
signal,
|
|
71
80
|
onUpdate,
|
|
81
|
+
present: (width, theme) => progress?.present(width, theme),
|
|
72
82
|
run: (control) => runWorker(control, {
|
|
73
83
|
prompt: params.prompt,
|
|
74
84
|
cwd: ctx.cwd,
|
|
@@ -76,11 +86,16 @@ export function createAgentTool(options = {}) {
|
|
|
76
86
|
thinking,
|
|
77
87
|
modelRuntime: ctx.modelRuntime,
|
|
78
88
|
projectTrusted: ctx.isProjectTrusted(),
|
|
89
|
+
sessionArtifactDir,
|
|
90
|
+
parentSession,
|
|
91
|
+
onProgress: (created) => {
|
|
92
|
+
progress = created;
|
|
93
|
+
},
|
|
79
94
|
}),
|
|
80
95
|
});
|
|
81
96
|
if (outcome.kind === "result")
|
|
82
97
|
return outcome.result;
|
|
83
|
-
return handoffResult(outcome.task,
|
|
98
|
+
return handoffResult(outcome.task, outcome.reason === "detached");
|
|
84
99
|
},
|
|
85
100
|
...agentRenderers,
|
|
86
101
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../src/extensions/agent/tool.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type } from \"typebox\";\nimport type { AgentToolResult, ToolDefinition } from \"../../core/extensions/types.ts\";\nimport { defineTool } from \"../../core/extensions/types.ts\";\nimport type { TaskSnapshot } from \"../../core/tasks/types.ts\";\nimport { clipText } from \"./activity.ts\";\nimport { agentRenderers } from \"./render.ts\";\nimport { resolveAgentConfiguration } from \"./settings.ts\";\nimport { AGENT_CONCURRENCY, AGENT_PROMPT_BYTES, type AgentToolDetails } from \"./types.ts\";\nimport { runWorker } from \"./worker.ts\";\n\nconst agentSchema = Type.Object(\n\t{\n\t\tprompt: Type.String({\n\t\t\tminLength: 1,\n\t\t\tdescription:\n\t\t\t\t\"Complete, self-contained task briefing: goal, relevant context and paths, constraints, whether to edit or only investigate, and expected verification and report. The Agent cannot see this conversation.\",\n\t\t}),\n\t\tdescription: Type.Optional(\n\t\t\tType.String({ description: \"Short (3–5 word) task label for the transcript and Tasks panel\" }),\n\t\t),\n\t\tbackground: Type.Optional(\n\t\t\tType.Boolean({ description: \"Return a task ID and deliver the final report asynchronously\" }),\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\n/** The model-facing handoff: who moved the Agent, whether it waits for a slot, and how to follow it. */\nfunction handoffResult(task: TaskSnapshot, byUser: boolean): AgentToolResult<AgentToolDetails> {\n\tconst moved = byUser\n\t\t? `The user moved this Agent to the background while it was running: ${task.id}. It continues unchanged.`\n\t\t: `Agent running in background: ${task.id}.`;\n\tconst queued = task.status === \"queued\" ? \" It is queued until an Agent slot frees.\" : \"\";\n\treturn {\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: `${moved}${queued} The report will be delivered automatically. Use tasks read/wait/kill to inspect, wait or stop.`,\n\t\t\t},\n\t\t],\n\t\tdetails: { version: 2, state: \"background\", taskId: task.id, byUser },\n\t};\n}\n\nexport function createAgentTool(\n\toptions: { concurrency?: number } = {},\n): ToolDefinition<typeof agentSchema, AgentToolDetails> {\n\tconst limit = options.concurrency ?? AGENT_CONCURRENCY;\n\treturn defineTool({\n\t\tname: \"Agent\",\n\t\tlabel: \"Agent\",\n\t\tdescription:\n\t\t\t\"Run one self-contained task in a fresh Agent session and get back only its final report. Use Agent when separate context or parallel execution clearly helps; handle known-path reads and small edits directly. The Agent cannot see this conversation, but shares your working directory and applicable project instructions, with read, bash, edit, and write. Foreground returns the report; background returns a task ID and delivers the report automatically.\",\n\t\tpromptSnippet: \"Delegate a self-contained task and receive only its final report\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use Agent primarily for independent research, verification, or well-specified, self-contained implementation when separate context or parallel execution clearly helps. Keep design and substantial coding in the main session; handle known-path reads and small edits directly. “Multiple angles” or “be thorough” alone does not justify an Agent.\",\n\t\t\t\"Give Agent a self-contained briefing: the goal and why it matters, prior findings or ruled-out options, relevant paths and constraints, whether to investigate or edit, and expected verification. For open investigations, hand over the question rather than a fragile step-by-step procedure; state any report-length limit.\",\n\t\t\t\"Keep ownership of synthesis when using Agent—never delegate understanding. For edits, supply your conclusions, target behavior, relevant files, and acceptance checks rather than “based on your findings, fix it.” Verify actual edits and test evidence before calling the work done.\",\n\t\t\t\"Run parallel Agents only on independent work; concurrent writers must not touch the same files or shared state. Do not duplicate delegated work or repeatedly poll a background Agent. Continue independent work, or wait when its result is needed.\",\n\t\t\t\"An Agent report is not automatically presented to the user. Relay the important outcome, verification result, and remaining risks concisely.\",\n\t\t],\n\t\tparameters: agentSchema,\n\t\tconstrainedSampling: { type: \"json_schema\", strict: \"prefer\" },\n\t\texecutionMode: \"parallel\",\n\t\tasync execute(toolCallId, params, signal, onUpdate, ctx) {\n\t\t\tif (!params.prompt.trim() || Buffer.byteLength(params.prompt) > AGENT_PROMPT_BYTES)\n\t\t\t\tthrow new Error(\"Agent prompt must contain text and fit within 16 KiB.\");\n\t\t\tconst { model, thinking } = resolveAgentConfiguration(ctx);\n\t\t\tconst auth = await ctx.modelRuntime.getAuth(model, { signal });\n\t\t\tif (!auth) throw new Error(`No authentication for Agent model ${model.provider}/${model.id}`);\n\t\t\tconst outcome = await ctx.tasks.execute<AgentToolDetails>({\n\t\t\t\tkind: \"agent\",\n\t\t\t\tlabel: \"Agent\",\n\t\t\t\ttitle: clipText((params.description?.trim() || params.prompt).replace(/\\s+/gu, \" \").trim(), 160),\n\t\t\t\toutput: \"report\",\n\t\t\t\tinput: { label: \"Prompt\", text: params.prompt, truncated: false },\n\t\t\t\tfacts: [\n\t\t\t\t\t[\"Model\", `${model.provider}/${model.id}`],\n\t\t\t\t\t[\"Thinking\", thinking],\n\t\t\t\t\t[\"Directory\", ctx.cwd],\n\t\t\t\t],\n\t\t\t\tconcurrency: { key: \"agent\", limit },\n\t\t\t\ttoolCallId,\n\t\t\t\tbackground: params.background,\n\t\t\t\tsignal,\n\t\t\t\tonUpdate,\n\t\t\t\trun: (control) =>\n\t\t\t\t\trunWorker(control, {\n\t\t\t\t\t\tprompt: params.prompt,\n\t\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tthinking,\n\t\t\t\t\t\tmodelRuntime: ctx.modelRuntime,\n\t\t\t\t\t\tprojectTrusted: ctx.isProjectTrusted(),\n\t\t\t\t\t}),\n\t\t\t});\n\t\t\tif (outcome.kind === \"result\") return outcome.result;\n\t\t\treturn handoffResult(outcome.task, params.background !== true);\n\t\t},\n\t\t...agentRenderers,\n\t});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../src/extensions/agent/tool.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type } from \"typebox\";\nimport type { AgentToolResult, ToolDefinition } from \"../../core/extensions/types.ts\";\nimport { defineTool } from \"../../core/extensions/types.ts\";\nimport { TASKS_TOOL_NAME, type TaskSnapshot } from \"../../core/tasks/types.ts\";\nimport { clipText } from \"./activity.ts\";\nimport type { AgentProgress } from \"./progress.ts\";\nimport { agentRenderers } from \"./render.ts\";\nimport { resolveAgentConfiguration } from \"./settings.ts\";\nimport { AGENT_CONCURRENCY, AGENT_PROMPT_BYTES, type AgentToolDetails } from \"./types.ts\";\nimport { runWorker } from \"./worker.ts\";\n\nconst agentSchema = Type.Object(\n\t{\n\t\tprompt: Type.String({\n\t\t\tminLength: 1,\n\t\t\tdescription:\n\t\t\t\t\"Complete, self-contained task briefing: goal, relevant context and paths, constraints, whether to edit or only investigate, and expected verification and report. The Agent cannot see this conversation.\",\n\t\t}),\n\t\tdescription: Type.Optional(\n\t\t\tType.String({ description: \"Short (3–5 word) task label for the transcript and Tasks panel\" }),\n\t\t),\n\t\tbackground: Type.Optional(\n\t\t\tType.Boolean({\n\t\t\t\tdescription:\n\t\t\t\t\t\"Only when you have independent work to do while it runs: return a task ID now; the report wakes you when it finishes\",\n\t\t\t}),\n\t\t),\n\t},\n\t{ additionalProperties: false },\n);\n\n/** The model-facing handoff: who moved the Agent, whether it waits for a slot, and how to follow it. */\nfunction handoffResult(task: TaskSnapshot, byUser: boolean): AgentToolResult<AgentToolDetails> {\n\tconst moved = byUser\n\t\t? `The user moved this Agent to the background while it was running: ${task.id}. It continues unchanged.`\n\t\t: `Agent running in background: ${task.id}.`;\n\tconst queued = task.status === \"queued\" ? \" It is queued until an Agent slot frees.\" : \"\";\n\treturn {\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: `${moved}${queued} When it finishes, its report wakes you automatically, even after your turn ends. Do not wait for it or poll it: continue independent work, or end your turn and tell the user it is running. Use ${TASKS_TOOL_NAME} kill only to stop it.`,\n\t\t\t},\n\t\t],\n\t\tdetails: { version: 2, state: \"background\", taskId: task.id, byUser },\n\t};\n}\n\nexport function createAgentTool(\n\toptions: { concurrency?: number } = {},\n): ToolDefinition<typeof agentSchema, AgentToolDetails> {\n\tconst limit = options.concurrency ?? AGENT_CONCURRENCY;\n\treturn defineTool({\n\t\tname: \"Agent\",\n\t\tlabel: \"Agent\",\n\t\tdescription:\n\t\t\t\"Run one self-contained task in a fresh Agent session and get back only its final report. Use Agent when separate context or parallel execution clearly helps; handle known-path reads and small edits directly. The Agent cannot see this conversation, but shares your working directory and applicable project instructions, with read, bash, edit, and write. Foreground returns the report; background returns a task ID, and the report notifies you when it finishes.\",\n\t\tpromptSnippet: \"Delegate a self-contained task and receive only its final report\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use Agent primarily for independent research, verification, or well-specified, self-contained implementation when separate context or parallel execution clearly helps. Keep design and substantial coding in the main session; handle known-path reads and small edits directly. “Multiple angles” or “be thorough” alone does not justify an Agent.\",\n\t\t\t\"Give Agent a self-contained briefing: the goal and why it matters, prior findings or ruled-out options, relevant paths and constraints, whether to investigate or edit, and expected verification. For open investigations, hand over the question rather than a fragile step-by-step procedure; state any report-length limit.\",\n\t\t\t\"Keep ownership of synthesis when using Agent—never delegate understanding. For edits, supply your conclusions, target behavior, relevant files, and acceptance checks rather than “based on your findings, fix it.” Verify actual edits and test evidence before calling the work done.\",\n\t\t\t\"Run parallel Agents only on independent work; concurrent writers must not touch the same files or shared state. Do not duplicate delegated work.\",\n\t\t\t\"Use background only when you have independent work to do while the Agent runs. Never wait for or poll a background Agent: once you run out of independent work, end your turn, and its report wakes you automatically.\",\n\t\t\t\"An Agent report is not automatically presented to the user. Relay the important outcome, verification result, and remaining risks concisely.\",\n\t\t],\n\t\tparameters: agentSchema,\n\t\tconstrainedSampling: { type: \"json_schema\", strict: \"prefer\" },\n\t\texecutionMode: \"parallel\",\n\t\tasync execute(toolCallId, params, signal, onUpdate, ctx) {\n\t\t\tif (!params.prompt.trim() || Buffer.byteLength(params.prompt) > AGENT_PROMPT_BYTES)\n\t\t\t\tthrow new Error(\"Agent prompt must contain text and fit within 16 KiB.\");\n\t\t\tconst { model, thinking } = resolveAgentConfiguration(ctx);\n\t\t\tconst auth = await ctx.modelRuntime.getAuth(model, { signal });\n\t\t\tif (!auth) throw new Error(`No authentication for Agent model ${model.provider}/${model.id}`);\n\t\t\t// Captured now: a background Agent may outlive the session that launched it.\n\t\t\tconst sessionArtifactDir = ctx.sessionManager.getArtifactDir();\n\t\t\tconst parentSession = ctx.sessionManager.getSessionFile();\n\t\t\t// The live view reads the run's own progress, which exists only once the run starts.\n\t\t\tlet progress: AgentProgress | undefined;\n\t\t\tconst outcome = await ctx.tasks.execute<AgentToolDetails>({\n\t\t\t\tkind: \"agent\",\n\t\t\t\tlabel: \"Agent\",\n\t\t\t\ttitle: clipText((params.description?.trim() || params.prompt).replace(/\\s+/gu, \" \").trim(), 160),\n\t\t\t\toutput: \"report\",\n\t\t\t\tinput: { label: \"Prompt\", text: params.prompt, truncated: false },\n\t\t\t\tfacts: [\n\t\t\t\t\t[\"Model\", `${model.provider}/${model.id}`],\n\t\t\t\t\t[\"Thinking\", thinking],\n\t\t\t\t\t[\"Directory\", ctx.cwd],\n\t\t\t\t],\n\t\t\t\tconcurrency: { key: \"agent\", limit },\n\t\t\t\ttoolCallId,\n\t\t\t\tbackground: params.background,\n\t\t\t\tsignal,\n\t\t\t\tonUpdate,\n\t\t\t\tpresent: (width, theme) => progress?.present(width, theme),\n\t\t\t\trun: (control) =>\n\t\t\t\t\trunWorker(control, {\n\t\t\t\t\t\tprompt: params.prompt,\n\t\t\t\t\t\tcwd: ctx.cwd,\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tthinking,\n\t\t\t\t\t\tmodelRuntime: ctx.modelRuntime,\n\t\t\t\t\t\tprojectTrusted: ctx.isProjectTrusted(),\n\t\t\t\t\t\tsessionArtifactDir,\n\t\t\t\t\t\tparentSession,\n\t\t\t\t\t\tonProgress: (created) => {\n\t\t\t\t\t\t\tprogress = created;\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t});\n\t\t\tif (outcome.kind === \"result\") return outcome.result;\n\t\t\treturn handoffResult(outcome.task, outcome.reason === \"detached\");\n\t\t},\n\t\t...agentRenderers,\n\t});\n}\n"]}
|