pi-subagents 0.49.0 → 0.51.0
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 +97 -0
- package/agents/gpt-pro.md +17 -0
- package/agents/oracle.md +7 -5
- package/agents/researcher.md +1 -1
- package/agents/reviewer.md +2 -2
- package/agents/scout.md +1 -1
- package/agents/worker.md +1 -1
- package/async-retention-discovery-worker.mjs +180 -0
- package/docs/agents.md +37 -2
- package/docs/configuration.md +76 -14
- package/docs/extension-api.md +78 -1
- package/docs/missions.md +1 -1
- package/docs/observability.md +20 -4
- package/docs/tool-reference.md +55 -39
- package/docs/workflows.md +171 -5
- package/package.json +4 -2
- package/skills/pi-subagents/SKILL.md +5 -4
- package/skills/pi-subagents/references/constraints-and-recipes.md +9 -6
- package/skills/pi-subagents/references/execution-controls.md +22 -18
- package/skills/pi-subagents/references/management-authoring-rpc.md +5 -5
- package/skills/pi-subagents/references/prompting-and-roles.md +33 -17
- package/src/agents/agent-management.ts +100 -345
- package/src/agents/agent-serializer.ts +2 -0
- package/src/agents/agents.ts +135 -25
- package/src/api/external-job-provider.ts +185 -0
- package/src/api/external-runs.ts +174 -84
- package/src/api/preflight.ts +42 -11
- package/src/api/shared-types.ts +2 -0
- package/src/extension/config.ts +36 -3
- package/src/extension/doctor.ts +3 -6
- package/src/extension/fanout-child.ts +2 -2
- package/src/extension/index.ts +210 -90
- package/src/extension/public-execution.ts +31 -2
- package/src/extension/rpc.ts +5 -1
- package/src/extension/schemas.ts +14 -36
- package/src/extension/tool-description.ts +37 -24
- package/src/inspectors/herdr/actions.ts +5 -9
- package/src/inspectors/herdr/inspector-runner.ts +2 -1
- package/src/inspectors/herdr/project-panes.ts +4 -8
- package/src/inspectors/herdr/shell-command.ts +16 -0
- package/src/intercom/intercom-bridge.ts +2 -3
- package/src/intercom/native-supervisor-channel.ts +49 -51
- package/src/missions/goal-driver.ts +3 -1
- package/src/missions/lifecycle.ts +6 -1
- package/src/missions/store.ts +4 -9
- package/src/profiles/profiles.ts +3 -1
- package/src/runs/background/active-run-index.ts +94 -1
- package/src/runs/background/async-execution.ts +98 -38
- package/src/runs/background/async-job-tracker.ts +21 -4
- package/src/runs/background/async-resume.ts +30 -17
- package/src/runs/background/async-retention.ts +888 -0
- package/src/runs/background/async-status-snapshot.ts +277 -0
- package/src/runs/background/async-status.ts +47 -56
- package/src/runs/background/chain-append.ts +3 -33
- package/src/runs/background/chain-root-attachment.ts +2 -2
- package/src/runs/background/completion-replay.ts +11 -1
- package/src/runs/background/control-channel.ts +14 -68
- package/src/runs/background/fleet-view.ts +3 -1
- package/src/runs/background/index-segment.ts +59 -0
- package/src/runs/background/notify.ts +3 -1
- package/src/runs/background/result-files.ts +505 -0
- package/src/runs/background/result-watcher.ts +250 -51
- package/src/runs/background/retained-children.ts +79 -20
- package/src/runs/background/run-id-query.ts +7 -0
- package/src/runs/background/run-id-resolver.ts +37 -29
- package/src/runs/background/run-status.ts +34 -20
- package/src/runs/background/scheduled-runs.ts +71 -27
- package/src/runs/background/stale-run-reconciler.ts +33 -16
- package/src/runs/background/steering.ts +11 -1
- package/src/runs/background/subagent-runner.ts +535 -161
- package/src/runs/background/subagent-wait.ts +9 -7
- package/src/runs/background/terminal-run-index.ts +129 -0
- package/src/runs/background/wait-completions.ts +22 -2
- package/src/runs/background/wait-subscriptions.ts +80 -1
- package/src/runs/foreground/async-dismiss-action.ts +2 -1
- package/src/runs/foreground/async-steering-action.ts +21 -14
- package/src/runs/foreground/execution.ts +221 -15
- package/src/runs/foreground/subagent-executor.ts +529 -1519
- package/src/runs/foreground/workflow-foreground-steering.ts +6 -5
- package/src/runs/shared/chain-outputs.ts +1 -3
- package/src/runs/shared/completion-guard.ts +96 -6
- package/src/runs/shared/external-cli-runner.ts +4 -0
- package/src/runs/shared/external-job-bridge.ts +450 -0
- package/src/runs/shared/external-job-runner.ts +286 -0
- package/src/runs/shared/mcp-direct-tool-allowlist.ts +14 -0
- package/src/runs/shared/model-fallback.ts +34 -3
- package/src/runs/shared/nested-events.ts +66 -62
- package/src/runs/shared/orca-progress-tabs.ts +437 -0
- package/src/runs/shared/parallel-handoff.ts +46 -4
- package/src/runs/shared/parallel-utils.ts +6 -15
- package/src/runs/shared/permissions.ts +5 -1
- package/src/runs/shared/pi-args.ts +8 -1
- package/src/runs/shared/subagent-control.ts +41 -4
- package/src/runs/shared/subagent-prompt-runtime.ts +13 -15
- package/src/runs/shared/subagent-startup-retry.ts +12 -0
- package/src/runs/shared/tool-timeout.ts +93 -0
- package/src/runs/shared/workflow-graph.ts +1 -23
- package/src/runs/shared/worktree.ts +12 -1
- package/src/shared/atomic-json.ts +22 -2
- package/src/shared/capacity-resilient-json.ts +102 -0
- package/src/shared/completion-owner.ts +14 -0
- package/src/shared/file-system-retry.ts +49 -1
- package/src/shared/fork-context.ts +42 -0
- package/src/shared/prompt-resources.ts +0 -40
- package/src/shared/settings.ts +3 -27
- package/src/shared/types.ts +88 -27
- package/src/shared/utils.ts +8 -0
- package/src/shared/watch-strategy.ts +10 -0
- package/src/slash/slash-commands.ts +45 -28
- package/src/slash/slash-live-state.ts +3 -0
- package/src/tui/fleet-status.ts +160 -45
- package/src/tui/fleet.ts +186 -28
- package/src/tui/render.ts +41 -10
- package/src/workflows/chat-progress.ts +7 -5
- package/src/workflows/scripted-workflow.ts +424 -125
- package/src/runs/foreground/chain-clarify.ts +0 -1354
- package/src/runs/foreground/chain-execution.ts +0 -1565
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
import * as fs from "node:fs";
|
|
2
1
|
import * as path from "node:path";
|
|
3
2
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { parseFrontmatter } from "../agents/frontmatter.ts";
|
|
5
3
|
import { getAgentDir, getProjectConfigDir } from "./utils.ts";
|
|
6
4
|
|
|
7
|
-
const PROMPT_REF_PATTERN = /^(package|user|project):([A-Za-z0-9][A-Za-z0-9._-]{0,127})$/;
|
|
8
|
-
const PROMPT_VARIABLE_PATTERN = /\{\{(\w+)\}\}/g;
|
|
9
|
-
|
|
10
|
-
type PromptVariable = string | number | boolean;
|
|
11
|
-
|
|
12
5
|
export function getPromptDirectories(cwd: string) {
|
|
13
6
|
return {
|
|
14
7
|
package: path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "prompts"),
|
|
@@ -16,36 +9,3 @@ export function getPromptDirectories(cwd: string) {
|
|
|
16
9
|
project: path.join(getProjectConfigDir(cwd), "prompts"),
|
|
17
10
|
};
|
|
18
11
|
}
|
|
19
|
-
|
|
20
|
-
function promptVariables(vars: unknown): Record<string, PromptVariable> {
|
|
21
|
-
if (vars === undefined) return {};
|
|
22
|
-
if (!vars || typeof vars !== "object" || Array.isArray(vars)) throw new Error("prompts.render vars must be a plain object.");
|
|
23
|
-
const prototype = Object.getPrototypeOf(vars);
|
|
24
|
-
if (prototype !== null && prototype !== Object.prototype) throw new Error("prompts.render vars must be a plain object.");
|
|
25
|
-
for (const [name, value] of Object.entries(vars)) {
|
|
26
|
-
if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
|
|
27
|
-
throw new Error(`prompts.render variable '${name}' must be a string, number, or boolean.`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return vars as Record<string, PromptVariable>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function renderWorkflowPrompt(ref: string, vars: unknown, cwd: string): string {
|
|
34
|
-
const match = ref.match(PROMPT_REF_PATTERN);
|
|
35
|
-
if (!match) throw new Error("prompts.render ref must use package:<name>, user:<name>, or project:<name>.");
|
|
36
|
-
const scope = match[1] as keyof ReturnType<typeof getPromptDirectories>;
|
|
37
|
-
const name = match[2]!;
|
|
38
|
-
const filePath = path.join(getPromptDirectories(cwd)[scope], `${name}.md`);
|
|
39
|
-
let content: string;
|
|
40
|
-
try {
|
|
41
|
-
if (!fs.lstatSync(filePath).isFile()) throw new Error("not a regular file");
|
|
42
|
-
content = fs.readFileSync(filePath, "utf-8");
|
|
43
|
-
} catch (error) {
|
|
44
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
45
|
-
throw new Error(`Could not read prompt fragment '${ref}': ${detail}`);
|
|
46
|
-
}
|
|
47
|
-
const variables = promptVariables(vars);
|
|
48
|
-
return parseFrontmatter(content).body.trim().replace(PROMPT_VARIABLE_PATTERN, (placeholder, variable: string) => {
|
|
49
|
-
return Object.hasOwn(variables, variable) ? String(variables[variable]) : placeholder;
|
|
50
|
-
});
|
|
51
|
-
}
|
package/src/shared/settings.ts
CHANGED
|
@@ -64,6 +64,8 @@ export interface SequentialStep {
|
|
|
64
64
|
acceptance?: AcceptanceInput;
|
|
65
65
|
agentContract?: AgentContract;
|
|
66
66
|
gateOn?: ChainGateLayer;
|
|
67
|
+
/** Internal workflow child isolation; public workflowScript supplies this on runs.run. */
|
|
68
|
+
worktree?: boolean;
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
/** Parallel task item within a parallel step */
|
|
@@ -119,24 +121,6 @@ export interface DynamicParallelStep {
|
|
|
119
121
|
gateOn?: ChainGateLayer;
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
/** Approval checkpoint: pause before later chain steps until parent approval. */
|
|
123
|
-
export interface CheckpointStep {
|
|
124
|
-
checkpoint: string;
|
|
125
|
-
message?: string;
|
|
126
|
-
phase?: string;
|
|
127
|
-
label?: string;
|
|
128
|
-
agent?: string;
|
|
129
|
-
task?: string;
|
|
130
|
-
as?: string;
|
|
131
|
-
output?: OutputOverrideInput;
|
|
132
|
-
outputMode?: OutputMode;
|
|
133
|
-
reads?: string[] | false;
|
|
134
|
-
progress?: boolean;
|
|
135
|
-
skill?: string | string[] | false;
|
|
136
|
-
skills?: string[] | false;
|
|
137
|
-
model?: string;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
124
|
/** Parallel step: multiple agents running concurrently */
|
|
141
125
|
export interface ParallelStep {
|
|
142
126
|
parallel: ParallelTaskItem[];
|
|
@@ -149,16 +133,12 @@ export interface ParallelStep {
|
|
|
149
133
|
}
|
|
150
134
|
|
|
151
135
|
/** Union type for chain steps */
|
|
152
|
-
export type ChainStep = SequentialStep | ParallelStep | DynamicParallelStep
|
|
136
|
+
export type ChainStep = SequentialStep | ParallelStep | DynamicParallelStep;
|
|
153
137
|
|
|
154
138
|
// =============================================================================
|
|
155
139
|
// Type Guards
|
|
156
140
|
// =============================================================================
|
|
157
141
|
|
|
158
|
-
export function isCheckpointStep(step: ChainStep): step is CheckpointStep {
|
|
159
|
-
return "checkpoint" in step;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
142
|
export function isParallelStep(step: ChainStep): step is ParallelStep {
|
|
163
143
|
return "parallel" in step && Array.isArray((step as ParallelStep).parallel);
|
|
164
144
|
}
|
|
@@ -169,9 +149,6 @@ export function isDynamicParallelStep(step: ChainStep): step is DynamicParallelS
|
|
|
169
149
|
|
|
170
150
|
/** Get all agent names in a step (single for sequential, multiple for parallel) */
|
|
171
151
|
export function getStepAgents(step: ChainStep): string[] {
|
|
172
|
-
if (isCheckpointStep(step)) {
|
|
173
|
-
return [];
|
|
174
|
-
}
|
|
175
152
|
if (isParallelStep(step)) {
|
|
176
153
|
return step.parallel.map((t) => t.agent);
|
|
177
154
|
}
|
|
@@ -239,7 +216,6 @@ export function resolveChainTemplates(
|
|
|
239
216
|
steps: ChainStep[],
|
|
240
217
|
): ResolvedTemplates {
|
|
241
218
|
return steps.map((step, i) => {
|
|
242
|
-
if (isCheckpointStep(step)) return "";
|
|
243
219
|
if (isParallelStep(step)) {
|
|
244
220
|
// Parallel step: resolve each task's template
|
|
245
221
|
return step.parallel.map((task) => {
|
package/src/shared/types.ts
CHANGED
|
@@ -41,7 +41,7 @@ export type WorkflowNodeStatus = "pending" | "running" | "completed" | "failed"
|
|
|
41
41
|
|
|
42
42
|
export interface WorkflowGraphNode {
|
|
43
43
|
id: string;
|
|
44
|
-
kind: "step" | "parallel-group" | "dynamic-parallel-group" | "agent"
|
|
44
|
+
kind: "step" | "parallel-group" | "dynamic-parallel-group" | "agent";
|
|
45
45
|
agent?: string;
|
|
46
46
|
phase?: string;
|
|
47
47
|
label: string;
|
|
@@ -61,16 +61,6 @@ export interface WorkflowGraphNode {
|
|
|
61
61
|
structured?: boolean;
|
|
62
62
|
acceptanceStatus?: AcceptanceLedgerStatus;
|
|
63
63
|
error?: string;
|
|
64
|
-
checkpoint?: ChainCheckpointState;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface ChainCheckpointState {
|
|
68
|
-
name: string;
|
|
69
|
-
message?: string;
|
|
70
|
-
status: "pending" | "approved" | "rejected";
|
|
71
|
-
stepIndex: number;
|
|
72
|
-
approvedAt?: number;
|
|
73
|
-
rejectedAt?: number;
|
|
74
64
|
}
|
|
75
65
|
|
|
76
66
|
export interface WorkflowGraphSnapshot {
|
|
@@ -215,7 +205,7 @@ export interface ControlEvent {
|
|
|
215
205
|
nestedRunId?: string;
|
|
216
206
|
nestingPath?: NestedRunAddress["path"];
|
|
217
207
|
message: string;
|
|
218
|
-
reason?: "idle" | "completion_guard" | "active_long_running" | "tool_failures" | "supervisor_request" | "time_threshold" | "turn_threshold" | "token_threshold";
|
|
208
|
+
reason?: "idle" | "completion_guard" | "active_long_running" | "tool_failures" | "supervisor_request" | "time_threshold" | "turn_threshold" | "token_threshold" | "tool_open_threshold";
|
|
219
209
|
turns?: number;
|
|
220
210
|
tokens?: number;
|
|
221
211
|
toolCount?: number;
|
|
@@ -224,6 +214,10 @@ export interface ControlEvent {
|
|
|
224
214
|
currentPath?: string;
|
|
225
215
|
elapsedMs?: number;
|
|
226
216
|
recentFailureSummary?: string;
|
|
217
|
+
workflowKey?: string;
|
|
218
|
+
phase?: string;
|
|
219
|
+
label?: string;
|
|
220
|
+
taskPreview?: string;
|
|
227
221
|
}
|
|
228
222
|
|
|
229
223
|
export type SubagentResultStatus = "completed" | "failed" | "paused" | "stopped" | "detached";
|
|
@@ -282,7 +276,7 @@ export interface ParallelHandoffGroup {
|
|
|
282
276
|
export interface ParallelHandoffManifest {
|
|
283
277
|
version: 1;
|
|
284
278
|
runId: string;
|
|
285
|
-
mode: "parallel" | "chain";
|
|
279
|
+
mode: "single" | "parallel" | "chain";
|
|
286
280
|
source: "foreground" | "async";
|
|
287
281
|
cwd: string;
|
|
288
282
|
createdAt: number;
|
|
@@ -1031,6 +1025,7 @@ export interface Details {
|
|
|
1031
1025
|
controlEvents?: ControlEvent[];
|
|
1032
1026
|
steering?: SteerActionResult;
|
|
1033
1027
|
asyncId?: string;
|
|
1028
|
+
background?: boolean;
|
|
1034
1029
|
asyncDir?: string;
|
|
1035
1030
|
timeoutMs?: number;
|
|
1036
1031
|
deadlineAt?: number;
|
|
@@ -1056,7 +1051,6 @@ export interface Details {
|
|
|
1056
1051
|
totalSteps?: number; // Total steps in chain
|
|
1057
1052
|
currentStepIndex?: number; // 0-indexed current step (for running chains)
|
|
1058
1053
|
workflowGraph?: WorkflowGraphSnapshot;
|
|
1059
|
-
checkpoint?: ChainCheckpointState;
|
|
1060
1054
|
outputs?: ChainOutputMap;
|
|
1061
1055
|
// Aggregated child usage across all agents in the run
|
|
1062
1056
|
totalChildUsage?: Usage;
|
|
@@ -1086,9 +1080,9 @@ export interface Details {
|
|
|
1086
1080
|
workflow?: {
|
|
1087
1081
|
value?: unknown;
|
|
1088
1082
|
trace: Array<{
|
|
1089
|
-
operation: "run" | "status";
|
|
1083
|
+
operation: "run" | "status" | "steer";
|
|
1090
1084
|
key: string;
|
|
1091
|
-
state: "started" | "completed" | "failed" | "stopped" | "reused";
|
|
1085
|
+
state: "started" | "completed" | "failed" | "detached" | "stopped" | "reused" | "queued" | "delivered" | "missed";
|
|
1092
1086
|
agent?: string;
|
|
1093
1087
|
runId?: string;
|
|
1094
1088
|
phase?: string;
|
|
@@ -1265,6 +1259,7 @@ export interface AsyncStartedEvent {
|
|
|
1265
1259
|
sessionRoot?: string;
|
|
1266
1260
|
pid?: number;
|
|
1267
1261
|
sessionId?: string;
|
|
1262
|
+
completionOwnerId?: string;
|
|
1268
1263
|
mode?: SubagentRunMode;
|
|
1269
1264
|
agent?: string;
|
|
1270
1265
|
agents?: string[];
|
|
@@ -1276,7 +1271,6 @@ export interface AsyncStartedEvent {
|
|
|
1276
1271
|
chainStepCount?: number;
|
|
1277
1272
|
parallelGroups?: AsyncParallelGroupStatus[];
|
|
1278
1273
|
workflowGraph?: WorkflowGraphSnapshot;
|
|
1279
|
-
checkpoint?: ChainCheckpointState;
|
|
1280
1274
|
launchContractDigest?: string;
|
|
1281
1275
|
launchResolvedExtensions?: LaunchResolvedChildExtensionsV1;
|
|
1282
1276
|
runtimeAcknowledgedExtensions?: RuntimeAcknowledgedChildExtensionsV1;
|
|
@@ -1297,6 +1291,11 @@ export type AgentRunnerConfig =
|
|
|
1297
1291
|
command: string;
|
|
1298
1292
|
args?: string[];
|
|
1299
1293
|
promptDelivery?: "stdin";
|
|
1294
|
+
}
|
|
1295
|
+
| {
|
|
1296
|
+
type: "external-job";
|
|
1297
|
+
provider: string;
|
|
1298
|
+
options?: Record<string, unknown>;
|
|
1300
1299
|
};
|
|
1301
1300
|
|
|
1302
1301
|
export interface ExternalCliRunnerStatus {
|
|
@@ -1313,6 +1312,35 @@ export interface ExternalCliRunnerStatus {
|
|
|
1313
1312
|
};
|
|
1314
1313
|
}
|
|
1315
1314
|
|
|
1315
|
+
export interface ExternalJobRunnerStatus {
|
|
1316
|
+
type: "external-job";
|
|
1317
|
+
provider: string;
|
|
1318
|
+
options: Record<string, unknown>;
|
|
1319
|
+
capabilities: {
|
|
1320
|
+
stop: false;
|
|
1321
|
+
steer: false;
|
|
1322
|
+
resume: false;
|
|
1323
|
+
structuredOutput: false;
|
|
1324
|
+
toolEvents: false;
|
|
1325
|
+
};
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
export interface ExternalJobStatus {
|
|
1329
|
+
provider: string;
|
|
1330
|
+
providerJobId?: string;
|
|
1331
|
+
promptDigest: string;
|
|
1332
|
+
options: Record<string, unknown>;
|
|
1333
|
+
handleUrl?: string;
|
|
1334
|
+
conversationUrl?: string;
|
|
1335
|
+
resultArtifactPath?: string;
|
|
1336
|
+
state: "queued" | "running" | "completed" | "failed" | "stopped" | "blocked";
|
|
1337
|
+
failureCode?: string;
|
|
1338
|
+
failureMessage?: string;
|
|
1339
|
+
blockingJobId?: string;
|
|
1340
|
+
startedAt?: number;
|
|
1341
|
+
updatedAt?: number;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1316
1344
|
export interface ExternalProcessStatus {
|
|
1317
1345
|
pid?: number;
|
|
1318
1346
|
startedAt: number;
|
|
@@ -1327,6 +1355,8 @@ export interface ExternalProcessStatus {
|
|
|
1327
1355
|
export interface AsyncStatus {
|
|
1328
1356
|
lifecycleArtifactVersion?: SubagentLifecycleArtifactVersion;
|
|
1329
1357
|
runId: string;
|
|
1358
|
+
/** Parent Pi process/window that owns local completion delivery. */
|
|
1359
|
+
completionOwnerId?: string;
|
|
1330
1360
|
/** Host tool-call id retained when it differs from the internal run id. */
|
|
1331
1361
|
toolCallId?: string;
|
|
1332
1362
|
sessionId?: string;
|
|
@@ -1360,12 +1390,13 @@ export interface AsyncStatus {
|
|
|
1360
1390
|
usageBudget?: UsageBudgetState;
|
|
1361
1391
|
pid?: number;
|
|
1362
1392
|
cwd?: string;
|
|
1393
|
+
/** Parent-resolved child session root retained for trusted restored transcript lookup. */
|
|
1394
|
+
sessionRoot?: string;
|
|
1363
1395
|
currentStep?: number;
|
|
1364
1396
|
chainStepCount?: number;
|
|
1365
1397
|
pendingAppends?: number;
|
|
1366
1398
|
parallelGroups?: AsyncParallelGroupStatus[];
|
|
1367
1399
|
workflowGraph?: WorkflowGraphSnapshot;
|
|
1368
|
-
checkpoint?: ChainCheckpointState;
|
|
1369
1400
|
processTerminal?: ProcessTerminalV1;
|
|
1370
1401
|
runFanoutBudget?: RunFanoutBudgetSnapshot;
|
|
1371
1402
|
runFanoutBudgetDescriptor?: RunFanoutBudgetDescriptor;
|
|
@@ -1379,8 +1410,9 @@ export interface AsyncStatus {
|
|
|
1379
1410
|
workflowKey?: string;
|
|
1380
1411
|
steps?: Array<{
|
|
1381
1412
|
agent: string;
|
|
1382
|
-
runner?: ExternalCliRunnerStatus;
|
|
1413
|
+
runner?: ExternalCliRunnerStatus | ExternalJobRunnerStatus;
|
|
1383
1414
|
externalProcess?: ExternalProcessStatus;
|
|
1415
|
+
externalJob?: ExternalJobStatus;
|
|
1384
1416
|
/** Resolved launch context for this child step. */
|
|
1385
1417
|
context?: "fresh" | "fork";
|
|
1386
1418
|
/** Short caller-facing task/goal shown in fleet surfaces when available. */
|
|
@@ -1395,7 +1427,6 @@ export interface AsyncStatus {
|
|
|
1395
1427
|
parentWorkflowRunId?: string;
|
|
1396
1428
|
outputName?: string;
|
|
1397
1429
|
structured?: boolean;
|
|
1398
|
-
checkpoint?: ChainCheckpointState;
|
|
1399
1430
|
status: "pending" | "running" | "complete" | "completed" | "failed" | "paused" | "stopped" | "rejected";
|
|
1400
1431
|
children?: NestedRunSummary[];
|
|
1401
1432
|
sessionFile?: string;
|
|
@@ -1464,6 +1495,8 @@ export type AsyncJobStep = NonNullable<AsyncStatus["steps"]>[number] & {
|
|
|
1464
1495
|
export interface AsyncJobState {
|
|
1465
1496
|
asyncId: string;
|
|
1466
1497
|
asyncDir: string;
|
|
1498
|
+
/** Host tool-call id retained when it differs from the internal run id. */
|
|
1499
|
+
toolCallId?: string;
|
|
1467
1500
|
/** Parent-resolved launch directory retained for trusted live artifact lookup. */
|
|
1468
1501
|
cwd?: string;
|
|
1469
1502
|
/** Parent-resolved child session root retained for trusted live transcript lookup. */
|
|
@@ -1473,6 +1506,7 @@ export interface AsyncJobState {
|
|
|
1473
1506
|
description?: string;
|
|
1474
1507
|
pid?: number;
|
|
1475
1508
|
sessionId?: string;
|
|
1509
|
+
completionOwnerId?: string;
|
|
1476
1510
|
activityState?: ActivityState;
|
|
1477
1511
|
lastActivityAt?: number;
|
|
1478
1512
|
currentTool?: string;
|
|
@@ -1489,7 +1523,6 @@ export interface AsyncJobState {
|
|
|
1489
1523
|
chainStepCount?: number;
|
|
1490
1524
|
parallelGroups?: AsyncParallelGroupStatus[];
|
|
1491
1525
|
steps?: AsyncJobStep[];
|
|
1492
|
-
checkpoint?: ChainCheckpointState;
|
|
1493
1526
|
stepsTotal?: number;
|
|
1494
1527
|
runningSteps?: number;
|
|
1495
1528
|
completedSteps?: number;
|
|
@@ -1567,7 +1600,6 @@ export interface ForegroundResumeRun {
|
|
|
1567
1600
|
/** Originating parent session. Detached exits can outlive the active session. */
|
|
1568
1601
|
sessionId?: string;
|
|
1569
1602
|
updatedAt: number;
|
|
1570
|
-
checkpoint?: ChainCheckpointState;
|
|
1571
1603
|
children: ForegroundResumeChild[];
|
|
1572
1604
|
}
|
|
1573
1605
|
|
|
@@ -1660,6 +1692,8 @@ export interface ActiveAsyncCapacitySnapshot {
|
|
|
1660
1692
|
export interface SubagentState {
|
|
1661
1693
|
baseCwd: string;
|
|
1662
1694
|
currentSessionId: string | null;
|
|
1695
|
+
/** Reload-stable identity for this parent Pi process/window. */
|
|
1696
|
+
completionOwnerId?: string;
|
|
1663
1697
|
/** Runtime-owned artifact resolution inputs used by Fleet transcript targeting. */
|
|
1664
1698
|
artifactDirPreference?: ArtifactDirPreference;
|
|
1665
1699
|
/** Runtime authority snapshot used by optional inspector controls. */
|
|
@@ -1767,6 +1801,10 @@ export interface RunSyncOptions {
|
|
|
1767
1801
|
interruptSignal?: AbortSignal;
|
|
1768
1802
|
timeoutMs?: number;
|
|
1769
1803
|
deadlineAt?: number;
|
|
1804
|
+
/** Per-call per-tool timeout (ms), resolved with the agent/config/environment ladder at execution. */
|
|
1805
|
+
toolTimeoutMs?: number;
|
|
1806
|
+
/** Raw global config.toolTimeoutMs, used by the per-child resolver. */
|
|
1807
|
+
configToolTimeoutMs?: number;
|
|
1770
1808
|
turnBudget?: ResolvedTurnBudget;
|
|
1771
1809
|
usageBudget?: UsageBudgetConfig;
|
|
1772
1810
|
/** Enforce maxTurns + graceTurns as a hard model-turn boundary. */
|
|
@@ -1831,6 +1869,8 @@ export interface RunSyncOptions {
|
|
|
1831
1869
|
};
|
|
1832
1870
|
/** Private live callback for the exact child prompt after runtime acceptance injection. */
|
|
1833
1871
|
onEffectivePrompt?: (prompt: string) => void;
|
|
1872
|
+
/** Internal lifecycle hook for the observer shared across retries of one logical child. */
|
|
1873
|
+
onOrcaProgressTabCreated?: (tab: import("../runs/shared/orca-progress-tabs.ts").OrcaProgressTab) => void;
|
|
1834
1874
|
}
|
|
1835
1875
|
|
|
1836
1876
|
export type IntercomBridgeMode = "off" | "fork-only" | "always";
|
|
@@ -1892,6 +1932,11 @@ export const FLEET_KEYBINDING_ACTIONS = [
|
|
|
1892
1932
|
export type FleetKeybindingAction = typeof FLEET_KEYBINDING_ACTIONS[number];
|
|
1893
1933
|
export type FleetKeybindingsConfig = Partial<Record<FleetKeybindingAction, string[]>>;
|
|
1894
1934
|
|
|
1935
|
+
export interface OrcaProgressTabsConfig {
|
|
1936
|
+
/** Create one Orca terminal tab per running subagent. Experimental and opt-in. */
|
|
1937
|
+
enabled?: boolean;
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1895
1940
|
export interface MainWindowRendererConfig {
|
|
1896
1941
|
/** Unit of horizontal space in main chat subagent call/result rows. Omit to preserve current spacing. Set 0 for no extra padding. */
|
|
1897
1942
|
horizontalSpacing?: number;
|
|
@@ -1901,6 +1946,10 @@ export interface MainWindowRendererConfig {
|
|
|
1901
1946
|
|
|
1902
1947
|
export interface ExtensionConfig {
|
|
1903
1948
|
asyncByDefault?: boolean;
|
|
1949
|
+
/** Set the context for launches that omit an explicit context. */
|
|
1950
|
+
defaultSubagentContext?: "fresh" | "fork";
|
|
1951
|
+
/** Optional shortcut that detaches the active foreground single-subagent run. */
|
|
1952
|
+
foregroundDetachShortcut?: string;
|
|
1904
1953
|
/** Show the Claude Code-style navigable fleet. Defaults to true. */
|
|
1905
1954
|
fleetView?: boolean;
|
|
1906
1955
|
/** Place the persistent FleetView above or below the editor. Defaults to belowEditor. */
|
|
@@ -1909,14 +1958,14 @@ export interface ExtensionConfig {
|
|
|
1909
1958
|
fleetKeybindings?: FleetKeybindingsConfig;
|
|
1910
1959
|
/** Show the under-editor async runs widget. Defaults to true, including when FleetView is enabled. */
|
|
1911
1960
|
asyncWidget?: boolean;
|
|
1912
|
-
/** Tool description variant registered for the parent-facing subagent tool. Defaults to
|
|
1961
|
+
/** Tool description variant registered for the parent-facing subagent tool. Defaults to split metadata. */
|
|
1913
1962
|
toolDescriptionMode?: ToolDescriptionMode;
|
|
1914
|
-
/** Include legacy append-step and checkpoint controls in the registered tool schema. Defaults to false. */
|
|
1915
|
-
legacyChainControls?: boolean;
|
|
1916
1963
|
/** Inline chat rendering for the subagent tool. Defaults to rich. */
|
|
1917
1964
|
inlineToolDisplay?: InlineToolDisplay;
|
|
1918
1965
|
/** Density controls for the main chat subagent call/result renderer. */
|
|
1919
1966
|
mainWindowRenderer?: MainWindowRendererConfig;
|
|
1967
|
+
/** Experimental observer: mirror each native subagent's progress into a new Orca tab. */
|
|
1968
|
+
orcaProgressTabs?: OrcaProgressTabsConfig;
|
|
1920
1969
|
forceTopLevelAsync?: boolean;
|
|
1921
1970
|
waitTool?: WaitToolConfig;
|
|
1922
1971
|
defaultSessionDir?: string;
|
|
@@ -1940,6 +1989,15 @@ export interface ExtensionConfig {
|
|
|
1940
1989
|
* Must be a positive integer; invalid values are ignored.
|
|
1941
1990
|
*/
|
|
1942
1991
|
timeoutMs?: number;
|
|
1992
|
+
/**
|
|
1993
|
+
* Optional hard per-tool-call timeout in milliseconds. Bounds a single
|
|
1994
|
+
* subagent tool call inside the child; the run-level timeout remains
|
|
1995
|
+
* authoritative. Known-fast built-in tools have a five-minute default when
|
|
1996
|
+
* this is undefined. Precedence: call param > agent frontmatter > this config >
|
|
1997
|
+
* PI_SUBAGENT_TOOL_TIMEOUT_MS. Must be a positive integer; invalid values
|
|
1998
|
+
* are rejected with an error.
|
|
1999
|
+
*/
|
|
2000
|
+
toolTimeoutMs?: number;
|
|
1943
2001
|
control?: ControlConfig;
|
|
1944
2002
|
completionBatch?: CompletionBatchConfig;
|
|
1945
2003
|
turnBudget?: TurnBudgetConfig;
|
|
@@ -2040,7 +2098,10 @@ export function resolveTempScopeId(options?: {
|
|
|
2040
2098
|
|
|
2041
2099
|
const MAX_PARALLEL = 8;
|
|
2042
2100
|
export const MAX_CONCURRENCY = 4;
|
|
2043
|
-
|
|
2101
|
+
const configuredTempRoot = process.env.PI_SUBAGENTS_TEMP_ROOT?.trim();
|
|
2102
|
+
export const TEMP_ROOT_DIR = configuredTempRoot
|
|
2103
|
+
? path.resolve(configuredTempRoot)
|
|
2104
|
+
: path.join(os.tmpdir(), `pi-subagents-${resolveTempScopeId()}`);
|
|
2044
2105
|
export const RESULTS_DIR = path.join(TEMP_ROOT_DIR, "async-subagent-results");
|
|
2045
2106
|
export const ASYNC_DIR = path.join(TEMP_ROOT_DIR, "async-subagent-runs");
|
|
2046
2107
|
export const CHAIN_RUNS_DIR = path.join(TEMP_ROOT_DIR, "chain-runs");
|
|
@@ -2063,7 +2124,7 @@ export const SLASH_SUBAGENT_CANCEL_EVENT = "subagent:slash:cancel";
|
|
|
2063
2124
|
export const POLL_INTERVAL_MS = 250;
|
|
2064
2125
|
export const MAX_WIDGET_JOBS = 4;
|
|
2065
2126
|
export const DEFAULT_SUBAGENT_MAX_DEPTH = 2;
|
|
2066
|
-
export const SUBAGENT_ACTIONS = ["list", "get", "models", "children.list", "guide", "create", "update", "delete", "eject", "disable", "enable", "reset", "mission.create", "mission.list", "mission.show", "mission.update", "mission.resolve-decision", "mission.attach-run", "mission.close", "worktree.discard", "refine", "refine.show", "refine.rollback", "inspector.open", "inspector.status", "inspector.close", "project.open", "project.status", "project.close", "status", "debug.run", "grant-spawn-budget", "interrupt", "resume", "steer", "stop", "dismiss", "
|
|
2127
|
+
export const SUBAGENT_ACTIONS = ["list", "get", "models", "children.list", "guide", "create", "update", "delete", "eject", "disable", "enable", "reset", "mission.create", "mission.list", "mission.show", "mission.update", "mission.resolve-decision", "mission.attach-run", "mission.close", "worktree.discard", "refine", "refine.show", "refine.rollback", "inspector.open", "inspector.status", "inspector.close", "project.open", "project.status", "project.close", "status", "debug.run", "grant-spawn-budget", "interrupt", "resume", "steer", "stop", "dismiss", "doctor", "watchdog.status", "watchdog.check", "watchdog.configure", "watchdog.recommend-model", "schedule.create", "schedule.list", "schedule.show", "schedule.history", "schedule.pause", "schedule.resume", "schedule.run", "schedule.run-due", "schedule.delete"] as const;
|
|
2067
2128
|
|
|
2068
2129
|
export const DEFAULT_FORK_PREAMBLE =
|
|
2069
2130
|
"You are a delegated subagent running from a fork of the parent session. " +
|
package/src/shared/utils.ts
CHANGED
|
@@ -102,6 +102,7 @@ export function getAgentDir(): string {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
const statusCache = new Map<string, { mtime: number; ctime: number; size: number; ino: number; status: AsyncStatus }>();
|
|
105
|
+
const MAX_STATUS_CACHE_ENTRIES = 512;
|
|
105
106
|
|
|
106
107
|
export function pruneStatusCacheForAsyncRoot(asyncDirRoot: string, runIds: Iterable<string>): number {
|
|
107
108
|
const root = path.resolve(asyncDirRoot);
|
|
@@ -163,6 +164,8 @@ export function readStatus(asyncDir: string): AsyncStatus | null {
|
|
|
163
164
|
&& cached.size === stat.size
|
|
164
165
|
&& cached.ino === stat.ino
|
|
165
166
|
) {
|
|
167
|
+
statusCache.delete(statusPath);
|
|
168
|
+
statusCache.set(statusPath, cached);
|
|
166
169
|
return cached.status;
|
|
167
170
|
}
|
|
168
171
|
|
|
@@ -195,6 +198,11 @@ export function readStatus(asyncDir: string): AsyncStatus | null {
|
|
|
195
198
|
ino: stat.ino,
|
|
196
199
|
status,
|
|
197
200
|
});
|
|
201
|
+
while (statusCache.size > MAX_STATUS_CACHE_ENTRIES) {
|
|
202
|
+
const oldest = statusCache.keys().next().value as string | undefined;
|
|
203
|
+
if (oldest === undefined) break;
|
|
204
|
+
statusCache.delete(oldest);
|
|
205
|
+
}
|
|
198
206
|
return status;
|
|
199
207
|
}
|
|
200
208
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type FileWatchPurpose =
|
|
2
|
+
| "result-delivery"
|
|
3
|
+
| "supervisor-channel"
|
|
4
|
+
| "async-job-tracker"
|
|
5
|
+
| "runner-control-inbox"
|
|
6
|
+
| "child-steering-inbox";
|
|
7
|
+
|
|
8
|
+
export function shouldUseNativeFsWatch(_purpose: FileWatchPurpose, platform: NodeJS.Platform = process.platform): boolean {
|
|
9
|
+
return platform !== "darwin";
|
|
10
|
+
}
|
|
@@ -2,8 +2,8 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { keyText, type ExtensionAPI, type ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
5
|
-
import { Key, matchesKey, truncateToWidth, type Component, type TUI } from "@earendil-works/pi-tui";
|
|
6
|
-
import { BUILTIN_AGENT_NAMES, discoverAgents } from "../agents/agents.ts";
|
|
5
|
+
import { Key, matchesKey, truncateToWidth, type Component, type KeyId, type TUI } from "@earendil-works/pi-tui";
|
|
6
|
+
import { BUILTIN_AGENT_NAMES, discoverAgents, findBlockingAgentDiagnostic, resolveAgentName } from "../agents/agents.ts";
|
|
7
7
|
import { resolveExistingReadPaths } from "../shared/settings.ts";
|
|
8
8
|
import {
|
|
9
9
|
DEFAULT_PROVIDER_MODELS_MAX_AGE_DAYS,
|
|
@@ -631,7 +631,7 @@ function slashRunWorkflowScript(key: string, child: Record<string, unknown>): st
|
|
|
631
631
|
export function registerSlashCommands(
|
|
632
632
|
pi: ExtensionAPI,
|
|
633
633
|
state: SubagentState,
|
|
634
|
-
options: { fleetKeybindings?: FleetKeybindingsConfig } = {},
|
|
634
|
+
options: { fleetKeybindings?: FleetKeybindingsConfig; foregroundDetachShortcut?: string } = {},
|
|
635
635
|
): void {
|
|
636
636
|
let fleetOpen = false;
|
|
637
637
|
const showFleet = async (ctx: ExtensionContext) => {
|
|
@@ -671,8 +671,16 @@ export function registerSlashCommands(
|
|
|
671
671
|
const task = firstSpace === -1 ? "" : input.slice(firstSpace + 1).trim();
|
|
672
672
|
|
|
673
673
|
if (!state.baseCwd) { ctx.ui.notify("Subagent session cwd is not initialized yet", "error"); return; }
|
|
674
|
-
const
|
|
675
|
-
|
|
674
|
+
const discovered = discoverAgents(state.baseCwd, "both");
|
|
675
|
+
const resolvedAgent = resolveAgentName(agentName, discovered.agents);
|
|
676
|
+
const candidates = resolvedAgent.error
|
|
677
|
+
? discovered.agents.filter((agent) => resolveAgentName(agentName, [agent]).agent)
|
|
678
|
+
: resolvedAgent.agent;
|
|
679
|
+
const diagnostic = findBlockingAgentDiagnostic(agentName, candidates, discovered.agentDiagnostics);
|
|
680
|
+
if (diagnostic || resolvedAgent.error || !resolvedAgent.agent) {
|
|
681
|
+
ctx.ui.notify(diagnostic ? `Agent '${agentName}' has invalid configuration: ${diagnostic.error}` : resolvedAgent.error ?? `Unknown agent: ${agentName}`, "error");
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
676
684
|
|
|
677
685
|
let finalTask = task;
|
|
678
686
|
if (inline.reads && Array.isArray(inline.reads) && inline.reads.length > 0) {
|
|
@@ -741,33 +749,42 @@ export function registerSlashCommands(
|
|
|
741
749
|
handler: async (ctx) => showFleet(ctx),
|
|
742
750
|
});
|
|
743
751
|
|
|
752
|
+
const detachForegroundRun = (args: string, ctx: ExtensionContext): void => {
|
|
753
|
+
const id = args.trim();
|
|
754
|
+
let control: ReturnType<typeof selectForegroundDetachControl>;
|
|
755
|
+
try {
|
|
756
|
+
control = selectForegroundDetachControl(state, id);
|
|
757
|
+
} catch (error) {
|
|
758
|
+
ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
if (!control) {
|
|
762
|
+
ctx.ui.notify(id ? `No active foreground run found for '${id}'.` : "No active foreground single-subagent run to detach.", "info");
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
if (control.mode !== "single") {
|
|
766
|
+
ctx.ui.notify("/subagents-detach currently supports single-subagent runs only.", "error");
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
if (!control.detach?.()) {
|
|
770
|
+
ctx.ui.notify(`Foreground run ${control.runId} is not currently detachable.`, "info");
|
|
771
|
+
return;
|
|
772
|
+
}
|
|
773
|
+
sendSlashText(pi, `Detached foreground run ${control.runId} without terminating its child. Use subagent({ action: "status", id: ${JSON.stringify(control.runId)} }) or subagent_wait({ id: ${JSON.stringify(control.runId)} }) to recover the eventual result. This does not daemonize the process or guarantee survival across Pi reload/restart.`);
|
|
774
|
+
};
|
|
775
|
+
|
|
744
776
|
pi.registerCommand("subagents-detach", {
|
|
745
777
|
description: "Detach the active foreground single-subagent run without terminating it",
|
|
746
|
-
handler: async (args, ctx) =>
|
|
747
|
-
const id = args.trim();
|
|
748
|
-
let control: ReturnType<typeof selectForegroundDetachControl>;
|
|
749
|
-
try {
|
|
750
|
-
control = selectForegroundDetachControl(state, id);
|
|
751
|
-
} catch (error) {
|
|
752
|
-
ctx.ui.notify(error instanceof Error ? error.message : String(error), "error");
|
|
753
|
-
return;
|
|
754
|
-
}
|
|
755
|
-
if (!control) {
|
|
756
|
-
ctx.ui.notify(id ? `No active foreground run found for '${id}'.` : "No active foreground single-subagent run to detach.", "info");
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
if (control.mode !== "single") {
|
|
760
|
-
ctx.ui.notify("/subagents-detach currently supports single-subagent runs only.", "error");
|
|
761
|
-
return;
|
|
762
|
-
}
|
|
763
|
-
if (!control.detach?.()) {
|
|
764
|
-
ctx.ui.notify(`Foreground run ${control.runId} is not currently detachable.`, "info");
|
|
765
|
-
return;
|
|
766
|
-
}
|
|
767
|
-
sendSlashText(pi, `Detached foreground run ${control.runId} without terminating its child. Use subagent({ action: "status", id: ${JSON.stringify(control.runId)} }) or subagent_wait({ id: ${JSON.stringify(control.runId)} }) to recover the eventual result. This does not daemonize the process or guarantee survival across Pi reload/restart.`);
|
|
768
|
-
},
|
|
778
|
+
handler: async (args, ctx) => detachForegroundRun(args, ctx),
|
|
769
779
|
});
|
|
770
780
|
|
|
781
|
+
if (options.foregroundDetachShortcut) {
|
|
782
|
+
pi.registerShortcut(options.foregroundDetachShortcut as KeyId, {
|
|
783
|
+
description: "Detach the active foreground subagent and keep it running in the background",
|
|
784
|
+
handler: async (ctx) => detachForegroundRun("", ctx),
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
|
|
771
788
|
pi.registerCommand("subagents-stop", {
|
|
772
789
|
description: "Stop a current-session async subagent run",
|
|
773
790
|
handler: async (args, ctx) => {
|
|
@@ -81,6 +81,7 @@ function buildParallelInitialResult(params: SubagentParamsLike): AgentToolResult
|
|
|
81
81
|
content: [{ type: "text", text: tasks.map((task) => `${task.agent}: ${task.task}`).join("\n\n") }],
|
|
82
82
|
details: {
|
|
83
83
|
mode: "parallel",
|
|
84
|
+
...(params.async ? { background: true } : {}),
|
|
84
85
|
...(params.context ? { context: params.context } : {}),
|
|
85
86
|
results: tasks.map((task, index) => createPlaceholderResult(task.agent, task.task, "running", index)),
|
|
86
87
|
progress: tasks.map((task, index) => ({
|
|
@@ -136,6 +137,7 @@ function buildChainInitialResult(params: SubagentParamsLike): AgentToolResult<De
|
|
|
136
137
|
}],
|
|
137
138
|
details: {
|
|
138
139
|
mode: "chain",
|
|
140
|
+
...(params.async ? { background: true } : {}),
|
|
139
141
|
...(params.context ? { context: params.context } : {}),
|
|
140
142
|
results,
|
|
141
143
|
progress: results.map((result, index) => ({
|
|
@@ -164,6 +166,7 @@ function buildSingleInitialResult(params: SubagentParamsLike): AgentToolResult<D
|
|
|
164
166
|
content: [{ type: "text", text: task }],
|
|
165
167
|
details: {
|
|
166
168
|
mode: "single",
|
|
169
|
+
...(params.async ? { background: true } : {}),
|
|
167
170
|
...(params.context ? { context: params.context } : {}),
|
|
168
171
|
results: [createPlaceholderResult(agent, task, "running", 0)],
|
|
169
172
|
progress: [{
|