pi-extensible-workflows 3.3.0 → 3.4.1
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/README.md +2 -2
- package/dist/src/agent-execution.d.ts +63 -9
- package/dist/src/agent-execution.js +265 -92
- package/dist/src/cli.js +11 -2
- package/dist/src/doctor-cleanup.js +66 -31
- package/dist/src/execution.d.ts +1 -1
- package/dist/src/execution.js +29 -13
- package/dist/src/host.d.ts +5 -5
- package/dist/src/host.js +160 -76
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.js +1 -1
- package/dist/src/persistence.d.ts +4 -8
- package/dist/src/persistence.js +3 -0
- package/dist/src/registry.d.ts +3 -2
- package/dist/src/registry.js +16 -4
- package/dist/src/session-inspector.js +14 -22
- package/dist/src/types.d.ts +123 -60
- package/dist/src/validation.js +20 -5
- package/dist/src/workflow-artifacts.d.ts +1 -0
- package/dist/src/workflow-artifacts.js +1 -0
- package/package.json +2 -2
- package/skills/pi-extensible-workflows/SKILL.md +13 -5
- package/src/agent-execution.ts +221 -90
- package/src/cli.ts +14 -3
- package/src/doctor-cleanup.ts +36 -3
- package/src/execution.ts +27 -15
- package/src/host.ts +136 -62
- package/src/index.ts +3 -3
- package/src/persistence.ts +5 -3
- package/src/registry.ts +14 -5
- package/src/session-inspector.ts +13 -22
- package/src/types.ts +45 -27
- package/src/validation.ts +13 -4
- package/src/workflow-artifacts.ts +1 -0
package/dist/src/cli.js
CHANGED
|
@@ -386,6 +386,8 @@ class CliProgress {
|
|
|
386
386
|
#frame = 0;
|
|
387
387
|
#run;
|
|
388
388
|
#runId;
|
|
389
|
+
#runtimeStartedAt = 0;
|
|
390
|
+
#runtimeBaseMs = 0;
|
|
389
391
|
#timer;
|
|
390
392
|
#interactive;
|
|
391
393
|
#styles;
|
|
@@ -399,6 +401,12 @@ class CliProgress {
|
|
|
399
401
|
if (this.#runId !== run.id) {
|
|
400
402
|
this.#runId = run.id;
|
|
401
403
|
this.onRunId(run.id);
|
|
404
|
+
this.#runtimeStartedAt = Date.now();
|
|
405
|
+
this.#runtimeBaseMs = run.usage?.durationMs ?? 0;
|
|
406
|
+
}
|
|
407
|
+
else if (this.#run && this.#run.state !== "running" && run.state === "running") {
|
|
408
|
+
this.#runtimeStartedAt = Date.now();
|
|
409
|
+
this.#runtimeBaseMs = run.usage?.durationMs ?? 0;
|
|
402
410
|
}
|
|
403
411
|
this.#run = run;
|
|
404
412
|
if (!this.#interactive) {
|
|
@@ -414,8 +422,9 @@ class CliProgress {
|
|
|
414
422
|
render() {
|
|
415
423
|
if (!this.#run)
|
|
416
424
|
return;
|
|
425
|
+
const run = this.#run.state !== "running" ? this.#run : { ...this.#run, usage: { ...(this.#run.usage ?? { tokens: 0, costUsd: 0, durationMs: 0, agentLaunches: 0 }), durationMs: Math.max(this.#run.usage?.durationMs ?? 0, this.#runtimeBaseMs + Date.now() - this.#runtimeStartedAt) } };
|
|
417
426
|
if (!this.#interactive) {
|
|
418
|
-
const stable = formatWorkflowProgress(
|
|
427
|
+
const stable = formatWorkflowProgress(run, "◇", this.#styles);
|
|
419
428
|
if (stable !== this.#lastStable) {
|
|
420
429
|
this.#lastStable = stable;
|
|
421
430
|
this.stderr(`${stable}\n`);
|
|
@@ -424,7 +433,7 @@ class CliProgress {
|
|
|
424
433
|
}
|
|
425
434
|
const spinner = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"][this.#frame++ % 10] ?? "◇";
|
|
426
435
|
const width = process.stderr.columns || 80;
|
|
427
|
-
const text = truncateWorkflowProgress(formatWorkflowProgress(
|
|
436
|
+
const text = truncateWorkflowProgress(formatWorkflowProgress(run, spinner, this.#styles), width).join("\n");
|
|
428
437
|
this.stderr(`${this.#lines ? `\x1b[${String(this.#lines)}A` : ""}${this.#lines ? "" : "\x1b[?25l"}\x1b[0J${text}\n`);
|
|
429
438
|
this.#lines = text.split("\n").length;
|
|
430
439
|
}
|
|
@@ -63,36 +63,70 @@ function validateScheduledOptions(value, label) { if (!object(value) || typeof v
|
|
|
63
63
|
optionalString(value.agentIdentity.parentBreadcrumb, `${label}.agentIdentity.parentBreadcrumb`);
|
|
64
64
|
optionalString(value.agentIdentity.worktreeOwner, `${label}.agentIdentity.worktreeOwner`);
|
|
65
65
|
} }
|
|
66
|
-
function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
66
|
+
function validateSessionReference(value, label) {
|
|
67
|
+
if (!object(value) || typeof value.transport !== "string" || !value.transport || typeof value.sessionId !== "string" || !value.sessionId || (value.locator !== undefined && !jsonValue(value.locator)))
|
|
68
|
+
throw new Error(`${label} is invalid`);
|
|
69
|
+
}
|
|
70
|
+
function validateAgentSetup(value, label) {
|
|
71
|
+
if (!object(value))
|
|
72
|
+
throw new Error(`${label} is invalid`);
|
|
73
|
+
stringList(value.hookNames, `${label}.hookNames`);
|
|
74
|
+
model(value.model, `${label}.model`);
|
|
75
|
+
stringList(value.tools, `${label}.tools`);
|
|
76
|
+
if (typeof value.cwd !== "string" || !value.cwd)
|
|
77
|
+
throw new Error(`${label}.cwd is invalid`);
|
|
78
|
+
resourceExclusions(value.disabledAgentResources, `${label}.disabledAgentResources`);
|
|
79
|
+
}
|
|
80
|
+
function validateAgent(value, label) {
|
|
81
|
+
if (!object(value) || typeof value.id !== "string" || !value.id || typeof value.name !== "string" || !value.name || typeof value.path !== "string" || !value.path || typeof value.state !== "string" || !AGENT_STATES.has(value.state))
|
|
82
|
+
throw new Error(`${label} is invalid`);
|
|
83
|
+
optionalString(value.systemPrompt, `${label}.systemPrompt`);
|
|
84
|
+
optionalString(value.prompt, `${label}.prompt`);
|
|
85
|
+
optionalString(value.label, `${label}.label`);
|
|
86
|
+
optionalString(value.parentId, `${label}.parentId`);
|
|
87
|
+
if (value.structuralPath !== undefined)
|
|
88
|
+
stringList(value.structuralPath, `${label}.structuralPath`);
|
|
89
|
+
optionalString(value.parentBreadcrumb, `${label}.parentBreadcrumb`);
|
|
90
|
+
optionalString(value.worktreeOwner, `${label}.worktreeOwner`);
|
|
91
|
+
optionalString(value.role, `${label}.role`);
|
|
92
|
+
optionalString(value.requestedModel, `${label}.requestedModel`);
|
|
93
|
+
model(value.model, `${label}.model`);
|
|
94
|
+
stringList(value.tools, `${label}.tools`);
|
|
95
|
+
nonNegativeInteger(value.attempts, `${label}.attempts`);
|
|
96
|
+
if (value.attemptDetails !== undefined) {
|
|
97
|
+
if (!Array.isArray(value.attemptDetails))
|
|
98
|
+
throw new Error(`${label}.attemptDetails is invalid`);
|
|
99
|
+
for (const [index, attempt] of value.attemptDetails.entries()) {
|
|
100
|
+
const at = `${label}.attemptDetails[${String(index)}]`;
|
|
101
|
+
if (!object(attempt) || !Number.isSafeInteger(attempt.attempt) || Number(attempt.attempt) < 1 || typeof attempt.transport !== "string" || !attempt.transport || Object.hasOwn(attempt, "sessionId") || Object.hasOwn(attempt, "sessionFile"))
|
|
102
|
+
throw new Error(`${at} is invalid`);
|
|
103
|
+
validateAgentSetup(attempt.setup, `${at}.setup`);
|
|
104
|
+
if (attempt.session !== undefined) {
|
|
105
|
+
validateSessionReference(attempt.session, `${at}.session`);
|
|
106
|
+
if (attempt.session.transport !== attempt.transport)
|
|
107
|
+
throw new Error(`${at}.session transport does not match attempt transport`);
|
|
108
|
+
}
|
|
109
|
+
accounting(attempt.accounting, `${at}.accounting`);
|
|
110
|
+
if (attempt.error !== undefined && (!object(attempt.error) || typeof attempt.error.code !== "string" || typeof attempt.error.message !== "string"))
|
|
111
|
+
throw new Error(`${at}.error is invalid`);
|
|
85
112
|
}
|
|
86
113
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
for (const call of value.toolCalls)
|
|
92
|
-
if (!object(call) || typeof call.id !== "string" || typeof call.name !== "string" || !["running", "completed", "failed"].includes(call.state))
|
|
114
|
+
if (value.accounting !== undefined)
|
|
115
|
+
accounting(value.accounting, `${label}.accounting`);
|
|
116
|
+
if (value.toolCalls !== undefined) {
|
|
117
|
+
if (!Array.isArray(value.toolCalls))
|
|
93
118
|
throw new Error(`${label}.toolCalls is invalid`);
|
|
94
|
-
|
|
95
|
-
|
|
119
|
+
for (const [index, call] of value.toolCalls.entries())
|
|
120
|
+
if (!object(call) || typeof call.id !== "string" || !call.id || typeof call.name !== "string" || !call.name || !["running", "completed", "failed"].includes(call.state))
|
|
121
|
+
throw new Error(`${label}.toolCalls[${String(index)}] is invalid`);
|
|
122
|
+
}
|
|
123
|
+
if (value.activity !== undefined) {
|
|
124
|
+
if (!object(value.activity) || !["reasoning", "tool", "text"].includes(value.activity.kind) || typeof value.activity.text !== "string")
|
|
125
|
+
throw new Error(`${label}.activity is invalid`);
|
|
126
|
+
}
|
|
127
|
+
if (value.lastEventAt !== undefined)
|
|
128
|
+
finiteNumber(value.lastEventAt, `${label}.lastEventAt`);
|
|
129
|
+
}
|
|
96
130
|
function validateUsage(value, label) { if (!object(value))
|
|
97
131
|
throw new Error(`${label} is invalid`); for (const key of ["tokens", "costUsd", "durationMs", "agentLaunches"])
|
|
98
132
|
finiteNumber(value[key], `${label}.${key}`); }
|
|
@@ -107,7 +141,7 @@ function validateBudgetEvents(value) { if (value === undefined)
|
|
|
107
141
|
} }
|
|
108
142
|
function validateRunRecord(run) {
|
|
109
143
|
const value = run;
|
|
110
|
-
if (!object(value) || typeof value.id !== "string" || !value.id || typeof value.workflowName !== "string" || !value.workflowName || typeof value.cwd !== "string" || !value.cwd || typeof value.sessionId !== "string" || !value.sessionId || !RUN_STATES.includes(value.state) || !Array.isArray(value.agents) || !Array.isArray(value.nativeSessions))
|
|
144
|
+
if (!object(value) || typeof value.id !== "string" || !value.id || typeof value.workflowName !== "string" || !value.workflowName || typeof value.cwd !== "string" || !value.cwd || typeof value.sessionId !== "string" || !value.sessionId || !RUN_STATES.includes(value.state) || !Array.isArray(value.agents) || !Array.isArray(value.agentSessions) || Object.hasOwn(value, "nativeSessions"))
|
|
111
145
|
throw new Error("Persisted run state is invalid");
|
|
112
146
|
const agents = value.agents;
|
|
113
147
|
agents.forEach((agent, index) => { validateAgent(agent, `agents[${String(index)}]`); });
|
|
@@ -132,9 +166,9 @@ function validateRunRecord(run) {
|
|
|
132
166
|
parent = typeof parentAgent?.parentId === "string" ? parentAgent.parentId : undefined;
|
|
133
167
|
}
|
|
134
168
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
169
|
+
const sessions = value.agentSessions;
|
|
170
|
+
for (const [index, session] of sessions.entries())
|
|
171
|
+
validateSessionReference(session, `agentSessions[${String(index)}]`);
|
|
138
172
|
optionalString(value.parentRunId, "Persisted parent run");
|
|
139
173
|
optionalString(value.failedAt, "Persisted failed path");
|
|
140
174
|
if (value.retry !== undefined) {
|
|
@@ -267,6 +301,7 @@ async function validateRunArtifacts(store, workflowScript, state) {
|
|
|
267
301
|
throw new Error(`${label} is invalid`);
|
|
268
302
|
ownershipIds.add(record.id);
|
|
269
303
|
optionalString(record.parentId, `${label}.parentId`);
|
|
304
|
+
optionalString(record.prompt, `${label}.prompt`);
|
|
270
305
|
validateScheduledOptions(record.options, `${label}.options`);
|
|
271
306
|
}
|
|
272
307
|
for (const record of ownership)
|
package/dist/src/execution.d.ts
CHANGED
|
@@ -12,6 +12,6 @@ export declare function agentWorktree(identity: AgentIdentity): {
|
|
|
12
12
|
};
|
|
13
13
|
export declare function executeShellCommand(command: string, options: ShellOptions, signal: AbortSignal, cwd?: string): Promise<ShellResult>;
|
|
14
14
|
export declare function runWorkflow(script: string, args?: JsonValue, bridge?: WorkflowBridge, signal?: AbortSignal): WorkflowExecution;
|
|
15
|
-
export declare function persistActiveAgentAttempt(store: RunStore, id: string, active:
|
|
15
|
+
export declare function persistActiveAgentAttempt(store: RunStore, id: string, active: AgentAttempt): Promise<void>;
|
|
16
16
|
export declare function persistAgentAttempts(store: RunStore, id: string, attempts: readonly AgentAttempt[]): Promise<void>;
|
|
17
17
|
export type { AgentIdentity, ShellIdentity, WorkflowBridge, WorkflowExecution } from "./types.js";
|
package/dist/src/execution.js
CHANGED
|
@@ -9,6 +9,7 @@ import { asWorkflowError, errorText, fail, isWorkflowAuthored, jsonValue, markWo
|
|
|
9
9
|
import { instrumentWorkflow, validateAgentOptions, validateShellCommand, validateShellOptions } from "./validation.js";
|
|
10
10
|
export const RPC_LIMIT_BYTES = 10 * 1024 * 1024;
|
|
11
11
|
export const HEARTBEAT_TIMEOUT_MS = 5000;
|
|
12
|
+
const HEARTBEAT_INTERVAL_MS = 1000;
|
|
12
13
|
const OUTCOME_ERRORS = new Set(["AGENT_TIMEOUT", "AGENT_FAILED", "RESULT_INVALID"]);
|
|
13
14
|
const WORK_RESULT_BRAND = "__workResult";
|
|
14
15
|
const childSource = String.raw `
|
|
@@ -58,7 +59,7 @@ process.on("message", raw => {
|
|
|
58
59
|
if (message.ok) request.resolve(message.value);
|
|
59
60
|
else request.reject(workflowError(message.error));
|
|
60
61
|
});
|
|
61
|
-
const heartbeat = setInterval(() => send({ type: "heartbeat" }),
|
|
62
|
+
const heartbeat = setInterval(() => send({ type: "heartbeat" }), ${HEARTBEAT_INTERVAL_MS});
|
|
62
63
|
send({ type: "heartbeat" });
|
|
63
64
|
const BRAND = "${WORK_RESULT_BRAND}";
|
|
64
65
|
const workError = (code, message) => Object.assign(new Error(message), { code });
|
|
@@ -458,7 +459,20 @@ export function runWorkflow(script, args = null, bridge = {}, signal) {
|
|
|
458
459
|
const controller = new AbortController();
|
|
459
460
|
let settled = false;
|
|
460
461
|
let rejectResult = () => undefined;
|
|
461
|
-
let
|
|
462
|
+
let lastHeartbeatAt = performance.now();
|
|
463
|
+
let lastWatchdogCheckAt = lastHeartbeatAt;
|
|
464
|
+
const watchdog = setInterval(() => {
|
|
465
|
+
const now = performance.now();
|
|
466
|
+
// A check delayed enough to bridge the normal heartbeat margin makes elapsed time unreliable.
|
|
467
|
+
const watchdogCheckWasDelayed = now - lastWatchdogCheckAt >= HEARTBEAT_TIMEOUT_MS - HEARTBEAT_INTERVAL_MS;
|
|
468
|
+
lastWatchdogCheckAt = now;
|
|
469
|
+
if (watchdogCheckWasDelayed) {
|
|
470
|
+
lastHeartbeatAt = now;
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
if (now - lastHeartbeatAt >= HEARTBEAT_TIMEOUT_MS)
|
|
474
|
+
stop("WORKER_UNRESPONSIVE", "Workflow worker missed its five-second heartbeat");
|
|
475
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
462
476
|
const result = new Promise((resolve, reject) => {
|
|
463
477
|
rejectResult = reject;
|
|
464
478
|
child.on("message", (raw) => {
|
|
@@ -469,8 +483,7 @@ export function runWorkflow(script, args = null, bridge = {}, signal) {
|
|
|
469
483
|
if (!jsonValue(message))
|
|
470
484
|
fail("RPC_LIMIT_EXCEEDED", "Worker RPC must contain JSON-compatible values");
|
|
471
485
|
if (message.type === "heartbeat") {
|
|
472
|
-
|
|
473
|
-
watchdog = setTimeout(() => { stop("WORKER_UNRESPONSIVE", "Workflow worker missed its five-second heartbeat"); }, HEARTBEAT_TIMEOUT_MS);
|
|
486
|
+
lastHeartbeatAt = performance.now();
|
|
474
487
|
return;
|
|
475
488
|
}
|
|
476
489
|
if (message.type === "result") {
|
|
@@ -502,7 +515,7 @@ export function runWorkflow(script, args = null, bridge = {}, signal) {
|
|
|
502
515
|
child.kill("SIGKILL"); }, 1000).unref();
|
|
503
516
|
}
|
|
504
517
|
}
|
|
505
|
-
function finish() { settled = true;
|
|
518
|
+
function finish() { settled = true; clearInterval(watchdog); signal?.removeEventListener("abort", cancel); killChild(); rmSync(childDir, { recursive: true, force: true }); }
|
|
506
519
|
function stop(code, message) { if (settled)
|
|
507
520
|
return; controller.abort(); finish(); rejectResult(new WorkflowError(code, message)); }
|
|
508
521
|
function branded(result) { return { ...result, [WORK_RESULT_BRAND]: true }; }
|
|
@@ -612,8 +625,8 @@ export function runWorkflow(script, args = null, bridge = {}, signal) {
|
|
|
612
625
|
signal?.addEventListener("abort", cancel, { once: true });
|
|
613
626
|
return { result, cancel };
|
|
614
627
|
}
|
|
615
|
-
function
|
|
616
|
-
return {
|
|
628
|
+
function attemptSummary(attempt, accounting = attempt.accounting) {
|
|
629
|
+
return { attempt: attempt.attempt, transport: attempt.transport, ...(attempt.session ? { session: attempt.session } : {}), ...(attempt.error ? { error: attempt.error } : {}), accounting, setup: attempt.setup };
|
|
617
630
|
}
|
|
618
631
|
export async function persistActiveAgentAttempt(store, id, active) {
|
|
619
632
|
await store.updateState((run) => {
|
|
@@ -621,9 +634,11 @@ export async function persistActiveAgentAttempt(store, id, active) {
|
|
|
621
634
|
if (!agent)
|
|
622
635
|
throw new WorkflowError("INTERNAL_ERROR", `Missing production ownership record: ${id}`);
|
|
623
636
|
const accounting = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 };
|
|
624
|
-
const
|
|
625
|
-
const
|
|
626
|
-
|
|
637
|
+
const detail = attemptSummary(active, accounting);
|
|
638
|
+
const details = [...(agent.attemptDetails ?? []).filter((candidate) => candidate.attempt !== active.attempt), detail];
|
|
639
|
+
const session = active.session;
|
|
640
|
+
const agentSessions = session && !run.agentSessions.some(({ transport, sessionId }) => transport === session.transport && sessionId === session.sessionId) ? [...run.agentSessions, session] : run.agentSessions;
|
|
641
|
+
return { ...run, agents: run.agents.map((candidate) => candidate.id === id ? { ...candidate, attempts: Math.max(candidate.attempts, active.attempt), attemptDetails: details } : candidate), agentSessions };
|
|
627
642
|
});
|
|
628
643
|
}
|
|
629
644
|
export async function persistAgentAttempts(store, id, attempts) {
|
|
@@ -632,8 +647,9 @@ export async function persistAgentAttempts(store, id, attempts) {
|
|
|
632
647
|
if (!agent)
|
|
633
648
|
throw new WorkflowError("INTERNAL_ERROR", `Missing production ownership record: ${id}`);
|
|
634
649
|
const total = attempts.reduce((sum, attempt) => ({ input: sum.input + attempt.accounting.input, output: sum.output + attempt.accounting.output, cacheRead: sum.cacheRead + attempt.accounting.cacheRead, cacheWrite: sum.cacheWrite + attempt.accounting.cacheWrite, cost: sum.cost + attempt.accounting.cost }), { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 });
|
|
635
|
-
const attemptDetails = attempts.map((
|
|
636
|
-
const
|
|
637
|
-
|
|
650
|
+
const attemptDetails = attempts.map((attempt) => attemptSummary(attempt));
|
|
651
|
+
const sessions = attempts.map((attempt) => attempt.session).filter((session) => session !== undefined);
|
|
652
|
+
const sessionKeys = new Set(sessions.map(({ transport, sessionId }) => `${transport}:${sessionId}`));
|
|
653
|
+
return { ...run, agents: run.agents.map((candidate) => candidate.id === id ? { ...candidate, attempts: attempts.length, attemptDetails, accounting: total } : candidate), agentSessions: [...run.agentSessions.filter(({ transport, sessionId }) => !sessionKeys.has(`${transport}:${sessionId}`)), ...sessions] };
|
|
638
654
|
});
|
|
639
655
|
}
|
package/dist/src/host.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Type } from "@earendil-works/pi-ai";
|
|
2
2
|
import { copyToClipboard, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
3
|
-
import { type SessionFactory } from "./agent-execution.js";
|
|
4
3
|
import type { AwaitingCheckpoint, PersistedRun, WorktreeReference } from "./persistence.js";
|
|
5
|
-
import { type AgentRecord, type LaunchSnapshot, type RunState, type WorkflowFailureDiagnostics } from "./types.js";
|
|
4
|
+
import { type AgentRecord, type AgentTransport, type LaunchSnapshot, type RunState, type WorkflowFailureDiagnostics } from "./types.js";
|
|
6
5
|
export interface WorkflowProgressStyles {
|
|
7
6
|
accent(text: string): string;
|
|
8
7
|
success(text: string): string;
|
|
@@ -34,12 +33,13 @@ export declare function formatWorkflowPreview(args: {
|
|
|
34
33
|
description?: unknown;
|
|
35
34
|
}): string;
|
|
36
35
|
export declare const WORKFLOW_TOOL_LABEL = "Workflow";
|
|
37
|
-
export declare const WORKFLOW_TOOL_DESCRIPTION = "Run a deterministic JavaScript workflow with a named inline parallel-to-summary path by default";
|
|
38
|
-
export declare const WORKFLOW_TOOL_PROMPT_SNIPPET = "Run a deterministic, resumable JavaScript workflow. Prefer a named inline script that fans out independent work with parallel(...), awaits the keyed results before interpolating them into one summarizing agent(...), and returns. Inline launches require
|
|
36
|
+
export declare const WORKFLOW_TOOL_DESCRIPTION = "Run a deterministic JavaScript workflow with a named inline or file-backed parallel-to-summary path by default";
|
|
37
|
+
export declare const WORKFLOW_TOOL_PROMPT_SNIPPET = "Run a deterministic, resumable JavaScript workflow. Prefer a named inline script that fans out independent work with parallel(...), awaits the keyed results before interpolating them into one summarizing agent(...), and returns. Inline and file-backed launches require a non-empty name; registered function launches may use name as an optional run label and otherwise use workflow as the run name. Advanced controls include registered functions, outputSchema, budgets, checkpoints, worktrees, retry/resume, CLI export, and pipelines. Use workflow_retry with an explicit failed run ID; parentRunId only reuses named worktrees. Runs are in the background by default; completion arrives as a follow-up message. Set foreground: true when the caller must wait for the final value. If a foreground call detaches before its result is accepted, its terminal success or failure is promoted to one follow-up message. Foreground results include the completed run ID. Recovery inherits the source launch mode; legacy snapshots without launchMode recover in the background. Set foreground: true or false on workflow_resume/workflow_retry to override it; foreground recovery waits for terminal value and run details, while background recovery returns immediately with a follow-up. Recovery map: agent(..., { retries }) reruns one agent call in the same run for transient failures; workflow_retry({ runId, foreground? }) replays a failed run into a child; workflow_resume({ runId, budget?, foreground? }) continues a budget_exhausted run; parentRunId on a new launch only borrows named worktrees and never replays or resumes.";
|
|
39
38
|
export declare const WORKFLOW_TOOL_PARAMETERS: Type.TObject<{
|
|
40
39
|
name: Type.TOptional<Type.TString>;
|
|
41
40
|
description: Type.TOptional<Type.TString>;
|
|
42
41
|
script: Type.TOptional<Type.TString>;
|
|
42
|
+
scriptPath: Type.TOptional<Type.TString>;
|
|
43
43
|
workflow: Type.TOptional<Type.TString>;
|
|
44
44
|
args: Type.TOptional<Type.TUnknown>;
|
|
45
45
|
foreground: Type.TOptional<Type.TBoolean>;
|
|
@@ -140,5 +140,5 @@ export declare function formatNavigatorRun(loaded: {
|
|
|
140
140
|
export declare function formatWorkflowPhaseDashboard(run: PersistedRun, snapshot: Readonly<LaunchSnapshot>, width: number, selection?: WorkflowPhaseSelection, styles?: WorkflowProgressStyles, now?: number): string[];
|
|
141
141
|
export declare function formatWorkflowFailureDiagnostics(diagnostic: WorkflowFailureDiagnostics): string;
|
|
142
142
|
export declare function formatWorkflowFailureDelivery(diagnostic: WorkflowFailureDiagnostics): string;
|
|
143
|
-
export default function workflowExtension(pi: ExtensionAPI, home?: string, clipboard?: typeof copyToClipboard,
|
|
143
|
+
export default function workflowExtension(pi: ExtensionAPI, home?: string, clipboard?: typeof copyToClipboard, transport?: AgentTransport, agentDir?: string, additionalSkillPaths?: readonly string[]): void;
|
|
144
144
|
export {};
|