@marcoscale98/pi-extensible-workflows 5.14.1-fork.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/CHANGELOG.md +536 -0
- package/README.md +64 -0
- package/dist/src/agent-execution.d.ts +338 -0
- package/dist/src/agent-execution.js +1633 -0
- package/dist/src/background-widget.d.ts +74 -0
- package/dist/src/background-widget.js +1340 -0
- package/dist/src/budget.d.ts +38 -0
- package/dist/src/budget.js +188 -0
- package/dist/src/changelog.d.ts +6 -0
- package/dist/src/changelog.js +112 -0
- package/dist/src/decoders.d.ts +96 -0
- package/dist/src/decoders.js +629 -0
- package/dist/src/execution.d.ts +19 -0
- package/dist/src/execution.js +749 -0
- package/dist/src/herdr.d.ts +53 -0
- package/dist/src/herdr.js +270 -0
- package/dist/src/host-delivery.d.ts +95 -0
- package/dist/src/host-delivery.js +376 -0
- package/dist/src/host-navigator.d.ts +83 -0
- package/dist/src/host-navigator.js +1087 -0
- package/dist/src/host-phases.d.ts +89 -0
- package/dist/src/host-phases.js +320 -0
- package/dist/src/host-recovery.d.ts +141 -0
- package/dist/src/host-recovery.js +356 -0
- package/dist/src/host-runtime.d.ts +78 -0
- package/dist/src/host-runtime.js +378 -0
- package/dist/src/host-view.d.ts +116 -0
- package/dist/src/host-view.js +868 -0
- package/dist/src/host.d.ts +40 -0
- package/dist/src/host.js +1641 -0
- package/dist/src/index.d.ts +29 -0
- package/dist/src/index.js +13725 -0
- package/dist/src/index.js.map +6 -0
- package/dist/src/io.d.ts +14 -0
- package/dist/src/io.js +82 -0
- package/dist/src/package-identity.d.ts +4 -0
- package/dist/src/package-identity.js +6 -0
- package/dist/src/paths.d.ts +14 -0
- package/dist/src/paths.js +51 -0
- package/dist/src/persistence.d.ts +5 -0
- package/dist/src/persistence.js +5 -0
- package/dist/src/pi-runtime-adapter.d.ts +27 -0
- package/dist/src/pi-runtime-adapter.js +243 -0
- package/dist/src/pi-runtime-runner.d.ts +42 -0
- package/dist/src/pi-runtime-runner.js +505 -0
- package/dist/src/registry.d.ts +48 -0
- package/dist/src/registry.js +379 -0
- package/dist/src/retention.d.ts +17 -0
- package/dist/src/retention.js +195 -0
- package/dist/src/runtime/agent-runner.d.ts +143 -0
- package/dist/src/runtime/agent-runner.js +12 -0
- package/dist/src/runtime/index.d.ts +2 -0
- package/dist/src/runtime/index.js +2 -0
- package/dist/src/runtime/namespace.d.ts +14 -0
- package/dist/src/runtime/namespace.js +1 -0
- package/dist/src/runtime/workflow-result.d.ts +2 -0
- package/dist/src/runtime/workflow-result.js +6 -0
- package/dist/src/session-handoff.d.ts +2 -0
- package/dist/src/session-handoff.js +82 -0
- package/dist/src/session-lease.d.ts +12 -0
- package/dist/src/session-lease.js +180 -0
- package/dist/src/store.d.ts +95 -0
- package/dist/src/store.js +951 -0
- package/dist/src/subagent-manager-handle.d.ts +4 -0
- package/dist/src/subagent-manager-handle.js +6 -0
- package/dist/src/tool-timing.d.ts +12 -0
- package/dist/src/tool-timing.js +33 -0
- package/dist/src/trajectory-contracts.d.ts +8 -0
- package/dist/src/trajectory-contracts.js +9 -0
- package/dist/src/trajectory-host-handle.d.ts +12 -0
- package/dist/src/trajectory-host-handle.js +6 -0
- package/dist/src/trajectory.d.ts +128 -0
- package/dist/src/trajectory.js +594 -0
- package/dist/src/types.d.ts +960 -0
- package/dist/src/types.js +60 -0
- package/dist/src/utils.d.ts +57 -0
- package/dist/src/utils.js +225 -0
- package/dist/src/validation.d.ts +29 -0
- package/dist/src/validation.js +1100 -0
- package/dist/src/workflow-artifacts.d.ts +14 -0
- package/dist/src/workflow-artifacts.js +40 -0
- package/dist/starter/index.d.ts +1 -0
- package/dist/starter/index.js +103 -0
- package/dist/starter/index.js.map +6 -0
- package/dist/starter/review-loop.d.ts +72 -0
- package/dist/starter/review-loop.js +43 -0
- package/dist/starter/roles/developer.md +6 -0
- package/dist/starter/roles/oracle.md +18 -0
- package/dist/starter/roles/researcher.md +20 -0
- package/dist/starter/roles/reviewer.md +19 -0
- package/dist/starter/roles/scout.md +18 -0
- package/dist/subagents/index.d.ts +8 -0
- package/dist/subagents/index.js +8021 -0
- package/dist/subagents/index.js.map +6 -0
- package/dist/subagents/src/contracts.d.ts +173 -0
- package/dist/subagents/src/contracts.js +68 -0
- package/dist/subagents/src/decode.d.ts +15 -0
- package/dist/subagents/src/decode.js +182 -0
- package/dist/subagents/src/index.d.ts +12 -0
- package/dist/subagents/src/index.js +180 -0
- package/dist/subagents/src/manager.d.ts +3 -0
- package/dist/subagents/src/manager.js +1636 -0
- package/dist/subagents/src/navigator.d.ts +5 -0
- package/dist/subagents/src/navigator.js +627 -0
- package/dist/subagents/src/view.d.ts +70 -0
- package/dist/subagents/src/view.js +387 -0
- package/dist/subagents/src/worktree.d.ts +34 -0
- package/dist/subagents/src/worktree.js +68 -0
- package/dist/trajectory/assets/favicon.png +0 -0
- package/dist/trajectory/assets/index.html +772 -0
- package/dist/trajectory/assets/marked.min.js +6 -0
- package/dist/trajectory/assets/morphdom.min.js +1 -0
- package/dist/trajectory/index.d.ts +5 -0
- package/dist/trajectory/index.js +3459 -0
- package/dist/trajectory/index.js.map +6 -0
- package/dist/trajectory/src/assets/favicon.png +0 -0
- package/dist/trajectory/src/assets/index.html +772 -0
- package/dist/trajectory/src/assets/marked.min.js +6 -0
- package/dist/trajectory/src/assets/morphdom.min.js +1 -0
- package/dist/trajectory/src/export.d.ts +25 -0
- package/dist/trajectory/src/export.js +80 -0
- package/dist/trajectory/src/index.d.ts +26 -0
- package/dist/trajectory/src/index.js +732 -0
- package/dist/trajectory/src/server.d.ts +7 -0
- package/dist/trajectory/src/server.js +2534 -0
- package/dist/trajectory/src/server.js.map +6 -0
- package/examples/advanced-patterns/auto-model-router.mjs +78 -0
- package/examples/workflow-extension-template/README.md +37 -0
- package/examples/workflow-extension-template/extension.test.mjs +59 -0
- package/examples/workflow-extension-template/index.js +51 -0
- package/examples/workflow-extension-template/roles/reviewer.md +4 -0
- package/package.json +105 -0
- package/skills/pi-extensible-workflows/SKILL.md +160 -0
- package/src/agent-execution.ts +1533 -0
- package/src/background-widget.ts +1496 -0
- package/src/budget.ts +109 -0
- package/src/changelog.ts +114 -0
- package/src/decoders.ts +567 -0
- package/src/execution.ts +652 -0
- package/src/herdr.ts +240 -0
- package/src/host-delivery.ts +346 -0
- package/src/host-navigator.ts +871 -0
- package/src/host-phases.ts +264 -0
- package/src/host-recovery.ts +333 -0
- package/src/host-runtime.ts +373 -0
- package/src/host-view.ts +828 -0
- package/src/host.ts +1502 -0
- package/src/index.ts +29 -0
- package/src/io.ts +73 -0
- package/src/package-identity.ts +7 -0
- package/src/paths.ts +49 -0
- package/src/persistence.ts +11 -0
- package/src/pi-runtime-adapter.ts +247 -0
- package/src/pi-runtime-runner.ts +436 -0
- package/src/registry.ts +321 -0
- package/src/retention.ts +178 -0
- package/src/runtime/agent-runner.ts +158 -0
- package/src/runtime/index.ts +2 -0
- package/src/runtime/namespace.ts +16 -0
- package/src/runtime/workflow-result.ts +8 -0
- package/src/session-handoff.ts +78 -0
- package/src/session-lease.ts +125 -0
- package/src/store.ts +832 -0
- package/src/subagent-manager-handle.ts +8 -0
- package/src/tool-timing.ts +47 -0
- package/src/trajectory-contracts.ts +13 -0
- package/src/trajectory-host-handle.ts +16 -0
- package/src/trajectory.ts +543 -0
- package/src/types.ts +374 -0
- package/src/utils.ts +192 -0
- package/src/validation.ts +910 -0
- package/src/workflow-artifacts.ts +35 -0
- package/starter/index.ts +35 -0
- package/starter/prompts/council.md +16 -0
- package/starter/prompts/deep-research.md +16 -0
- package/starter/prompts/oracle.md +14 -0
- package/starter/prompts/parallel-review.md +22 -0
- package/starter/prompts/parallel-scout.md +16 -0
- package/starter/prompts/review-loop.md +14 -0
- package/starter/prompts/review.md +14 -0
- package/starter/prompts/scout.md +14 -0
- package/starter/review-loop.ts +73 -0
- package/starter/roles/developer.md +6 -0
- package/starter/roles/oracle.md +18 -0
- package/starter/roles/researcher.md +20 -0
- package/starter/roles/reviewer.md +19 -0
- package/starter/roles/scout.md +18 -0
- package/subagents/README.md +145 -0
- package/subagents/index.ts +8 -0
- package/subagents/src/contracts.ts +176 -0
- package/subagents/src/decode.ts +158 -0
- package/subagents/src/index.ts +194 -0
- package/subagents/src/manager.ts +1560 -0
- package/subagents/src/navigator.ts +488 -0
- package/subagents/src/view.ts +376 -0
- package/subagents/src/worktree.ts +99 -0
- package/trajectory/index.ts +5 -0
- package/trajectory/src/assets/favicon.png +0 -0
- package/trajectory/src/assets/index.html +772 -0
- package/trajectory/src/assets/marked.min.js +6 -0
- package/trajectory/src/assets/morphdom.min.js +1 -0
- package/trajectory/src/export.ts +85 -0
- package/trajectory/src/index.ts +604 -0
- package/trajectory/src/server.ts +447 -0
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
import { createPiRuntimeSessionAdapter, isEmptyAbortedAssistant, isTurnBoundaryStart, isTurnEnd, normalizePiMessage } from "./pi-runtime-adapter.js";
|
|
2
|
+
import { RuntimeAgentProviderError } from "./runtime/agent-runner.js";
|
|
3
|
+
import { errorText, jsonValue } from "./utils.js";
|
|
4
|
+
import { WorkflowError } from "./types.js";
|
|
5
|
+
const providerContinuationPrompt = "The provider error was transient. Continue the task from your current state.";
|
|
6
|
+
const handoffContinuationPrompt = "Continue the task from the current session state.";
|
|
7
|
+
export function runtimeToolFromPiDefinition(definition, context) {
|
|
8
|
+
const parameters = definition.parameters;
|
|
9
|
+
if (!jsonValue(parameters))
|
|
10
|
+
throw new WorkflowError("INVALID_METADATA", `Pi tool ${definition.name} has a non-JSON parameter schema`);
|
|
11
|
+
return {
|
|
12
|
+
name: definition.name,
|
|
13
|
+
description: definition.description,
|
|
14
|
+
parameters: parameters,
|
|
15
|
+
async execute(call) {
|
|
16
|
+
const result = await definition.execute(call.id, call.input, call.signal, undefined, context);
|
|
17
|
+
const isError = typeof result === "object" && result !== null && "isError" in result && result.isError === true;
|
|
18
|
+
if (!jsonValue(result))
|
|
19
|
+
throw new WorkflowError("RESULT_INVALID", `Pi tool ${definition.name} returned a non-JSON result`);
|
|
20
|
+
return { value: runtimeValue(result), ...(isError ? { isError: true } : {}) };
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function hasToolCall(message) {
|
|
25
|
+
return typeof message === "object" && message !== null && Array.isArray(message.content) && message.content.some((part) => typeof part === "object" && part !== null && part.type === "toolCall");
|
|
26
|
+
}
|
|
27
|
+
function isHandoffAbort(message) { return message?.role === "assistant" && message.stopReason === "error" && Array.isArray(message.content) && message.content.length === 0 && typeof message.errorMessage === "string" && /abort/i.test(message.errorMessage); }
|
|
28
|
+
function isTerminalAssistant(message) { return Boolean(message) && message?.stopReason !== "aborted" && !hasToolCall(message); }
|
|
29
|
+
function runtimeUsage(session) {
|
|
30
|
+
const stats = session.getSessionStats();
|
|
31
|
+
const values = [stats.tokens.input, stats.tokens.output, stats.tokens.cacheRead, stats.tokens.cacheWrite, stats.cost];
|
|
32
|
+
if (values.some((value) => !Number.isFinite(value)))
|
|
33
|
+
return { availability: "unavailable" };
|
|
34
|
+
return { availability: "complete", input: stats.tokens.input, output: stats.tokens.output, cacheRead: stats.tokens.cacheRead, cacheWrite: stats.tokens.cacheWrite, costUsd: stats.cost };
|
|
35
|
+
}
|
|
36
|
+
function providerFailure(session, message) {
|
|
37
|
+
if (message?.stopReason !== "error")
|
|
38
|
+
return undefined;
|
|
39
|
+
const state = session.getState();
|
|
40
|
+
return { provider: state.model.provider, model: state.model.model, error: message.errorMessage ?? "Workflow agent session ended with a terminal provider error" };
|
|
41
|
+
}
|
|
42
|
+
function runtimeValue(value) { return value; }
|
|
43
|
+
function unstructuredResult(value) {
|
|
44
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || typeof value.result !== "string")
|
|
45
|
+
return undefined;
|
|
46
|
+
return value.result;
|
|
47
|
+
}
|
|
48
|
+
function remaining(timeoutMs, started) { return timeoutMs === null || timeoutMs === undefined ? timeoutMs : Math.max(1, timeoutMs - (Date.now() - started)); }
|
|
49
|
+
function providerLimited(error) {
|
|
50
|
+
if (!error || typeof error !== "object")
|
|
51
|
+
return false;
|
|
52
|
+
const candidate = error;
|
|
53
|
+
return candidate.status === 429 || candidate.code === 429 || candidate.code === "rate_limit_exceeded" || candidate.code === "RATE_LIMITED";
|
|
54
|
+
}
|
|
55
|
+
function isToolError(result) { return typeof result === "object" && result !== null && "isError" in result && result.isError === true; }
|
|
56
|
+
function piToolFromRuntime(definition, signal) {
|
|
57
|
+
if (typeof definition.name !== "string" || !definition.name || typeof definition.description !== "string" || !jsonValue(definition.parameters) || typeof definition.execute !== "function")
|
|
58
|
+
throw new WorkflowError("INVALID_METADATA", `Runtime tool ${definition.name || "<unnamed>"} is not JSON-compatible`);
|
|
59
|
+
return {
|
|
60
|
+
name: definition.name,
|
|
61
|
+
label: definition.name,
|
|
62
|
+
description: definition.description,
|
|
63
|
+
parameters: definition.parameters,
|
|
64
|
+
async execute(toolCallId, input, toolSignal) {
|
|
65
|
+
if (!jsonValue(input))
|
|
66
|
+
throw new WorkflowError("INVALID_METADATA", `Runtime tool ${definition.name} received a non-JSON input`);
|
|
67
|
+
const result = await definition.execute({ id: toolCallId, input: runtimeValue(input), signal: toolSignal ?? signal });
|
|
68
|
+
if (!jsonValue(result.value))
|
|
69
|
+
throw new WorkflowError("RESULT_INVALID", `Runtime tool ${definition.name} returned a non-JSON result`);
|
|
70
|
+
return { content: [{ type: "text", text: JSON.stringify(result.value) }], details: result.value, ...(result.isError ? { isError: true } : {}) };
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function preparedForRuntimeRequest(prepared, customTools, signal, captureResult, resultTool = prepared.resultTool) {
|
|
75
|
+
const names = new Set([...prepared.tools, ...(prepared.customTools ?? []).map(({ name }) => name), ...(resultTool ? [resultTool.name] : [])]);
|
|
76
|
+
const additions = customTools.map((tool) => {
|
|
77
|
+
if (names.has(tool.name))
|
|
78
|
+
throw new WorkflowError("INTERNAL_ERROR", `Runtime tool ${tool.name} conflicts with the prepared Pi tool policy`);
|
|
79
|
+
names.add(tool.name);
|
|
80
|
+
return piToolFromRuntime(tool, signal);
|
|
81
|
+
});
|
|
82
|
+
const nativeResultTool = resultTool;
|
|
83
|
+
const wrappedResultTool = nativeResultTool ? Object.freeze({
|
|
84
|
+
...nativeResultTool,
|
|
85
|
+
async execute(toolCallId, input, toolSignal, onUpdate, context) {
|
|
86
|
+
const result = await nativeResultTool.execute(toolCallId, input, toolSignal, onUpdate, context);
|
|
87
|
+
if (!isToolError(result) && jsonValue(input))
|
|
88
|
+
captureResult(runtimeValue(structuredClone(input)));
|
|
89
|
+
return result;
|
|
90
|
+
},
|
|
91
|
+
}) : undefined;
|
|
92
|
+
if (additions.length === 0 && wrappedResultTool === undefined)
|
|
93
|
+
return prepared;
|
|
94
|
+
return Object.freeze({
|
|
95
|
+
...prepared,
|
|
96
|
+
...(additions.length === 0 ? {} : { customTools: Object.freeze([...(prepared.customTools ?? []), ...additions]) }),
|
|
97
|
+
...(wrappedResultTool === undefined ? {} : { resultTool: wrappedResultTool }),
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
export function isRuntimeAgentProviderError(error) { return error instanceof RuntimeAgentProviderError; }
|
|
101
|
+
export function normalizePiRuntimeError(error, signal, setupFailed = false) {
|
|
102
|
+
if (error instanceof WorkflowError)
|
|
103
|
+
return error;
|
|
104
|
+
if (error instanceof RuntimeAgentProviderError)
|
|
105
|
+
return new WorkflowError("AGENT_FAILED", error.failure.error);
|
|
106
|
+
return new WorkflowError(signal.aborted && setupFailed ? "CANCELLED" : "AGENT_FAILED", errorText(error));
|
|
107
|
+
}
|
|
108
|
+
async function withTimeout(work, timeoutMs, signal, session) {
|
|
109
|
+
if (signal.aborted)
|
|
110
|
+
throw new WorkflowError("CANCELLED", "Agent cancelled");
|
|
111
|
+
let timer;
|
|
112
|
+
let abort;
|
|
113
|
+
const state = { interrupted: false };
|
|
114
|
+
const timeout = timeoutMs === undefined || timeoutMs === null ? new Promise(() => undefined) : new Promise((_, reject) => {
|
|
115
|
+
timer = setTimeout(() => { state.interrupted = true; reject(new WorkflowError("AGENT_TIMEOUT", "Agent attempt timed out")); }, timeoutMs);
|
|
116
|
+
});
|
|
117
|
+
const cancelled = new Promise((_, reject) => {
|
|
118
|
+
abort = () => { state.interrupted = true; reject(new WorkflowError("CANCELLED", "Agent cancelled")); };
|
|
119
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
120
|
+
});
|
|
121
|
+
try {
|
|
122
|
+
return await Promise.race([work, timeout, cancelled]);
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
if (timer)
|
|
126
|
+
clearTimeout(timer);
|
|
127
|
+
if (abort)
|
|
128
|
+
signal.removeEventListener("abort", abort);
|
|
129
|
+
if (state.interrupted)
|
|
130
|
+
await session.abort();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async function promptWithProviderPause(session, textValue, timeoutMs, started, request) {
|
|
134
|
+
const promptTimeout = remaining(timeoutMs, started);
|
|
135
|
+
for (;;) {
|
|
136
|
+
try {
|
|
137
|
+
return await withTimeout(session.prompt(textValue), promptTimeout, request.signal, session);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
if (!request.onProviderLimit || !providerLimited(error))
|
|
141
|
+
throw error;
|
|
142
|
+
await request.onProviderLimit();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
export class PiRuntimeAgentRunner {
|
|
147
|
+
id = "pi";
|
|
148
|
+
// Prepared Pi definitions remain native; request-neutral tools are adapted before session creation.
|
|
149
|
+
capabilities = { customTools: true, structuredResults: true, steering: true, handoff: true, usage: "complete" };
|
|
150
|
+
#options;
|
|
151
|
+
constructor(options) { this.#options = options; }
|
|
152
|
+
run(request) { return this.#runOnce(request); }
|
|
153
|
+
async #runOnce(request) {
|
|
154
|
+
if (request.signal.aborted)
|
|
155
|
+
throw new WorkflowError("CANCELLED", "Agent cancelled");
|
|
156
|
+
if (request.timeoutMs !== undefined && request.timeoutMs !== null && (!Number.isInteger(request.timeoutMs) || request.timeoutMs <= 0))
|
|
157
|
+
throw new WorkflowError("INVALID_METADATA", "timeoutMs must be null or a positive integer");
|
|
158
|
+
const started = Date.now();
|
|
159
|
+
const prepared = this.#options.prepared;
|
|
160
|
+
if (request.cwd !== prepared.cwd || request.model.provider !== prepared.model.provider || request.model.model !== prepared.model.model || request.model.thinking !== prepared.model.thinking || request.enabledTools.length !== prepared.tools.length || request.enabledTools.some((tool, index) => tool !== prepared.tools[index]))
|
|
161
|
+
throw new WorkflowError("INTERNAL_ERROR", "Pi runtime request does not match the prepared session");
|
|
162
|
+
let session;
|
|
163
|
+
let structuredResult;
|
|
164
|
+
const resultTool = prepared.resultTool;
|
|
165
|
+
if (!resultTool)
|
|
166
|
+
throw new WorkflowError("INTERNAL_ERROR", "Workflow agent session is missing its workflow_result tool");
|
|
167
|
+
const preparedForSession = preparedForRuntimeRequest(prepared, request.customTools, request.signal, (value) => { structuredResult = value; }, resultTool);
|
|
168
|
+
const callbacks = this.#options.callbacks;
|
|
169
|
+
const handoff = this.#options.handoff;
|
|
170
|
+
let adapter;
|
|
171
|
+
let unsubscribe;
|
|
172
|
+
let disposeStarted = false;
|
|
173
|
+
let sessionReady = false;
|
|
174
|
+
let successfulInvocation = false;
|
|
175
|
+
let progress = Promise.resolve();
|
|
176
|
+
const progressState = { failed: false, error: undefined };
|
|
177
|
+
const eventNotifications = new Set();
|
|
178
|
+
let systemPromptTurn = 0;
|
|
179
|
+
let systemPromptWrite = Promise.resolve();
|
|
180
|
+
let systemPromptWriteError;
|
|
181
|
+
let turnStarted = false;
|
|
182
|
+
let turnPolicyFailure;
|
|
183
|
+
let lastAssistant;
|
|
184
|
+
let handoffBoundaryAssistant;
|
|
185
|
+
let handoffAbortHandled = false;
|
|
186
|
+
const hasResult = () => structuredResult !== undefined;
|
|
187
|
+
// Session event observations are best effort, matching the legacy synchronous subscription.
|
|
188
|
+
const trackEvent = (notification) => {
|
|
189
|
+
eventNotifications.add(notification);
|
|
190
|
+
void notification.then(() => { eventNotifications.delete(notification); }, () => { eventNotifications.delete(notification); });
|
|
191
|
+
};
|
|
192
|
+
const flushEvents = async () => {
|
|
193
|
+
while (eventNotifications.size > 0) {
|
|
194
|
+
const pending = [...eventNotifications];
|
|
195
|
+
await Promise.allSettled(pending);
|
|
196
|
+
for (const notification of pending)
|
|
197
|
+
eventNotifications.delete(notification);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
const report = (value) => {
|
|
201
|
+
const progressHandler = request.onProgress;
|
|
202
|
+
if (!progressHandler || progressState.failed)
|
|
203
|
+
return;
|
|
204
|
+
const materialized = typeof value === "function" ? value() : value;
|
|
205
|
+
progress = progress.then(() => {
|
|
206
|
+
if (progressState.failed)
|
|
207
|
+
return;
|
|
208
|
+
return progressHandler(materialized);
|
|
209
|
+
}).then(() => undefined).catch((error) => {
|
|
210
|
+
if (progressState.failed)
|
|
211
|
+
return;
|
|
212
|
+
progressState.failed = true;
|
|
213
|
+
progressState.error = error;
|
|
214
|
+
if (session)
|
|
215
|
+
void session.abort().catch(() => undefined);
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
const flushProgress = async () => {
|
|
219
|
+
await progress;
|
|
220
|
+
if (progressState.failed)
|
|
221
|
+
throw progressState.error;
|
|
222
|
+
};
|
|
223
|
+
const throwIfProgressFailed = () => { if (progressState.failed)
|
|
224
|
+
throw progressState.error; };
|
|
225
|
+
const recordSystemPrompt = (entry) => {
|
|
226
|
+
systemPromptWrite = systemPromptWrite.then(() => callbacks?.onSystemPrompt?.(entry)).catch((error) => { systemPromptWriteError ??= error; });
|
|
227
|
+
};
|
|
228
|
+
const flushSystemPrompts = async () => {
|
|
229
|
+
await systemPromptWrite;
|
|
230
|
+
if (systemPromptWriteError !== undefined)
|
|
231
|
+
throw new WorkflowError("INTERNAL_ERROR", `Failed to persist effective system prompt: ${errorText(systemPromptWriteError)}`);
|
|
232
|
+
};
|
|
233
|
+
const policy = request.turnPolicy;
|
|
234
|
+
const turnPolicyError = (error) => error instanceof WorkflowError ? error : new WorkflowError("BUDGET_EXHAUSTED", errorText(error));
|
|
235
|
+
const beginTurn = (abortOnFailure = true) => {
|
|
236
|
+
if (!policy || turnStarted)
|
|
237
|
+
return;
|
|
238
|
+
try {
|
|
239
|
+
policy.beforeTurn();
|
|
240
|
+
turnStarted = true;
|
|
241
|
+
}
|
|
242
|
+
catch (error) {
|
|
243
|
+
turnPolicyFailure ??= turnPolicyError(error);
|
|
244
|
+
if (abortOnFailure && session)
|
|
245
|
+
void session.abort().catch(() => undefined);
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
const throwIfTurnPolicyFailed = () => { const failure = turnPolicyFailure; if (failure)
|
|
249
|
+
throw failure; };
|
|
250
|
+
const completeTurn = (final, steerInstruction, force = false) => {
|
|
251
|
+
if (!policy) {
|
|
252
|
+
turnStarted = false;
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
if (turnPolicyFailure && !force) {
|
|
256
|
+
turnStarted = false;
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
const instruction = policy.afterTurn(runtimeUsage(session), final, steerInstruction);
|
|
261
|
+
if (steerInstruction && instruction && session)
|
|
262
|
+
void session.steer(instruction).catch(() => undefined);
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
turnPolicyFailure ??= turnPolicyError(error);
|
|
266
|
+
if (session)
|
|
267
|
+
void session.abort().catch(() => undefined);
|
|
268
|
+
}
|
|
269
|
+
turnStarted = false;
|
|
270
|
+
};
|
|
271
|
+
const acceptAssistant = (candidate) => {
|
|
272
|
+
if (isEmptyAbortedAssistant(candidate)) {
|
|
273
|
+
const previous = session?.getLastAssistant();
|
|
274
|
+
if (previous && !isEmptyAbortedAssistant(previous))
|
|
275
|
+
lastAssistant = previous;
|
|
276
|
+
}
|
|
277
|
+
else if (candidate)
|
|
278
|
+
lastAssistant = candidate;
|
|
279
|
+
};
|
|
280
|
+
const throwIfCancelled = () => { if (request.signal.aborted)
|
|
281
|
+
throw new WorkflowError("CANCELLED", "Agent cancelled"); };
|
|
282
|
+
try {
|
|
283
|
+
session = await this.#options.transport.createSession(preparedForSession, this.#options.context);
|
|
284
|
+
if (session.reference.transport !== this.#options.transport.id) {
|
|
285
|
+
const actualTransport = session.reference.transport;
|
|
286
|
+
disposeStarted = true;
|
|
287
|
+
await session.dispose();
|
|
288
|
+
session = undefined;
|
|
289
|
+
throw new WorkflowError("INTERNAL_ERROR", `Agent transport ${this.#options.transport.id} created a session for ${actualTransport}`);
|
|
290
|
+
}
|
|
291
|
+
sessionReady = true;
|
|
292
|
+
const createdAdapter = createPiRuntimeSessionAdapter(session, handoff);
|
|
293
|
+
adapter = createdAdapter;
|
|
294
|
+
await callbacks?.onSession?.(session, handoff, preparedForSession);
|
|
295
|
+
const activeSession = session;
|
|
296
|
+
const runtimeHandoff = request.handoff ?? adapter.handoff;
|
|
297
|
+
const preparedTools = new Set([...preparedForSession.tools, ...(preparedForSession.customTools ?? []).map(({ name }) => name), ...(preparedForSession.resultTool ? [preparedForSession.resultTool.name] : [])]);
|
|
298
|
+
if (session.getState().tools.some((tool) => !preparedTools.has(tool)))
|
|
299
|
+
throw new WorkflowError("INTERNAL_ERROR", `Agent transport ${this.#options.transport.id} widened the prepared tool policy`);
|
|
300
|
+
await callbacks?.onSessionReady?.();
|
|
301
|
+
const handleSessionEvent = async (event) => {
|
|
302
|
+
const observation = adapter?.observe(event);
|
|
303
|
+
if (!observation || !session)
|
|
304
|
+
return;
|
|
305
|
+
const observedEvent = observation.event;
|
|
306
|
+
if (isTurnEnd(observedEvent.type))
|
|
307
|
+
handoffBoundaryAssistant = observedEvent.message?.role === "assistant" ? observedEvent.message : session.getLastAssistant() ?? lastAssistant;
|
|
308
|
+
if (runtimeHandoff !== adapter?.handoff)
|
|
309
|
+
runtimeHandoff.observe({ type: observedEvent.type });
|
|
310
|
+
if (isTurnEnd(observedEvent.type) && runtimeHandoff.state === "takeover-pending")
|
|
311
|
+
void session.abort().catch(() => undefined);
|
|
312
|
+
if (observedEvent.type === "agent_start" && session.getState().systemPrompt !== undefined) {
|
|
313
|
+
systemPromptTurn += 1;
|
|
314
|
+
recordSystemPrompt({ sessionId: session.reference.sessionId, turn: systemPromptTurn, prompt: session.getState().systemPrompt ?? "" });
|
|
315
|
+
}
|
|
316
|
+
if (isTurnBoundaryStart(observedEvent.type) || (observedEvent.type === "message_start" && observedEvent.message?.role === "assistant"))
|
|
317
|
+
beginTurn();
|
|
318
|
+
if (observedEvent.type === "message_end" && observedEvent.message?.role === "assistant") {
|
|
319
|
+
acceptAssistant(observedEvent.message);
|
|
320
|
+
const final = !hasToolCall(observedEvent.message) || hasResult();
|
|
321
|
+
completeTurn(final, !final);
|
|
322
|
+
}
|
|
323
|
+
if (observation.report)
|
|
324
|
+
report(() => observation.progress);
|
|
325
|
+
};
|
|
326
|
+
if (session.subscribeAsync)
|
|
327
|
+
unsubscribe = session.subscribeAsync((event) => { const notification = handleSessionEvent(event); trackEvent(notification); return notification; });
|
|
328
|
+
else
|
|
329
|
+
unsubscribe = session.subscribe((event) => { trackEvent(handleSessionEvent(event)); });
|
|
330
|
+
report(() => createdAdapter.snapshot(false));
|
|
331
|
+
await request.onControl?.({ handoff: runtimeHandoff, steer: (message) => activeSession.steer(message) });
|
|
332
|
+
const promptOnce = async (prompt, turnAlreadyStarted = false) => {
|
|
333
|
+
if (!turnAlreadyStarted)
|
|
334
|
+
beginTurn();
|
|
335
|
+
throwIfTurnPolicyFailed();
|
|
336
|
+
const response = await promptWithProviderPause(session, prompt, request.timeoutMs, started, request);
|
|
337
|
+
acceptAssistant(normalizePiMessage(response.assistant));
|
|
338
|
+
await flushEvents();
|
|
339
|
+
};
|
|
340
|
+
const recoverTerminal = async () => {
|
|
341
|
+
let continued = false;
|
|
342
|
+
for (;;) {
|
|
343
|
+
if (hasResult())
|
|
344
|
+
return continued;
|
|
345
|
+
const failure = providerFailure(session, lastAssistant);
|
|
346
|
+
if (!failure)
|
|
347
|
+
return continued;
|
|
348
|
+
if (!request.onProviderError)
|
|
349
|
+
throw new RuntimeAgentProviderError(failure, undefined, false);
|
|
350
|
+
let recovery;
|
|
351
|
+
try {
|
|
352
|
+
recovery = await request.onProviderError(failure);
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
throw new RuntimeAgentProviderError({ ...failure, error: `${failure.error} (provider recovery failed: ${errorText(error)})` }, undefined, true);
|
|
356
|
+
}
|
|
357
|
+
if (recovery !== "retry")
|
|
358
|
+
throw new RuntimeAgentProviderError(failure, recovery, true);
|
|
359
|
+
continued = true;
|
|
360
|
+
try {
|
|
361
|
+
await promptOnce(providerContinuationPrompt);
|
|
362
|
+
}
|
|
363
|
+
catch (error) {
|
|
364
|
+
acceptAssistant(session?.getLastAssistant() ?? lastAssistant);
|
|
365
|
+
if (!hasResult())
|
|
366
|
+
throw error;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
const promptAndRecover = async (prompt, turnAlreadyStarted = false) => {
|
|
371
|
+
let promptFailed = false;
|
|
372
|
+
let promptError;
|
|
373
|
+
try {
|
|
374
|
+
await promptOnce(prompt, turnAlreadyStarted);
|
|
375
|
+
}
|
|
376
|
+
catch (error) {
|
|
377
|
+
acceptAssistant(session?.getLastAssistant() ?? lastAssistant);
|
|
378
|
+
promptFailed = true;
|
|
379
|
+
promptError = error;
|
|
380
|
+
}
|
|
381
|
+
const handoffWasAttempted = runtimeHandoff.state !== "local-running";
|
|
382
|
+
throwIfCancelled();
|
|
383
|
+
throwIfProgressFailed();
|
|
384
|
+
const suppressHandoffAbort = handoffWasAttempted && !handoffAbortHandled && isHandoffAbort(lastAssistant);
|
|
385
|
+
if (suppressHandoffAbort)
|
|
386
|
+
handoffAbortHandled = true;
|
|
387
|
+
const recovered = suppressHandoffAbort ? false : await recoverTerminal();
|
|
388
|
+
const preHandoffAssistant = handoffBoundaryAssistant;
|
|
389
|
+
handoffBoundaryAssistant = undefined;
|
|
390
|
+
throwIfCancelled();
|
|
391
|
+
await runtimeHandoff.waitForResume();
|
|
392
|
+
throwIfCancelled();
|
|
393
|
+
const resumed = session?.getLastAssistant();
|
|
394
|
+
const preservePreHandoffResult = runtimeHandoff.transferred && isTerminalAssistant(preHandoffAssistant);
|
|
395
|
+
if (preservePreHandoffResult)
|
|
396
|
+
lastAssistant = preHandoffAssistant;
|
|
397
|
+
else
|
|
398
|
+
acceptAssistant(resumed);
|
|
399
|
+
let handoffError;
|
|
400
|
+
let handoffRecovered = false;
|
|
401
|
+
if (runtimeHandoff.transferred && !preservePreHandoffResult && !hasResult() && (!resumed || resumed.stopReason === "aborted" || isHandoffAbort(resumed) || hasToolCall(resumed))) {
|
|
402
|
+
try {
|
|
403
|
+
await promptOnce(handoffContinuationPrompt);
|
|
404
|
+
}
|
|
405
|
+
catch (error) {
|
|
406
|
+
handoffError = error;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (handoffWasAttempted && !runtimeHandoff.transferred && promptFailed && !hasResult()) {
|
|
410
|
+
try {
|
|
411
|
+
await promptOnce(handoffContinuationPrompt);
|
|
412
|
+
handoffRecovered = true;
|
|
413
|
+
}
|
|
414
|
+
catch (error) {
|
|
415
|
+
handoffError = error;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (handoffError && !hasResult())
|
|
419
|
+
throw handoffError instanceof Error ? handoffError : new Error(errorText(handoffError));
|
|
420
|
+
if (promptFailed && !hasResult() && !recovered && !handoffRecovered && !runtimeHandoff.transferred)
|
|
421
|
+
throw promptError instanceof Error ? promptError : new Error(errorText(promptError));
|
|
422
|
+
};
|
|
423
|
+
throwIfProgressFailed();
|
|
424
|
+
beginTurn(false);
|
|
425
|
+
throwIfTurnPolicyFailed();
|
|
426
|
+
await promptAndRecover(request.task, true);
|
|
427
|
+
completeTurn(hasResult() || !hasToolCall(lastAssistant), false, true);
|
|
428
|
+
if (turnPolicyFailure)
|
|
429
|
+
throw turnPolicyFailure;
|
|
430
|
+
if (!hasResult()) {
|
|
431
|
+
throwIfProgressFailed();
|
|
432
|
+
beginTurn(false);
|
|
433
|
+
throwIfTurnPolicyFailed();
|
|
434
|
+
await promptAndRecover("Submit the final result now by calling workflow_result exactly once. Do not return prose.", true);
|
|
435
|
+
completeTurn(true, false, true);
|
|
436
|
+
}
|
|
437
|
+
if (!hasResult()) {
|
|
438
|
+
throwIfProgressFailed();
|
|
439
|
+
beginTurn(false);
|
|
440
|
+
throwIfTurnPolicyFailed();
|
|
441
|
+
await promptAndRecover("Your result was missing or invalid. Repair it by calling workflow_result exactly once with a schema-valid value.", true);
|
|
442
|
+
completeTurn(true, false, true);
|
|
443
|
+
}
|
|
444
|
+
if (!hasResult())
|
|
445
|
+
throw new WorkflowError("RESULT_INVALID", "Agent did not submit a valid workflow_result after one repair");
|
|
446
|
+
await callbacks?.onBeforeComplete?.();
|
|
447
|
+
report(() => createdAdapter.snapshot(true));
|
|
448
|
+
await flushProgress();
|
|
449
|
+
await flushEvents();
|
|
450
|
+
await flushSystemPrompts();
|
|
451
|
+
unsubscribe();
|
|
452
|
+
createdAdapter.dispose();
|
|
453
|
+
adapter = undefined;
|
|
454
|
+
const value = request.resultSchema === undefined ? unstructuredResult(structuredResult) : structuredResult;
|
|
455
|
+
if (value === undefined)
|
|
456
|
+
throw new WorkflowError("RESULT_INVALID", "Agent did not submit a valid workflow_result after one repair");
|
|
457
|
+
const result = { value, usage: runtimeUsage(session), reference: { transport: session.reference.transport, ...(session.reference.locator === undefined ? {} : { locator: runtimeValue(session.reference.locator) }) } };
|
|
458
|
+
successfulInvocation = true;
|
|
459
|
+
await callbacks?.onComplete?.(result, session);
|
|
460
|
+
disposeStarted = true;
|
|
461
|
+
await session.dispose();
|
|
462
|
+
session = undefined;
|
|
463
|
+
return result;
|
|
464
|
+
}
|
|
465
|
+
catch (error) {
|
|
466
|
+
const typed = turnPolicyFailure ?? normalizePiRuntimeError(error, request.signal);
|
|
467
|
+
if (session && sessionReady) {
|
|
468
|
+
const activeSession = session;
|
|
469
|
+
const activeAdapter = adapter;
|
|
470
|
+
report(() => activeAdapter?.snapshot(true) ?? { usage: runtimeUsage(activeSession), toolCalls: [], state: activeSession.getState(), persist: true });
|
|
471
|
+
//NOTE: best-effort telemetry flush during teardown; the agent failure is rethrown after this block, so dropping the flush must not mask the primary error.
|
|
472
|
+
await flushProgress().catch(() => undefined);
|
|
473
|
+
await flushEvents().catch(() => undefined);
|
|
474
|
+
await flushSystemPrompts().catch(() => undefined);
|
|
475
|
+
unsubscribe?.();
|
|
476
|
+
activeAdapter?.dispose();
|
|
477
|
+
adapter = undefined;
|
|
478
|
+
if (!successfulInvocation && !turnPolicyFailure && typed.code !== "BUDGET_EXHAUSTED") {
|
|
479
|
+
try {
|
|
480
|
+
request.turnPolicy?.afterTurn(runtimeUsage(activeSession), true);
|
|
481
|
+
}
|
|
482
|
+
catch (budgetFailure) {
|
|
483
|
+
turnPolicyFailure ??= turnPolicyError(budgetFailure);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
let callbackFailure;
|
|
487
|
+
if (!successfulInvocation) {
|
|
488
|
+
try {
|
|
489
|
+
await callbacks?.onFailure?.(turnPolicyFailure ?? typed, activeSession);
|
|
490
|
+
}
|
|
491
|
+
catch (failure) {
|
|
492
|
+
callbackFailure = failure;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
if (!disposeStarted) {
|
|
496
|
+
await activeSession.dispose().catch(() => undefined);
|
|
497
|
+
}
|
|
498
|
+
if (callbackFailure !== undefined)
|
|
499
|
+
throw callbackFailure instanceof Error ? callbackFailure : new Error(errorText(callbackFailure));
|
|
500
|
+
}
|
|
501
|
+
throw turnPolicyFailure ?? (error instanceof Error ? error : new Error(errorText(error)));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
export function createPiRuntimeAgentRunner(options) { return new PiRuntimeAgentRunner(options); }
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { AgentAttemptAction, JsonValue, RegisteredAgentSetupHook, WorkflowCatalog, WorkflowCatalogContext, WorkflowCatalogError, WorkflowCatalogFunction, WorkflowCatalogIndex, WorkflowCatalogModelAlias, WorkflowExtension, WorkflowExtensionSettings, WorkflowExtensionSettingsValidatorContext, WorkflowFunction, WorkflowFunctionContext, WorkflowFunctionSource, WorkflowJournal, WorkflowModelAlias, WorkflowModelAliasResolverContext, WorkflowRoleDirectoryRegistration } from "./types.js";
|
|
2
|
+
import type { SubagentRunRequest, SubagentStatus } from "../subagents/src/contracts.js";
|
|
3
|
+
export type SubagentStatusObserver = (status: Readonly<SubagentStatus>, request: Readonly<SubagentRunRequest>) => void;
|
|
4
|
+
export declare class WorkflowRegistry {
|
|
5
|
+
#private;
|
|
6
|
+
get frozen(): boolean;
|
|
7
|
+
freeze(): void;
|
|
8
|
+
setSubagentStatusObserver(observer: SubagentStatusObserver | undefined): void;
|
|
9
|
+
observeSubagentStatus(status: Readonly<SubagentStatus>, request: Readonly<SubagentRunRequest>): void;
|
|
10
|
+
register(extension: WorkflowExtension): void;
|
|
11
|
+
function(name: string): WorkflowFunction;
|
|
12
|
+
functions(): Readonly<Record<string, WorkflowFunction>>;
|
|
13
|
+
functionSources(): Readonly<Record<string, WorkflowFunctionSource>>;
|
|
14
|
+
catalog(context?: WorkflowCatalogContext): WorkflowCatalog;
|
|
15
|
+
catalogIndex(context?: WorkflowCatalogContext): WorkflowCatalogIndex;
|
|
16
|
+
catalogDetail(name: string, context?: WorkflowCatalogContext): WorkflowCatalogFunction | WorkflowCatalogModelAlias | WorkflowCatalogError;
|
|
17
|
+
globals(): Readonly<Record<string, {
|
|
18
|
+
name: string;
|
|
19
|
+
}>>;
|
|
20
|
+
validateExtensionSettings(settings: Readonly<WorkflowExtensionSettings> | undefined, context: WorkflowExtensionSettingsValidatorContext): void;
|
|
21
|
+
invokeFunction(name: string, input: unknown, context: Readonly<WorkflowFunctionContext>, path: string, journal: WorkflowJournal): Promise<JsonValue>;
|
|
22
|
+
agentSetupHooks(): readonly RegisteredAgentSetupHook[];
|
|
23
|
+
agentAttemptActions(): Readonly<Record<string, AgentAttemptAction>>;
|
|
24
|
+
roleDirectories(): readonly string[];
|
|
25
|
+
roleDirectoryRegistrations(): readonly WorkflowRoleDirectoryRegistration[];
|
|
26
|
+
modelAliases(): readonly {
|
|
27
|
+
name: string;
|
|
28
|
+
version: string;
|
|
29
|
+
headline: string;
|
|
30
|
+
resolve: WorkflowModelAlias["resolve"];
|
|
31
|
+
}[];
|
|
32
|
+
resolveModelAliases(context: Readonly<WorkflowModelAliasResolverContext>, shadowed?: ReadonlySet<string>): Promise<Readonly<Record<string, string>>>;
|
|
33
|
+
}
|
|
34
|
+
export type WorkflowRegistryApi = Pick<WorkflowRegistry, "frozen" | "freeze" | "register" | "function" | "functions" | "functionSources" | "catalog" | "catalogIndex" | "catalogDetail" | "globals" | "invokeFunction" | "validateExtensionSettings" | "modelAliases" | "resolveModelAliases" | "agentSetupHooks" | "agentAttemptActions" | "roleDirectories" | "roleDirectoryRegistrations" | "setSubagentStatusObserver" | "observeSubagentStatus">;
|
|
35
|
+
export declare function resetWorkflowRegistry(): void;
|
|
36
|
+
export declare function resetWorkflowRegistryIfIdle(): void;
|
|
37
|
+
export declare function beginWorkflowExtensionLoading(): void;
|
|
38
|
+
export declare function retainWorkflowRegistry(): () => void;
|
|
39
|
+
export declare function loadingRegistry(): WorkflowRegistryApi;
|
|
40
|
+
export declare function registerWorkflowExtension(extension: WorkflowExtension): void;
|
|
41
|
+
export declare function workflowCatalog(context?: WorkflowCatalogContext): WorkflowCatalog;
|
|
42
|
+
export declare function workflowCatalogIndex(context?: WorkflowCatalogContext): WorkflowCatalogIndex;
|
|
43
|
+
export declare function workflowCatalogDetail(name: string, context?: WorkflowCatalogContext): WorkflowCatalogFunction | WorkflowCatalogModelAlias | WorkflowCatalogError;
|
|
44
|
+
export declare function registeredWorkflowFunctions(): Readonly<Record<string, WorkflowFunction>>;
|
|
45
|
+
export declare function registeredWorkflowFunctionSources(): Readonly<Record<string, WorkflowFunctionSource>>;
|
|
46
|
+
export declare function registeredWorkflowRoleDirectories(): readonly string[];
|
|
47
|
+
export declare function registeredWorkflowRoleDirectoryRegistrations(): readonly WorkflowRoleDirectoryRegistration[];
|
|
48
|
+
export type { WorkflowCatalog, WorkflowCatalogContext, WorkflowCatalogError, WorkflowCatalogFunction, WorkflowCatalogIndex, WorkflowCatalogIndexFunction, WorkflowCatalogModelAlias, WorkflowCatalogSettings, WorkflowRoleDirectoryRegistration } from "./types.js";
|