@leclabs/agent-flow-navigator-mcp 1.4.1 → 1.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.
- package/engine.js +45 -3
- package/index.js +6 -0
- package/package.json +1 -1
- package/types.d.ts +21 -0
package/engine.js
CHANGED
|
@@ -310,6 +310,7 @@ function buildNavigateResponse(
|
|
|
310
310
|
terminal: getTerminalType(stepDef),
|
|
311
311
|
action,
|
|
312
312
|
retriesIncremented,
|
|
313
|
+
autonomyContinued: false,
|
|
313
314
|
maxRetries: stepDef.maxRetries || 0,
|
|
314
315
|
orchestratorInstructions,
|
|
315
316
|
metadata,
|
|
@@ -482,7 +483,7 @@ export class WorkflowEngine {
|
|
|
482
483
|
* @param {string} [options.description] - User's task description
|
|
483
484
|
* @returns {Object} Navigation response with currentStep, stepInstructions, terminal, action, metadata, etc.
|
|
484
485
|
*/
|
|
485
|
-
navigate({ taskFilePath, workflowType, result, description, projectRoot } = {}) {
|
|
486
|
+
navigate({ taskFilePath, workflowType, result, description, projectRoot, autonomy } = {}) {
|
|
486
487
|
let currentStep = null;
|
|
487
488
|
let retryCount = 0;
|
|
488
489
|
|
|
@@ -501,11 +502,16 @@ export class WorkflowEngine {
|
|
|
501
502
|
workflowType: metaWorkflow,
|
|
502
503
|
currentStep: metaStep,
|
|
503
504
|
retryCount: metaRetry = 0,
|
|
505
|
+
autonomy: metaAutonomy,
|
|
504
506
|
} = task.metadata;
|
|
505
507
|
workflowType = metaWorkflow;
|
|
506
508
|
currentStep = metaStep;
|
|
507
509
|
retryCount = metaRetry;
|
|
508
510
|
description = description || userDescription;
|
|
511
|
+
// Explicit parameter takes precedence over stored value
|
|
512
|
+
if (autonomy === undefined || autonomy === null) {
|
|
513
|
+
autonomy = metaAutonomy;
|
|
514
|
+
}
|
|
509
515
|
}
|
|
510
516
|
|
|
511
517
|
// Validate workflowType
|
|
@@ -615,7 +621,7 @@ export class WorkflowEngine {
|
|
|
615
621
|
// Unconditional advances within retry loops (e.g., work → gate) preserve the count
|
|
616
622
|
const resetRetryCount = action === "advance" && evaluation.action === "conditional";
|
|
617
623
|
|
|
618
|
-
|
|
624
|
+
let response = buildNavigateResponse(
|
|
619
625
|
workflowType,
|
|
620
626
|
evaluation.nextStep,
|
|
621
627
|
nextStepDef,
|
|
@@ -628,14 +634,49 @@ export class WorkflowEngine {
|
|
|
628
634
|
sourceRoot
|
|
629
635
|
);
|
|
630
636
|
|
|
637
|
+
// Autonomy mode: auto-continue through stage boundary end nodes
|
|
638
|
+
// Stage boundary = end node with on:"passed" outgoing edge to a non-terminal node
|
|
639
|
+
// Never auto-continue HITL nodes (they exist because the agent needs human help)
|
|
640
|
+
if (autonomy && response.terminal === "success") {
|
|
641
|
+
const graph = this.buildEdgeGraph(workflowType);
|
|
642
|
+
const outgoing = graph.edges.get(response.currentStep) || [];
|
|
643
|
+
const passedEdge = outgoing.find((e) => e.on === "passed");
|
|
644
|
+
if (passedEdge) {
|
|
645
|
+
const continuedDef = nodes[passedEdge.to];
|
|
646
|
+
if (continuedDef && !isTerminalNode(continuedDef)) {
|
|
647
|
+
response = buildNavigateResponse(
|
|
648
|
+
workflowType,
|
|
649
|
+
passedEdge.to,
|
|
650
|
+
continuedDef,
|
|
651
|
+
"advance",
|
|
652
|
+
false,
|
|
653
|
+
0, // fresh retryCount for the new stage
|
|
654
|
+
description,
|
|
655
|
+
true, // resetRetryCount
|
|
656
|
+
projectRoot,
|
|
657
|
+
sourceRoot
|
|
658
|
+
);
|
|
659
|
+
response.autonomyContinued = true;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// Persist autonomy in metadata
|
|
665
|
+
if (autonomy) {
|
|
666
|
+
response.metadata.autonomy = true;
|
|
667
|
+
}
|
|
668
|
+
|
|
631
669
|
// Write-through: persist state transition and presentation to task file
|
|
670
|
+
// IMPORTANT: preserve task.id — Claude Code's task system requires filename
|
|
671
|
+
// and id field to match ({id}.json must contain "id": "{id}")
|
|
632
672
|
if (taskFilePath) {
|
|
633
673
|
const task = readTaskFile(taskFilePath);
|
|
634
674
|
if (task) {
|
|
675
|
+
const originalId = task.id;
|
|
635
676
|
const userDesc = task.metadata?.userDescription || "";
|
|
636
677
|
task.metadata = { ...task.metadata, ...response.metadata };
|
|
637
678
|
task.subject = buildTaskSubject(
|
|
638
|
-
|
|
679
|
+
originalId,
|
|
639
680
|
userDesc,
|
|
640
681
|
response.metadata.workflowType,
|
|
641
682
|
response.currentStep,
|
|
@@ -652,6 +693,7 @@ export class WorkflowEngine {
|
|
|
652
693
|
if (response.orchestratorInstructions) {
|
|
653
694
|
task.description = response.orchestratorInstructions;
|
|
654
695
|
}
|
|
696
|
+
task.id = originalId;
|
|
655
697
|
writeFileSync(taskFilePath, JSON.stringify(task, null, 2));
|
|
656
698
|
}
|
|
657
699
|
}
|
package/index.js
CHANGED
|
@@ -164,6 +164,11 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
164
164
|
description: "Step result (for advance). Omit to just get current state.",
|
|
165
165
|
},
|
|
166
166
|
description: { type: "string", description: "User's task description (for start)" },
|
|
167
|
+
autonomy: {
|
|
168
|
+
type: "boolean",
|
|
169
|
+
description:
|
|
170
|
+
"When true, auto-continue through stage boundary end nodes (non-HITL end nodes with outgoing edges).",
|
|
171
|
+
},
|
|
167
172
|
},
|
|
168
173
|
},
|
|
169
174
|
},
|
|
@@ -271,6 +276,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
271
276
|
result: args.result,
|
|
272
277
|
description: args.description,
|
|
273
278
|
projectRoot: PROJECT_ROOT,
|
|
279
|
+
autonomy: args.autonomy,
|
|
274
280
|
});
|
|
275
281
|
return jsonResponse(result);
|
|
276
282
|
}
|
package/package.json
CHANGED
package/types.d.ts
CHANGED
|
@@ -144,6 +144,27 @@ export interface NavigateOptions {
|
|
|
144
144
|
result?: "passed" | "failed";
|
|
145
145
|
description?: string;
|
|
146
146
|
projectRoot?: string;
|
|
147
|
+
autonomy?: boolean;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export interface NavigateResponse {
|
|
151
|
+
currentStep: string;
|
|
152
|
+
stage: Stage | null;
|
|
153
|
+
subagent: string | null;
|
|
154
|
+
stepInstructions: { name: string; description: string | null; guidance: string } | null;
|
|
155
|
+
terminal: "start" | "success" | "hitl" | "failure" | null;
|
|
156
|
+
action: string;
|
|
157
|
+
retriesIncremented: boolean;
|
|
158
|
+
autonomyContinued: boolean;
|
|
159
|
+
maxRetries: number;
|
|
160
|
+
orchestratorInstructions: string | null;
|
|
161
|
+
metadata: {
|
|
162
|
+
workflowType: string;
|
|
163
|
+
currentStep: string;
|
|
164
|
+
retryCount: number;
|
|
165
|
+
autonomy?: boolean;
|
|
166
|
+
};
|
|
167
|
+
sourceRoot: string | null;
|
|
147
168
|
}
|
|
148
169
|
|
|
149
170
|
// =============================================================================
|