@astralyn/pi 1.4.5 → 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 +20 -0
- package/dist/bundle/chunks/{chunk-I5S7H7GA.js → chunk-EYKC6ESU.js} +1 -1
- package/dist/bundle/chunks/chunk-KDO6L76C.js +230 -0
- package/dist/bundle/chunks/chunk-RBTJBQWX.js +1500 -0
- package/dist/bundle/chunks/{execute-GMFGC27P.js → execute-5ZQUS52M.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-6FUV7ZDV.js → virtual-modules-KCQU7LOC.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/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/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/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 -6
- package/dist/core/tasks/output.d.ts.map +1 -1
- package/dist/core/tasks/output.js +38 -38
- 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 -254
- 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 -53
- 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/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 +4 -4
- package/dist/extensions/agent/activity.d.ts.map +1 -1
- package/dist/extensions/agent/activity.js +15 -24
- package/dist/extensions/agent/activity.js.map +1 -1
- package/dist/extensions/agent/index.d.ts +2 -11
- package/dist/extensions/agent/index.d.ts.map +1 -1
- package/dist/extensions/agent/index.js +3 -88
- package/dist/extensions/agent/index.js.map +1 -1
- 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.map +1 -1
- package/dist/extensions/agent/render.js +8 -17
- package/dist/extensions/agent/render.js.map +1 -1
- 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 +1 -1
- package/dist/extensions/agent/settings.d.ts.map +1 -1
- package/dist/extensions/agent/settings.js +101 -83
- package/dist/extensions/agent/settings.js.map +1 -1
- 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 +19 -21
- package/dist/extensions/agent/types.d.ts.map +1 -1
- package/dist/extensions/agent/types.js +2 -10
- package/dist/extensions/agent/types.js.map +1 -1
- 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/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 -5
- package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/views.js +61 -36
- 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/extensions/agent.md +12 -10
- package/docs/bundled/extensions/statusline.md +1 -1
- package/docs/bundled/tasks.md +15 -14
- package/docs/extensions.md +22 -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/dist/bundle/chunks/chunk-FSJ45CRP.js +0 -229
- package/dist/bundle/chunks/chunk-W3FIUMGM.js +0 -1501
- 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 -131
- package/dist/core/tasks/history.js.map +0 -1
- package/dist/extensions/agent/runner.d.ts +0 -24
- package/dist/extensions/agent/runner.d.ts.map +0 -1
- package/dist/extensions/agent/runner.js +0 -274
- package/dist/extensions/agent/runner.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activity.js","sourceRoot":"","sources":["../../../src/extensions/agent/activity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"activity.js","sourceRoot":"","sources":["../../../src/extensions/agent/activity.ts"],"names":[],"mappings":"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","sourcesContent":["/** Compact, bounded formatting of an Agent's tool-call activity, shared by the Transcript and /tasks. */\nimport { boundText } from \"../../core/tasks/output.ts\";\nimport type { AgentActivity } from \"./types.ts\";\n\nexport function clipText(text: string, bytes: number): string {\n\tif (Buffer.byteLength(text) <= bytes) return text;\n\treturn `${boundText(text, Math.max(1, bytes - 1))}…`;\n}\n\nexport function compactArguments(args: unknown): string {\n\ttry {\n\t\treturn clipText(JSON.stringify(args) ?? String(args), 512).replace(/\\s+/gu, \" \");\n\t} catch {\n\t\treturn \"{…}\";\n\t}\n}\n\n/** A short display target; full arguments remain available in Tasks Output. */\nexport function activityTarget(name: string, args: unknown): string {\n\tif (!args || typeof args !== \"object\" || Array.isArray(args)) return compactArguments(args);\n\tconst record = args as Record<string, unknown>;\n\tconst keys =\n\t\tname === \"bash\" || name === \"powershell\"\n\t\t\t? [\"command\"]\n\t\t\t: name === \"grep\" || name === \"find\"\n\t\t\t\t? [\"pattern\", \"path\"]\n\t\t\t\t: [\"path\", \"pattern\", \"command\"];\n\tfor (const key of keys) {\n\t\tconst value = record[key];\n\t\tif (typeof value !== \"string\" || !value.trim()) continue;\n\t\tconst first = key === \"command\" ? value.split(/\\r?\\n/).find((line) => line.trim()) : value;\n\t\treturn clipText((first ?? value).trim().replace(/[ \\t]+/gu, \" \"), 160);\n\t}\n\treturn compactArguments(args);\n}\n\n/** The stored display target, or one derived from the bounded arguments. */\nexport function targetOf(activity: AgentActivity): string {\n\tif (activity.target) return activity.target;\n\ttry {\n\t\treturn activityTarget(activity.name, JSON.parse(activity.args));\n\t} catch {\n\t\treturn activity.args;\n\t}\n}\n\nexport function formatActivityDuration(ms: number | undefined): string {\n\tif (ms === undefined) return \"\";\n\treturn ms < 1000 ? `${Math.round(ms)}ms` : `${(ms / 1000).toFixed(1)}s`;\n}\n\nexport function activityGlyph(status: AgentActivity[\"status\"]): string {\n\tswitch (status) {\n\t\tcase \"running\":\n\t\t\treturn \"…\";\n\t\tcase \"ok\":\n\t\t\treturn \"✓\";\n\t\tcase \"error\":\n\t\t\treturn \"✗\";\n\t\tcase \"cancelled\":\n\t\t\treturn \"⊘\";\n\t}\n}\n\n/** The Transcript's `glyph tool target · duration` form, plus an indented failure excerpt. */\nexport function activityText(activity: AgentActivity, includeError = true): string {\n\tconst target = targetOf(activity);\n\tconst duration = formatActivityDuration(activity.durationMs);\n\tconst line = `${activityGlyph(activity.status)} ${activity.name}${target ? ` ${target}` : \"\"}${duration ? ` · ${duration}` : \"\"}`;\n\treturn includeError && activity.error\n\t\t? `${line}\\n ${clipText(activity.error, 1000).replaceAll(\"\\n\", \"\\n \")}`\n\t\t: line;\n}\n\nexport function activitiesText(activities: readonly AgentActivity[]): string {\n\treturn activities.map((activity) => activityText(activity)).join(\"\\n\");\n}\n"]}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import { AgentGate } from "./runner.ts";
|
|
4
|
-
import type { AgentToolDetails } from "./types.ts";
|
|
5
|
-
declare const agentSchema: Type.TObject<{
|
|
6
|
-
prompt: Type.TString;
|
|
7
|
-
description: Type.TOptional<Type.TString>;
|
|
8
|
-
background: Type.TOptional<Type.TBoolean>;
|
|
9
|
-
}>;
|
|
10
|
-
export declare function createAgentTool(gate?: AgentGate): ToolDefinition<typeof agentSchema, AgentToolDetails>;
|
|
1
|
+
import type { ExtensionAPI } from "../../core/extensions/types.ts";
|
|
2
|
+
export { createAgentTool } from "./tool.ts";
|
|
11
3
|
export default function agentExtension(pi: ExtensionAPI): void;
|
|
12
|
-
export {};
|
|
13
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAInE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAM7D"}
|
|
@@ -1,91 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { agentRenderers } from "./render.js";
|
|
5
|
-
import { AgentGate, runAgent } from "./runner.js";
|
|
6
|
-
import { openAgentSettings, resolveAgentConfiguration } from "./settings.js";
|
|
7
|
-
const agentSchema = Type.Object({
|
|
8
|
-
prompt: Type.String({
|
|
9
|
-
minLength: 1,
|
|
10
|
-
description: "Complete, self-contained task briefing; the Agent cannot see this conversation",
|
|
11
|
-
}),
|
|
12
|
-
description: Type.Optional(Type.String({ description: "Short task label for the transcript and Tasks panel" })),
|
|
13
|
-
background: Type.Optional(Type.Boolean({ description: "Return a task ID and deliver the final report asynchronously" })),
|
|
14
|
-
}, { additionalProperties: false });
|
|
15
|
-
export function createAgentTool(gate = new AgentGate()) {
|
|
16
|
-
return defineTool({
|
|
17
|
-
name: "Agent",
|
|
18
|
-
label: "Agent",
|
|
19
|
-
description: "Delegate independent work to a temporary isolated Agent when separate context or parallel execution offers a clear benefit. Use sparingly; handle known-path reads and small edits directly. The Agent cannot see the parent conversation, so include all necessary context and desired verification in prompt. Foreground returns the final report; background returns a task ID and delivers it automatically.",
|
|
20
|
-
promptSnippet: "Delegate an independent task",
|
|
21
|
-
promptGuidelines: [
|
|
22
|
-
"Give Agent a complete, self-contained briefing with relevant paths, constraints and expected verification; use parallel calls only for independent, non-overlapping work.",
|
|
23
|
-
],
|
|
24
|
-
parameters: agentSchema,
|
|
25
|
-
constrainedSampling: { type: "json_schema", strict: "prefer" },
|
|
26
|
-
executionMode: "parallel",
|
|
27
|
-
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
28
|
-
if (!params.prompt.trim() || Buffer.byteLength(params.prompt) > 16 * 1024)
|
|
29
|
-
throw new Error("Agent prompt must contain text and fit within 16 KiB.");
|
|
30
|
-
const { model, thinking } = resolveAgentConfiguration(ctx);
|
|
31
|
-
const auth = await ctx.modelRuntime.getAuth(model, { signal });
|
|
32
|
-
if (!auth)
|
|
33
|
-
throw new Error(`No authentication for Agent model ${model.provider}/${model.id}`);
|
|
34
|
-
const title = clipText((params.description?.trim() || params.prompt).replace(/\s+/gu, " ").trim(), 160);
|
|
35
|
-
const modelName = `${model.provider}/${model.id}`;
|
|
36
|
-
const info = [
|
|
37
|
-
"Agent",
|
|
38
|
-
`Model ${modelName}`,
|
|
39
|
-
`Thinking ${thinking}`,
|
|
40
|
-
`Directory ${ctx.cwd}`,
|
|
41
|
-
"",
|
|
42
|
-
"Prompt",
|
|
43
|
-
params.prompt,
|
|
44
|
-
].join("\n");
|
|
45
|
-
let activities = [];
|
|
46
|
-
const outcome = await ctx.tasks.execute({
|
|
47
|
-
kind: "agent",
|
|
48
|
-
title,
|
|
49
|
-
toolCallId,
|
|
50
|
-
cwd: ctx.cwd,
|
|
51
|
-
info,
|
|
52
|
-
background: params.background,
|
|
53
|
-
signal,
|
|
54
|
-
onUpdate: (result) => {
|
|
55
|
-
activities = result.details?.activities ?? activities;
|
|
56
|
-
onUpdate?.(result);
|
|
57
|
-
},
|
|
58
|
-
run: (control) => runAgent(control, {
|
|
59
|
-
prompt: params.prompt,
|
|
60
|
-
cwd: ctx.cwd,
|
|
61
|
-
model,
|
|
62
|
-
thinking,
|
|
63
|
-
modelRuntime: ctx.modelRuntime,
|
|
64
|
-
projectTrusted: ctx.isProjectTrusted(),
|
|
65
|
-
}, gate),
|
|
66
|
-
});
|
|
67
|
-
if (outcome.kind === "result")
|
|
68
|
-
return outcome.result;
|
|
69
|
-
return {
|
|
70
|
-
content: [
|
|
71
|
-
{
|
|
72
|
-
type: "text",
|
|
73
|
-
text: `Agent running in background: ${outcome.task.id}. The report will be delivered automatically. Use tasks read/wait/kill to inspect, wait or stop.`,
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
details: {
|
|
77
|
-
version: 1,
|
|
78
|
-
taskId: outcome.task.id,
|
|
79
|
-
status: "background",
|
|
80
|
-
model: modelName,
|
|
81
|
-
thinking,
|
|
82
|
-
activities,
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
},
|
|
86
|
-
...agentRenderers,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
1
|
+
import { openAgentSettings } from "./settings.js";
|
|
2
|
+
import { createAgentTool } from "./tool.js";
|
|
3
|
+
export { createAgentTool } from "./tool.js";
|
|
89
4
|
export default function agentExtension(pi) {
|
|
90
5
|
pi.registerTool(createAgentTool());
|
|
91
6
|
pi.registerCommand("agent", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/agent/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/agent/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAgB;IACtD,EAAE,CAAC,YAAY,CAAC,eAAe,EAAE,CAAC,CAAC;IACnC,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE;QAC3B,WAAW,EAAE,uDAAuD;QACpE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC;KACrD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { ExtensionAPI } from \"../../core/extensions/types.ts\";\nimport { openAgentSettings } from \"./settings.ts\";\nimport { createAgentTool } from \"./tool.ts\";\n\nexport { createAgentTool } from \"./tool.ts\";\n\nexport default function agentExtension(pi: ExtensionAPI): void {\n\tpi.registerTool(createAgentTool());\n\tpi.registerCommand(\"agent\", {\n\t\tdescription: \"Choose the model and thinking level for future Agents\",\n\t\thandler: async (_args, ctx) => openAgentSettings(ctx),\n\t});\n}\n"]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AgentMessage } from "@earendil-works/pi-agent-core";
|
|
2
|
+
import type { AgentSessionEvent } from "../../core/agent-session.ts";
|
|
3
|
+
import type { TaskCompletion, TaskControl, TaskTerminalStatus } from "../../core/tasks/types.ts";
|
|
4
|
+
import { type AgentToolDetails } from "./types.ts";
|
|
5
|
+
export declare function finalAssistantText(messages: readonly AgentMessage[]): string;
|
|
6
|
+
/**
|
|
7
|
+
* One worker session translated into task progress: a one-line status for the model,
|
|
8
|
+
* tool activity for humans, and cumulative usage for the ledger.
|
|
9
|
+
*/
|
|
10
|
+
export declare class AgentProgress {
|
|
11
|
+
private readonly control;
|
|
12
|
+
private readonly activities;
|
|
13
|
+
private readonly counted;
|
|
14
|
+
private calls;
|
|
15
|
+
private usage;
|
|
16
|
+
private last?;
|
|
17
|
+
constructor(control: TaskControl<AgentToolDetails>);
|
|
18
|
+
handle(event: AgentSessionEvent): void;
|
|
19
|
+
publish(): void;
|
|
20
|
+
/** Classify a finished run from its last assistant message. */
|
|
21
|
+
outcome(): {
|
|
22
|
+
status: TaskTerminalStatus;
|
|
23
|
+
error?: string;
|
|
24
|
+
};
|
|
25
|
+
complete(status: TaskTerminalStatus, error: string | undefined, report: string): TaskCompletion<AgentToolDetails>;
|
|
26
|
+
/** Model-readable progress: the report is the contract, so intermediate text never leaves the worker. */
|
|
27
|
+
private status;
|
|
28
|
+
/** Human-only Output: compact tool calls, never sent to the model. */
|
|
29
|
+
private display;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../src/extensions/agent/progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAGjG,OAAO,EAA4C,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAuB7F,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAM5E;AAWD;;;GAGG;AACH,qBAAa,aAAa;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,IAAI,CAAC,CAAmB;gBAEpB,OAAO,EAAE,WAAW,CAAC,gBAAgB,CAAC;IAIlD,MAAM,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI;IAsCtC,OAAO,IAAI,IAAI;IAgBf,+DAA+D;IAC/D,OAAO,IAAI;QAAE,MAAM,EAAE,kBAAkB,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE;IAYzD,QAAQ,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,gBAAgB,CAAC;IAcjH,yGAAyG;IACzG,OAAO,CAAC,MAAM;IAOd,sEAAsE;IACtE,OAAO,CAAC,OAAO;CAGf"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { combineUsage } from "../../core/usage-totals.js";
|
|
2
|
+
import { activitiesText, activityTarget, clipText, compactArguments } from "./activity.js";
|
|
3
|
+
import { AGENT_MAX_ACTIVITIES } from "./types.js";
|
|
4
|
+
function emptyUsage() {
|
|
5
|
+
return {
|
|
6
|
+
input: 0,
|
|
7
|
+
output: 0,
|
|
8
|
+
cacheRead: 0,
|
|
9
|
+
cacheWrite: 0,
|
|
10
|
+
totalTokens: 0,
|
|
11
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function assistantText(message) {
|
|
15
|
+
if (message.role !== "assistant")
|
|
16
|
+
return "";
|
|
17
|
+
return message.content
|
|
18
|
+
.filter((block) => block.type === "text")
|
|
19
|
+
.map((block) => block.text)
|
|
20
|
+
.join("\n");
|
|
21
|
+
}
|
|
22
|
+
export function finalAssistantText(messages) {
|
|
23
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
24
|
+
const text = assistantText(messages[index]);
|
|
25
|
+
if (text.trim())
|
|
26
|
+
return text;
|
|
27
|
+
}
|
|
28
|
+
return "";
|
|
29
|
+
}
|
|
30
|
+
function toolErrorText(result) {
|
|
31
|
+
const content = result.content;
|
|
32
|
+
const text = content
|
|
33
|
+
?.filter((block) => block.type === "text")
|
|
34
|
+
.map((block) => block.text ?? "")
|
|
35
|
+
.join("\n");
|
|
36
|
+
return clipText(text || "Tool call failed.", 1000);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* One worker session translated into task progress: a one-line status for the model,
|
|
40
|
+
* tool activity for humans, and cumulative usage for the ledger.
|
|
41
|
+
*/
|
|
42
|
+
export class AgentProgress {
|
|
43
|
+
constructor(control) {
|
|
44
|
+
this.activities = [];
|
|
45
|
+
this.counted = new WeakSet();
|
|
46
|
+
this.calls = 0;
|
|
47
|
+
this.usage = emptyUsage();
|
|
48
|
+
this.control = control;
|
|
49
|
+
}
|
|
50
|
+
handle(event) {
|
|
51
|
+
switch (event.type) {
|
|
52
|
+
case "message_end":
|
|
53
|
+
if (event.message.role !== "assistant")
|
|
54
|
+
return;
|
|
55
|
+
this.last = event.message;
|
|
56
|
+
if (!this.counted.has(event.message)) {
|
|
57
|
+
this.counted.add(event.message);
|
|
58
|
+
this.usage = combineUsage(this.usage, event.message.usage);
|
|
59
|
+
}
|
|
60
|
+
return;
|
|
61
|
+
case "compaction_end":
|
|
62
|
+
if (event.result?.usage)
|
|
63
|
+
this.usage = combineUsage(this.usage, event.result.usage);
|
|
64
|
+
return;
|
|
65
|
+
case "tool_execution_start":
|
|
66
|
+
this.calls++;
|
|
67
|
+
this.activities.push({
|
|
68
|
+
id: event.toolCallId,
|
|
69
|
+
name: event.toolName,
|
|
70
|
+
args: compactArguments(event.args),
|
|
71
|
+
target: activityTarget(event.toolName, event.args),
|
|
72
|
+
status: "running",
|
|
73
|
+
});
|
|
74
|
+
if (this.activities.length > AGENT_MAX_ACTIVITIES)
|
|
75
|
+
this.activities.shift();
|
|
76
|
+
break;
|
|
77
|
+
case "tool_execution_end": {
|
|
78
|
+
const activity = this.activities.findLast((item) => item.id === event.toolCallId);
|
|
79
|
+
if (!activity)
|
|
80
|
+
return;
|
|
81
|
+
activity.status = this.control.signal.aborted ? "cancelled" : event.isError ? "error" : "ok";
|
|
82
|
+
activity.durationMs = event.durationMs;
|
|
83
|
+
if (event.isError)
|
|
84
|
+
activity.error = toolErrorText(event.result);
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
default:
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
this.publish();
|
|
91
|
+
}
|
|
92
|
+
publish() {
|
|
93
|
+
this.control.publish({
|
|
94
|
+
result: {
|
|
95
|
+
content: [{ type: "text", text: this.status() }],
|
|
96
|
+
details: {
|
|
97
|
+
version: 2,
|
|
98
|
+
state: "running",
|
|
99
|
+
taskId: this.control.id,
|
|
100
|
+
activities: structuredClone(this.activities),
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
display: this.display(),
|
|
104
|
+
usage: this.usage,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/** Classify a finished run from its last assistant message. */
|
|
108
|
+
outcome() {
|
|
109
|
+
const last = this.last;
|
|
110
|
+
if (this.control.signal.aborted || last?.stopReason === "aborted")
|
|
111
|
+
return { status: "cancelled", error: "Agent cancelled." };
|
|
112
|
+
if (!last || last.stopReason === "error" || last.stopReason === "length")
|
|
113
|
+
return {
|
|
114
|
+
status: "failed",
|
|
115
|
+
error: clipText(last?.errorMessage || "Agent ended without a complete report.", 4096),
|
|
116
|
+
};
|
|
117
|
+
return { status: "completed" };
|
|
118
|
+
}
|
|
119
|
+
complete(status, error, report) {
|
|
120
|
+
return {
|
|
121
|
+
status,
|
|
122
|
+
error,
|
|
123
|
+
usage: this.usage,
|
|
124
|
+
display: this.display(),
|
|
125
|
+
result: {
|
|
126
|
+
content: [{ type: "text", text: report }],
|
|
127
|
+
details: { version: 2, state: status, taskId: this.control.id, ...(error ? { error } : {}) },
|
|
128
|
+
...(status === "completed" ? {} : { isError: true }),
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/** Model-readable progress: the report is the contract, so intermediate text never leaves the worker. */
|
|
133
|
+
status() {
|
|
134
|
+
const latest = this.activities.at(-1);
|
|
135
|
+
if (!latest)
|
|
136
|
+
return "Agent running; no tool calls yet.";
|
|
137
|
+
const calls = `${this.calls} tool ${this.calls === 1 ? "call" : "calls"}`;
|
|
138
|
+
return `Agent running · ${calls} · latest: ${latest.name}${latest.target ? ` ${latest.target}` : ""}`;
|
|
139
|
+
}
|
|
140
|
+
/** Human-only Output: compact tool calls, never sent to the model. */
|
|
141
|
+
display() {
|
|
142
|
+
return this.activities.length ? `Tool calls\n${activitiesText(this.activities)}` : "";
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=progress.js.map
|
|
@@ -0,0 +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 } 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 emptyUsage(): Usage {\n\treturn {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\ttotalTokens: 0,\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t};\n}\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 +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;AAIzG,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAIlE,KAAK,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,CAAC,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;AAIzG,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAIlE,KAAK,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC;AAiH1G,eAAO,MAAM,cAAc,EAAE,aA0B5B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Container, TruncatedText, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
2
2
|
import { getTextOutput, startToolTimer, toolTimerText } from "../../core/tools/render-utils.js";
|
|
3
|
-
import { activityGlyph,
|
|
3
|
+
import { activityGlyph, clipText, formatActivityDuration, targetOf } from "./activity.js";
|
|
4
4
|
const EXPANDED_ACTIVITIES = 5;
|
|
5
5
|
class AgentCallComponent {
|
|
6
6
|
constructor(theme) {
|
|
@@ -49,16 +49,6 @@ function activityColor(status) {
|
|
|
49
49
|
return "muted";
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
function targetOf(activity) {
|
|
53
|
-
if (activity.target)
|
|
54
|
-
return activity.target;
|
|
55
|
-
try {
|
|
56
|
-
return activityTarget(activity.name, JSON.parse(activity.args));
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
return activity.args;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
52
|
function renderActivity(activity, theme) {
|
|
63
53
|
const target = targetOf(activity);
|
|
64
54
|
const duration = formatActivityDuration(activity.durationMs);
|
|
@@ -69,20 +59,20 @@ function renderActivity(activity, theme) {
|
|
|
69
59
|
}
|
|
70
60
|
function detailsOf(result) {
|
|
71
61
|
const details = result?.details;
|
|
72
|
-
return details?.version ===
|
|
62
|
+
return details?.version === 2 && typeof details.state === "string" ? details : undefined;
|
|
73
63
|
}
|
|
74
64
|
function singleLine(text, bytes = 120) {
|
|
75
65
|
return clipText(text.replace(/\s+/gu, " ").trim(), bytes);
|
|
76
66
|
}
|
|
77
67
|
function errorOf(result, details) {
|
|
78
|
-
if (details
|
|
68
|
+
if (details && "error" in details && details.error)
|
|
79
69
|
return singleLine(details.error, 240);
|
|
80
70
|
const output = result ? getTextOutput(result, false).trim() : "";
|
|
81
71
|
const marker = output.lastIndexOf("Error:");
|
|
82
72
|
return singleLine(marker >= 0 ? output.slice(marker + 6) : output.split("\n")[0] || "Failed", 240);
|
|
83
73
|
}
|
|
84
74
|
function statusParts(context, details) {
|
|
85
|
-
const status = details?.
|
|
75
|
+
const status = details?.state;
|
|
86
76
|
if (status === "background") {
|
|
87
77
|
toolTimerText(context, false);
|
|
88
78
|
return { diagnostic: "Background", tasks: "/tasks" };
|
|
@@ -91,7 +81,7 @@ function statusParts(context, details) {
|
|
|
91
81
|
const duration = timer?.replace(/^(?:Took|Elapsed) /, "");
|
|
92
82
|
const tasks = details?.taskId ? "/tasks" : undefined;
|
|
93
83
|
if (context.isPartial || status === "running") {
|
|
94
|
-
const latest = details?.activities.at(-1);
|
|
84
|
+
const latest = details?.state === "running" ? details.activities.at(-1) : undefined;
|
|
95
85
|
const activity = latest ? `${latest.name}${targetOf(latest) ? ` ${targetOf(latest)}` : ""}` : "Starting…";
|
|
96
86
|
return { diagnostic: context.expanded ? undefined : activity, duration };
|
|
97
87
|
}
|
|
@@ -119,9 +109,10 @@ export const agentRenderers = {
|
|
|
119
109
|
const component = context.lastComponent ?? new Container();
|
|
120
110
|
component.clear();
|
|
121
111
|
const details = detailsOf(result);
|
|
122
|
-
|
|
112
|
+
// Only live progress carries activities; settled rows stay one line.
|
|
113
|
+
if (details?.state !== "running" || !options.expanded)
|
|
123
114
|
return component;
|
|
124
|
-
for (const activity of
|
|
115
|
+
for (const activity of details.activities.slice(-EXPANDED_ACTIVITIES))
|
|
125
116
|
component.addChild(new TruncatedText(renderActivity(activity, theme), 0, 0));
|
|
126
117
|
return component;
|
|
127
118
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/extensions/agent/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAEjH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAEhG,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAGhG,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAU9B,MAAM,kBAAkB;IAKvB,YAAY,KAAY;QAJhB,UAAK,GAAG,EAAE,CAAC;QACX,UAAK,GAAgB,EAAE,CAAC;QAI/B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,KAAY,EAAE,KAAa,EAAE,KAAkB;QACrD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,KAAa;QACnB,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACrE,MAAM,SAAS,GAAG,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpD,IAAI,SAAS,IAAI,CAAC;YAAE,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;QAEjE,oFAAoF;QACpF,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC;QACnD,MAAM,UAAU,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjE,MAAM,MAAM,GAAG,eAAe,CAC7B,YAAY,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,IAAI,EAAE,CAAC,EAC9E,SAAS,EACT,GAAG,CACH,CAAC;QACF,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,MAAM,eAAe,GAAG,eAAe,CAAC,UAAU,IAAI,EAAE,EAAE,YAAY,EAAE,GAAG,CAAC,CAAC;QAC7E,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC,eAAe,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzG,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG;YACb,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;YACjD,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,SAAS;YACnE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;SACjD,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClB,OAAO,CAAC,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACxF,CAAC;IAED,UAAU,KAAU,CAAC;CACrB;AAED,SAAS,aAAa,CAAC,MAA+B;IACrD,QAAQ,MAAM,EAAE,CAAC;QAChB,KAAK,SAAS;YACb,OAAO,SAAS,CAAC;QAClB,KAAK,IAAI;YACR,OAAO,SAAS,CAAC;QAClB,KAAK,OAAO;YACX,OAAO,OAAO,CAAC;QAChB,KAAK,WAAW;YACf,OAAO,OAAO,CAAC;IACjB,CAAC;AACF,CAAC;AAED,SAAS,QAAQ,CAAC,QAAuB;IACxC,IAAI,QAAQ,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC,MAAM,CAAC;IAC5C,IAAI,CAAC;QACJ,OAAO,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,QAAQ,CAAC,IAAI,CAAC;IACtB,CAAC;AACF,CAAC;AAED,SAAS,cAAc,CAAC,QAAuB,EAAE,KAAY;IAC5D,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAC7D,OAAO;QACN,GAAG,KAAK,CAAC,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE;QACrK,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,SAAS,CAAC,MAAqD;IACvE,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO,CAAC;IAChC,OAAO,OAAO,EAAE,OAAO,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1F,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,KAAK,GAAG,GAAG;IAC5C,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,OAAO,CAAC,MAAqD,EAAE,OAAqC;IAC5G,IAAI,OAAO,EAAE,KAAK;QAAE,OAAO,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC5C,OAAO,UAAU,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,EAAE,GAAG,CAAC,CAAC;AACpG,CAAC;AAED,SAAS,WAAW,CACnB,OAAsD,EACtD,OAAqC;IAErC,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,CAAC;IAC/B,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;QAC7B,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC9B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACtD,CAAC;IACD,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,KAAK,EAAE,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;IAC1D,MAAM,KAAK,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACrD,IAAI,OAAO,CAAC,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;QAC1G,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAC1E,CAAC;IACD,IAAI,MAAM,KAAK,WAAW;QAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAChF,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,OAAO;QACjE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC1E,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAkB;IAC5C,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO;QAC9B,cAAc,CAAC,OAAO,CAAC,CAAC;QACxB,MAAM,KAAK,GAAG,IAAmD,CAAC;QAClE,MAAM,KAAK,GACV,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE;YAChE,CAAC,CAAC,KAAK,CAAC,WAAW;YACnB,CAAC,CAAC,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;gBACjC,CAAC,CAAC,KAAK,CAAC,MAAM;gBACd,CAAC,CAAC,gBAAgB,CAAC;QACtB,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9D,MAAM,SAAS,GACd,OAAO,CAAC,aAAa,YAAY,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC7G,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QACtC,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;QAC3C,MAAM,SAAS,GAAI,OAAO,CAAC,aAAuC,IAAI,IAAI,SAAS,EAAE,CAAC;QACtF,SAAS,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,EAAE,MAAM,KAAK,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QACjG,KAAK,MAAM,QAAQ,IAAI,CAAC,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,mBAAmB,CAAC;YAC7E,SAAS,CAAC,QAAQ,CAAC,IAAI,aAAa,CAAC,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9E,OAAO,SAAS,CAAC;IAClB,CAAC;CACD,CAAC","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, activityTarget, clipText, formatActivityDuration } 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 targetOf(activity: AgentActivity): string {\n\tif (activity.target) return activity.target;\n\ttry {\n\t\treturn activityTarget(activity.name, JSON.parse(activity.args));\n\t} catch {\n\t\treturn activity.args;\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 === 1 && Array.isArray(details.activities) ? 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) 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?.status;\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?.activities.at(-1);\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\tif ((!options.isPartial && details?.status !== \"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, 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"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TaskControl } from "../../core/tasks/types.ts";
|
|
2
|
+
import { type AgentToolDetails } from "./types.ts";
|
|
3
|
+
export declare function boundedReport(text: string, fullOutputPath?: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* The model-facing report. An oversized report keeps its beginning and names a managed
|
|
6
|
+
* Markdown file with the complete text, which the task owns and cleans up.
|
|
7
|
+
*/
|
|
8
|
+
export declare function finalReport(control: TaskControl<AgentToolDetails>, report: string, error: string | undefined): Promise<string>;
|
|
9
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +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;AAEvE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAM3E;AAQD;;;GAGG;AACH,wBAAsB,WAAW,CAChC,OAAO,EAAE,WAAW,CAAC,gBAAgB,CAAC,EACtC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,GACvB,OAAO,CAAC,MAAM,CAAC,CAajB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { unlink } from "node:fs/promises";
|
|
2
|
+
import { boundText } from "../../core/tasks/output.js";
|
|
3
|
+
import { writeOutputFile } from "../../utils/output-files.js";
|
|
4
|
+
import { AGENT_REPORT_BYTES } from "./types.js";
|
|
5
|
+
export function boundedReport(text, fullOutputPath) {
|
|
6
|
+
if (Buffer.byteLength(text) <= AGENT_REPORT_BYTES)
|
|
7
|
+
return text;
|
|
8
|
+
const notice = fullOutputPath
|
|
9
|
+
? `\n\n[Agent output truncated. Full output: ${fullOutputPath}]`
|
|
10
|
+
: "\n\n[Agent output truncated. Full output unavailable.]";
|
|
11
|
+
return boundText(text, AGENT_REPORT_BYTES - Buffer.byteLength(notice)) + notice;
|
|
12
|
+
}
|
|
13
|
+
async function removeOutputFile(path) {
|
|
14
|
+
await unlink(path).catch((error) => {
|
|
15
|
+
if (error.code !== "ENOENT")
|
|
16
|
+
throw error;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The model-facing report. An oversized report keeps its beginning and names a managed
|
|
21
|
+
* Markdown file with the complete text, which the task owns and cleans up.
|
|
22
|
+
*/
|
|
23
|
+
export async function finalReport(control, report, error) {
|
|
24
|
+
const text = !report ? (error ?? "No report returned.") : error ? `${report}\n\nError: ${error}` : report;
|
|
25
|
+
if (Buffer.byteLength(text) <= AGENT_REPORT_BYTES)
|
|
26
|
+
return text;
|
|
27
|
+
let path;
|
|
28
|
+
try {
|
|
29
|
+
path = await writeOutputFile("pi-agent", ".md", text);
|
|
30
|
+
const saved = path;
|
|
31
|
+
control.attachOutput(saved, () => removeOutputFile(saved));
|
|
32
|
+
return boundedReport(text, saved);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
if (path)
|
|
36
|
+
await removeOutputFile(path).catch(() => { });
|
|
37
|
+
return boundedReport(text);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/extensions/agent/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAyB,MAAM,YAAY,CAAC;AAEvE,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,cAAuB;IAClE,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAC/D,MAAM,MAAM,GAAG,cAAc;QAC5B,CAAC,CAAC,6CAA6C,cAAc,GAAG;QAChE,CAAC,CAAC,wDAAwD,CAAC;IAC5D,OAAO,SAAS,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC;AACjF,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAA4B,EAAE,EAAE;QACzD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,KAAK,CAAC;IAC1C,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,OAAsC,EACtC,MAAc,EACd,KAAyB;IAEzB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,qBAAqB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,cAAc,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAC1G,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,kBAAkB;QAAE,OAAO,IAAI,CAAC;IAC/D,IAAI,IAAwB,CAAC;IAC7B,IAAI,CAAC;QACJ,IAAI,GAAG,MAAM,eAAe,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC;QACnB,OAAO,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3D,OAAO,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACR,IAAI,IAAI;YAAE,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACvD,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;AACF,CAAC","sourcesContent":["import { unlink } 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 { AGENT_REPORT_BYTES, type AgentToolDetails } from \"./types.ts\";\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/**\n * The model-facing report. An oversized report keeps its beginning and names a managed\n * Markdown file with the complete text, which the task owns and cleans up.\n */\nexport async function finalReport(\n\tcontrol: TaskControl<AgentToolDetails>,\n\treport: string,\n\terror: string | undefined,\n): Promise<string> {\n\tconst text = !report ? (error ?? \"No report returned.\") : error ? `${report}\\n\\nError: ${error}` : report;\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 boundedReport(text, saved);\n\t} catch {\n\t\tif (path) await removeOutputFile(path).catch(() => {});\n\t\treturn boundedReport(text);\n\t}\n}\n"]}
|