taskflow-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/analyst.md +30 -0
- package/dist/agents/critic.md +31 -0
- package/dist/agents/doc-writer.md +43 -0
- package/dist/agents/executor-code.md +36 -0
- package/dist/agents/executor-fast.md +26 -0
- package/dist/agents/executor-ui.md +35 -0
- package/dist/agents/executor.md +29 -0
- package/dist/agents/final-arbiter.md +29 -0
- package/dist/agents/plan-arbiter.md +35 -0
- package/dist/agents/planner.md +30 -0
- package/dist/agents/recover.md +28 -0
- package/dist/agents/reviewer.md +37 -0
- package/dist/agents/risk-reviewer.md +37 -0
- package/dist/agents/scout.md +51 -0
- package/dist/agents/security-reviewer.md +39 -0
- package/dist/agents/test-engineer.md +31 -0
- package/dist/agents/verifier.md +29 -0
- package/dist/agents/visual-explorer.md +32 -0
- package/dist/agents.d.ts +55 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +265 -0
- package/dist/agents.js.map +1 -0
- package/dist/cache.d.ts +57 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +256 -0
- package/dist/cache.js.map +1 -0
- package/dist/compile.d.ts +37 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +324 -0
- package/dist/compile.js.map +1 -0
- package/dist/context-store.d.ts +142 -0
- package/dist/context-store.d.ts.map +1 -0
- package/dist/context-store.js +383 -0
- package/dist/context-store.js.map +1 -0
- package/dist/detached-runner.d.ts +12 -0
- package/dist/detached-runner.d.ts.map +1 -0
- package/dist/detached-runner.js +68 -0
- package/dist/detached-runner.js.map +1 -0
- package/dist/flowir/hash.d.ts +51 -0
- package/dist/flowir/hash.d.ts.map +1 -0
- package/dist/flowir/hash.js +90 -0
- package/dist/flowir/hash.js.map +1 -0
- package/dist/flowir/index.d.ts +43 -0
- package/dist/flowir/index.d.ts.map +1 -0
- package/dist/flowir/index.js +62 -0
- package/dist/flowir/index.js.map +1 -0
- package/dist/flowir/meta.d.ts +103 -0
- package/dist/flowir/meta.d.ts.map +1 -0
- package/dist/flowir/meta.js +19 -0
- package/dist/flowir/meta.js.map +1 -0
- package/dist/flowir/phasefp.d.ts +55 -0
- package/dist/flowir/phasefp.d.ts.map +1 -0
- package/dist/flowir/phasefp.js +123 -0
- package/dist/flowir/phasefp.js.map +1 -0
- package/dist/flowir/translate.d.ts +37 -0
- package/dist/flowir/translate.d.ts.map +1 -0
- package/dist/flowir/translate.js +137 -0
- package/dist/flowir/translate.js.map +1 -0
- package/dist/frontmatter.d.ts +21 -0
- package/dist/frontmatter.d.ts.map +1 -0
- package/dist/frontmatter.js +107 -0
- package/dist/frontmatter.js.map +1 -0
- package/dist/host/runner-types.d.ts +98 -0
- package/dist/host/runner-types.d.ts.map +1 -0
- package/dist/host/runner-types.js +21 -0
- package/dist/host/runner-types.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/interpolate.d.ts +52 -0
- package/dist/interpolate.d.ts.map +1 -0
- package/dist/interpolate.js +418 -0
- package/dist/interpolate.js.map +1 -0
- package/dist/paths.d.ts +23 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +43 -0
- package/dist/paths.js.map +1 -0
- package/dist/runner-core.d.ts +49 -0
- package/dist/runner-core.d.ts.map +1 -0
- package/dist/runner-core.js +208 -0
- package/dist/runner-core.js.map +1 -0
- package/dist/runtime.d.ts +234 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +2284 -0
- package/dist/runtime.js.map +1 -0
- package/dist/schema.d.ts +257 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +795 -0
- package/dist/schema.js.map +1 -0
- package/dist/stale.d.ts +72 -0
- package/dist/stale.d.ts.map +1 -0
- package/dist/stale.js +179 -0
- package/dist/stale.js.map +1 -0
- package/dist/store.d.ts +237 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +761 -0
- package/dist/store.js.map +1 -0
- package/dist/typebox-helpers.d.ts +15 -0
- package/dist/typebox-helpers.d.ts.map +1 -0
- package/dist/typebox-helpers.js +19 -0
- package/dist/typebox-helpers.js.map +1 -0
- package/dist/usage.d.ts +21 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +33 -0
- package/dist/usage.js.map +1 -0
- package/dist/verify.d.ts +38 -0
- package/dist/verify.d.ts.map +1 -0
- package/dist/verify.js +324 -0
- package/dist/verify.js.map +1 -0
- package/dist/workspace.d.ts +64 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +178 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template interpolation for taskflow tasks.
|
|
3
|
+
*
|
|
4
|
+
* Supported placeholders:
|
|
5
|
+
* {args.X} invocation argument
|
|
6
|
+
* {steps.ID.output} prior phase final output (string)
|
|
7
|
+
* {steps.ID.json} prior phase output parsed as JSON (stringified back if object)
|
|
8
|
+
* {previous.output} alias for the immediately-preceding completed phase output
|
|
9
|
+
* {item} / {item.f} map loop variable (or custom name via phase.as)
|
|
10
|
+
*
|
|
11
|
+
* Unknown placeholders are left intact rather than throwing, so a
|
|
12
|
+
* partially-specified task still runs. The unresolved refs are returned in
|
|
13
|
+
* `missing[]`; the runtime surfaces them as a phase warning (see
|
|
14
|
+
* `warnUnresolvedRefs` in runtime.ts) — logged and persisted to
|
|
15
|
+
* `PhaseState.warnings`.
|
|
16
|
+
*/
|
|
17
|
+
const PLACEHOLDER = /\{([a-zA-Z0-9_-]+(?:\.[a-zA-Z0-9_-]+)*)\}/g;
|
|
18
|
+
export function interpolate(template, ctx) {
|
|
19
|
+
const missing = [];
|
|
20
|
+
const text = String(template ?? "").replace(PLACEHOLDER, (whole, path) => {
|
|
21
|
+
const value = resolvePath(path, ctx);
|
|
22
|
+
if (value === undefined) {
|
|
23
|
+
missing.push(path);
|
|
24
|
+
return whole;
|
|
25
|
+
}
|
|
26
|
+
return stringify(value);
|
|
27
|
+
});
|
|
28
|
+
return { text, missing };
|
|
29
|
+
}
|
|
30
|
+
/** Resolve + record an observed read (M3 observed-readSet). Fires only on
|
|
31
|
+
* successful resolution so an unresolved ref is NOT logged as a dependency
|
|
32
|
+
* (it stays a `missing` warning). The runtime threads a collector here to
|
|
33
|
+
* capture which upstream phases this phase actually consumed — the overstory
|
|
34
|
+
* "observed readSet@version" moat (nobody else records this). */
|
|
35
|
+
function resolvePath(path, ctx) {
|
|
36
|
+
const value = _resolvePath(path, ctx);
|
|
37
|
+
if (value !== undefined)
|
|
38
|
+
ctx.onRead?.(path);
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
41
|
+
function _resolvePath(path, ctx) {
|
|
42
|
+
const parts = path.split(".");
|
|
43
|
+
const head = parts[0];
|
|
44
|
+
// previous.output
|
|
45
|
+
if (head === "previous") {
|
|
46
|
+
if (parts[1] === "output")
|
|
47
|
+
return ctx.previousOutput ?? undefined;
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
// args.*
|
|
51
|
+
if (head === "args") {
|
|
52
|
+
return dig(ctx.args, parts.slice(1));
|
|
53
|
+
}
|
|
54
|
+
// steps.<id>.output | steps.<id>.json | steps.<id>.json.<field>
|
|
55
|
+
if (head === "steps") {
|
|
56
|
+
const stepId = parts[1];
|
|
57
|
+
const step = stepId ? ctx.steps[stepId] : undefined;
|
|
58
|
+
if (!step)
|
|
59
|
+
return undefined;
|
|
60
|
+
const field = parts[2];
|
|
61
|
+
if (field === "output") {
|
|
62
|
+
// Guard: {steps.X.output.trailing} — trailing segments after output are
|
|
63
|
+
// likely author errors (output is a string, not an object). Return
|
|
64
|
+
// undefined so the placeholder is left intact with a missing warning.
|
|
65
|
+
if (parts.length > 3)
|
|
66
|
+
return undefined;
|
|
67
|
+
return step.output;
|
|
68
|
+
}
|
|
69
|
+
if (field === "json") {
|
|
70
|
+
const json = step.json ?? safeParse(step.output);
|
|
71
|
+
return dig(json, parts.slice(3));
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
// locals (map loop variable), e.g. item / item.field
|
|
76
|
+
if (ctx.locals && head in ctx.locals) {
|
|
77
|
+
return dig(ctx.locals[head], parts.slice(1));
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Traverse an object by a sequence of property keys. Returns `undefined`
|
|
83
|
+
* when any segment is missing or the current value is not an object —
|
|
84
|
+
* never throws, so extra path segments like {steps.X.json.a.b} where the
|
|
85
|
+
* data is shallower resolve gracefully to undefined (M-8).
|
|
86
|
+
*/
|
|
87
|
+
function dig(obj, parts) {
|
|
88
|
+
let cur = obj;
|
|
89
|
+
for (const part of parts) {
|
|
90
|
+
if (cur === null || cur === undefined)
|
|
91
|
+
return undefined;
|
|
92
|
+
if (typeof cur !== "object")
|
|
93
|
+
return undefined;
|
|
94
|
+
cur = cur[part];
|
|
95
|
+
}
|
|
96
|
+
return cur;
|
|
97
|
+
}
|
|
98
|
+
function stringify(value) {
|
|
99
|
+
if (typeof value === "string")
|
|
100
|
+
return value;
|
|
101
|
+
if (value === null || value === undefined)
|
|
102
|
+
return "";
|
|
103
|
+
try {
|
|
104
|
+
return JSON.stringify(value, null, 2);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return String(value);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function safeParse(text) {
|
|
111
|
+
const trimmed = text.trim();
|
|
112
|
+
if (!trimmed)
|
|
113
|
+
return undefined;
|
|
114
|
+
// Direct parse
|
|
115
|
+
try {
|
|
116
|
+
return JSON.parse(trimmed);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// noop
|
|
120
|
+
}
|
|
121
|
+
// Extract from fenced blocks. Outputs often contain multiple fences
|
|
122
|
+
// (e.g. a ```typescript evidence block before the ```json payload), so try
|
|
123
|
+
// every fence — json-tagged blocks first, then untagged/other blocks.
|
|
124
|
+
const fenceRe = /```(\w*)[ \t]*\r?\n?([\s\S]*?)```/g;
|
|
125
|
+
const fenced = [];
|
|
126
|
+
let fm;
|
|
127
|
+
while ((fm = fenceRe.exec(trimmed)) !== null) {
|
|
128
|
+
fenced.push({ lang: fm[1].toLowerCase(), body: fm[2].trim() });
|
|
129
|
+
}
|
|
130
|
+
const ordered = [...fenced.filter((b) => b.lang === "json"), ...fenced.filter((b) => b.lang !== "json")];
|
|
131
|
+
for (const block of ordered) {
|
|
132
|
+
try {
|
|
133
|
+
return JSON.parse(block.body);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// noop — try the next fence
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Extract the first balanced [...] or {...}
|
|
140
|
+
const arrStart = trimmed.indexOf("[");
|
|
141
|
+
const objStart = trimmed.indexOf("{");
|
|
142
|
+
const start = arrStart === -1 ? objStart : objStart === -1 ? arrStart : Math.min(arrStart, objStart);
|
|
143
|
+
if (start !== -1) {
|
|
144
|
+
const open = trimmed[start];
|
|
145
|
+
const close = open === "[" ? "]" : "}";
|
|
146
|
+
const end = trimmed.lastIndexOf(close);
|
|
147
|
+
if (end > start) {
|
|
148
|
+
try {
|
|
149
|
+
return JSON.parse(trimmed.slice(start, end + 1));
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// noop
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
// Anti-pattern detection (v0.0.8.1): array followed by a stray top-level
|
|
157
|
+
// "key": value. A common LLM mistake — the model appends
|
|
158
|
+
// `"deferred": [...]` after a JSON array, producing a non-JSON hybrid that
|
|
159
|
+
// none of the above strategies can recover. We surface a diagnostic hint
|
|
160
|
+
// so flow authors can spot the bug fast.
|
|
161
|
+
//
|
|
162
|
+
// We check the original (trimmed) input rather than the slice tail,
|
|
163
|
+
// because `lastIndexOf(close)` lands on the *last* bracket — for the
|
|
164
|
+
// anti-pattern the stray key is between the array's `]` and the trailing
|
|
165
|
+
// `]`, not after the last one.
|
|
166
|
+
if (/]\s*[\},]?\s*"[^"\n]+"\s*:/.test(trimmed)) {
|
|
167
|
+
console.warn("[pi-taskflow safeParse] input looks like a JSON array followed by a stray top-level key " +
|
|
168
|
+
`(pattern: [{...}], "key": ...). This is not valid JSON. ` +
|
|
169
|
+
`Hint: put extra data as array members (e.g. {"id":"D-001","status":"deferred",...}) ` +
|
|
170
|
+
`or split into a separate phase.`);
|
|
171
|
+
}
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
/** Coerce a parsed value into an array for map fan-out. */
|
|
175
|
+
export function coerceArray(value) {
|
|
176
|
+
if (Array.isArray(value))
|
|
177
|
+
return value;
|
|
178
|
+
if (value && typeof value === "object") {
|
|
179
|
+
// {items: [...]} or {results: [...]} convenience
|
|
180
|
+
for (const key of ["items", "results", "list", "data", "findings"]) {
|
|
181
|
+
const v = value[key];
|
|
182
|
+
if (Array.isArray(v))
|
|
183
|
+
return v;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
const OPS = ["&&", "||", "==", "!=", ">=", "<=", ">", "<", "!", "(", ")"];
|
|
189
|
+
function tokenize(input) {
|
|
190
|
+
const toks = [];
|
|
191
|
+
let i = 0;
|
|
192
|
+
const n = input.length;
|
|
193
|
+
while (i < n) {
|
|
194
|
+
const c = input[i];
|
|
195
|
+
if (c === " " || c === "\t" || c === "\n" || c === "\r") {
|
|
196
|
+
i++;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
// placeholder {path.to.value}
|
|
200
|
+
if (c === "{") {
|
|
201
|
+
const end = input.indexOf("}", i);
|
|
202
|
+
if (end === -1)
|
|
203
|
+
throw new Error("unterminated placeholder");
|
|
204
|
+
toks.push({ t: "ref", v: input.slice(i + 1, end).trim() });
|
|
205
|
+
i = end + 1;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// quoted string
|
|
209
|
+
if (c === '"' || c === "'") {
|
|
210
|
+
// Handle escaped quotes. Note: ALL \X sequences are interpreted as literal X
|
|
211
|
+
// (including \n → n, \t → t). This differs from JSON/JS escaping but is
|
|
212
|
+
// correct for condition strings which only need quote escaping.
|
|
213
|
+
let j = i + 1;
|
|
214
|
+
let val = "";
|
|
215
|
+
while (j < n) {
|
|
216
|
+
if (input[j] === "\\" && j + 1 < n) {
|
|
217
|
+
val += input[j + 1];
|
|
218
|
+
j += 2;
|
|
219
|
+
}
|
|
220
|
+
else if (input[j] === c) {
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
val += input[j];
|
|
225
|
+
j++;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (j >= n)
|
|
229
|
+
throw new Error("unterminated string");
|
|
230
|
+
toks.push({ t: "str", v: val });
|
|
231
|
+
i = j + 1;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
// multi/single char operators
|
|
235
|
+
const op = OPS.find((o) => input.startsWith(o, i));
|
|
236
|
+
if (op) {
|
|
237
|
+
toks.push({ t: "op", v: op });
|
|
238
|
+
i += op.length;
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
// number
|
|
242
|
+
const numMatch = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/.exec(input.slice(i));
|
|
243
|
+
if (numMatch) {
|
|
244
|
+
toks.push({ t: "num", v: Number(numMatch[0]) });
|
|
245
|
+
i += numMatch[0].length;
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
// bareword → literal (true/false/null keywords, else string)
|
|
249
|
+
const word = /^[^\s&|!=<>()"'{}]+/.exec(input.slice(i));
|
|
250
|
+
if (word) {
|
|
251
|
+
const w = word[0];
|
|
252
|
+
if (w === "true")
|
|
253
|
+
toks.push({ t: "bool", v: true });
|
|
254
|
+
else if (w === "false")
|
|
255
|
+
toks.push({ t: "bool", v: false });
|
|
256
|
+
else if (w === "null")
|
|
257
|
+
toks.push({ t: "null" });
|
|
258
|
+
else
|
|
259
|
+
toks.push({ t: "str", v: w });
|
|
260
|
+
i += w.length;
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
throw new Error(`unexpected char '${c}'`);
|
|
264
|
+
}
|
|
265
|
+
return toks;
|
|
266
|
+
}
|
|
267
|
+
function isNumeric(v) {
|
|
268
|
+
if (typeof v === "number")
|
|
269
|
+
return Number.isFinite(v);
|
|
270
|
+
if (typeof v === "string" && v.trim() !== "")
|
|
271
|
+
return Number.isFinite(Number(v));
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
function truthy(v) {
|
|
275
|
+
if (v === undefined || v === null)
|
|
276
|
+
return false;
|
|
277
|
+
if (typeof v === "boolean")
|
|
278
|
+
return v;
|
|
279
|
+
if (typeof v === "number")
|
|
280
|
+
return v !== 0;
|
|
281
|
+
if (typeof v === "string") {
|
|
282
|
+
const s = v.trim().toLowerCase();
|
|
283
|
+
return !(s === "" || s === "false" || s === "0" || s === "no" || s === "off" || s === "null");
|
|
284
|
+
}
|
|
285
|
+
if (Array.isArray(v))
|
|
286
|
+
return v.length > 0;
|
|
287
|
+
if (typeof v === "object")
|
|
288
|
+
return Object.keys(v).length > 0;
|
|
289
|
+
return Boolean(v);
|
|
290
|
+
}
|
|
291
|
+
function compare(a, op, b) {
|
|
292
|
+
if (isNumeric(a) && isNumeric(b)) {
|
|
293
|
+
const x = Number(a);
|
|
294
|
+
const y = Number(b);
|
|
295
|
+
switch (op) {
|
|
296
|
+
case "==": return x === y;
|
|
297
|
+
case "!=": return x !== y;
|
|
298
|
+
case ">": return x > y;
|
|
299
|
+
case "<": return x < y;
|
|
300
|
+
case ">=": return x >= y;
|
|
301
|
+
case "<=": return x <= y;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
const sa = a === undefined || a === null ? "" : String(a);
|
|
305
|
+
const sb = b === undefined || b === null ? "" : String(b);
|
|
306
|
+
switch (op) {
|
|
307
|
+
case "==": return sa === sb;
|
|
308
|
+
case "!=": return sa !== sb;
|
|
309
|
+
case ">": return sa > sb;
|
|
310
|
+
case "<": return sa < sb;
|
|
311
|
+
case ">=": return sa >= sb;
|
|
312
|
+
case "<=": return sa <= sb;
|
|
313
|
+
}
|
|
314
|
+
return false;
|
|
315
|
+
}
|
|
316
|
+
/** Recursive-descent parser/evaluator over the token stream. */
|
|
317
|
+
class CondParser {
|
|
318
|
+
pos = 0;
|
|
319
|
+
toks;
|
|
320
|
+
ctx;
|
|
321
|
+
constructor(toks, ctx) {
|
|
322
|
+
this.toks = toks;
|
|
323
|
+
this.ctx = ctx;
|
|
324
|
+
}
|
|
325
|
+
parse() {
|
|
326
|
+
const v = this.parseOr();
|
|
327
|
+
if (this.pos < this.toks.length)
|
|
328
|
+
throw new Error("trailing tokens");
|
|
329
|
+
return v;
|
|
330
|
+
}
|
|
331
|
+
peek() {
|
|
332
|
+
return this.toks[this.pos];
|
|
333
|
+
}
|
|
334
|
+
eat(op) {
|
|
335
|
+
const t = this.peek();
|
|
336
|
+
if (t && t.t === "op" && t.v === op) {
|
|
337
|
+
this.pos++;
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
parseOr() {
|
|
343
|
+
let left = this.parseAnd();
|
|
344
|
+
while (this.eat("||")) {
|
|
345
|
+
const right = this.parseAnd();
|
|
346
|
+
left = truthy(left) || truthy(right);
|
|
347
|
+
}
|
|
348
|
+
return left;
|
|
349
|
+
}
|
|
350
|
+
parseAnd() {
|
|
351
|
+
let left = this.parseNot();
|
|
352
|
+
while (this.eat("&&")) {
|
|
353
|
+
const right = this.parseNot();
|
|
354
|
+
left = truthy(left) && truthy(right);
|
|
355
|
+
}
|
|
356
|
+
return left;
|
|
357
|
+
}
|
|
358
|
+
parseNot() {
|
|
359
|
+
if (this.eat("!"))
|
|
360
|
+
return !truthy(this.parseNot());
|
|
361
|
+
return this.parseComparison();
|
|
362
|
+
}
|
|
363
|
+
parseComparison() {
|
|
364
|
+
const left = this.parsePrimary();
|
|
365
|
+
const t = this.peek();
|
|
366
|
+
if (t && t.t === "op" && ["==", "!=", ">", "<", ">=", "<="].includes(t.v)) {
|
|
367
|
+
this.pos++;
|
|
368
|
+
const right = this.parsePrimary();
|
|
369
|
+
return compare(left, t.v, right);
|
|
370
|
+
}
|
|
371
|
+
return left;
|
|
372
|
+
}
|
|
373
|
+
parsePrimary() {
|
|
374
|
+
if (this.eat("(")) {
|
|
375
|
+
const v = this.parseOr();
|
|
376
|
+
if (!this.eat(")"))
|
|
377
|
+
throw new Error("missing )");
|
|
378
|
+
return v;
|
|
379
|
+
}
|
|
380
|
+
const t = this.peek();
|
|
381
|
+
if (!t)
|
|
382
|
+
throw new Error("unexpected end");
|
|
383
|
+
this.pos++;
|
|
384
|
+
switch (t.t) {
|
|
385
|
+
case "ref": return resolvePath(t.v, this.ctx);
|
|
386
|
+
case "str": return t.v;
|
|
387
|
+
case "num": return t.v;
|
|
388
|
+
case "bool": return t.v;
|
|
389
|
+
case "null": return null;
|
|
390
|
+
default: throw new Error(`unexpected operator '${t.v}'`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Evaluate a `when` expression to a boolean. Returns `{ value, error }`.
|
|
396
|
+
* Parse errors set `error` and fail OPEN (`value: true`) so a broken guard
|
|
397
|
+
* never silently drops a phase.
|
|
398
|
+
*/
|
|
399
|
+
export function tryEvaluateCondition(expr, ctx) {
|
|
400
|
+
const trimmed = (expr ?? "").trim();
|
|
401
|
+
if (!trimmed)
|
|
402
|
+
return { value: true };
|
|
403
|
+
try {
|
|
404
|
+
const toks = tokenize(trimmed);
|
|
405
|
+
if (toks.length === 0)
|
|
406
|
+
return { value: true };
|
|
407
|
+
const result = new CondParser(toks, ctx).parse();
|
|
408
|
+
return { value: truthy(result) };
|
|
409
|
+
}
|
|
410
|
+
catch (e) {
|
|
411
|
+
return { value: true, error: e instanceof Error ? e.message : String(e) };
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
/** Boolean convenience wrapper over {@link tryEvaluateCondition}. */
|
|
415
|
+
export function evaluateCondition(expr, ctx) {
|
|
416
|
+
return tryEvaluateCondition(expr, ctx).value;
|
|
417
|
+
}
|
|
418
|
+
//# sourceMappingURL=interpolate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpolate.js","sourceRoot":"","sources":["../src/interpolate.ts"],"names":[],"mappings":"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"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the base directory where taskflow persists saved flows and discovers
|
|
3
|
+
* user agents. Vendored so taskflow-core does not import the pi host SDK.
|
|
4
|
+
*
|
|
5
|
+
* Resolution order (first hit wins):
|
|
6
|
+
* 1. `TASKFLOW_AGENT_DIR` — host-neutral override (codex, tests, …)
|
|
7
|
+
* 2. `PI_CODING_AGENT_DIR` — pi's own override (keeps pi users' existing
|
|
8
|
+
* `~/.pi/agent/taskflows` working)
|
|
9
|
+
* 3. `~/.pi/agent` — the historical default
|
|
10
|
+
*
|
|
11
|
+
* A host adapter can also inject a dir explicitly via `setAgentDir()` at
|
|
12
|
+
* startup; that takes precedence over the env vars. Keeping the default at
|
|
13
|
+
* `~/.pi/agent` means a user who upgrades from the single-package pi-taskflow
|
|
14
|
+
* still finds every saved flow exactly where it was.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Override the agent dir for the current process (host adapters call this once
|
|
18
|
+
* at startup). Pass `undefined` to clear and fall back to env / default.
|
|
19
|
+
*/
|
|
20
|
+
export declare function setAgentDir(dir: string | undefined): void;
|
|
21
|
+
/** The base directory for taskflow persistence + user-agent discovery. */
|
|
22
|
+
export declare function getAgentDir(): string;
|
|
23
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAcH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAEzD;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,IAAI,MAAM,CAKpC"}
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the base directory where taskflow persists saved flows and discovers
|
|
3
|
+
* user agents. Vendored so taskflow-core does not import the pi host SDK.
|
|
4
|
+
*
|
|
5
|
+
* Resolution order (first hit wins):
|
|
6
|
+
* 1. `TASKFLOW_AGENT_DIR` — host-neutral override (codex, tests, …)
|
|
7
|
+
* 2. `PI_CODING_AGENT_DIR` — pi's own override (keeps pi users' existing
|
|
8
|
+
* `~/.pi/agent/taskflows` working)
|
|
9
|
+
* 3. `~/.pi/agent` — the historical default
|
|
10
|
+
*
|
|
11
|
+
* A host adapter can also inject a dir explicitly via `setAgentDir()` at
|
|
12
|
+
* startup; that takes precedence over the env vars. Keeping the default at
|
|
13
|
+
* `~/.pi/agent` means a user who upgrades from the single-package pi-taskflow
|
|
14
|
+
* still finds every saved flow exactly where it was.
|
|
15
|
+
*/
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
import { join } from "node:path";
|
|
18
|
+
let injectedDir;
|
|
19
|
+
/** Expand a leading `~` to the user's home directory. */
|
|
20
|
+
function expandTilde(p) {
|
|
21
|
+
if (p === "~")
|
|
22
|
+
return homedir();
|
|
23
|
+
if (p.startsWith("~/"))
|
|
24
|
+
return join(homedir(), p.slice(2));
|
|
25
|
+
return p;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Override the agent dir for the current process (host adapters call this once
|
|
29
|
+
* at startup). Pass `undefined` to clear and fall back to env / default.
|
|
30
|
+
*/
|
|
31
|
+
export function setAgentDir(dir) {
|
|
32
|
+
injectedDir = dir ? expandTilde(dir) : undefined;
|
|
33
|
+
}
|
|
34
|
+
/** The base directory for taskflow persistence + user-agent discovery. */
|
|
35
|
+
export function getAgentDir() {
|
|
36
|
+
if (injectedDir)
|
|
37
|
+
return injectedDir;
|
|
38
|
+
const envDir = process.env.TASKFLOW_AGENT_DIR || process.env.PI_CODING_AGENT_DIR;
|
|
39
|
+
if (envDir)
|
|
40
|
+
return expandTilde(envDir);
|
|
41
|
+
return join(homedir(), ".pi", "agent");
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,IAAI,WAA+B,CAAC;AAEpC,yDAAyD;AACzD,SAAS,WAAW,CAAC,CAAS;IAC7B,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,OAAO,EAAE,CAAC;IAChC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,CAAC;AACV,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAuB;IAClD,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,WAAW;IAC1B,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IACjF,IAAI,MAAM;QAAE,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host-neutral subagent-result helpers: failure classification, transient-error
|
|
3
|
+
* detection, error sanitization, and the NDJSON event accumulator/parser.
|
|
4
|
+
*
|
|
5
|
+
* This is the pure, host-SDK-free half of the original runner. The pi spawn
|
|
6
|
+
* machinery lives in the pi adapter (`pi-taskflow`); the codex spawn machinery
|
|
7
|
+
* in the codex adapter (`codex-taskflow`). Both reuse everything here so failure
|
|
8
|
+
* semantics, retry heuristics, and usage folding are identical across hosts.
|
|
9
|
+
*/
|
|
10
|
+
import { type UsageStats } from "./usage.ts";
|
|
11
|
+
import type { CoreMessage, LiveUpdate, RunResult } from "./host/runner-types.ts";
|
|
12
|
+
export type { CoreMessage, LiveUpdate, RunOptions, RunResult, SubagentRunner } from "./host/runner-types.ts";
|
|
13
|
+
export declare function isFailed(r: RunResult): boolean;
|
|
14
|
+
export declare function isTransientError(r: RunResult): boolean;
|
|
15
|
+
/** Placeholder written to a failed phase's `output` so downstream interpolation
|
|
16
|
+
* can detect "upstream failed" without being polluted by raw HTML/JSON. */
|
|
17
|
+
export declare const TRANSPORT_ERROR_PLACEHOLDER = "(upstream error: subagent failed; see error)";
|
|
18
|
+
/** Hard cap on the errorMessage field stored in PhaseState (≈ 4 KB). */
|
|
19
|
+
export declare const ERROR_MESSAGE_MAX_LEN = 4096;
|
|
20
|
+
/** Cheap HTML/JSON detector so we can summarize upstream garbage. */
|
|
21
|
+
export declare function looksLikeHtmlOrJson(s: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Truncate and (when obviously HTML) summarize an errorMessage before it is
|
|
24
|
+
* persisted. Returns the cleaned string. Empty input returns empty.
|
|
25
|
+
*/
|
|
26
|
+
export declare function sanitizeErrorMessage(raw: string | undefined): string;
|
|
27
|
+
export declare function getFinalOutput(messages: CoreMessage[]): string;
|
|
28
|
+
/** Accumulated state folded from a subagent's NDJSON event stream. */
|
|
29
|
+
export interface EventAccumulator {
|
|
30
|
+
messages: CoreMessage[];
|
|
31
|
+
usage: UsageStats;
|
|
32
|
+
model?: string;
|
|
33
|
+
stopReason?: string;
|
|
34
|
+
errorMessage?: string;
|
|
35
|
+
lastActivity: string;
|
|
36
|
+
/** Set when message cap was hit — output gets a truncation notice. */
|
|
37
|
+
truncated?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export declare function newAccumulator(model?: string): EventAccumulator;
|
|
40
|
+
/**
|
|
41
|
+
* Fold one NDJSON line into the accumulator. Returns a LiveUpdate when an
|
|
42
|
+
* assistant message ended (for streaming), else null. Empty, malformed, and
|
|
43
|
+
* non-`message_end` lines are ignored — making the parser robust to partial
|
|
44
|
+
* buffers/noise and unit-testable without spawning a process.
|
|
45
|
+
*/
|
|
46
|
+
export declare function foldEventLine(acc: EventAccumulator, line: string): LiveUpdate | null;
|
|
47
|
+
/** Run an array of items through `fn` with a bounded concurrency pool. */
|
|
48
|
+
export declare function mapWithConcurrencyLimit<TIn, TOut>(items: TIn[], concurrency: number, fn: (item: TIn, index: number) => Promise<TOut>): Promise<TOut[]>;
|
|
49
|
+
//# sourceMappingURL=runner-core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-core.d.ts","sourceRoot":"","sources":["../src/runner-core.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAIjF,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7G,wBAAgB,QAAQ,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAE9C;AAUD,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,CAMtD;AAED;4EAC4E;AAC5E,eAAO,MAAM,2BAA2B,iDAAiD,CAAC;AAE1F,wEAAwE;AACxE,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,qEAAqE;AACrE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CActD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAyBpE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAU9D;AAED,sEAAsE;AACtE,MAAM,WAAW,gBAAgB;IAChC,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAoCpF;AAwCD,0EAA0E;AAC1E,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,IAAI,EACtD,KAAK,EAAE,GAAG,EAAE,EACZ,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAC7C,OAAO,CAAC,IAAI,EAAE,CAAC,CAcjB"}
|