@vinhnt-sdk/step-executor 0.1.3

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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -0
  3. package/dist/approval-handler.d.ts +18 -0
  4. package/dist/approval-handler.d.ts.map +1 -0
  5. package/dist/approval-handler.js +39 -0
  6. package/dist/approval-handler.js.map +1 -0
  7. package/dist/circuit-breaker.d.ts +48 -0
  8. package/dist/circuit-breaker.d.ts.map +1 -0
  9. package/dist/circuit-breaker.js +171 -0
  10. package/dist/circuit-breaker.js.map +1 -0
  11. package/dist/hooks.d.ts +15 -0
  12. package/dist/hooks.d.ts.map +1 -0
  13. package/dist/hooks.js +2 -0
  14. package/dist/hooks.js.map +1 -0
  15. package/dist/index.d.ts +22 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +22 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/kernel-error.d.ts +10 -0
  20. package/dist/kernel-error.d.ts.map +1 -0
  21. package/dist/kernel-error.js +12 -0
  22. package/dist/kernel-error.js.map +1 -0
  23. package/dist/kernel-utils.d.ts +49 -0
  24. package/dist/kernel-utils.d.ts.map +1 -0
  25. package/dist/kernel-utils.js +117 -0
  26. package/dist/kernel-utils.js.map +1 -0
  27. package/dist/path-policy.d.ts +18 -0
  28. package/dist/path-policy.d.ts.map +1 -0
  29. package/dist/path-policy.js +38 -0
  30. package/dist/path-policy.js.map +1 -0
  31. package/dist/permission-gate.d.ts +93 -0
  32. package/dist/permission-gate.d.ts.map +1 -0
  33. package/dist/permission-gate.js +303 -0
  34. package/dist/permission-gate.js.map +1 -0
  35. package/dist/run-context.d.ts +26 -0
  36. package/dist/run-context.d.ts.map +1 -0
  37. package/dist/run-context.js +13 -0
  38. package/dist/run-context.js.map +1 -0
  39. package/dist/run-state.d.ts +27 -0
  40. package/dist/run-state.d.ts.map +1 -0
  41. package/dist/run-state.js +88 -0
  42. package/dist/run-state.js.map +1 -0
  43. package/dist/self-correction.d.ts +29 -0
  44. package/dist/self-correction.d.ts.map +1 -0
  45. package/dist/self-correction.js +89 -0
  46. package/dist/self-correction.js.map +1 -0
  47. package/dist/step-executor.d.ts +81 -0
  48. package/dist/step-executor.d.ts.map +1 -0
  49. package/dist/step-executor.js +314 -0
  50. package/dist/step-executor.js.map +1 -0
  51. package/dist/termination.d.ts +87 -0
  52. package/dist/termination.d.ts.map +1 -0
  53. package/dist/termination.js +89 -0
  54. package/dist/termination.js.map +1 -0
  55. package/dist/tool-context-builder.d.ts +22 -0
  56. package/dist/tool-context-builder.d.ts.map +1 -0
  57. package/dist/tool-context-builder.js +42 -0
  58. package/dist/tool-context-builder.js.map +1 -0
  59. package/dist/tool-error-router.d.ts +26 -0
  60. package/dist/tool-error-router.d.ts.map +1 -0
  61. package/dist/tool-error-router.js +85 -0
  62. package/dist/tool-error-router.js.map +1 -0
  63. package/dist/tool-result-processor.d.ts +24 -0
  64. package/dist/tool-result-processor.d.ts.map +1 -0
  65. package/dist/tool-result-processor.js +47 -0
  66. package/dist/tool-result-processor.js.map +1 -0
  67. package/package.json +63 -0
@@ -0,0 +1,314 @@
1
+ import { RunAbortedError } from "@vinhnt-sdk/schema";
2
+ import { detectDoomLoop, hashArgs, DOOM_LOOP_THRESHOLD, raceWithAbort, toolDomain, withToolTimeout } from "./kernel-utils.js";
3
+ import { inferStepType } from "@vinhnt-sdk/schema";
4
+ import { buildToolContext } from "./tool-context-builder.js";
5
+ import { handleApproval as handleApprovalFn } from "./approval-handler.js";
6
+ import { handleToolError as handleToolErrorFn } from "./tool-error-router.js";
7
+ import { runSelfCorrection as runSelfCorrectionFn } from "./self-correction.js";
8
+ import { redactObjectSecrets } from "@vinhnt-sdk/security";
9
+ import { processToolResults } from "./tool-result-processor.js";
10
+ import { checkExternalPaths } from "./path-policy.js";
11
+ async function safeEmit(store, event) {
12
+ try {
13
+ await store.emitEvent(event);
14
+ }
15
+ catch (err) {
16
+ console.warn("[safeEmit] Failed to emit event:", err);
17
+ }
18
+ }
19
+ /**
20
+ * Executes tool calls within a run step — manages permissions, approval,
21
+ * plugin hooks, doom-loop detection, external-path checking, concurrent
22
+ * execution, self-correction, saga recording, and fallback strategies.
23
+ */
24
+ export class StepExecutor {
25
+ deps;
26
+ constructor(deps) {
27
+ this.deps = deps;
28
+ }
29
+ /** Swap the saga reference for per-run saga scoping */
30
+ setSaga(saga) {
31
+ this.deps.saga = saga;
32
+ }
33
+ /** Swap the current agent reference for per-run agent scoping */
34
+ setCurrentAgent(agent) {
35
+ this.deps.currentAgent = agent;
36
+ }
37
+ /** Get the current agent reference (used by kernel to save prev before swap) */
38
+ getCurrentAgent() {
39
+ return this.deps.currentAgent;
40
+ }
41
+ /** Resolve the agent that owns the given run, falling back to the instance default. */
42
+ agentFor(runId) {
43
+ return this.deps.agentForRun ? this.deps.agentForRun(runId) : this.deps.currentAgent;
44
+ }
45
+ /** Resolve the saga that owns the given run, falling back to the instance default. */
46
+ sagaFor(runId) {
47
+ return this.deps.sagaForRun ? this.deps.sagaForRun(runId) : this.deps.saga;
48
+ }
49
+ async runConcurrent(tasks, concurrency) {
50
+ const results = new Array(tasks.length);
51
+ const running = [];
52
+ let idx = 0;
53
+ const exec = async (i) => {
54
+ const task = tasks[i];
55
+ if (!task)
56
+ return;
57
+ try {
58
+ results[i] = { status: "fulfilled", value: await task() };
59
+ }
60
+ catch (e) {
61
+ results[i] = { status: "rejected", reason: e };
62
+ }
63
+ };
64
+ const next = () => {
65
+ if (idx >= tasks.length)
66
+ return Promise.resolve();
67
+ const i = idx++;
68
+ const p = exec(i).then(next);
69
+ running.push(p);
70
+ if (running.length >= concurrency) {
71
+ return Promise.race(running).then(() => Promise.resolve());
72
+ }
73
+ return next();
74
+ };
75
+ await next();
76
+ await Promise.allSettled(running);
77
+ return results;
78
+ }
79
+ /**
80
+ * Execute a batch of tool calls for the current step.
81
+ * Handles permission gating, approval dialogs, plugin hooks, doom-loop
82
+ * detection, external-path checks, concurrent execution with configurable
83
+ * concurrency, self-correction on failure, and saga compensation recording.
84
+ */
85
+ async executeToolCalls(toolCalls, messages, step, runId, ctx, runAbort, sessionId, runModel) {
86
+ const selfCorrectTokens = { input: 0, output: 0 };
87
+ let toolCallCount = 0;
88
+ const recentCalls = [];
89
+ const toolResults = [];
90
+ const limit = this.deps.maxToolCallsPerStep;
91
+ for (let batchStart = 0; batchStart < toolCalls.length && !runAbort.signal.aborted && toolCallCount < limit; batchStart += limit) {
92
+ const batch = toolCalls.slice(batchStart, Math.min(batchStart + limit, toolCalls.length));
93
+ // Filter out doom-loop tools from the concurrent batch
94
+ const doomThreshold = this.deps.doomLoopThreshold ?? DOOM_LOOP_THRESHOLD;
95
+ const doomResult = [];
96
+ const batchIdentical = new Map();
97
+ const pendingEmits = [];
98
+ const execBatch = batch.filter((tc) => {
99
+ const argsKey = hashArgs(tc.args);
100
+ const key = `${tc.toolName}:${argsKey}`;
101
+ const prevCount = recentCalls.filter((r) => r.id === tc.toolName && (r.argsKey ?? hashArgs(r.args)) === argsKey).length;
102
+ const totalSoFar = prevCount + (batchIdentical.get(key) ?? 0);
103
+ if (totalSoFar >= doomThreshold) {
104
+ doomResult.push({ tc, result: "doom" });
105
+ pendingEmits.push(safeEmit(this.deps.store, {
106
+ id: crypto.randomUUID(), runId, type: "tool.failed",
107
+ occurredAt: new Date().toISOString(), traceId: ctx.traceId,
108
+ data: { toolId: tc.toolId, toolName: tc.toolName, domain: toolDomain(tc.toolName), error: `Doom loop: "${tc.toolName}" called ${this.deps.doomLoopThreshold}x with identical args` },
109
+ }));
110
+ return false;
111
+ }
112
+ batchIdentical.set(key, (batchIdentical.get(key) ?? 0) + 1);
113
+ return true;
114
+ });
115
+ const tasks = execBatch.map((tc) => async () => {
116
+ if (detectDoomLoop(recentCalls, tc.toolName, tc.args, doomThreshold)) {
117
+ await safeEmit(this.deps.store, {
118
+ id: crypto.randomUUID(), runId, type: "tool.failed",
119
+ occurredAt: new Date().toISOString(), traceId: ctx.traceId,
120
+ data: { toolId: tc.toolId, toolName: tc.toolName, domain: toolDomain(tc.toolName), error: `Doom loop: "${tc.toolName}" called ${doomThreshold}x with identical args` },
121
+ });
122
+ return { tc, result: "doom" };
123
+ }
124
+ if (this.deps.externalDirectoryAccess !== true && this.deps.workspaceRoot) {
125
+ const externalPath = checkExternalPaths(tc.toolName, tc.args, this.deps.workspaceRoot);
126
+ if (externalPath) {
127
+ await safeEmit(this.deps.store, {
128
+ id: crypto.randomUUID(), runId, type: "tool.failed",
129
+ occurredAt: new Date().toISOString(), traceId: ctx.traceId,
130
+ data: { toolId: tc.toolId, toolName: tc.toolName, domain: toolDomain(tc.toolName), error: `External directory: ${externalPath}` },
131
+ });
132
+ return { tc, result: "external", reason: `External directory: ${externalPath}` };
133
+ }
134
+ }
135
+ const tool = this.deps.findTool(tc.toolName, runId);
136
+ if (!tool) {
137
+ const registered = this.deps.hasTool(tc.toolName);
138
+ await safeEmit(this.deps.store, {
139
+ id: crypto.randomUUID(), runId, type: "tool.failed",
140
+ occurredAt: new Date().toISOString(), traceId: ctx.traceId,
141
+ data: {
142
+ toolId: tc.toolId, toolName: tc.toolName,
143
+ domain: toolDomain(tc.toolName),
144
+ ...(registered ? { decision: "deny" } : {}),
145
+ error: registered
146
+ ? `Tool "${tc.toolName}" not found (denied by policy)`
147
+ : `Tool "${tc.toolName}" not found`,
148
+ },
149
+ });
150
+ return { tc, result: "not-found" };
151
+ }
152
+ // P1-F: onBeforeToolExecution fired below — right before tool.execute.
153
+ const permResult = this.deps.permissionGate.checkTool(tc.toolName, tool.risk, tc.args, this.agentFor(runId));
154
+ if (!permResult.allowed && !permResult.needsApproval) {
155
+ await safeEmit(this.deps.store, {
156
+ id: crypto.randomUUID(), runId, type: "tool.failed",
157
+ occurredAt: new Date().toISOString(), traceId: ctx.traceId,
158
+ data: { toolId: tc.toolId, toolName: tc.toolName, domain: toolDomain(tc.toolName), decision: "deny", error: permResult.reason },
159
+ });
160
+ return { tc, result: "denied", reason: permResult.reason };
161
+ }
162
+ const compensationRef = { current: null };
163
+ const metadataRef = {};
164
+ const toolCtx = await this.buildToolContext(tc, runId, sessionId, ctx, runAbort, tool, compensationRef, metadataRef);
165
+ const approved = await this.handleApproval(permResult, tc, toolCtx, runId, ctx, sessionId, messages, tool.selfApproving);
166
+ if (!approved)
167
+ return { tc, result: "rejected" };
168
+ await safeEmit(this.deps.store, {
169
+ id: crypto.randomUUID(), runId, type: "step.type_changed",
170
+ occurredAt: new Date().toISOString(), traceId: ctx.traceId,
171
+ data: { stepType: inferStepType(tc.toolName), stepNumber: step, toolName: tc.toolName },
172
+ });
173
+ await safeEmit(this.deps.store, {
174
+ id: crypto.randomUUID(), runId, type: "tool.invoked",
175
+ occurredAt: new Date().toISOString(), traceId: ctx.traceId,
176
+ data: { toolId: tc.toolId, toolName: tc.toolName, domain: toolDomain(tc.toolName), decision: "allow", input: tc.args },
177
+ });
178
+ const invHookResult = await this.deps.pluginManager?.fireHook("onToolInvoked", {
179
+ toolId: tc.toolId, toolName: tc.toolName, input: tc.args,
180
+ });
181
+ const effectiveInput = invHookResult?.modified?.input ?? tc.args;
182
+ // P1-F: onBeforeToolExecution — intercept/modify input right before execution.
183
+ const beforeExecResult = await this.deps.pluginManager?.fireHook("onBeforeToolExecution", {
184
+ toolId: tc.toolId, toolName: tc.toolName, input: effectiveInput,
185
+ });
186
+ const execInput = beforeExecResult?.modified?.input ?? effectiveInput;
187
+ // Re-validate permission if the execution hook modified the input further.
188
+ if (execInput !== effectiveInput) {
189
+ const rePerm = this.deps.permissionGate.checkTool(tc.toolName, tool.risk, execInput, this.agentFor(runId));
190
+ if (!rePerm.allowed && !rePerm.needsApproval) {
191
+ await safeEmit(this.deps.store, {
192
+ id: crypto.randomUUID(), runId, type: "tool.failed",
193
+ occurredAt: new Date().toISOString(), traceId: ctx.traceId,
194
+ data: { toolId: tc.toolId, toolName: tc.toolName, domain: toolDomain(tc.toolName), decision: "deny", error: `Plugin-modified input rejected: ${rePerm.reason}` },
195
+ });
196
+ return { tc, result: "denied", reason: rePerm.reason };
197
+ }
198
+ }
199
+ const toolTimeout = tool.timeoutMs;
200
+ // RV-19: cooperative timeout — the tool's context signal is replaced
201
+ // with a local controller aborted at the deadline so the tool can stop
202
+ // its side effects, while the promise still hard-caps at the deadline.
203
+ const execPromise = toolTimeout
204
+ ? withToolTimeout((signal) => tool.execute(execInput, { ...toolCtx, signal }), toolTimeout, runAbort.signal, `Tool "${tc.toolName}" timed out after ${toolTimeout}ms`)
205
+ : tool.execute(execInput, toolCtx);
206
+ try {
207
+ const output = await raceWithAbort(execPromise, runAbort.signal, runId);
208
+ // P1-F: onAfterToolExecution — intercept/modify the raw tool output.
209
+ const afterExecResult = await this.deps.pluginManager?.fireHook("onAfterToolExecution", {
210
+ toolId: tc.toolId, toolName: tc.toolName, output,
211
+ });
212
+ const execOutput = afterExecResult?.modified?.output ?? output;
213
+ const compHookResult = await this.deps.pluginManager?.fireHook("onToolCompleted", {
214
+ toolId: tc.toolId, toolName: tc.toolName, output: execOutput,
215
+ });
216
+ const effectiveOutput = compHookResult?.modified?.output ?? execOutput;
217
+ this.sagaFor(runId).record({
218
+ toolId: tc.toolId, toolName: tc.toolName,
219
+ input: effectiveInput, output: effectiveOutput,
220
+ timestamp: Date.now(), step,
221
+ });
222
+ if (compensationRef.current) {
223
+ this.sagaFor(runId).registerCompensation(tc.toolId, {
224
+ entry: { toolId: tc.toolId, toolName: tc.toolName, input: effectiveInput, output: effectiveOutput, timestamp: Date.now(), step },
225
+ compensate: compensationRef.current,
226
+ });
227
+ }
228
+ await safeEmit(this.deps.store, {
229
+ id: crypto.randomUUID(), runId, type: "tool.completed",
230
+ occurredAt: new Date().toISOString(), traceId: ctx.traceId,
231
+ data: {
232
+ toolId: tc.toolId, toolName: tc.toolName, domain: toolDomain(tc.toolName),
233
+ output: effectiveOutput,
234
+ ...(metadataRef.current ? { metadata: metadataRef.current } : {}),
235
+ },
236
+ });
237
+ return { tc, result: "success", output: effectiveOutput };
238
+ }
239
+ catch (err) {
240
+ if (!(err instanceof RunAbortedError)) {
241
+ // P1-N: never log raw tool args — they may contain apiKeys/secrets.
242
+ console.error("[step-executor] Tool execution error", { toolId: tc.toolId, toolName: tc.toolName, error: err instanceof Error ? err.message : String(err), input: redactObjectSecrets(tc.args) });
243
+ }
244
+ await handleToolErrorFn(err, tc, tool, messages, step, runId, ctx, runAbort, toolCtx, sessionId, recentCalls, runModel, {
245
+ store: this.deps.store,
246
+ addSessionMessage: this.deps.addSessionMessage,
247
+ pluginManager: this.deps.pluginManager,
248
+ permissionGate: this.deps.permissionGate,
249
+ selfCorrectOnFailure: this.deps.selfCorrectOnFailure,
250
+ ...(this.deps.externalDirectoryAccess !== undefined ? { externalDirectoryAccess: this.deps.externalDirectoryAccess } : {}),
251
+ ...(this.deps.workspaceRoot !== undefined ? { workspaceRoot: this.deps.workspaceRoot } : {}),
252
+ findTool: this.deps.findTool,
253
+ currentAgent: this.agentFor(runId),
254
+ runSelfCorrection: (tc, messages, recentCalls, step, runId, ctx, runAbort, toolCtx, errorMsg, runModel) => this.runSelfCorrection(tc, messages, recentCalls, step, runId, ctx, runAbort, toolCtx, errorMsg, runModel, selfCorrectTokens),
255
+ });
256
+ await this.sagaFor(runId).rollbackStep(step);
257
+ return { tc, result: "failed" };
258
+ }
259
+ });
260
+ await Promise.all(pendingEmits);
261
+ const concurrency = this.deps.maxConcurrentToolCalls ?? 5;
262
+ const results = await this.runConcurrent(tasks, concurrency);
263
+ if (runAbort.signal.aborted)
264
+ break;
265
+ // Process pre-identified doom loops after batch execution
266
+ if (doomResult.length > 0) {
267
+ const doom = doomResult[0];
268
+ const errorMsg = `Tool "${doom.tc.toolName}" called with identical arguments ${doomThreshold} consecutive times. Aborting to prevent infinite loop.`;
269
+ messages.push({ role: "tool", toolCallId: doom.tc.toolId, content: `Error: ${errorMsg}` });
270
+ break;
271
+ }
272
+ const processed = await processToolResults(results, doomThreshold, messages, sessionId, { model: runModel.model }, toolCallCount, recentCalls, toolResults, {
273
+ addSessionMessage: this.deps.addSessionMessage,
274
+ });
275
+ toolCallCount = processed.toolCallCount;
276
+ recentCalls.length = 0;
277
+ recentCalls.push(...processed.recentCalls);
278
+ toolResults.length = 0;
279
+ toolResults.push(...processed.toolResults);
280
+ if (processed.breakBatch)
281
+ break;
282
+ }
283
+ return { toolCallCount, recentCalls, selfCorrectTokens, toolResults };
284
+ }
285
+ async buildToolContext(tc, runId, sessionId, ctx, runAbort, tool, compensationRef, metadataRef) {
286
+ return buildToolContext(tc, runId, sessionId, ctx, runAbort, compensationRef, metadataRef, {
287
+ pluginManager: this.deps.pluginManager,
288
+ permissionGate: this.deps.permissionGate,
289
+ currentAgent: this.agentFor(runId),
290
+ toolRisk: tool.risk,
291
+ });
292
+ }
293
+ async handleApproval(permResult, tc, toolCtx, runId, ctx, _sessionId, messages, selfApproving) {
294
+ return handleApprovalFn(permResult, tc, toolCtx, runId, ctx, _sessionId, messages, {
295
+ store: this.deps.store,
296
+ permissionGate: this.deps.permissionGate,
297
+ pluginManager: this.deps.pluginManager,
298
+ currentAgent: this.agentFor(runId),
299
+ }, selfApproving);
300
+ }
301
+ async runSelfCorrection(tc, messages, recentCalls, step, runId, ctx, runAbort, toolCtx, errorMsg, runModel, selfCorrectTokens) {
302
+ return runSelfCorrectionFn(tc, messages, recentCalls, step, runId, ctx, runAbort, toolCtx, errorMsg, runModel, {
303
+ store: this.deps.store,
304
+ modelCaller: this.deps.modelCaller,
305
+ maxSelfCorrectAttempts: this.deps.maxSelfCorrectAttempts,
306
+ doomLoopThreshold: this.deps.doomLoopThreshold,
307
+ findTool: this.deps.findTool,
308
+ permissionGate: this.deps.permissionGate,
309
+ pluginManager: this.deps.pluginManager,
310
+ currentAgent: this.agentFor(runId),
311
+ }, selfCorrectTokens);
312
+ }
313
+ }
314
+ //# sourceMappingURL=step-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-executor.js","sourceRoot":"","sources":["../src/step-executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import type { RunId } from "@vinhnt-sdk/schema";
2
+ /**
3
+ * ── Termination policy (Phase 4) ─────────────────────────────────────────
4
+ * A declarative, per-run exit strategy layered on top of the plain loop:
5
+ * hard step cap, token budget, and stop conditions / hooks that are verified
6
+ * after each step. The loop stays the unit of execution; the policy decides
7
+ * when it may stop early (success) or must be cut (budget exhausted).
8
+ */
9
+ /** Result of one tool invocation, used by stop-condition evaluation. */
10
+ export interface ToolCallOutcome {
11
+ readonly toolName: string;
12
+ readonly output?: string;
13
+ readonly exitCode?: number;
14
+ }
15
+ /** Read-only snapshot the loop exposes to stop conditions / hooks each step. */
16
+ export interface StepVerificationContext {
17
+ readonly runId: RunId;
18
+ readonly step: number;
19
+ readonly finalOutput: string;
20
+ readonly totalInputTokens: number;
21
+ readonly totalOutputTokens: number;
22
+ readonly lastStepToolOutcomes: readonly ToolCallOutcome[];
23
+ }
24
+ /** Declarative condition that can end the loop early. */
25
+ export type StopCondition = {
26
+ kind: "tool-output";
27
+ tool: string;
28
+ expect: {
29
+ exitCode?: number;
30
+ };
31
+ } | {
32
+ kind: "file-unchanged";
33
+ path: string;
34
+ } | {
35
+ kind: "screenshot";
36
+ } | {
37
+ kind: "llm-judge";
38
+ agent: string;
39
+ criteria: readonly string[];
40
+ } | {
41
+ kind: "state";
42
+ predicate: (ctx: StepVerificationContext) => boolean;
43
+ };
44
+ /** Hard limits and stop conditions that terminate a run. */
45
+ export interface TerminationPolicy {
46
+ /** Per-run hard step cap (overrides the kernel default when set). */
47
+ readonly maxSteps?: number;
48
+ /** Token budget — the loop is cut when any limit is exceeded. */
49
+ readonly budgetTokens?: {
50
+ readonly input?: number;
51
+ readonly output?: number;
52
+ readonly total?: number;
53
+ };
54
+ /** Declarative conditions checked after each step (e.g. stop-when-build-green). */
55
+ readonly stopConditions?: readonly StopCondition[];
56
+ /** Deterministic async hooks — return "stop" to end the run early as success. */
57
+ readonly stopHooks?: readonly {
58
+ onStepEnded(ctx: StepVerificationContext): Promise<"continue" | "stop">;
59
+ }[];
60
+ /** Evaluator-optimizer: id of the judge agent used for `llm-judge` conditions. */
61
+ readonly evaluatorAgent?: string;
62
+ }
63
+ /** Normalize an arbitrary tool result into an outcome (exitCode from structured output). */
64
+ export declare function toToolCallOutcome(toolName: string, output: unknown): ToolCallOutcome;
65
+ /**
66
+ * Evaluate declarative stop conditions against a step context. Returns the
67
+ * first matching condition, or undefined to continue. Kinds that need external
68
+ * infrastructure (file-unchanged, screenshot, llm-judge) return undefined here;
69
+ * wire them through `stopHooks` / an evaluator agent instead.
70
+ */
71
+ export declare function evaluateStopConditions(conditions: readonly StopCondition[], ctx: StepVerificationContext): StopCondition | undefined;
72
+ /**
73
+ * Build the judge prompt for an `llm-judge` stop condition. The evaluator is
74
+ * asked to return a single verdict, not a long essay — cheap enough to run
75
+ * every step.
76
+ */
77
+ export declare function buildJudgeMessages(condition: Extract<StopCondition, {
78
+ kind: "llm-judge";
79
+ }>, ctx: StepVerificationContext, evaluatorAgent?: string): {
80
+ role: "system" | "user";
81
+ content: string;
82
+ }[];
83
+ /** Parse a judge verdict (`{"met": true|false}`) tolerantly. */
84
+ export declare function parseJudgeVerdict(content: string): {
85
+ met: boolean;
86
+ };
87
+ //# sourceMappingURL=termination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"termination.d.ts","sourceRoot":"","sources":["../src/termination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD;;;;;;GAMG;AAEH,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,gFAAgF;AAChF,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,oBAAoB,EAAE,SAAS,eAAe,EAAE,CAAC;CAC3D;AAED,yDAAyD;AACzD,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACpE;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,CAAC,GAAG,EAAE,uBAAuB,KAAK,OAAO,CAAA;CAAE,CAAC;AAE5E,4DAA4D;AAC5D,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,YAAY,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvG,mFAAmF;IACnF,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACnD,iFAAiF;IACjF,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS;QAAE,WAAW,CAAC,GAAG,EAAE,uBAAuB,GAAG,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC,CAAA;KAAE,EAAE,CAAC;IAC5G,kFAAkF;IAClF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,4FAA4F;AAC5F,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,eAAe,CAapF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,GAAG,EAAE,uBAAuB,GAC3B,aAAa,GAAG,SAAS,CAK3B;AAqBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,OAAO,CAAC,aAAa,EAAE;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC,EACxD,GAAG,EAAE,uBAAuB,EAC5B,cAAc,CAAC,EAAE,MAAM,GACtB;IAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAAE,CA0BhD;AAED,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,CAInE"}
@@ -0,0 +1,89 @@
1
+ /** Normalize an arbitrary tool result into an outcome (exitCode from structured output). */
2
+ export function toToolCallOutcome(toolName, output) {
3
+ if (typeof output === "string")
4
+ return { toolName, output };
5
+ if (output && typeof output === "object") {
6
+ const structured = output;
7
+ const text = typeof structured.output === "string" ? structured.output : undefined;
8
+ const code = typeof structured.exitCode === "number" ? structured.exitCode : undefined;
9
+ return {
10
+ toolName,
11
+ ...(text !== undefined ? { output: text } : {}),
12
+ ...(code !== undefined ? { exitCode: code } : {}),
13
+ };
14
+ }
15
+ return { toolName };
16
+ }
17
+ /**
18
+ * Evaluate declarative stop conditions against a step context. Returns the
19
+ * first matching condition, or undefined to continue. Kinds that need external
20
+ * infrastructure (file-unchanged, screenshot, llm-judge) return undefined here;
21
+ * wire them through `stopHooks` / an evaluator agent instead.
22
+ */
23
+ export function evaluateStopConditions(conditions, ctx) {
24
+ for (const condition of conditions) {
25
+ if (matchesCondition(condition, ctx))
26
+ return condition;
27
+ }
28
+ return undefined;
29
+ }
30
+ function matchesCondition(condition, ctx) {
31
+ switch (condition.kind) {
32
+ case "tool-output": {
33
+ const outcome = ctx.lastStepToolOutcomes.find((o) => o.toolName === condition.tool);
34
+ if (!outcome)
35
+ return false;
36
+ if (condition.expect?.exitCode !== undefined)
37
+ return outcome.exitCode === condition.expect.exitCode;
38
+ return outcome.output !== undefined;
39
+ }
40
+ case "state":
41
+ return condition.predicate(ctx);
42
+ case "file-unchanged":
43
+ case "screenshot":
44
+ case "llm-judge":
45
+ return false;
46
+ default:
47
+ return false;
48
+ }
49
+ }
50
+ /**
51
+ * Build the judge prompt for an `llm-judge` stop condition. The evaluator is
52
+ * asked to return a single verdict, not a long essay — cheap enough to run
53
+ * every step.
54
+ */
55
+ export function buildJudgeMessages(condition, ctx, evaluatorAgent) {
56
+ const persona = evaluatorAgent ? ` (agent "${evaluatorAgent}")` : "";
57
+ const toolLog = ctx.lastStepToolOutcomes.length > 0
58
+ ? ctx.lastStepToolOutcomes
59
+ .map((o) => `- ${o.toolName}${o.exitCode !== undefined ? ` (exit ${o.exitCode})` : ""}${o.output ? `: ${String(o.output).slice(0, 300)}` : ""}`)
60
+ .join("\n")
61
+ : "(no tool output this step)";
62
+ return [
63
+ {
64
+ role: "system",
65
+ content: `You are an evaluator judge${persona}. Given the criteria and the evidence, decide whether the task is complete. Respond with ONLY a valid JSON object of the form {"met": true} or {"met": false}. No prose.`,
66
+ },
67
+ {
68
+ role: "user",
69
+ content: [
70
+ `Criteria (ALL must be met):`,
71
+ condition.criteria.map((c) => `- ${c}`).join("\n"),
72
+ "",
73
+ "Evidence:",
74
+ `Final output: ${ctx.finalOutput || "(none yet)"}`,
75
+ `Tool outputs this step:\n${toolLog}`,
76
+ "",
77
+ "Are all criteria met? Reply JSON only.",
78
+ ].join("\n"),
79
+ },
80
+ ];
81
+ }
82
+ /** Parse a judge verdict (`{"met": true|false}`) tolerantly. */
83
+ export function parseJudgeVerdict(content) {
84
+ const match = content.match(/"met"\s*:\s*(true|false)/i);
85
+ if (match)
86
+ return { met: match[1].toLowerCase() === "true" };
87
+ return { met: false };
88
+ }
89
+ //# sourceMappingURL=termination.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"termination.js","sourceRoot":"","sources":["../src/termination.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { RunId, RequestContext } from "@vinhnt-sdk/schema";
2
+ import type { ToolContext, ToolRisk } from "@vinhnt-sdk/tools";
3
+ import type { StepExecutorPluginHooks } from "./hooks.js";
4
+ import type { PermissionGate } from "./permission-gate.js";
5
+ import type { ToolExecutionPlan } from "./step-executor.js";
6
+ import type { AgentConfig } from "@vinhnt-sdk/schema";
7
+ /** Dependencies required by {@link buildToolContext}. */
8
+ export interface ToolContextBuilderDeps {
9
+ readonly pluginManager: StepExecutorPluginHooks | undefined;
10
+ readonly permissionGate: PermissionGate;
11
+ readonly currentAgent: AgentConfig | undefined;
12
+ /** Tool risk used to evaluate the tool's own `ctx.ask` against the gate. */
13
+ readonly toolRisk: ToolRisk;
14
+ }
15
+ /** Mutable ref through which tools attach observability metadata. */
16
+ export interface MetadataRef {
17
+ current?: Record<string, unknown> | undefined;
18
+ }
19
+ export declare function buildToolContext(tc: ToolExecutionPlan, runId: RunId, sessionId: string | undefined, ctx: RequestContext, runAbort: AbortController, compensationRef: {
20
+ current: (() => Promise<void>) | null;
21
+ }, metadataRef: MetadataRef, deps: ToolContextBuilderDeps): Promise<ToolContext>;
22
+ //# sourceMappingURL=tool-context-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-context-builder.d.ts","sourceRoot":"","sources":["../src/tool-context-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,yDAAyD;AACzD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,aAAa,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC5D,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,YAAY,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/C,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC7B;AAED,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAC/C;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,iBAAiB,EACrB,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,eAAe,EACzB,eAAe,EAAE;IAAE,OAAO,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAA;CAAE,EAC1D,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,WAAW,CAAC,CA2CtB"}
@@ -0,0 +1,42 @@
1
+ import { sanitizeEnv } from "@vinhnt-sdk/security";
2
+ export async function buildToolContext(tc, runId, sessionId, ctx, runAbort, compensationRef, metadataRef, deps) {
3
+ // P1-G: default env is the sanitized whitelist, never raw process.env.
4
+ let shellEnv = sanitizeEnv();
5
+ const shellEnvResult = await deps.pluginManager?.fireHook("onShellEnv", { env: {} });
6
+ if (shellEnvResult?.modified?.env) {
7
+ shellEnv = { ...shellEnv, ...shellEnvResult.modified.env };
8
+ }
9
+ metadataRef.current = undefined;
10
+ return {
11
+ sessionId: sessionId ?? "",
12
+ runId,
13
+ agentId: deps.currentAgent?.id ?? "",
14
+ agentName: deps.currentAgent?.profile.name ?? "",
15
+ signal: runAbort.signal,
16
+ env: shellEnv,
17
+ parentContext: ctx,
18
+ // P1-H: single approval path — gate decide first (saved patterns / rules),
19
+ // then prompt via the approval store passing savePatterns for "always".
20
+ ask: async (askInput) => {
21
+ const decision = deps.permissionGate.checkTool(tc.toolName, deps.toolRisk, tc.args, deps.currentAgent);
22
+ if (decision.allowed)
23
+ return "once";
24
+ // Deny rules must always win over any previously saved approval — a
25
+ // per-tool approval must not resurrect a tool that is now deny-listed.
26
+ if (!decision.needsApproval)
27
+ return "reject";
28
+ if (deps.permissionGate.checkSavedApproval(tc.toolName, tc.args, deps.currentAgent?.id))
29
+ return "once";
30
+ return deps.permissionGate.askForTool(tc.toolName, tc.toolId, runId, sessionId ?? "", askInput.reason, deps.currentAgent?.id ?? "", ctx.traceId, deps.pluginManager, askInput.savePatterns, runAbort.signal);
31
+ },
32
+ metadata: (input) => {
33
+ metadataRef.current = {
34
+ ...metadataRef.current,
35
+ ...(input.metadata ?? {}),
36
+ ...(input.title ? { title: input.title } : {}),
37
+ };
38
+ },
39
+ setCompensation: (action) => { compensationRef.current = action; },
40
+ };
41
+ }
42
+ //# sourceMappingURL=tool-context-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-context-builder.js","sourceRoot":"","sources":["../src/tool-context-builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAqBnD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,EAAqB,EACrB,KAAY,EACZ,SAA6B,EAC7B,GAAmB,EACnB,QAAyB,EACzB,eAA0D,EAC1D,WAAwB,EACxB,IAA4B;IAE5B,uEAAuE;IACvE,IAAI,QAAQ,GAA2B,WAAW,EAAE,CAAC;IACrD,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;IACrF,IAAI,cAAc,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAClC,QAAQ,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,cAAc,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;IAC7D,CAAC;IACD,WAAW,CAAC,OAAO,GAAG,SAAS,CAAC;IAChC,OAAO;QACL,SAAS,EAAE,SAAS,IAAI,EAAE;QAC1B,KAAK;QACL,OAAO,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE;QACpC,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;QAChD,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,GAAG,EAAE,QAAQ;QACb,aAAa,EAAE,GAAG;QAClB,2EAA2E;QAC3E,wEAAwE;QACxE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;YACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAC5C,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,IAA+B,EAAE,IAAI,CAAC,YAAY,CAClF,CAAC;YACF,IAAI,QAAQ,CAAC,OAAO;gBAAE,OAAO,MAAM,CAAC;YACpC,oEAAoE;YACpE,uEAAuE;YACvE,IAAI,CAAC,QAAQ,CAAC,aAAa;gBAAE,OAAO,QAAQ,CAAC;YAC7C,IAAI,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAA+B,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;gBAAE,OAAO,MAAM,CAAC;YAClI,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,CACnC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,EAC9C,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,EAC5C,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,EAC/B,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CACvC,CAAC;QACJ,CAAC;QACD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;YAClB,WAAW,CAAC,OAAO,GAAG;gBACpB,GAAG,WAAW,CAAC,OAAO;gBACtB,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;gBACzB,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/C,CAAC;QACJ,CAAC;QACD,eAAe,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,eAAe,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC;KACnE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { RunId, RequestContext } from "@vinhnt-sdk/schema";
2
+ import type { ChatMessage } from "@vinhnt-sdk/schema";
3
+ import type { ToolContext, ToolDefinition } from "@vinhnt-sdk/tools";
4
+ import type { StepExecutorPluginHooks } from "./hooks.js";
5
+ import type { PermissionGate } from "./permission-gate.js";
6
+ import type { RecentCall } from "./kernel-utils.js";
7
+ import type { ToolExecutionPlan } from "./step-executor.js";
8
+ import type { ModelProvider } from "@vinhnt-sdk/schema";
9
+ /** Dependencies required by {@link handleToolError}. */
10
+ export interface ToolErrorRouterDeps {
11
+ readonly store: {
12
+ emitEvent(event: Omit<import("@vinhnt-sdk/schema").KnownRunEvent, "sequence">, persist?: boolean): Promise<void>;
13
+ };
14
+ readonly addSessionMessage: (sessionId: string | undefined, role: string, content: string, extra?: Record<string, unknown>) => Promise<void>;
15
+ readonly pluginManager: StepExecutorPluginHooks | undefined;
16
+ readonly permissionGate: PermissionGate;
17
+ readonly selfCorrectOnFailure: boolean;
18
+ readonly externalDirectoryAccess?: boolean;
19
+ readonly workspaceRoot?: string;
20
+ readonly findTool: (name: string, runId?: RunId) => ToolDefinition | undefined;
21
+ currentAgent: import("@vinhnt-sdk/schema").AgentConfig | undefined;
22
+ runSelfCorrection: (tc: ToolExecutionPlan, messages: ChatMessage[], recentCalls: RecentCall[], step: number, runId: RunId, ctx: RequestContext, runAbort: AbortController, toolCtx: ToolContext, errorMsg: string, runModel: ModelProvider) => Promise<void>;
23
+ }
24
+ export declare function handleToolError(err: unknown, tc: ToolExecutionPlan, _tool: ToolDefinition, messages: ChatMessage[], step: number, runId: RunId, ctx: RequestContext, runAbort: AbortController, toolCtx: ToolContext, sessionId: string | undefined, recentCalls: RecentCall[], runModel: ModelProvider, deps: ToolErrorRouterDeps): Promise<void>;
25
+ export declare function tryReadFileFallback(tc: ToolExecutionPlan, runAbort: AbortController, runId: RunId, ctx: RequestContext, sessionId: string | undefined, messages: ChatMessage[], errorMsg: string, runModel: ModelProvider, deps: ToolErrorRouterDeps): Promise<boolean>;
26
+ //# sourceMappingURL=tool-error-router.d.ts.map