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,208 @@
|
|
|
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 { emptyUsage } from "./usage.js";
|
|
11
|
+
export function isFailed(r) {
|
|
12
|
+
return r.exitCode !== 0 || r.stopReason === "error" || r.stopReason === "aborted";
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Heuristic: did this failure look like a transient/retryable provider error
|
|
16
|
+
* (rate limit, overload, timeout, 5xx)? Such errors should be retried inside
|
|
17
|
+
* the taskflow run with backoff rather than bubbled up — otherwise the calling
|
|
18
|
+
* agent tends to re-invoke the whole tool, producing duplicate progress blocks.
|
|
19
|
+
*/
|
|
20
|
+
const TRANSIENT_ERROR_RE = /rate[_\s-]?limit|too\s+many\s+requests|overloaded|\b429\b|\b503\b|\b502\b|\b504\b|service\s+unavailable|temporarily\s+unavailable|timeout|timed?\s+out|econnreset|etimedout|socket\s+hang\s*up/i;
|
|
21
|
+
export function isTransientError(r) {
|
|
22
|
+
if (r.stopReason === "aborted")
|
|
23
|
+
return false;
|
|
24
|
+
// Idle timeout is a deterministic stall — retrying won't help.
|
|
25
|
+
if (r.stopReason === "error" && r.idleTimeout)
|
|
26
|
+
return false;
|
|
27
|
+
const hay = `${r.errorMessage ?? ""} ${r.stderr ?? ""} ${r.output ?? ""}`;
|
|
28
|
+
return TRANSIENT_ERROR_RE.test(hay);
|
|
29
|
+
}
|
|
30
|
+
/** Placeholder written to a failed phase's `output` so downstream interpolation
|
|
31
|
+
* can detect "upstream failed" without being polluted by raw HTML/JSON. */
|
|
32
|
+
export const TRANSPORT_ERROR_PLACEHOLDER = "(upstream error: subagent failed; see error)";
|
|
33
|
+
/** Hard cap on the errorMessage field stored in PhaseState (≈ 4 KB). */
|
|
34
|
+
export const ERROR_MESSAGE_MAX_LEN = 4096;
|
|
35
|
+
/** Cheap HTML/JSON detector so we can summarize upstream garbage. */
|
|
36
|
+
export function looksLikeHtmlOrJson(s) {
|
|
37
|
+
const t = s.trimStart();
|
|
38
|
+
if (!t)
|
|
39
|
+
return false;
|
|
40
|
+
if (t.startsWith("<")) {
|
|
41
|
+
// HTML/XML/Cloudflare challenge pages
|
|
42
|
+
return /^<(?:!doctype\s+html|html|head|body|script|svg|div|iframe|span|p)\b/i.test(t);
|
|
43
|
+
}
|
|
44
|
+
if (t.startsWith("{")) {
|
|
45
|
+
// Truncated JSON. A genuine JSON envelope is fine to keep; an unwrapped
|
|
46
|
+
// {error: "..."} from an SDK is short. We only treat it as "garbage" if
|
|
47
|
+
// it parses and is huge — but that's caught by the size cap below.
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Truncate and (when obviously HTML) summarize an errorMessage before it is
|
|
54
|
+
* persisted. Returns the cleaned string. Empty input returns empty.
|
|
55
|
+
*/
|
|
56
|
+
export function sanitizeErrorMessage(raw) {
|
|
57
|
+
if (!raw)
|
|
58
|
+
return "";
|
|
59
|
+
const cleaned = raw.replace(/\s+/g, " ").trim();
|
|
60
|
+
if (!cleaned)
|
|
61
|
+
return "";
|
|
62
|
+
// Decide the sanitization branch on the RAW length, not the whitespace-
|
|
63
|
+
// collapsed length — otherwise an HTML page padded with spaces would slip
|
|
64
|
+
// through the "looks like HTML" branch and be persisted as-is.
|
|
65
|
+
const rawLen = raw.length;
|
|
66
|
+
if (rawLen > ERROR_MESSAGE_MAX_LEN) {
|
|
67
|
+
const head = cleaned.slice(0, 200);
|
|
68
|
+
const tail = cleaned.slice(-200);
|
|
69
|
+
return `${head} ... [truncated ${rawLen - 400} chars] ... ${tail}`;
|
|
70
|
+
}
|
|
71
|
+
if (looksLikeHtmlOrJson(cleaned)) {
|
|
72
|
+
// Any document-like HTML (Cloudflare challenge pages, proxy error pages,
|
|
73
|
+
// gateway error pages) is a strong signal the upstream returned a page
|
|
74
|
+
// instead of JSON. Summarize it instead of letting HTML pollute the
|
|
75
|
+
// phase's error and downstream interpolation contexts.
|
|
76
|
+
const title = cleaned.match(/<title[^>]*>([^<]*)<\/title>/i)?.[1]?.trim();
|
|
77
|
+
const stripped = cleaned.replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
78
|
+
const m = stripped.match(/(?:Unable to load site|Ray ID[: ]+([A-Za-z0-9]+)|[A-Z][a-z]+Error[: ]+(.{0,200}))/i);
|
|
79
|
+
const hint = title || (m ? (m[1] || m[0]).trim() : stripped.slice(0, 200));
|
|
80
|
+
return `Upstream returned non-JSON response (${rawLen} chars). Hint: ${hint}`;
|
|
81
|
+
}
|
|
82
|
+
return cleaned;
|
|
83
|
+
}
|
|
84
|
+
export function getFinalOutput(messages) {
|
|
85
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
86
|
+
const msg = messages[i];
|
|
87
|
+
if (msg.role === "assistant") {
|
|
88
|
+
for (const part of msg.content) {
|
|
89
|
+
if (part.type === "text" && part.text?.trim())
|
|
90
|
+
return part.text;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return "";
|
|
95
|
+
}
|
|
96
|
+
export function newAccumulator(model) {
|
|
97
|
+
return { messages: [], usage: emptyUsage(), model, lastActivity: "" };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Fold one NDJSON line into the accumulator. Returns a LiveUpdate when an
|
|
101
|
+
* assistant message ended (for streaming), else null. Empty, malformed, and
|
|
102
|
+
* non-`message_end` lines are ignored — making the parser robust to partial
|
|
103
|
+
* buffers/noise and unit-testable without spawning a process.
|
|
104
|
+
*/
|
|
105
|
+
export function foldEventLine(acc, line) {
|
|
106
|
+
if (!line.trim())
|
|
107
|
+
return null;
|
|
108
|
+
let event;
|
|
109
|
+
try {
|
|
110
|
+
event = JSON.parse(line);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
if (event.type !== "message_end" || !event.message)
|
|
116
|
+
return null;
|
|
117
|
+
const msg = event.message;
|
|
118
|
+
// Cap prevents OOM from misconfigured loops. 500 messages is generous for
|
|
119
|
+
// normal subagent tasks (50 turns × 10 messages each). Messages beyond the
|
|
120
|
+
// cap are still parsed for usage/model/stopReason extraction.
|
|
121
|
+
const MAX_MESSAGES = 500;
|
|
122
|
+
if (acc.messages.length < MAX_MESSAGES) {
|
|
123
|
+
acc.messages.push(msg);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
acc.truncated = true;
|
|
127
|
+
}
|
|
128
|
+
if (msg.role !== "assistant")
|
|
129
|
+
return null;
|
|
130
|
+
acc.usage.turns++;
|
|
131
|
+
const u = msg.usage;
|
|
132
|
+
if (u) {
|
|
133
|
+
acc.usage.input += u.input || 0;
|
|
134
|
+
acc.usage.output += u.output || 0;
|
|
135
|
+
acc.usage.cacheRead += u.cacheRead || 0;
|
|
136
|
+
acc.usage.cacheWrite += u.cacheWrite || 0;
|
|
137
|
+
acc.usage.cost += u.cost?.total || 0;
|
|
138
|
+
acc.usage.contextTokens = u.totalTokens || 0;
|
|
139
|
+
}
|
|
140
|
+
if (!acc.model && msg.model)
|
|
141
|
+
acc.model = msg.model;
|
|
142
|
+
if (msg.stopReason)
|
|
143
|
+
acc.stopReason = msg.stopReason;
|
|
144
|
+
if (msg.errorMessage)
|
|
145
|
+
acc.errorMessage = msg.errorMessage;
|
|
146
|
+
const activity = describeActivity(msg);
|
|
147
|
+
if (activity)
|
|
148
|
+
acc.lastActivity = activity;
|
|
149
|
+
return { text: acc.lastActivity, usage: { ...acc.usage }, model: acc.model };
|
|
150
|
+
}
|
|
151
|
+
/** One-line description of the most recent assistant activity (text or tool call). */
|
|
152
|
+
function describeActivity(msg) {
|
|
153
|
+
if (msg.role !== "assistant")
|
|
154
|
+
return "";
|
|
155
|
+
let lastText = "";
|
|
156
|
+
let lastTool = "";
|
|
157
|
+
for (const part of msg.content ?? []) {
|
|
158
|
+
if (part.type === "text" && part.text?.trim())
|
|
159
|
+
lastText = part.text.trim();
|
|
160
|
+
else if (part.type === "toolCall")
|
|
161
|
+
lastTool = summarizeToolCall(part.name, part.arguments ?? {});
|
|
162
|
+
}
|
|
163
|
+
const chosen = lastText || lastTool;
|
|
164
|
+
return chosen.replace(/\s+/g, " ").trim();
|
|
165
|
+
}
|
|
166
|
+
function summarizeToolCall(name, args) {
|
|
167
|
+
const short = (p) => {
|
|
168
|
+
const s = String(p ?? "");
|
|
169
|
+
return s.length > 48 ? `${s.slice(0, 48)}…` : s;
|
|
170
|
+
};
|
|
171
|
+
switch (name) {
|
|
172
|
+
case "bash":
|
|
173
|
+
return `$ ${short(args.command)}`;
|
|
174
|
+
case "read":
|
|
175
|
+
return `read ${short(args.path ?? args.file_path)}`;
|
|
176
|
+
case "write":
|
|
177
|
+
return `write ${short(args.path ?? args.file_path)}`;
|
|
178
|
+
case "edit":
|
|
179
|
+
return `edit ${short(args.path ?? args.file_path)}`;
|
|
180
|
+
case "grep":
|
|
181
|
+
return `grep ${short(args.pattern)}`;
|
|
182
|
+
case "find":
|
|
183
|
+
return `find ${short(args.pattern)}`;
|
|
184
|
+
case "ls":
|
|
185
|
+
return `ls ${short(args.path)}`;
|
|
186
|
+
default:
|
|
187
|
+
return `${name}`;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** Run an array of items through `fn` with a bounded concurrency pool. */
|
|
191
|
+
export async function mapWithConcurrencyLimit(items, concurrency, fn) {
|
|
192
|
+
if (items.length === 0)
|
|
193
|
+
return [];
|
|
194
|
+
const limit = Math.max(1, Math.min(concurrency, items.length));
|
|
195
|
+
const results = new Array(items.length);
|
|
196
|
+
let nextIndex = 0;
|
|
197
|
+
const workers = new Array(limit).fill(null).map(async () => {
|
|
198
|
+
while (true) {
|
|
199
|
+
const current = nextIndex++;
|
|
200
|
+
if (current >= items.length)
|
|
201
|
+
return;
|
|
202
|
+
results[current] = await fn(items[current], current);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
await Promise.all(workers);
|
|
206
|
+
return results;
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=runner-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner-core.js","sourceRoot":"","sources":["../src/runner-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taskflow runtime — the orchestration engine.
|
|
3
|
+
*
|
|
4
|
+
* Resolves the phase DAG into topological layers and executes each phase by
|
|
5
|
+
* delegating to isolated subagents. Intermediate phase outputs live here (in
|
|
6
|
+
* RunState) and never enter the host conversation's context window — only the
|
|
7
|
+
* final phase output is returned to the caller.
|
|
8
|
+
*
|
|
9
|
+
* Supports resume: phases whose resolved input hash matches a cached completed
|
|
10
|
+
* result are skipped.
|
|
11
|
+
*/
|
|
12
|
+
import type { AgentConfig } from "./agents.ts";
|
|
13
|
+
import type { SubagentRunner } from "./host/runner-types.ts";
|
|
14
|
+
/** The host-neutral subagent runner signature the engine drives. A host adapter
|
|
15
|
+
* (pi, codex) injects a concrete `runTask` via `RuntimeDeps`. */
|
|
16
|
+
type RunTaskFn = SubagentRunner<any>["runTask"];
|
|
17
|
+
import { type UsageStats } from "./usage.ts";
|
|
18
|
+
import { type CacheScope, type Taskflow } from "./schema.ts";
|
|
19
|
+
import { type PhaseState, type RunState } from "./store.ts";
|
|
20
|
+
import { CacheStore } from "./cache.ts";
|
|
21
|
+
/** A human-in-the-loop approval request raised by an `approval` phase. */
|
|
22
|
+
export interface ApprovalRequest {
|
|
23
|
+
phaseId: string;
|
|
24
|
+
/** Interpolated prompt shown to the human. */
|
|
25
|
+
message: string;
|
|
26
|
+
/** Output of the immediately-upstream phase, for context. */
|
|
27
|
+
upstream?: string;
|
|
28
|
+
}
|
|
29
|
+
/** The human's decision. `edit` carries guidance passed downstream as the phase output. */
|
|
30
|
+
export interface ApprovalDecision {
|
|
31
|
+
decision: "approve" | "reject" | "edit";
|
|
32
|
+
note?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface RuntimeDeps {
|
|
35
|
+
cwd: string;
|
|
36
|
+
agents: AgentConfig[];
|
|
37
|
+
globalThinking?: string;
|
|
38
|
+
signal?: AbortSignal;
|
|
39
|
+
/** Persist run state after each phase (for resume). */
|
|
40
|
+
persist?: (state: RunState) => void;
|
|
41
|
+
/** Live progress callback for TUI streaming. */
|
|
42
|
+
onProgress?: (state: RunState) => void;
|
|
43
|
+
/** Injectable task runner (defaults to spawning a real subagent). Enables testing. */
|
|
44
|
+
runTask?: RunTaskFn;
|
|
45
|
+
/** Resolve an `approval` phase. Omit for non-interactive runs (auto-reject). */
|
|
46
|
+
requestApproval?: (req: ApprovalRequest) => Promise<ApprovalDecision>;
|
|
47
|
+
/** Resolve a saved taskflow by name for `flow` (sub-workflow) phases. */
|
|
48
|
+
loadFlow?: (name: string) => Taskflow | undefined;
|
|
49
|
+
/** Cross-run memoization store. Omit to construct a default one for `deps.cwd`. */
|
|
50
|
+
cacheStore?: CacheStore;
|
|
51
|
+
/** Default cache scope for phases that don't specify one. */
|
|
52
|
+
cacheScopeDefault?: CacheScope;
|
|
53
|
+
/** Internal: sub-flow call stack, for recursion detection. */
|
|
54
|
+
_stack?: string[];
|
|
55
|
+
/** Internal: pre-resolved Shared Context Tree dir for this run (sub-flows inherit the parent's). */
|
|
56
|
+
_ctxDir?: string;
|
|
57
|
+
/** Internal: an isolated workspace dir override for the current phase (worktree isolation). */
|
|
58
|
+
_cwdOverride?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface RuntimeResult {
|
|
61
|
+
state: RunState;
|
|
62
|
+
finalOutput: string;
|
|
63
|
+
ok: boolean;
|
|
64
|
+
totalUsage: UsageStats;
|
|
65
|
+
/** Incremental-reuse summary: how many phases were reused from cache vs.
|
|
66
|
+
* freshly executed this run, and the cost the reused work would otherwise
|
|
67
|
+
* have incurred (known only for within-run resume; cross-run hits zero
|
|
68
|
+
* their usage so their original cost is not recoverable). Optional &
|
|
69
|
+
* additive — callers that ignore it are unaffected. */
|
|
70
|
+
reuse?: ReuseSummary;
|
|
71
|
+
}
|
|
72
|
+
/** A run's incremental-reuse accounting (see RuntimeResult.reuse). */
|
|
73
|
+
export interface ReuseSummary {
|
|
74
|
+
/** Phases that completed by executing a subagent this run. */
|
|
75
|
+
executed: number;
|
|
76
|
+
/** Phases served from the within-run resume cache (no new tokens). */
|
|
77
|
+
reusedRunOnly: number;
|
|
78
|
+
/** Phases restored from the cross-run store (no new tokens). */
|
|
79
|
+
reusedCrossRun: number;
|
|
80
|
+
/** Total phases that reached `done` (executed + reused). */
|
|
81
|
+
done: number;
|
|
82
|
+
/** USD the within-run-reused phases would have cost if re-executed (their
|
|
83
|
+
* preserved prior usage). Cross-run hits are excluded (cost not recoverable). */
|
|
84
|
+
savedUSD: number;
|
|
85
|
+
}
|
|
86
|
+
/** Compute the incremental-reuse summary from a run's terminal phase states.
|
|
87
|
+
* Pure, total, never throws. A phase is "reused" iff it carries a `cacheHit`
|
|
88
|
+
* marker (set by `cachedPhase` for both within-run resume and cross-run hits). */
|
|
89
|
+
export declare function summarizeReuse(state: RunState): ReuseSummary;
|
|
90
|
+
/**
|
|
91
|
+
* Per-phase cache policy resolved once at the top of executePhase. Carries the
|
|
92
|
+
* scope, optional TTL, and a pre-resolved fingerprint string so each phase-type
|
|
93
|
+
* branch can fold it into its inputHash and consult the cross-run store uniformly.
|
|
94
|
+
*/
|
|
95
|
+
export interface PhaseCacheCtx {
|
|
96
|
+
scope: CacheScope;
|
|
97
|
+
ttlMs?: number;
|
|
98
|
+
fingerprint: string;
|
|
99
|
+
store: CacheStore;
|
|
100
|
+
prior: PhaseState | undefined;
|
|
101
|
+
phaseId: string;
|
|
102
|
+
flowName: string;
|
|
103
|
+
runId: string;
|
|
104
|
+
/** Per-phase execution config that materially affects subagent output and
|
|
105
|
+
* therefore must be part of the cache identity (else a config change could
|
|
106
|
+
* silently serve a stale cross-run hit). */
|
|
107
|
+
thinking?: string;
|
|
108
|
+
tools?: string[];
|
|
109
|
+
/** Resolved `context` pre-read content. Explicitly part of the cache identity
|
|
110
|
+
* so a context-file change always invalidates the phase — independent of
|
|
111
|
+
* whether a given branch happens to fold preRead into its task string
|
|
112
|
+
* (previously this was only incidentally true via `fullTask`). */
|
|
113
|
+
preRead?: string;
|
|
114
|
+
/** Content fingerprint of the desugared flow definition — folded into the
|
|
115
|
+
* key so two structurally-different flows that share a name can never
|
|
116
|
+
* collide, and a changed flow never serves a stale cross-run hit. */
|
|
117
|
+
flowDefHash?: string | "failed";
|
|
118
|
+
/** Per-phase structural sub-fingerprint (M6). When present, folds into the
|
|
119
|
+
* key as `v3:phasefp:<subfp>` so editing phase B invalidates only B + its
|
|
120
|
+
* transitive dependents. When absent (sub-flow inner states, or a phase
|
|
121
|
+
* for which per-phase soundness couldn't be guaranteed), `cacheKeys`
|
|
122
|
+
* falls back to `flowDefHash` — preserving pre-M6 whole-flow behavior. */
|
|
123
|
+
phaseFp?: string;
|
|
124
|
+
/** Force this phase to re-execute, ignoring the within-run prior AND the
|
|
125
|
+
* cross-run store (M5 recompute seed). Downstream phases are NOT forced —
|
|
126
|
+
* they re-evaluate naturally: if the seed's new output changed their
|
|
127
|
+
* inputHash they miss and re-run, otherwise they hit (early cutoff). */
|
|
128
|
+
forceRerun?: boolean;
|
|
129
|
+
}
|
|
130
|
+
/** Fold the phase fingerprint into the base hash parts to form the final cache key. */
|
|
131
|
+
/** A computed cache identity: the new (versioned) key plus the read-only
|
|
132
|
+
* fallback keys used to honor entries written by older releases. The `key`
|
|
133
|
+
* is what we WRITE under and what `PhaseState.inputHash` carries; the
|
|
134
|
+
* `v2Key`/`bareKey`/`legacyKey` are consulted READ-ONLY on a miss so an
|
|
135
|
+
* upgrade never produces a miss-storm. See docs/internal/cache-migration.md. */
|
|
136
|
+
export interface CacheKeys {
|
|
137
|
+
/** Current key: folds `v3:phasefp:<subfp>` (the per-phase structural
|
|
138
|
+
* sub-fingerprint; degrades to the whole-flow hash when per-phase
|
|
139
|
+
* soundness couldn't be guaranteed). */
|
|
140
|
+
key: string;
|
|
141
|
+
/** Pre-M6 key: `v2:flowdef:<flowDefHash>` (whole-flow fingerprint).
|
|
142
|
+
* Read-only. */
|
|
143
|
+
v2Key: string;
|
|
144
|
+
/** Bare (unversioned) `flowdef:` key — written by pre-H1 code that folded
|
|
145
|
+
* the hash without a `v2:` prefix. Read-only. Removed in v0.1.0. */
|
|
146
|
+
bareKey: string;
|
|
147
|
+
/** Pre-flowDefHash-era key: the flowdef line OMITTED entirely. Read-only. */
|
|
148
|
+
legacyKey: string;
|
|
149
|
+
}
|
|
150
|
+
/** Fold the phase fingerprint into the base hash parts to form the cache keys.
|
|
151
|
+
*
|
|
152
|
+
* Four keys are produced for backward compatibility (see
|
|
153
|
+
* docs/internal/cache-migration.md):
|
|
154
|
+
* - `key` : `v3:phasefp:<subfp>` — the current write key (per-phase
|
|
155
|
+
* structural sub-fingerprint; falls back to the whole-flow hash when
|
|
156
|
+
* `cc.phaseFp` is absent).
|
|
157
|
+
* - `v2Key` : `v2:flowdef:<flowDefHash>` — pre-M6 whole-flow key.
|
|
158
|
+
* - `bareKey` : bare `flowdef:<flowDefHash>` (unversioned) — pre-H1 entries.
|
|
159
|
+
* - `legacyKey`: the flowdef line omitted — pre-flowDefHash entries.
|
|
160
|
+
* `cachedPhase` consults all four READ-ONLY on a miss; `recordCache` writes
|
|
161
|
+
* only `key`. This means an upgrade never produces a miss-storm: existing
|
|
162
|
+
* entries (whichever shape) still hit, and new writes converge on `key`. */
|
|
163
|
+
export declare function cacheKeys(cc: PhaseCacheCtx, baseParts: string[]): CacheKeys;
|
|
164
|
+
/**
|
|
165
|
+
* Parse a gate phase's output into a verdict. Blocks the flow only on an
|
|
166
|
+
* explicit negative signal; ambiguous output passes (fail-open).
|
|
167
|
+
* Accepts JSON ({continue|pass: bool} or {verdict: "..."}) or a text marker
|
|
168
|
+
* `VERDICT: PASS|BLOCK|FAIL|STOP|OK|REJECT|HALT` (last occurrence wins).
|
|
169
|
+
*/
|
|
170
|
+
export declare function parseGateVerdict(output: string): {
|
|
171
|
+
verdict: "pass" | "block";
|
|
172
|
+
reason?: string;
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* Parse a judge's pick of the winning variant. Accepts JSON ({"winner":n} or
|
|
176
|
+
* {"best":n}) or a `WINNER: n` line (last match wins). Clamps to [1, count].
|
|
177
|
+
* Fail-open: an unreadable verdict defaults to variant 1 so the work is never
|
|
178
|
+
* lost. Returns the 1-based index plus an optional reason.
|
|
179
|
+
*/
|
|
180
|
+
export declare function parseTournamentWinner(output: string, count: number): {
|
|
181
|
+
winner: number;
|
|
182
|
+
reason?: string;
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Execute a full taskflow. Mutates and persists `state` as it progresses.
|
|
186
|
+
*/
|
|
187
|
+
/** Result of a recompute: what was (or would be) re-executed vs reused.
|
|
188
|
+
* `cutoff` is the prize — phases in the stale frontier whose inputHash did
|
|
189
|
+
* NOT move, so they hit their cached result instead of re-running (early
|
|
190
|
+
* cutoff). That is what makes recompute cheaper than a full re-run. */
|
|
191
|
+
export interface RecomputeReport {
|
|
192
|
+
readonly dryRun: boolean;
|
|
193
|
+
readonly aborted: boolean;
|
|
194
|
+
readonly seeds: readonly string[];
|
|
195
|
+
/** Phases that were (dry-run: would be) re-executed, or whose result moved. */
|
|
196
|
+
readonly rerun: readonly string[];
|
|
197
|
+
/** Phases outside the frontier — untouched, reused verbatim. */
|
|
198
|
+
readonly reused: readonly string[];
|
|
199
|
+
/** Phases in the frontier whose inputHash did NOT move → cached result
|
|
200
|
+
* reused, no re-execution (early cutoff). Empty in dry-run (unknowable). */
|
|
201
|
+
readonly cutoff: readonly string[];
|
|
202
|
+
/** Per-phase decision trace: WHY each phase was rerun / cut off / reused.
|
|
203
|
+
* The "explainable reactivity" layer — like React DevTools telling you why
|
|
204
|
+
* a component re-rendered. Additive; callers that ignore it are unaffected. */
|
|
205
|
+
readonly decisions: readonly RecomputeDecision[];
|
|
206
|
+
}
|
|
207
|
+
/** Why a single phase landed in its recompute outcome. */
|
|
208
|
+
export interface RecomputeDecision {
|
|
209
|
+
readonly phaseId: string;
|
|
210
|
+
/** What happened (real run) or would happen (dry-run). */
|
|
211
|
+
readonly outcome: "rerun" | "cutoff" | "reused" | "failed";
|
|
212
|
+
/** Human-readable cause. */
|
|
213
|
+
readonly reason: string;
|
|
214
|
+
/** The upstream phase(s) that caused this outcome, when applicable
|
|
215
|
+
* (e.g. the changed upstreams that forced a rerun). */
|
|
216
|
+
readonly causedBy?: readonly string[];
|
|
217
|
+
}
|
|
218
|
+
/** Recompute a completed run minimally: force-rerun the `seeds`, then walk
|
|
219
|
+
* their stale frontier in topological order. The cache provides early cutoff
|
|
220
|
+
* for free — a downstream whose inputHash didn't move (because the seed's new
|
|
221
|
+
* output happened to equal the old) hits its prior and is reused rather than
|
|
222
|
+
* re-executed. `dryRun` computes the worst-case frontier without spending a
|
|
223
|
+
* token. Returns a fresh state + a report. Throws only when dryRun:false is
|
|
224
|
+
* requested for a flow with unobserved dependencies; callers should surface
|
|
225
|
+
* that as a user-facing error. */
|
|
226
|
+
export declare function recomputeTaskflow(state: RunState, deps: RuntimeDeps, seeds: readonly string[], opts?: {
|
|
227
|
+
dryRun?: boolean;
|
|
228
|
+
}): Promise<{
|
|
229
|
+
report: RecomputeReport;
|
|
230
|
+
state: RunState;
|
|
231
|
+
}>;
|
|
232
|
+
export declare function executeTaskflow(state: RunState, deps: RuntimeDeps): Promise<RuntimeResult>;
|
|
233
|
+
export {};
|
|
234
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|