@rk0429/agentic-relay 19.4.3 → 19.5.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.
Files changed (65) hide show
  1. package/dist/application/event-log-sink.d.ts +22 -0
  2. package/dist/application/event-log-sink.js +101 -0
  3. package/dist/application/event-log-sink.js.map +1 -0
  4. package/dist/application/housekeeping.d.ts +2 -0
  5. package/dist/application/housekeeping.js +62 -6
  6. package/dist/application/housekeeping.js.map +1 -1
  7. package/dist/application/workflow-execution-service.d.ts +146 -0
  8. package/dist/application/workflow-execution-service.js +989 -0
  9. package/dist/application/workflow-execution-service.js.map +1 -0
  10. package/dist/bin/relay.js +203 -9
  11. package/dist/bin/relay.js.map +1 -1
  12. package/dist/core/types.d.ts +2 -1
  13. package/dist/domain/config.d.ts +1 -0
  14. package/dist/domain/config.js +8 -0
  15. package/dist/domain/config.js.map +1 -1
  16. package/dist/domain/exit-condition-evaluator.d.ts +13 -0
  17. package/dist/domain/exit-condition-evaluator.js +37 -0
  18. package/dist/domain/exit-condition-evaluator.js.map +1 -0
  19. package/dist/domain/loop-execution.d.ts +123 -0
  20. package/dist/domain/loop-execution.js +419 -0
  21. package/dist/domain/loop-execution.js.map +1 -0
  22. package/dist/domain/session-resolver.d.ts +6 -0
  23. package/dist/domain/session-resolver.js +49 -0
  24. package/dist/domain/session-resolver.js.map +1 -0
  25. package/dist/domain/workflow-loader.d.ts +16 -0
  26. package/dist/domain/workflow-loader.js +140 -0
  27. package/dist/domain/workflow-loader.js.map +1 -0
  28. package/dist/domain/workflow-schema.d.ts +144 -0
  29. package/dist/domain/workflow-schema.js +236 -0
  30. package/dist/domain/workflow-schema.js.map +1 -0
  31. package/dist/index.d.ts +3 -0
  32. package/dist/index.js +3 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/infrastructure/backends/streaming-text-extractors.js +1 -1
  35. package/dist/infrastructure/backends/streaming-text-extractors.js.map +1 -1
  36. package/dist/infrastructure/store/loop-state-repository.d.ts +28 -0
  37. package/dist/infrastructure/store/loop-state-repository.js +250 -0
  38. package/dist/infrastructure/store/loop-state-repository.js.map +1 -0
  39. package/dist/infrastructure/store/relay-store.d.ts +5 -0
  40. package/dist/infrastructure/store/relay-store.js +41 -0
  41. package/dist/infrastructure/store/relay-store.js.map +1 -1
  42. package/dist/interfaces/cli/components/InputBar.js +14 -4
  43. package/dist/interfaces/cli/components/InputBar.js.map +1 -1
  44. package/dist/interfaces/cli/components/MessageList.d.ts +2 -1
  45. package/dist/interfaces/cli/components/MessageList.js +4 -3
  46. package/dist/interfaces/cli/components/MessageList.js.map +1 -1
  47. package/dist/interfaces/cli/components/StatusBar.js +1 -1
  48. package/dist/interfaces/cli/components/StatusBar.js.map +1 -1
  49. package/dist/interfaces/cli/loop-progress-renderer.d.ts +11 -0
  50. package/dist/interfaces/cli/loop-progress-renderer.js +136 -0
  51. package/dist/interfaces/cli/loop-progress-renderer.js.map +1 -0
  52. package/dist/interfaces/cli/loop-progress-shell.d.ts +5 -0
  53. package/dist/interfaces/cli/loop-progress-shell.js +37 -0
  54. package/dist/interfaces/cli/loop-progress-shell.js.map +1 -0
  55. package/dist/interfaces/cli/relay-cli-args.d.ts +6 -0
  56. package/dist/interfaces/cli/relay-cli-args.js +39 -0
  57. package/dist/interfaces/cli/relay-cli-args.js.map +1 -1
  58. package/dist/interfaces/cli/relay-shell.js +21 -4
  59. package/dist/interfaces/cli/relay-shell.js.map +1 -1
  60. package/dist/interfaces/cli/text-input-utils.d.ts +8 -0
  61. package/dist/interfaces/cli/text-input-utils.js +34 -0
  62. package/dist/interfaces/cli/text-input-utils.js.map +1 -1
  63. package/dist/interfaces/mcp/relay-mcp-server.js +4 -3
  64. package/dist/interfaces/mcp/relay-mcp-server.js.map +1 -1
  65. package/package.json +2 -1
@@ -0,0 +1,419 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { ValidationError } from "../core/errors.js";
3
+ const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
4
+ export const LOOP_EXECUTION_SCHEMA_VERSION = 1;
5
+ export class LoopExecutionId {
6
+ value;
7
+ constructor(value) {
8
+ this.value = value;
9
+ }
10
+ static create() {
11
+ return new LoopExecutionId(randomUUID());
12
+ }
13
+ static restore(value) {
14
+ if (!UUID_PATTERN.test(value)) {
15
+ throw new ValidationError(`Invalid loop execution id: ${value}`, {
16
+ recoveryHint: "Loop execution IDs must be UUID strings.",
17
+ });
18
+ }
19
+ return new LoopExecutionId(value);
20
+ }
21
+ toString() {
22
+ return this.value;
23
+ }
24
+ }
25
+ export class NestDepth {
26
+ value;
27
+ maxDepth;
28
+ constructor(value, maxDepth = 5) {
29
+ if (!Number.isInteger(value) || value < 0) {
30
+ throw new ValidationError(`Invalid nest depth value: ${value}`, {
31
+ recoveryHint: "Nest depth must be a non-negative integer.",
32
+ });
33
+ }
34
+ if (!Number.isInteger(maxDepth) || maxDepth <= 0) {
35
+ throw new ValidationError(`Invalid max nest depth: ${maxDepth}`, {
36
+ recoveryHint: "Nest depth maxDepth must be a positive integer.",
37
+ });
38
+ }
39
+ this.value = value;
40
+ this.maxDepth = maxDepth;
41
+ }
42
+ increment() {
43
+ return new NestDepth(this.value + 1, this.maxDepth);
44
+ }
45
+ isAtLimit() {
46
+ return this.value >= this.maxDepth;
47
+ }
48
+ }
49
+ export class LoopExecution {
50
+ workflow;
51
+ executionIdValue;
52
+ nestDepthValue;
53
+ workflowPathValue;
54
+ workflowDigestValue;
55
+ statusValue;
56
+ currentIterationValue;
57
+ stepResultsValue;
58
+ completionReasonValue;
59
+ initialSessionIdValue;
60
+ pendingExitConditionValue;
61
+ nextStepIdValue;
62
+ startedAtValue;
63
+ completedAtValue;
64
+ constructor(options) {
65
+ assertNonEmptyString(options.workflowPath, "workflowPath");
66
+ assertNonEmptyString(options.workflowDigest, "workflowDigest");
67
+ assertTimestamp(options.startedAt, "startedAt");
68
+ if (options.completedAt) {
69
+ assertTimestamp(options.completedAt, "completedAt");
70
+ }
71
+ if (!Number.isInteger(options.currentIteration) || options.currentIteration < 0) {
72
+ throw new ValidationError(`Invalid current iteration: ${options.currentIteration}`, {
73
+ recoveryHint: "Current iteration must be a non-negative integer.",
74
+ });
75
+ }
76
+ validateStepResults(options.stepResults);
77
+ this.workflow = options.workflow;
78
+ this.executionIdValue = options.executionId;
79
+ this.nestDepthValue = options.nestDepth;
80
+ this.workflowPathValue = options.workflowPath;
81
+ this.workflowDigestValue = options.workflowDigest;
82
+ this.statusValue = options.status;
83
+ this.currentIterationValue = options.currentIteration;
84
+ this.stepResultsValue = cloneStepResults(options.stepResults);
85
+ this.startedAtValue = options.startedAt;
86
+ this.initialSessionIdValue = options.initialSessionId ?? null;
87
+ this.pendingExitConditionValue = options.pendingExitCondition ?? null;
88
+ this.nextStepIdValue = options.nextStepId ?? null;
89
+ this.completionReasonValue = options.completionReason;
90
+ this.completedAtValue = options.completedAt;
91
+ }
92
+ static create(workflow, options) {
93
+ return new LoopExecution({
94
+ workflow,
95
+ executionId: LoopExecutionId.create(),
96
+ nestDepth: options.nestDepth,
97
+ workflowPath: options.workflowPath,
98
+ workflowDigest: options.workflowDigest,
99
+ status: "created",
100
+ currentIteration: 0,
101
+ stepResults: [],
102
+ startedAt: options.startedAt ?? new Date().toISOString(),
103
+ initialSessionId: options.initialSessionId ?? null,
104
+ nextStepId: workflow.steps[0]?.id ?? null,
105
+ });
106
+ }
107
+ static resume(workflow, state, nestDepth) {
108
+ if (state.schemaVersion !== LOOP_EXECUTION_SCHEMA_VERSION) {
109
+ throw new ValidationError(`Unsupported loop interrupt state schema version: ${state.schemaVersion}`, {
110
+ recoveryHint: "Only schemaVersion 1 is currently supported.",
111
+ });
112
+ }
113
+ if (state.frames.length === 0) {
114
+ throw new ValidationError("Loop interrupt state must contain at least one frame.", {
115
+ recoveryHint: "Retry resume with a valid loop state file.",
116
+ });
117
+ }
118
+ assertTimestamp(state.startedAt, "startedAt");
119
+ assertTimestamp(state.interruptedAt, "interruptedAt");
120
+ const frame = state.frames[state.frames.length - 1];
121
+ validateWorkflowResumeFrame(frame);
122
+ return new LoopExecution({
123
+ workflow,
124
+ executionId: LoopExecutionId.restore(state.executionId),
125
+ nestDepth,
126
+ workflowPath: frame.workflowPath,
127
+ workflowDigest: frame.workflowDigest,
128
+ status: "running",
129
+ currentIteration: frame.currentIteration,
130
+ stepResults: frame.stepResults,
131
+ startedAt: state.startedAt,
132
+ initialSessionId: frame.initialSessionId ?? null,
133
+ nextStepId: frame.pendingExitCondition === undefined
134
+ ? frame.nextStepId ??
135
+ deriveNextStepId(workflow, frame.currentIteration, frame.stepResults)
136
+ : frame.nextStepId ?? null,
137
+ pendingExitCondition: frame.pendingExitCondition ?? null,
138
+ });
139
+ }
140
+ get executionId() {
141
+ return this.executionIdValue.value;
142
+ }
143
+ get executionIdObject() {
144
+ return this.executionIdValue;
145
+ }
146
+ get status() {
147
+ return this.statusValue;
148
+ }
149
+ get currentIteration() {
150
+ return this.currentIterationValue;
151
+ }
152
+ get stepResults() {
153
+ return cloneStepResults(this.stepResultsValue);
154
+ }
155
+ get completionReason() {
156
+ return this.completionReasonValue;
157
+ }
158
+ get nestDepth() {
159
+ return this.nestDepthValue;
160
+ }
161
+ get initialSessionId() {
162
+ return this.initialSessionIdValue;
163
+ }
164
+ get pendingExitCondition() {
165
+ return this.pendingExitConditionValue;
166
+ }
167
+ get nextStepId() {
168
+ return this.nextStepIdValue;
169
+ }
170
+ get startedAt() {
171
+ return this.startedAtValue;
172
+ }
173
+ get completedAt() {
174
+ return this.completedAtValue;
175
+ }
176
+ get workflowPath() {
177
+ return this.workflowPathValue;
178
+ }
179
+ get workflowDigest() {
180
+ return this.workflowDigestValue;
181
+ }
182
+ start() {
183
+ if (this.statusValue !== "created") {
184
+ throw new ValidationError(`Loop execution cannot start from status "${this.statusValue}".`, {
185
+ recoveryHint: 'Only loop executions in "created" status can be started.',
186
+ });
187
+ }
188
+ this.statusValue = "running";
189
+ this.nextStepIdValue = this.workflow.steps[0]?.id ?? null;
190
+ }
191
+ beginIteration() {
192
+ this.assertRunning("beginIteration");
193
+ if (this.currentIterationValue >= this.workflow.loop.maxIterations) {
194
+ throw new ValidationError(`Cannot begin iteration ${this.currentIterationValue + 1}; max_iterations is ${this.workflow.loop.maxIterations}.`, {
195
+ recoveryHint: "Complete the loop execution instead of starting another iteration.",
196
+ });
197
+ }
198
+ this.currentIterationValue += 1;
199
+ this.pendingExitConditionValue = null;
200
+ this.nextStepIdValue = this.workflow.steps[0]?.id ?? null;
201
+ }
202
+ recordStepResult(result) {
203
+ this.assertRunning("recordStepResult");
204
+ validateStepResult(result);
205
+ if (result.iteration !== this.currentIterationValue) {
206
+ throw new ValidationError(`Step result iteration ${result.iteration} does not match current iteration ${this.currentIterationValue}.`, {
207
+ recoveryHint: "Record step results against the active iteration only.",
208
+ });
209
+ }
210
+ const stepIndex = this.workflow.steps.findIndex((step) => step.id === result.stepId);
211
+ if (stepIndex === -1) {
212
+ throw new ValidationError(`Unknown step id "${result.stepId}" for this workflow.`, {
213
+ recoveryHint: "Record results only for steps that exist in the workflow definition.",
214
+ });
215
+ }
216
+ this.stepResultsValue = upsertStepResult(this.stepResultsValue, result);
217
+ if (result.status === "running" || result.status === "pending") {
218
+ this.nextStepIdValue = result.stepId;
219
+ return;
220
+ }
221
+ this.nextStepIdValue = this.workflow.steps[stepIndex + 1]?.id ?? null;
222
+ }
223
+ shouldEvaluateAfter(stepId) {
224
+ const exitCondition = this.workflow.loop.exitCondition;
225
+ if (!exitCondition) {
226
+ return false;
227
+ }
228
+ const evaluateAfter = exitCondition.evaluateAfter ?? this.workflow.steps.at(-1)?.id;
229
+ return evaluateAfter === stepId;
230
+ }
231
+ applyExitVerdict(verdict, options) {
232
+ this.assertRunning("applyExitVerdict");
233
+ if (verdict === "continue") {
234
+ this.pendingExitConditionValue = null;
235
+ return;
236
+ }
237
+ const evaluatedAfter = options?.evaluatedAfter ?? findLastCompletedStepId(this.stepResultsValue, this.currentIterationValue);
238
+ if (evaluatedAfter) {
239
+ const evaluatedAfterIndex = this.workflow.steps.findIndex((step) => step.id === evaluatedAfter);
240
+ if (evaluatedAfterIndex >= 0) {
241
+ for (const step of this.workflow.steps.slice(evaluatedAfterIndex + 1)) {
242
+ const existingResult = this.stepResultsValue.find((candidate) => candidate.iteration === this.currentIterationValue &&
243
+ candidate.stepId === step.id);
244
+ if (existingResult) {
245
+ continue;
246
+ }
247
+ this.stepResultsValue.push({
248
+ stepId: step.id,
249
+ iteration: this.currentIterationValue,
250
+ status: "skipped",
251
+ });
252
+ }
253
+ }
254
+ }
255
+ this.pendingExitConditionValue = null;
256
+ this.nextStepIdValue = null;
257
+ this.complete("exit_condition_met", options?.completedAt);
258
+ }
259
+ interrupt(options) {
260
+ this.assertRunning("interrupt");
261
+ const interruptedAt = options?.interruptedAt ?? new Date().toISOString();
262
+ assertTimestamp(interruptedAt, "interruptedAt");
263
+ const frame = {
264
+ workflowPath: this.workflowPathValue,
265
+ workflowDigest: this.workflowDigestValue,
266
+ currentIteration: this.currentIterationValue,
267
+ stepResults: cloneStepResults(this.stepResultsValue),
268
+ nextStepId: options?.nextStepId === undefined
269
+ ? this.nextStepIdValue ?? undefined
270
+ : options.nextStepId ?? undefined,
271
+ initialSessionId: this.initialSessionIdValue ?? undefined,
272
+ pendingExitCondition: options?.pendingExitCondition === undefined
273
+ ? this.pendingExitConditionValue ?? undefined
274
+ : options.pendingExitCondition ?? undefined,
275
+ };
276
+ this.statusValue = "interrupted";
277
+ this.nextStepIdValue = frame.nextStepId ?? null;
278
+ this.pendingExitConditionValue = frame.pendingExitCondition ?? null;
279
+ return {
280
+ schemaVersion: LOOP_EXECUTION_SCHEMA_VERSION,
281
+ executionId: this.executionIdValue.value,
282
+ startedAt: this.startedAtValue,
283
+ frames: [frame],
284
+ interruptedAt,
285
+ };
286
+ }
287
+ complete(reason, completedAt = new Date().toISOString()) {
288
+ this.assertRunning("complete");
289
+ assertTimestamp(completedAt, "completedAt");
290
+ this.statusValue = "completed";
291
+ this.completionReasonValue = reason;
292
+ this.completedAtValue = completedAt;
293
+ this.pendingExitConditionValue = null;
294
+ this.nextStepIdValue = null;
295
+ }
296
+ toProgressSnapshot() {
297
+ return {
298
+ executionId: this.executionIdValue.value,
299
+ workflowName: this.workflow.name,
300
+ currentIteration: this.currentIterationValue,
301
+ maxIterations: this.workflow.loop.maxIterations,
302
+ startedAt: this.startedAtValue,
303
+ steps: this.workflow.steps.map((step) => {
304
+ const currentResult = findLatestStepResult(this.stepResultsValue, step.id, this.currentIterationValue);
305
+ return {
306
+ stepId: step.id,
307
+ kind: isWorkflowStep(step) ? "workflow" : "agent",
308
+ status: this.currentIterationValue === 0
309
+ ? "pending"
310
+ : currentResult?.status ?? "pending",
311
+ backend: isWorkflowStep(step) ? undefined : step.backend,
312
+ role: isWorkflowStep(step) ? undefined : step.role,
313
+ duration: currentResult?.duration,
314
+ };
315
+ }),
316
+ };
317
+ }
318
+ assertRunning(operation) {
319
+ if (this.statusValue !== "running") {
320
+ throw new ValidationError(`Loop execution cannot ${operation} while status is "${this.statusValue}".`, {
321
+ recoveryHint: 'Only loop executions in "running" status support this operation.',
322
+ });
323
+ }
324
+ }
325
+ }
326
+ function validateWorkflowResumeFrame(frame) {
327
+ assertNonEmptyString(frame.workflowPath, "workflowPath");
328
+ assertNonEmptyString(frame.workflowDigest, "workflowDigest");
329
+ if (!Number.isInteger(frame.currentIteration) || frame.currentIteration < 0) {
330
+ throw new ValidationError(`Invalid interrupt state currentIteration: ${frame.currentIteration}`, {
331
+ recoveryHint: "Interrupt states must store a non-negative currentIteration.",
332
+ });
333
+ }
334
+ validateStepResults(frame.stepResults);
335
+ }
336
+ function validateStepResults(results) {
337
+ for (const result of results) {
338
+ validateStepResult(result);
339
+ }
340
+ }
341
+ function validateStepResult(result) {
342
+ assertNonEmptyString(result.stepId, "stepId");
343
+ if (!Number.isInteger(result.iteration) || result.iteration <= 0) {
344
+ throw new ValidationError(`Invalid step result iteration: ${result.iteration}`, {
345
+ recoveryHint: "Step result iteration must be a positive integer.",
346
+ });
347
+ }
348
+ if (!["pending", "running", "completed", "failed", "skipped"].includes(result.status)) {
349
+ throw new ValidationError(`Invalid step result status: ${result.status}`, {
350
+ recoveryHint: "Step result status must be one of pending, running, completed, failed, or skipped.",
351
+ });
352
+ }
353
+ if (result.duration !== undefined && (!Number.isFinite(result.duration) || result.duration < 0)) {
354
+ throw new ValidationError(`Invalid step result duration: ${result.duration}`, {
355
+ recoveryHint: "Step result duration must be a non-negative number.",
356
+ });
357
+ }
358
+ }
359
+ function upsertStepResult(results, result) {
360
+ const next = cloneStepResults(results);
361
+ const existingIndex = next.findIndex((candidate) => candidate.stepId === result.stepId && candidate.iteration === result.iteration);
362
+ if (existingIndex >= 0) {
363
+ next[existingIndex] = { ...result };
364
+ return next;
365
+ }
366
+ next.push({ ...result });
367
+ return next;
368
+ }
369
+ function cloneStepResults(results) {
370
+ return results.map((result) => ({ ...result }));
371
+ }
372
+ function deriveNextStepId(workflow, currentIteration, stepResults) {
373
+ if (currentIteration === 0) {
374
+ return workflow.steps[0]?.id ?? null;
375
+ }
376
+ for (const step of workflow.steps) {
377
+ const hasResultForIteration = stepResults.some((candidate) => candidate.stepId === step.id && candidate.iteration === currentIteration);
378
+ if (!hasResultForIteration) {
379
+ return step.id;
380
+ }
381
+ }
382
+ return null;
383
+ }
384
+ function findLastCompletedStepId(stepResults, iteration) {
385
+ for (let index = stepResults.length - 1; index >= 0; index -= 1) {
386
+ const candidate = stepResults[index];
387
+ if (candidate.iteration === iteration && candidate.status === "completed") {
388
+ return candidate.stepId;
389
+ }
390
+ }
391
+ return undefined;
392
+ }
393
+ function findLatestStepResult(stepResults, stepId, iteration) {
394
+ for (let index = stepResults.length - 1; index >= 0; index -= 1) {
395
+ const candidate = stepResults[index];
396
+ if (candidate.stepId === stepId && candidate.iteration === iteration) {
397
+ return candidate;
398
+ }
399
+ }
400
+ return undefined;
401
+ }
402
+ function isWorkflowStep(step) {
403
+ return "workflow" in step;
404
+ }
405
+ function assertNonEmptyString(value, field) {
406
+ if (value.trim().length === 0) {
407
+ throw new ValidationError(`Invalid ${field}: value must not be empty.`, {
408
+ recoveryHint: `${field} must be a non-empty string.`,
409
+ });
410
+ }
411
+ }
412
+ function assertTimestamp(value, field) {
413
+ if (Number.isNaN(Date.parse(value))) {
414
+ throw new ValidationError(`Invalid ${field}: ${value}`, {
415
+ recoveryHint: `${field} must be a valid ISO 8601 timestamp.`,
416
+ });
417
+ }
418
+ }
419
+ //# sourceMappingURL=loop-execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop-execution.js","sourceRoot":"","sources":["../../src/domain/loop-execution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { StepResult } from "./loop-execution.js";
2
+ import type { StepDefinition } from "./workflow-schema.js";
3
+ export declare function resolve(stepDef: StepDefinition, currentIteration: number, stepResults: StepResult[], initialSessionId?: string): string | null;
4
+ export declare const SessionResolver: {
5
+ resolve: typeof resolve;
6
+ };
@@ -0,0 +1,49 @@
1
+ import { ValidationError } from "../core/errors.js";
2
+ export function resolve(stepDef, currentIteration, stepResults, initialSessionId) {
3
+ if (!Number.isInteger(currentIteration) || currentIteration <= 0) {
4
+ throw new ValidationError(`Invalid current iteration for session resolution: ${currentIteration}`, {
5
+ recoveryHint: "currentIteration must be a positive integer.",
6
+ });
7
+ }
8
+ if (stepDef.session === undefined) {
9
+ if (initialSessionId && stepResults.length === 0) {
10
+ return initialSessionId;
11
+ }
12
+ return null;
13
+ }
14
+ const inheritFromStepId = stepDef.session.inheritFrom;
15
+ const targetIteration = inheritFromStepId === stepDef.id ? currentIteration - 1 : currentIteration;
16
+ if (inheritFromStepId === stepDef.id && currentIteration === 1) {
17
+ return null;
18
+ }
19
+ const targetResult = findLatestStepResult(stepResults, inheritFromStepId, targetIteration);
20
+ if (!targetResult) {
21
+ throw new ValidationError(`Step "${stepDef.id}" cannot inherit session from "${inheritFromStepId}" in iteration ${targetIteration}: the referenced step has not completed yet.`, {
22
+ recoveryHint: "inherit_from can only reference completed steps in the current workflow frame.",
23
+ });
24
+ }
25
+ if (targetResult.status !== "completed") {
26
+ throw new ValidationError(`Step "${stepDef.id}" cannot inherit session from "${inheritFromStepId}" in iteration ${targetIteration}: referenced step status is "${targetResult.status}".`, {
27
+ recoveryHint: "inherit_from can only reference completed steps. Failed, skipped, pending, and running steps are invalid.",
28
+ });
29
+ }
30
+ if (!targetResult.relaySessionId) {
31
+ throw new ValidationError(`Step "${stepDef.id}" cannot inherit session from "${inheritFromStepId}" in iteration ${targetIteration}: relaySessionId is missing.`, {
32
+ recoveryHint: "Only completed step results with relaySessionId can be used for session inheritance.",
33
+ });
34
+ }
35
+ return targetResult.relaySessionId;
36
+ }
37
+ export const SessionResolver = {
38
+ resolve,
39
+ };
40
+ function findLatestStepResult(stepResults, stepId, iteration) {
41
+ for (let index = stepResults.length - 1; index >= 0; index -= 1) {
42
+ const candidate = stepResults[index];
43
+ if (candidate.stepId === stepId && candidate.iteration === iteration) {
44
+ return candidate;
45
+ }
46
+ }
47
+ return undefined;
48
+ }
49
+ //# sourceMappingURL=session-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-resolver.js","sourceRoot":"","sources":["../../src/domain/session-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIpD,MAAM,UAAU,OAAO,CACrB,OAAuB,EACvB,gBAAwB,EACxB,WAAyB,EACzB,gBAAyB;IAEzB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,IAAI,gBAAgB,IAAI,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,eAAe,CACvB,qDAAqD,gBAAgB,EAAE,EACvE;YACE,YAAY,EAAE,8CAA8C;SAC7D,CACF,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,gBAAgB,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjD,OAAO,gBAAgB,CAAC;QAC1B,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC;IACtD,MAAM,eAAe,GACnB,iBAAiB,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAE7E,IAAI,iBAAiB,KAAK,OAAO,CAAC,EAAE,IAAI,gBAAgB,KAAK,CAAC,EAAE,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAG,oBAAoB,CAAC,WAAW,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;IAC3F,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,eAAe,CACvB,SAAS,OAAO,CAAC,EAAE,kCAAkC,iBAAiB,kBAAkB,eAAe,8CAA8C,EACrJ;YACE,YAAY,EACV,gFAAgF;SACnF,CACF,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACxC,MAAM,IAAI,eAAe,CACvB,SAAS,OAAO,CAAC,EAAE,kCAAkC,iBAAiB,kBAAkB,eAAe,gCAAgC,YAAY,CAAC,MAAM,IAAI,EAC9J;YACE,YAAY,EACV,2GAA2G;SAC9G,CACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;QACjC,MAAM,IAAI,eAAe,CACvB,SAAS,OAAO,CAAC,EAAE,kCAAkC,iBAAiB,kBAAkB,eAAe,8BAA8B,EACrI;YACE,YAAY,EACV,sFAAsF;SACzF,CACF,CAAC;IACJ,CAAC;IAED,OAAO,YAAY,CAAC,cAAc,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,OAAO;CACR,CAAC;AAEF,SAAS,oBAAoB,CAC3B,WAAyB,EACzB,MAAc,EACd,SAAiB;IAEjB,KAAK,IAAI,KAAK,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QAChE,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAE,CAAC;QACtC,IAAI,SAAS,CAAC,MAAM,KAAK,MAAM,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACrE,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { NestDepth } from "./loop-execution.js";
2
+ import { type WorkflowDefinition } from "./workflow-schema.js";
3
+ export interface WorkflowFileRepository {
4
+ read(path: string): Promise<string>;
5
+ exists(path: string): Promise<boolean>;
6
+ }
7
+ export interface WorkflowCapabilitySummary {
8
+ hasCommandRun: boolean;
9
+ commandRunWorkflowPaths: string[];
10
+ }
11
+ export interface WorkflowLoadResult {
12
+ workflow: WorkflowDefinition;
13
+ capabilitySummary: WorkflowCapabilitySummary;
14
+ }
15
+ export declare function loadWorkflow(rootPath: string, repo: WorkflowFileRepository, nestDepth?: NestDepth): Promise<WorkflowLoadResult>;
16
+ export declare function computeWorkflowDigest(yamlContent: string): string;
@@ -0,0 +1,140 @@
1
+ import { createHash } from "node:crypto";
2
+ import { dirname, isAbsolute, relative, resolve } from "node:path";
3
+ import { ValidationError } from "../core/errors.js";
4
+ import { NestDepth } from "./loop-execution.js";
5
+ import { parseWorkflowYaml, } from "./workflow-schema.js";
6
+ export async function loadWorkflow(rootPath, repo, nestDepth = new NestDepth(0)) {
7
+ const canonicalRootPath = resolve(rootPath);
8
+ const context = {
9
+ repo,
10
+ cache: new Map(),
11
+ errors: [],
12
+ commandRunWorkflowPaths: new Set(),
13
+ rootDir: dirname(canonicalRootPath),
14
+ };
15
+ const workflow = await loadWorkflowFrame(canonicalRootPath, nestDepth, [], context);
16
+ if (workflow === null || context.errors.length > 0) {
17
+ throw new ValidationError(context.errors.join("\n"), {
18
+ causeData: {
19
+ errors: [...context.errors],
20
+ },
21
+ recoveryHint: "Fix the workflow definition and try again.",
22
+ });
23
+ }
24
+ return {
25
+ workflow,
26
+ capabilitySummary: {
27
+ hasCommandRun: context.commandRunWorkflowPaths.size > 0,
28
+ commandRunWorkflowPaths: [...context.commandRunWorkflowPaths].sort(),
29
+ },
30
+ };
31
+ }
32
+ export function computeWorkflowDigest(yamlContent) {
33
+ return createHash("sha256").update(yamlContent).digest("hex");
34
+ }
35
+ async function loadWorkflowFrame(workflowPath, nestDepth, ancestry, context) {
36
+ const cached = context.cache.get(workflowPath);
37
+ if (cached) {
38
+ return cached.workflow;
39
+ }
40
+ if (ancestry.includes(workflowPath)) {
41
+ context.errors.push(formatCircularReferenceError(ancestry, workflowPath));
42
+ return null;
43
+ }
44
+ if (!(await context.repo.exists(workflowPath))) {
45
+ context.errors.push(`${workflowPath}: Workflow file does not exist.`);
46
+ return null;
47
+ }
48
+ const yamlContent = await context.repo.read(workflowPath);
49
+ const digest = computeWorkflowDigest(yamlContent);
50
+ let workflow;
51
+ try {
52
+ workflow = parseWorkflowYaml(yamlContent);
53
+ }
54
+ catch (error) {
55
+ collectValidationError(workflowPath, error, context.errors);
56
+ return null;
57
+ }
58
+ context.cache.set(workflowPath, {
59
+ digest,
60
+ workflow,
61
+ });
62
+ recordCapabilities(workflowPath, workflow, context.commandRunWorkflowPaths);
63
+ validateWorkflowGraph(workflowPath, workflow, context.errors);
64
+ const nextAncestry = [...ancestry, workflowPath];
65
+ for (const [index, step] of workflow.steps.entries()) {
66
+ if (!isWorkflowStep(step)) {
67
+ continue;
68
+ }
69
+ const childPath = resolve(dirname(workflowPath), step.workflow);
70
+ if (!isPathWithinRoot(context.rootDir, childPath)) {
71
+ context.errors.push(`${workflowPath}: steps[${index}].workflow: Subworkflow path "${step.workflow}" resolves outside the root workflow directory (${context.rootDir}).`);
72
+ continue;
73
+ }
74
+ if (nextAncestry.includes(childPath)) {
75
+ context.errors.push(`${workflowPath}: steps[${index}].workflow: Circular subworkflow reference detected: ${[
76
+ ...nextAncestry,
77
+ childPath,
78
+ ].join(" -> ")}.`);
79
+ continue;
80
+ }
81
+ if (nestDepth.isAtLimit()) {
82
+ context.errors.push(`${workflowPath}: steps[${index}].workflow: Nest depth limit exceeded while resolving "${step.workflow}" (${childPath}). Current depth ${nestDepth.value} reached maxDepth ${nestDepth.maxDepth}.`);
83
+ continue;
84
+ }
85
+ await loadWorkflowFrame(childPath, nestDepth.increment(), nextAncestry, context);
86
+ }
87
+ return workflow;
88
+ }
89
+ function validateWorkflowGraph(workflowPath, workflow, errors) {
90
+ const stepIds = new Set(workflow.steps.map((step) => step.id));
91
+ for (const [index, step] of workflow.steps.entries()) {
92
+ const inheritFrom = step.session?.inheritFrom;
93
+ if (inheritFrom && !stepIds.has(inheritFrom)) {
94
+ errors.push(`${workflowPath}: steps[${index}].session.inherit_from: Referenced step "${inheritFrom}" does not exist in the current workflow frame.`);
95
+ }
96
+ }
97
+ const evaluateAfter = workflow.loop.exitCondition?.evaluateAfter;
98
+ if (evaluateAfter && !stepIds.has(evaluateAfter)) {
99
+ errors.push(`${workflowPath}: loop.exit_condition.evaluate_after: Referenced step "${evaluateAfter}" does not exist in the current workflow frame.`);
100
+ }
101
+ }
102
+ function recordCapabilities(workflowPath, workflow, commandRunWorkflowPaths) {
103
+ if (workflow.loop.exitCondition?.type === "command") {
104
+ commandRunWorkflowPaths.add(workflowPath);
105
+ }
106
+ }
107
+ function collectValidationError(workflowPath, error, errors) {
108
+ if (error instanceof ValidationError) {
109
+ for (const line of splitMessageLines(error.message)) {
110
+ errors.push(`${workflowPath}: ${line}`);
111
+ }
112
+ return;
113
+ }
114
+ if (error instanceof Error) {
115
+ errors.push(`${workflowPath}: ${error.message}`);
116
+ return;
117
+ }
118
+ errors.push(`${workflowPath}: Failed to load workflow.`);
119
+ }
120
+ function splitMessageLines(message) {
121
+ return message
122
+ .split("\n")
123
+ .map((line) => line.trim())
124
+ .filter((line) => line.length > 0);
125
+ }
126
+ function formatCircularReferenceError(ancestry, workflowPath) {
127
+ return `Circular subworkflow reference detected: ${[
128
+ ...ancestry,
129
+ workflowPath,
130
+ ].join(" -> ")}.`;
131
+ }
132
+ function isPathWithinRoot(rootDir, candidatePath) {
133
+ const relativePath = relative(rootDir, candidatePath);
134
+ return (relativePath === "" ||
135
+ (!relativePath.startsWith("..") && !isAbsolute(relativePath)));
136
+ }
137
+ function isWorkflowStep(step) {
138
+ return "workflow" in step;
139
+ }
140
+ //# sourceMappingURL=workflow-loader.js.map