wave-agent-sdk 0.17.1 → 0.17.2
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/builtin/skills/deep-research/SKILL.md +90 -0
- package/builtin/skills/settings/ENV.md +6 -3
- package/dist/agent.d.ts +28 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +128 -34
- package/dist/constants/goalPrompts.d.ts +2 -0
- package/dist/constants/goalPrompts.d.ts.map +1 -0
- package/dist/constants/goalPrompts.js +10 -0
- package/dist/constants/tools.d.ts +1 -0
- package/dist/constants/tools.d.ts.map +1 -1
- package/dist/constants/tools.js +1 -0
- package/dist/managers/aiManager.d.ts +7 -0
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +77 -41
- package/dist/managers/backgroundTaskManager.d.ts.map +1 -1
- package/dist/managers/backgroundTaskManager.js +10 -2
- package/dist/managers/goalManager.d.ts +43 -0
- package/dist/managers/goalManager.d.ts.map +1 -0
- package/dist/managers/goalManager.js +177 -0
- package/dist/managers/messageManager.d.ts +2 -2
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageQueue.d.ts +10 -0
- package/dist/managers/messageQueue.d.ts.map +1 -1
- package/dist/managers/messageQueue.js +53 -1
- package/dist/managers/pluginManager.d.ts.map +1 -1
- package/dist/managers/pluginManager.js +7 -1
- package/dist/managers/skillManager.d.ts +2 -0
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +19 -9
- package/dist/managers/slashCommandManager.d.ts +6 -0
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +105 -0
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +5 -0
- package/dist/managers/workflowManager.d.ts +65 -0
- package/dist/managers/workflowManager.d.ts.map +1 -0
- package/dist/managers/workflowManager.js +380 -0
- package/dist/prompts/index.d.ts +2 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +3 -3
- package/dist/services/aiService.d.ts +23 -0
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +102 -9
- package/dist/services/configurationService.d.ts +1 -1
- package/dist/services/configurationService.d.ts.map +1 -1
- package/dist/services/configurationService.js +3 -16
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +4 -0
- package/dist/services/session.d.ts +9 -1
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +28 -1
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +49 -7
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +1 -1
- package/dist/tools/taskManagementTools.d.ts.map +1 -1
- package/dist/tools/taskManagementTools.js +103 -157
- package/dist/tools/types.d.ts +2 -0
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/webFetchTool.d.ts.map +1 -1
- package/dist/tools/webFetchTool.js +0 -9
- package/dist/tools/workflowTool.d.ts +11 -0
- package/dist/tools/workflowTool.d.ts.map +1 -0
- package/dist/tools/workflowTool.js +190 -0
- package/dist/types/agent.d.ts +2 -0
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/commands.d.ts +4 -0
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/config.d.ts +2 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/core.d.ts +1 -1
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/hooks.d.ts +2 -0
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/messaging.d.ts +2 -2
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/processes.d.ts +6 -2
- package/dist/types/processes.d.ts.map +1 -1
- package/dist/types/workflow.d.ts +2 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +1 -0
- package/dist/utils/cacheControlUtils.d.ts +13 -8
- package/dist/utils/cacheControlUtils.d.ts.map +1 -1
- package/dist/utils/cacheControlUtils.js +73 -102
- package/dist/utils/containerSetup.d.ts.map +1 -1
- package/dist/utils/containerSetup.js +7 -0
- package/dist/utils/markdownParser.d.ts.map +1 -1
- package/dist/utils/markdownParser.js +21 -6
- package/dist/utils/messageOperations.d.ts +2 -2
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/notificationXml.d.ts.map +1 -1
- package/dist/workflow/budgetTracker.d.ts +12 -0
- package/dist/workflow/budgetTracker.d.ts.map +1 -0
- package/dist/workflow/budgetTracker.js +30 -0
- package/dist/workflow/concurrencyLimiter.d.ts +14 -0
- package/dist/workflow/concurrencyLimiter.d.ts.map +1 -0
- package/dist/workflow/concurrencyLimiter.js +39 -0
- package/dist/workflow/journal.d.ts +19 -0
- package/dist/workflow/journal.d.ts.map +1 -0
- package/dist/workflow/journal.js +74 -0
- package/dist/workflow/progressReporter.d.ts +21 -0
- package/dist/workflow/progressReporter.d.ts.map +1 -0
- package/dist/workflow/progressReporter.js +118 -0
- package/dist/workflow/runState.d.ts +16 -0
- package/dist/workflow/runState.d.ts.map +1 -0
- package/dist/workflow/runState.js +57 -0
- package/dist/workflow/scriptRuntime.d.ts +35 -0
- package/dist/workflow/scriptRuntime.d.ts.map +1 -0
- package/dist/workflow/scriptRuntime.js +196 -0
- package/dist/workflow/structuredOutput.d.ts +27 -0
- package/dist/workflow/structuredOutput.d.ts.map +1 -0
- package/dist/workflow/structuredOutput.js +106 -0
- package/dist/workflow/types.d.ts +81 -0
- package/dist/workflow/types.d.ts.map +1 -0
- package/dist/workflow/types.js +1 -0
- package/dist/workflow/workflowApis.d.ts +46 -0
- package/dist/workflow/workflowApis.d.ts.map +1 -0
- package/dist/workflow/workflowApis.js +280 -0
- package/package.json +1 -1
- package/src/agent.ts +144 -34
- package/src/constants/goalPrompts.ts +10 -0
- package/src/constants/tools.ts +1 -0
- package/src/managers/aiManager.ts +91 -47
- package/src/managers/backgroundTaskManager.ts +16 -4
- package/src/managers/goalManager.ts +232 -0
- package/src/managers/messageManager.ts +2 -2
- package/src/managers/messageQueue.ts +59 -1
- package/src/managers/pluginManager.ts +8 -1
- package/src/managers/skillManager.ts +20 -9
- package/src/managers/slashCommandManager.ts +119 -0
- package/src/managers/toolManager.ts +7 -0
- package/src/managers/workflowManager.ts +491 -0
- package/src/prompts/index.ts +4 -2
- package/src/services/aiService.ts +166 -12
- package/src/services/configurationService.ts +2 -22
- package/src/services/hook.ts +5 -0
- package/src/services/session.ts +42 -2
- package/src/tools/bashTool.ts +64 -9
- package/src/tools/readTool.ts +1 -2
- package/src/tools/taskManagementTools.ts +146 -195
- package/src/tools/types.ts +2 -0
- package/src/tools/webFetchTool.ts +0 -12
- package/src/tools/workflowTool.ts +205 -0
- package/src/types/agent.ts +6 -0
- package/src/types/commands.ts +4 -0
- package/src/types/config.ts +2 -2
- package/src/types/core.ts +3 -3
- package/src/types/hooks.ts +2 -0
- package/src/types/index.ts +1 -0
- package/src/types/messaging.ts +2 -2
- package/src/types/processes.ts +10 -2
- package/src/types/workflow.ts +5 -0
- package/src/utils/cacheControlUtils.ts +106 -131
- package/src/utils/containerSetup.ts +9 -0
- package/src/utils/markdownParser.ts +26 -8
- package/src/utils/messageOperations.ts +2 -2
- package/src/utils/notificationXml.ts +6 -1
- package/src/workflow/budgetTracker.ts +34 -0
- package/src/workflow/concurrencyLimiter.ts +47 -0
- package/src/workflow/journal.ts +95 -0
- package/src/workflow/progressReporter.ts +141 -0
- package/src/workflow/runState.ts +65 -0
- package/src/workflow/scriptRuntime.ts +274 -0
- package/src/workflow/structuredOutput.ts +123 -0
- package/src/workflow/types.ts +95 -0
- package/src/workflow/workflowApis.ts +412 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { logger } from "../utils/globalLogger.js";
|
|
2
|
+
/** Patterns that are banned in workflow scripts for safety and determinism */
|
|
3
|
+
const BANNED_PATTERNS = [
|
|
4
|
+
{
|
|
5
|
+
pattern: /\brequire\s*\(/,
|
|
6
|
+
message: "require() is not available in workflow scripts",
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
pattern: /\bprocess\./,
|
|
10
|
+
message: "process.* is not available in workflow scripts",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
pattern: /\beval\s*\(/,
|
|
14
|
+
message: "eval() is not available in workflow scripts",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
pattern: /\bimport\s+/,
|
|
18
|
+
message: "import statements are not available in workflow scripts",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
pattern: /\bDate\.now\s*\(/,
|
|
22
|
+
message: "Date.now() would break resume determinism",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
pattern: /\bMath\.random\s*\(/,
|
|
26
|
+
message: "Math.random() would break resume determinism",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
pattern: /\bnew\s+Date\s*\(\s*\)/,
|
|
30
|
+
message: "argless new Date() would break resume determinism",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
pattern: /\brequire\s*\(\s*['"]fs['"]\s*\)/,
|
|
34
|
+
message: "filesystem access is not available in workflow scripts",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
pattern: /\bfs\.\w+/,
|
|
38
|
+
message: "filesystem access is not available in workflow scripts",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
pattern: /\bchild_process\b/,
|
|
42
|
+
message: "child_process is not available in workflow scripts",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
pattern: /\b__dirname\b/,
|
|
46
|
+
message: "__dirname is not available in workflow scripts",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
pattern: /\b__filename\b/,
|
|
50
|
+
message: "__filename is not available in workflow scripts",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
pattern: /\bglobal\./,
|
|
54
|
+
message: "global.* is not available in workflow scripts",
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
pattern: /\bglobalThis\b/,
|
|
58
|
+
message: "globalThis is not available in workflow scripts",
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
/**
|
|
62
|
+
* Validate a workflow script for banned patterns and required structure
|
|
63
|
+
*/
|
|
64
|
+
export function validateScript(script) {
|
|
65
|
+
const errors = [];
|
|
66
|
+
// Check for export const meta = {...}
|
|
67
|
+
if (!/export\s+const\s+meta\s*=/.test(script)) {
|
|
68
|
+
errors.push("Script must start with 'export const meta = {...}'");
|
|
69
|
+
}
|
|
70
|
+
// Check banned patterns
|
|
71
|
+
for (const { pattern, message } of BANNED_PATTERNS) {
|
|
72
|
+
if (pattern.test(script)) {
|
|
73
|
+
errors.push(message);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return { valid: errors.length === 0, errors };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Parse a workflow script into meta and body.
|
|
80
|
+
* Extracts the `export const meta = {...}` declaration and the rest of the script.
|
|
81
|
+
*/
|
|
82
|
+
export function parseScript(script) {
|
|
83
|
+
// Match: export const meta = { ... }
|
|
84
|
+
// We need to find the matching closing brace for the meta object
|
|
85
|
+
const metaStartMatch = script.match(/export\s+const\s+meta\s*=\s*/);
|
|
86
|
+
if (!metaStartMatch) {
|
|
87
|
+
throw new Error("Script must contain 'export const meta = {...}'");
|
|
88
|
+
}
|
|
89
|
+
const metaStartIndex = metaStartMatch.index + metaStartMatch[0].length;
|
|
90
|
+
// Find the matching closing brace for the meta object
|
|
91
|
+
let depth = 0;
|
|
92
|
+
let metaEndIndex = -1;
|
|
93
|
+
let inString = null;
|
|
94
|
+
let escaped = false;
|
|
95
|
+
for (let i = metaStartIndex; i < script.length; i++) {
|
|
96
|
+
const char = script[i];
|
|
97
|
+
if (escaped) {
|
|
98
|
+
escaped = false;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (char === "\\") {
|
|
102
|
+
escaped = true;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (inString) {
|
|
106
|
+
if (char === inString) {
|
|
107
|
+
inString = null;
|
|
108
|
+
}
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (char === '"' || char === "'" || char === "`") {
|
|
112
|
+
inString = char;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (char === "{") {
|
|
116
|
+
depth++;
|
|
117
|
+
}
|
|
118
|
+
else if (char === "}") {
|
|
119
|
+
depth--;
|
|
120
|
+
if (depth === 0) {
|
|
121
|
+
metaEndIndex = i + 1;
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (metaEndIndex === -1) {
|
|
127
|
+
throw new Error("Could not find matching closing brace for meta object");
|
|
128
|
+
}
|
|
129
|
+
const metaString = script.slice(metaStartIndex, metaEndIndex);
|
|
130
|
+
// Parse meta as JSON (allowing JS object syntax — unquoted keys, trailing commas)
|
|
131
|
+
// We use a safe approach: wrap in parentheses and use Function to evaluate
|
|
132
|
+
let meta;
|
|
133
|
+
try {
|
|
134
|
+
// Remove trailing comma before closing brace/bracket (common in JS objects)
|
|
135
|
+
const cleaned = metaString.replace(/,\s*([}\]])/g, "$1");
|
|
136
|
+
// Wrap unquoted keys with double quotes
|
|
137
|
+
const quoted = cleaned.replace(/(\w+)\s*:/g, '"$1":');
|
|
138
|
+
meta = JSON.parse(quoted);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
// Fallback: use Function constructor for safe evaluation
|
|
142
|
+
try {
|
|
143
|
+
const fn = new Function(`"use strict"; return (${metaString});`);
|
|
144
|
+
meta = fn();
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
throw new Error(`Failed to parse meta object: ${e instanceof Error ? e.message : String(e)}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Validate required meta fields
|
|
151
|
+
if (!meta.name || typeof meta.name !== "string") {
|
|
152
|
+
throw new Error("meta.name is required and must be a string");
|
|
153
|
+
}
|
|
154
|
+
if (!meta.description || typeof meta.description !== "string") {
|
|
155
|
+
throw new Error("meta.description is required and must be a string");
|
|
156
|
+
}
|
|
157
|
+
// Body is everything after the meta declaration (and any trailing semicolons/newlines)
|
|
158
|
+
const bodyStart = metaEndIndex;
|
|
159
|
+
const body = script.slice(bodyStart).replace(/^\s*;?\s*/, "");
|
|
160
|
+
return { meta, body };
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Execute a workflow script with the given API closures.
|
|
164
|
+
* The script body is wrapped in an async IIFE and executed via new Function().
|
|
165
|
+
*/
|
|
166
|
+
export async function executeScript(script, apis, abortSignal) {
|
|
167
|
+
// Validate first
|
|
168
|
+
const validation = validateScript(script);
|
|
169
|
+
if (!validation.valid) {
|
|
170
|
+
throw new Error(`Script validation failed:\n${validation.errors.join("\n")}`);
|
|
171
|
+
}
|
|
172
|
+
// Parse script
|
|
173
|
+
const { meta, body } = parseScript(script);
|
|
174
|
+
logger.info(`[Workflow] Executing script "${meta.name}": ${meta.description}`);
|
|
175
|
+
// Wrap the body in an async function and inject API closures
|
|
176
|
+
const fn = new Function("agent", "parallel", "pipeline", "phase", "log", "args", "budget", `"use strict"; return (async () => { ${body} })();`);
|
|
177
|
+
// Execute with abort support
|
|
178
|
+
const scriptPromise = fn(apis.agent, apis.parallel, apis.pipeline, apis.phase, apis.log, apis.args, apis.budget);
|
|
179
|
+
let result;
|
|
180
|
+
if (abortSignal) {
|
|
181
|
+
result = await Promise.race([
|
|
182
|
+
scriptPromise,
|
|
183
|
+
new Promise((_, reject) => {
|
|
184
|
+
if (abortSignal.aborted) {
|
|
185
|
+
reject(new Error("Workflow aborted"));
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
abortSignal.addEventListener("abort", () => reject(new Error("Workflow aborted")), { once: true });
|
|
189
|
+
}),
|
|
190
|
+
]);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
result = await scriptPromise;
|
|
194
|
+
}
|
|
195
|
+
return { meta, result };
|
|
196
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ToolPlugin } from "../tools/types.js";
|
|
2
|
+
declare const STRUCTURED_OUTPUT_TOOL_NAME = "StructuredOutput";
|
|
3
|
+
/**
|
|
4
|
+
* Creates a system prompt addition that instructs the agent to use structured output
|
|
5
|
+
*/
|
|
6
|
+
export declare function createStructuredOutputPrompt(schema: object): string;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a StructuredOutput ToolPlugin that enforces the given schema
|
|
9
|
+
*/
|
|
10
|
+
export declare function createStructuredOutputTool(schema: object): ToolPlugin;
|
|
11
|
+
/**
|
|
12
|
+
* Extract structured result from a completed subagent's messages.
|
|
13
|
+
* Looks for StructuredOutput tool calls in the messages.
|
|
14
|
+
* Falls back to JSON.parse on the last assistant message text.
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractStructuredResult(messages: Array<{
|
|
17
|
+
role: string;
|
|
18
|
+
content?: string;
|
|
19
|
+
tool_calls?: Array<{
|
|
20
|
+
function: {
|
|
21
|
+
name: string;
|
|
22
|
+
arguments: string;
|
|
23
|
+
};
|
|
24
|
+
}>;
|
|
25
|
+
}>, schema: object): unknown | null;
|
|
26
|
+
export { STRUCTURED_OUTPUT_TOOL_NAME };
|
|
27
|
+
//# sourceMappingURL=structuredOutput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structuredOutput.d.ts","sourceRoot":"","sources":["../../src/workflow/structuredOutput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,mBAAmB,CAAC;AAEhE,QAAA,MAAM,2BAA2B,qBAAqB,CAAC;AAEvD;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAqBrE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,KAAK,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC,CAAC;CACvE,CAAC,EACF,MAAM,EAAE,MAAM,GACb,OAAO,GAAG,IAAI,CAkDhB;AAuBD,OAAO,EAAE,2BAA2B,EAAE,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
const STRUCTURED_OUTPUT_TOOL_NAME = "StructuredOutput";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a system prompt addition that instructs the agent to use structured output
|
|
4
|
+
*/
|
|
5
|
+
export function createStructuredOutputPrompt(schema) {
|
|
6
|
+
return `\n\nIMPORTANT: You MUST call the ${STRUCTURED_OUTPUT_TOOL_NAME} tool with your final answer. Do not just write the answer as text — call the tool with a JSON object matching this schema:\n${JSON.stringify(schema, null, 2)}\n\nCall this tool exactly once with your complete answer.`;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Creates a StructuredOutput ToolPlugin that enforces the given schema
|
|
10
|
+
*/
|
|
11
|
+
export function createStructuredOutputTool(schema) {
|
|
12
|
+
return {
|
|
13
|
+
name: STRUCTURED_OUTPUT_TOOL_NAME,
|
|
14
|
+
config: {
|
|
15
|
+
type: "function",
|
|
16
|
+
function: {
|
|
17
|
+
name: STRUCTURED_OUTPUT_TOOL_NAME,
|
|
18
|
+
description: "Output structured data matching the required schema. Call this with your final answer.",
|
|
19
|
+
parameters: schema,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
execute: async (args) => {
|
|
23
|
+
// The tool just returns the args as-is — the real validation happens
|
|
24
|
+
// in extractStructuredResult after the agent completes
|
|
25
|
+
return {
|
|
26
|
+
success: true,
|
|
27
|
+
content: JSON.stringify(args),
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Extract structured result from a completed subagent's messages.
|
|
34
|
+
* Looks for StructuredOutput tool calls in the messages.
|
|
35
|
+
* Falls back to JSON.parse on the last assistant message text.
|
|
36
|
+
*/
|
|
37
|
+
export function extractStructuredResult(messages, schema) {
|
|
38
|
+
// Search messages in reverse for a StructuredOutput tool call
|
|
39
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
40
|
+
const msg = messages[i];
|
|
41
|
+
if (msg.tool_calls) {
|
|
42
|
+
for (const tc of msg.tool_calls) {
|
|
43
|
+
if (tc.function.name === STRUCTURED_OUTPUT_TOOL_NAME) {
|
|
44
|
+
try {
|
|
45
|
+
const parsed = JSON.parse(tc.function.arguments);
|
|
46
|
+
if (validateAgainstSchema(parsed, schema)) {
|
|
47
|
+
return parsed;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Parse error — continue searching
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Fallback: try to extract JSON from the last assistant message
|
|
58
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
59
|
+
const msg = messages[i];
|
|
60
|
+
if (msg.role === "assistant" && msg.content) {
|
|
61
|
+
// Try to find JSON in the content
|
|
62
|
+
const jsonMatch = msg.content.match(/```json\n([\s\S]*?)\n```/);
|
|
63
|
+
if (jsonMatch) {
|
|
64
|
+
try {
|
|
65
|
+
const parsed = JSON.parse(jsonMatch[1]);
|
|
66
|
+
if (validateAgainstSchema(parsed, schema)) {
|
|
67
|
+
return parsed;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Parse error — continue
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Try parsing the entire content as JSON
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(msg.content);
|
|
77
|
+
if (validateAgainstSchema(parsed, schema)) {
|
|
78
|
+
return parsed;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Not JSON — continue
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Basic schema validation — checks that required fields exist.
|
|
90
|
+
* This is intentionally lightweight; full JSON Schema validation
|
|
91
|
+
* would require a dependency like ajv.
|
|
92
|
+
*/
|
|
93
|
+
function validateAgainstSchema(data, schema) {
|
|
94
|
+
if (!data || typeof data !== "object")
|
|
95
|
+
return false;
|
|
96
|
+
const schemaObj = schema;
|
|
97
|
+
if (schemaObj.required && Array.isArray(schemaObj.required)) {
|
|
98
|
+
for (const field of schemaObj.required) {
|
|
99
|
+
if (!(field in data)) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
export { STRUCTURED_OUTPUT_TOOL_NAME };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export interface WorkflowMetaPhase {
|
|
2
|
+
title: string;
|
|
3
|
+
detail?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface WorkflowMeta {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
whenToUse?: string;
|
|
10
|
+
phases?: WorkflowMetaPhase[];
|
|
11
|
+
}
|
|
12
|
+
export interface WorkflowPhaseState {
|
|
13
|
+
title: string;
|
|
14
|
+
agentCount: number;
|
|
15
|
+
tokens: number;
|
|
16
|
+
elapsed: number;
|
|
17
|
+
startTime: number;
|
|
18
|
+
}
|
|
19
|
+
export interface WorkflowRun {
|
|
20
|
+
runId: string;
|
|
21
|
+
meta: WorkflowMeta;
|
|
22
|
+
status: "running" | "paused" | "completed" | "failed" | "aborted";
|
|
23
|
+
scriptPath: string;
|
|
24
|
+
args?: unknown;
|
|
25
|
+
startTime: number;
|
|
26
|
+
endTime?: number;
|
|
27
|
+
phases: WorkflowPhaseState[];
|
|
28
|
+
totalAgents: number;
|
|
29
|
+
totalTokens: number;
|
|
30
|
+
result?: unknown;
|
|
31
|
+
error?: string;
|
|
32
|
+
/** Resolves when the background execution finishes (completed/failed/aborted) */
|
|
33
|
+
completionPromise?: Promise<void>;
|
|
34
|
+
/** If set, this run resumes from a previous run's journal */
|
|
35
|
+
resumeFromRunId?: string;
|
|
36
|
+
/** Index of the agent that caused the workflow to fail */
|
|
37
|
+
failedAgentIndex?: number;
|
|
38
|
+
/** Error message from the failed agent */
|
|
39
|
+
failedAgentError?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface JournalEntry {
|
|
42
|
+
agentIndex: number;
|
|
43
|
+
prompt: string;
|
|
44
|
+
opts: Record<string, unknown>;
|
|
45
|
+
result: unknown;
|
|
46
|
+
tokens: number;
|
|
47
|
+
/** Subagent instance ID for linking to the full conversation transcript */
|
|
48
|
+
subagentId?: string;
|
|
49
|
+
/** Path to the subagent's transcript JSONL file */
|
|
50
|
+
transcriptPath?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface AgentMeta {
|
|
53
|
+
agentType: string;
|
|
54
|
+
subagentId: string;
|
|
55
|
+
transcriptPath: string;
|
|
56
|
+
label?: string;
|
|
57
|
+
phase?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface LogEntry {
|
|
60
|
+
type: "log";
|
|
61
|
+
message: string;
|
|
62
|
+
}
|
|
63
|
+
export interface AgentFailedEntry {
|
|
64
|
+
type: "agent_failed";
|
|
65
|
+
agentIndex: number;
|
|
66
|
+
error: string;
|
|
67
|
+
}
|
|
68
|
+
export type JournalLine = JournalEntry | LogEntry | AgentFailedEntry;
|
|
69
|
+
export interface BudgetInfo {
|
|
70
|
+
total: number | null;
|
|
71
|
+
spent: () => number;
|
|
72
|
+
remaining: () => number;
|
|
73
|
+
}
|
|
74
|
+
export interface WorkflowProgressEvent {
|
|
75
|
+
type: "phase_started" | "phase_completed" | "agent_started" | "agent_completed" | "agent_failed";
|
|
76
|
+
runId: string;
|
|
77
|
+
phaseIndex: number;
|
|
78
|
+
agentIndex?: number;
|
|
79
|
+
timestamp: number;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/workflow/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { SubagentManager } from "../managers/subagentManager.js";
|
|
2
|
+
import { ConcurrencyLimiter } from "./concurrencyLimiter.js";
|
|
3
|
+
import { BudgetTracker } from "./budgetTracker.js";
|
|
4
|
+
import { ProgressReporter } from "./progressReporter.js";
|
|
5
|
+
import { Journal } from "./journal.js";
|
|
6
|
+
import type { BudgetInfo, WorkflowProgressEvent } from "./types.js";
|
|
7
|
+
interface WorkflowApiContext {
|
|
8
|
+
subagentManager: SubagentManager;
|
|
9
|
+
concurrencyLimiter: ConcurrencyLimiter;
|
|
10
|
+
budgetTracker: BudgetTracker;
|
|
11
|
+
progressReporter: ProgressReporter;
|
|
12
|
+
journal: Journal;
|
|
13
|
+
abortSignal: AbortSignal;
|
|
14
|
+
args: unknown;
|
|
15
|
+
onLog?: (message: string) => void;
|
|
16
|
+
/** When resuming, offset the agent counter by this many existing entries */
|
|
17
|
+
initialAgentCount?: number;
|
|
18
|
+
/** Session directory for computing transcript paths */
|
|
19
|
+
sessionDir: string;
|
|
20
|
+
/** Per-run directory for writing agent metadata sidecars */
|
|
21
|
+
runDir: string;
|
|
22
|
+
/** Per-agent abort controllers for kill/skip support */
|
|
23
|
+
agentControllers: Map<number, AbortController>;
|
|
24
|
+
/** Optional callback for progress events */
|
|
25
|
+
onProgress?: (event: WorkflowProgressEvent) => void;
|
|
26
|
+
}
|
|
27
|
+
interface AgentOpts {
|
|
28
|
+
label?: string;
|
|
29
|
+
phase?: string;
|
|
30
|
+
schema?: object;
|
|
31
|
+
model?: string;
|
|
32
|
+
isolation?: string;
|
|
33
|
+
agentType?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface WorkflowApis {
|
|
36
|
+
agent: (prompt: string, opts?: AgentOpts) => Promise<unknown>;
|
|
37
|
+
parallel: (thunks: Array<() => Promise<unknown>>) => Promise<unknown[]>;
|
|
38
|
+
pipeline: (items: unknown[], ...stages: Array<(prev: unknown, item: unknown, index: number) => Promise<unknown>>) => Promise<unknown[]>;
|
|
39
|
+
phase: (title: string) => void;
|
|
40
|
+
log: (message: string) => void;
|
|
41
|
+
args: unknown;
|
|
42
|
+
budget: BudgetInfo;
|
|
43
|
+
}
|
|
44
|
+
export declare function createWorkflowApis(ctx: WorkflowApiContext): WorkflowApis;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=workflowApis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflowApis.d.ts","sourceRoot":"","sources":["../../src/workflow/workflowApis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAGtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAa,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAgC/E,UAAU,kBAAkB;IAC1B,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,aAAa,EAAE,aAAa,CAAC;IAC7B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAC;IACnB,4DAA4D;IAC5D,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/C,4CAA4C;IAC5C,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CACrD;AAED,UAAU,SAAS;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,QAAQ,EAAE,CACR,KAAK,EAAE,OAAO,EAAE,EAChB,GAAG,MAAM,EAAE,KAAK,CACd,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAClE,KACE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACxB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG,YAAY,CAuUxE"}
|