agentic-orchestrator 0.1.26 → 0.1.28
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/AGENTS.md +2 -2
- package/CLAUDE.md +2 -2
- package/README.md +47 -14
- package/agentic/orchestrator/agents.yaml +13 -0
- package/agentic/orchestrator/policy.yaml +3 -0
- package/agentic/orchestrator/schemas/agents.schema.json +76 -0
- package/agentic/orchestrator/schemas/policy.schema.json +16 -0
- package/agentic/orchestrator/schemas/policy.user.schema.json +16 -0
- package/agentic/orchestrator/schemas/state.schema.json +53 -0
- package/apps/control-plane/src/application/configuration-service.ts +181 -0
- package/apps/control-plane/src/application/kernel-tool-wiring.ts +292 -0
- package/apps/control-plane/src/application/services/checkpoint-service.ts +523 -0
- package/apps/control-plane/src/application/services/feature-send-message-service.ts +132 -0
- package/apps/control-plane/src/application/services/patch-service.ts +29 -5
- package/apps/control-plane/src/application/services/repo-operations-service.ts +276 -0
- package/apps/control-plane/src/application/services/worktree-watchdog-service.ts +156 -0
- package/apps/control-plane/src/cli/cli-argument-parser.ts +12 -0
- package/apps/control-plane/src/cli/help-command-handler.ts +17 -0
- package/apps/control-plane/src/cli/init-command-handler.ts +31 -0
- package/apps/control-plane/src/cli/resume-command-handler.ts +31 -4
- package/apps/control-plane/src/cli/rollback-command-handler.ts +217 -0
- package/apps/control-plane/src/cli/run-command-handler.ts +8 -0
- package/apps/control-plane/src/cli/types.ts +3 -0
- package/apps/control-plane/src/core/kernel-types.ts +55 -0
- package/apps/control-plane/src/core/kernel.ts +61 -878
- package/apps/control-plane/src/core/tool-caller.ts +10 -0
- package/apps/control-plane/src/core/utils/field-readers.ts +38 -0
- package/apps/control-plane/src/core/utils/index-normalizer.ts +119 -0
- package/apps/control-plane/src/core/utils/path-normalizers.ts +22 -0
- package/apps/control-plane/src/interfaces/cli/bootstrap.ts +15 -0
- package/apps/control-plane/src/providers/api-worker-provider.ts +14 -12
- package/apps/control-plane/src/providers/cli-worker-provider.ts +82 -12
- package/apps/control-plane/src/providers/providers.ts +45 -24
- package/apps/control-plane/src/providers/worker-provider-factory.ts +36 -1
- package/apps/control-plane/src/supervisor/run-coordinator.ts +91 -36
- package/apps/control-plane/src/supervisor/runtime.ts +107 -1
- package/apps/control-plane/src/supervisor/types.ts +9 -0
- package/apps/control-plane/src/supervisor/worker-decision-loop.ts +253 -14
- package/apps/control-plane/test/checkpoint-service.spec.ts +537 -0
- package/apps/control-plane/test/cli-helpers.spec.ts +28 -0
- package/apps/control-plane/test/cli.unit.spec.ts +52 -0
- package/apps/control-plane/test/configuration-service.spec.ts +466 -0
- package/apps/control-plane/test/dashboard-api.integration.spec.ts +537 -0
- package/apps/control-plane/test/dashboard-client.spec.ts +233 -0
- package/apps/control-plane/test/feature-send-message-service.spec.ts +314 -0
- package/apps/control-plane/test/init-wizard.spec.ts +35 -0
- package/apps/control-plane/test/path-normalizers.spec.ts +41 -0
- package/apps/control-plane/test/repo-operations-service.spec.ts +339 -0
- package/apps/control-plane/test/resume-command.spec.ts +33 -0
- package/apps/control-plane/test/review-workspace-logic.spec.ts +130 -0
- package/apps/control-plane/test/rollback-command.spec.ts +208 -0
- package/apps/control-plane/test/run-coordinator.spec.ts +119 -0
- package/apps/control-plane/test/worker-decision-loop.spec.ts +209 -0
- package/apps/control-plane/test/worker-provider-adapters.spec.ts +102 -0
- package/apps/control-plane/test/worker-provider-factory.spec.ts +14 -0
- package/apps/control-plane/test/worktree-watchdog-service.spec.ts +147 -0
- package/config/agentic/orchestrator/agents.yaml +13 -0
- package/dist/apps/control-plane/application/configuration-service.d.ts +19 -0
- package/dist/apps/control-plane/application/configuration-service.js +123 -0
- package/dist/apps/control-plane/application/configuration-service.js.map +1 -0
- package/dist/apps/control-plane/application/kernel-tool-wiring.d.ts +39 -0
- package/dist/apps/control-plane/application/kernel-tool-wiring.js +38 -0
- package/dist/apps/control-plane/application/kernel-tool-wiring.js.map +1 -0
- package/dist/apps/control-plane/application/services/checkpoint-service.d.ts +84 -0
- package/dist/apps/control-plane/application/services/checkpoint-service.js +367 -0
- package/dist/apps/control-plane/application/services/checkpoint-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/feature-send-message-service.d.ts +25 -0
- package/dist/apps/control-plane/application/services/feature-send-message-service.js +105 -0
- package/dist/apps/control-plane/application/services/feature-send-message-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/patch-service.d.ts +6 -0
- package/dist/apps/control-plane/application/services/patch-service.js +11 -2
- package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/repo-operations-service.d.ts +70 -0
- package/dist/apps/control-plane/application/services/repo-operations-service.js +213 -0
- package/dist/apps/control-plane/application/services/repo-operations-service.js.map +1 -0
- package/dist/apps/control-plane/application/services/worktree-watchdog-service.d.ts +23 -0
- package/dist/apps/control-plane/application/services/worktree-watchdog-service.js +119 -0
- package/dist/apps/control-plane/application/services/worktree-watchdog-service.js.map +1 -0
- package/dist/apps/control-plane/cli/cli-argument-parser.js +12 -0
- package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
- package/dist/apps/control-plane/cli/help-command-handler.js +17 -0
- package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/init-command-handler.js +23 -0
- package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/resume-command-handler.js +25 -5
- package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/rollback-command-handler.d.ts +6 -0
- package/dist/apps/control-plane/cli/rollback-command-handler.js +177 -0
- package/dist/apps/control-plane/cli/rollback-command-handler.js.map +1 -0
- package/dist/apps/control-plane/cli/run-command-handler.js +7 -1
- package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/types.d.ts +3 -0
- package/dist/apps/control-plane/cli/types.js +1 -0
- package/dist/apps/control-plane/cli/types.js.map +1 -1
- package/dist/apps/control-plane/core/configuration-service.d.ts +25 -0
- package/dist/apps/control-plane/core/configuration-service.js +130 -0
- package/dist/apps/control-plane/core/configuration-service.js.map +1 -0
- package/dist/apps/control-plane/core/kernel-tool-wiring.d.ts +50 -0
- package/dist/apps/control-plane/core/kernel-tool-wiring.js +44 -0
- package/dist/apps/control-plane/core/kernel-tool-wiring.js.map +1 -0
- package/dist/apps/control-plane/core/kernel-types.d.ts +48 -0
- package/dist/apps/control-plane/core/kernel-types.js +2 -0
- package/dist/apps/control-plane/core/kernel-types.js.map +1 -0
- package/dist/apps/control-plane/core/kernel.d.ts +17 -48
- package/dist/apps/control-plane/core/kernel.js +44 -539
- package/dist/apps/control-plane/core/kernel.js.map +1 -1
- package/dist/apps/control-plane/core/tool-caller.d.ts +10 -0
- package/dist/apps/control-plane/core/utils/error-normalizer.d.ts +2 -0
- package/dist/apps/control-plane/core/utils/error-normalizer.js +51 -0
- package/dist/apps/control-plane/core/utils/error-normalizer.js.map +1 -0
- package/dist/apps/control-plane/core/utils/field-readers.d.ts +9 -0
- package/dist/apps/control-plane/core/utils/field-readers.js +30 -0
- package/dist/apps/control-plane/core/utils/field-readers.js.map +1 -0
- package/dist/apps/control-plane/core/utils/index-normalizer.d.ts +7 -0
- package/dist/apps/control-plane/core/utils/index-normalizer.js +92 -0
- package/dist/apps/control-plane/core/utils/index-normalizer.js.map +1 -0
- package/dist/apps/control-plane/core/utils/path-normalizers.d.ts +2 -0
- package/dist/apps/control-plane/core/utils/path-normalizers.js +17 -0
- package/dist/apps/control-plane/core/utils/path-normalizers.js.map +1 -0
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js +13 -1
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
- package/dist/apps/control-plane/providers/api-worker-provider.d.ts +4 -13
- package/dist/apps/control-plane/providers/api-worker-provider.js +10 -0
- package/dist/apps/control-plane/providers/api-worker-provider.js.map +1 -1
- package/dist/apps/control-plane/providers/cli-worker-provider.d.ts +11 -13
- package/dist/apps/control-plane/providers/cli-worker-provider.js +64 -0
- package/dist/apps/control-plane/providers/cli-worker-provider.js.map +1 -1
- package/dist/apps/control-plane/providers/providers.d.ts +31 -24
- package/dist/apps/control-plane/providers/providers.js +10 -0
- package/dist/apps/control-plane/providers/providers.js.map +1 -1
- package/dist/apps/control-plane/providers/worker-provider-factory.d.ts +11 -0
- package/dist/apps/control-plane/providers/worker-provider-factory.js +20 -1
- package/dist/apps/control-plane/providers/worker-provider-factory.js.map +1 -1
- package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/run-coordinator.js +81 -33
- package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/runtime.d.ts +8 -1
- package/dist/apps/control-plane/supervisor/runtime.js +90 -0
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
- package/dist/apps/control-plane/supervisor/types.d.ts +11 -0
- package/dist/apps/control-plane/supervisor/types.js.map +1 -1
- package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +21 -1
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js +207 -13
- package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
- package/package.json +1 -1
- package/packages/web-dashboard/package.json +2 -0
- package/packages/web-dashboard/src/app/analytics/page.tsx +83 -2
- package/packages/web-dashboard/src/app/api/actions/route.ts +92 -1
- package/packages/web-dashboard/src/app/api/analytics/route.ts +5 -2
- package/packages/web-dashboard/src/app/api/features/[id]/checkpoints/[checkpointId]/diff/route.ts +43 -0
- package/packages/web-dashboard/src/app/api/features/[id]/checkpoints/compare/route.ts +45 -0
- package/packages/web-dashboard/src/app/api/features/[id]/checkpoints/stream/route.ts +170 -0
- package/packages/web-dashboard/src/app/api/features/[id]/file-diff/route.ts +144 -0
- package/packages/web-dashboard/src/app/api/features/[id]/log-stream/route.ts +167 -0
- package/packages/web-dashboard/src/app/api/features/[id]/raw-logs/[filename]/route.ts +65 -0
- package/packages/web-dashboard/src/app/api/features/[id]/raw-logs/route.ts +63 -0
- package/packages/web-dashboard/src/app/api/features/[id]/timeline/route.ts +60 -0
- package/packages/web-dashboard/src/app/feature/[id]/page.tsx +32 -11
- package/packages/web-dashboard/src/app/globals.css +2 -0
- package/packages/web-dashboard/src/components/detail-panel.tsx +483 -0
- package/packages/web-dashboard/src/components/review-workspace.tsx +1162 -0
- package/packages/web-dashboard/src/lib/aop-client.ts +725 -0
- package/packages/web-dashboard/src/lib/review-contracts.ts +182 -0
- package/packages/web-dashboard/src/lib/review-workspace-logic.ts +64 -0
- package/packages/web-dashboard/src/lib/types.ts +131 -0
- package/packages/web-dashboard/src/styles/dashboard.module.css +333 -0
- package/spec-files/completed/agentic_orchestrator_execution_mode_spec.md +1905 -0
- package/spec-files/outstanding/agentic_orchestrator_runtime_inspection_spec.md +940 -0
- package/spec-files/outstanding/execution_mode_critical_review.md +355 -0
- package/spec-files/outstanding/shadow_workspace_implementation_spec.md +1271 -0
- package/spec-files/outstanding/shadow_workspace_spec_summary.md +222 -0
- package/spec-files/progress.md +269 -1
|
@@ -63,6 +63,7 @@ export class RunCoordinator {
|
|
|
63
63
|
private readonly prMonitor: PrMonitorService | undefined;
|
|
64
64
|
private readonly issueTracker: IssueTracker | undefined;
|
|
65
65
|
private readonly statusCache: Map<string, string>;
|
|
66
|
+
private static readonly BACKGROUND_LEASE_RENEW_INTERVAL_MS = 30_000;
|
|
66
67
|
private static readonly TERMINAL_STATUSES = new Set<string>([
|
|
67
68
|
STATUS.MERGED,
|
|
68
69
|
STATUS.FAILED,
|
|
@@ -105,56 +106,110 @@ export class RunCoordinator {
|
|
|
105
106
|
});
|
|
106
107
|
|
|
107
108
|
this.state.runMetadata.took_over_stale = Boolean(leaseResult.data.took_over_stale);
|
|
109
|
+
const backgroundLeaseRenewal = this.startBackgroundLeaseRenewal();
|
|
108
110
|
|
|
109
|
-
|
|
111
|
+
try {
|
|
112
|
+
await this.sessionOrchestrator.ensureGlobalOrchestratorSession();
|
|
110
113
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
const sorted = [...features].sort((a, b) => a.feature_id.localeCompare(b.feature_id));
|
|
115
|
+
const scopedFeatureIds = sorted.map((item) => item.feature_id);
|
|
116
|
+
this.state.queue = sorted;
|
|
117
|
+
let activeFeatureIds: string[] = [];
|
|
115
118
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
await this.sessionOrchestrator.cleanupOrphanWorkerSessions(scopedFeatureIds);
|
|
120
|
+
await this.kernel.pruneFeatureSessionAssignments({
|
|
121
|
+
run_id: this.state.runId,
|
|
122
|
+
owner_instance_id: this.state.ownerInstanceId,
|
|
123
|
+
active_feature_ids: scopedFeatureIds,
|
|
124
|
+
});
|
|
122
125
|
|
|
123
|
-
|
|
126
|
+
activeFeatureIds = await this.rebalanceActiveFeatures(activeFeatureIds);
|
|
124
127
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
for (let iteration = 0; iteration < this.maxIterationsPerPhase; iteration += 1) {
|
|
129
|
+
this.throwIfBackgroundLeaseRenewalFailed(backgroundLeaseRenewal.error());
|
|
130
|
+
if (activeFeatureIds.length === 0 && this.state.queue.length === 0) {
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
await this.leaseHeartbeatService.renew();
|
|
134
|
+
this.throwIfBackgroundLeaseRenewalFailed(backgroundLeaseRenewal.error());
|
|
135
|
+
activeFeatureIds = await this.applyOrchestratorPrioritization(
|
|
136
|
+
activeFeatureIds,
|
|
137
|
+
iteration + 1,
|
|
138
|
+
);
|
|
139
|
+
// N3: Check budget before waves; pause over-budget features
|
|
140
|
+
activeFeatureIds = await this.pauseOverBudgetFeatures(activeFeatureIds);
|
|
141
|
+
await this.planningWaveExecutor.run(activeFeatureIds);
|
|
142
|
+
await this.buildWaveExecutor.run(activeFeatureIds, this.maxParallelGateRuns);
|
|
143
|
+
await this.qaWaveExecutor.run(activeFeatureIds, this.maxParallelGateRuns);
|
|
144
|
+
await this.planningWaveExecutor.runPostQaReconciliation(activeFeatureIds, iteration + 1);
|
|
145
|
+
await this.notifyStatusTransitions(activeFeatureIds);
|
|
146
|
+
activeFeatureIds = await this.rebalanceActiveFeatures(activeFeatureIds);
|
|
128
147
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
148
|
+
|
|
149
|
+
const dashboard = await this.toolCaller.callTool('orchestrator', TOOLS.REPORT_DASHBOARD, {});
|
|
150
|
+
const runtimeSessions = await this.kernel.getRuntimeSessions();
|
|
151
|
+
this.throwIfBackgroundLeaseRenewalFailed(backgroundLeaseRenewal.error());
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
status: 'running',
|
|
155
|
+
dashboard: dashboard.data,
|
|
156
|
+
queue_depth: this.state.queue.length,
|
|
157
|
+
run_metadata: {
|
|
158
|
+
...this.state.runMetadata,
|
|
159
|
+
runtime_sessions: runtimeSessions,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
} finally {
|
|
163
|
+
await backgroundLeaseRenewal.stop();
|
|
142
164
|
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private startBackgroundLeaseRenewal(): {
|
|
168
|
+
stop: () => Promise<void>;
|
|
169
|
+
error: () => unknown;
|
|
170
|
+
} {
|
|
171
|
+
let inFlight: Promise<void> | null = null;
|
|
172
|
+
let failedRenewal: unknown = null;
|
|
173
|
+
let stopped = false;
|
|
174
|
+
|
|
175
|
+
const renew = (): void => {
|
|
176
|
+
if (stopped || inFlight !== null || failedRenewal) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
inFlight = this.leaseHeartbeatService
|
|
180
|
+
.renew()
|
|
181
|
+
.catch((error: unknown) => {
|
|
182
|
+
failedRenewal = error;
|
|
183
|
+
})
|
|
184
|
+
.finally(() => {
|
|
185
|
+
inFlight = null;
|
|
186
|
+
});
|
|
187
|
+
};
|
|
143
188
|
|
|
144
|
-
const
|
|
145
|
-
|
|
189
|
+
const timer = setInterval(renew, RunCoordinator.BACKGROUND_LEASE_RENEW_INTERVAL_MS);
|
|
190
|
+
if (typeof timer.unref === 'function') {
|
|
191
|
+
timer.unref();
|
|
192
|
+
}
|
|
146
193
|
|
|
147
194
|
return {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
195
|
+
stop: async () => {
|
|
196
|
+
stopped = true;
|
|
197
|
+
clearInterval(timer);
|
|
198
|
+
if (inFlight !== null) {
|
|
199
|
+
await inFlight;
|
|
200
|
+
}
|
|
154
201
|
},
|
|
202
|
+
error: () => failedRenewal,
|
|
155
203
|
};
|
|
156
204
|
}
|
|
157
205
|
|
|
206
|
+
private throwIfBackgroundLeaseRenewalFailed(error: unknown): void {
|
|
207
|
+
if (!error) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
|
|
158
213
|
private async pauseOverBudgetFeatures(activeFeatureIds: string[]): Promise<string[]> {
|
|
159
214
|
const remaining: string[] = [];
|
|
160
215
|
for (const featureId of activeFeatureIds) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import { stableHash } from '../core/fs.js';
|
|
3
|
-
import type { WorkerProvider } from '../providers/providers.js';
|
|
3
|
+
import type { ExecutionMode, WorkerProvider } from '../providers/providers.js';
|
|
4
4
|
import { createOperationId, type ToolClient } from '../mcp/tool-client.js';
|
|
5
5
|
import { withOperationIdIfRequired } from '../application/tools/tool-metadata.js';
|
|
6
6
|
import { PromptBundleLoader } from './prompt-bundle-loader.js';
|
|
@@ -16,6 +16,11 @@ import { ReactionsService } from '../application/services/reactions-service.js';
|
|
|
16
16
|
import { ActivityMonitorService } from '../application/services/activity-monitor-service.js';
|
|
17
17
|
import { PrMonitorService, createGhRunner } from '../application/services/pr-monitor-service.js';
|
|
18
18
|
import { createIssueTracker } from '../application/services/issue-tracker-service.js';
|
|
19
|
+
import {
|
|
20
|
+
CheckpointService,
|
|
21
|
+
type InteractiveExecutionConfig,
|
|
22
|
+
} from '../application/services/checkpoint-service.js';
|
|
23
|
+
import { WorktreeWatchdogService } from '../application/services/worktree-watchdog-service.js';
|
|
19
24
|
import {
|
|
20
25
|
resolveMalformedWorkerOutputAction,
|
|
21
26
|
resolveNoProgressAction,
|
|
@@ -54,6 +59,34 @@ import type {
|
|
|
54
59
|
|
|
55
60
|
type NamedContract = { name: string };
|
|
56
61
|
|
|
62
|
+
function asPositiveInteger(value: unknown, fallback: number): number {
|
|
63
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value < 1) {
|
|
64
|
+
return fallback;
|
|
65
|
+
}
|
|
66
|
+
return Math.floor(value);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function asBoolean(value: unknown, fallback: boolean): boolean {
|
|
70
|
+
if (typeof value !== 'boolean') {
|
|
71
|
+
return fallback;
|
|
72
|
+
}
|
|
73
|
+
return value;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function asSeverity(value: unknown, fallback: InteractiveExecutionConfig['violationSeverity']) {
|
|
77
|
+
if (value === 'info' || value === 'warning' || value === 'error' || value === 'critical') {
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
return fallback;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function asExecutionMode(value: unknown): ExecutionMode | null {
|
|
84
|
+
if (value === 'deterministic' || value === 'interactive') {
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
57
90
|
function resolveAdapterName(
|
|
58
91
|
slot: AdapterSlot<NamedContract>,
|
|
59
92
|
configuredValue: unknown,
|
|
@@ -103,6 +136,10 @@ export class SupervisorRuntime
|
|
|
103
136
|
private readonly workerDecisionLoop: WorkerDecisionLoop;
|
|
104
137
|
private readonly leaseHeartbeatService: LeaseHeartbeatService;
|
|
105
138
|
private readonly runCoordinator: RunCoordinator;
|
|
139
|
+
private readonly cliExecutionMode: ExecutionMode | null;
|
|
140
|
+
private readonly interactiveConfig: InteractiveExecutionConfig;
|
|
141
|
+
private readonly worktreeWatchdogService: WorktreeWatchdogService;
|
|
142
|
+
private readonly checkpointService: CheckpointService;
|
|
106
143
|
private static readonly DEFAULT_MAX_ITERATIONS_PER_PHASE = 6;
|
|
107
144
|
|
|
108
145
|
constructor(
|
|
@@ -120,6 +157,22 @@ export class SupervisorRuntime
|
|
|
120
157
|
options.max_iterations_per_phase,
|
|
121
158
|
);
|
|
122
159
|
this.takeoverStaleRun = Boolean(options.takeover_stale_run);
|
|
160
|
+
this.cliExecutionMode = asExecutionMode(options.execution_mode);
|
|
161
|
+
this.interactiveConfig = this.resolveInteractiveExecutionConfig();
|
|
162
|
+
this.worktreeWatchdogService = new WorktreeWatchdogService();
|
|
163
|
+
this.checkpointService = new CheckpointService({
|
|
164
|
+
repoRoot: this.kernel.getRepoRoot(),
|
|
165
|
+
featurePathResolver: (featureId: string) => this.kernel.featurePath(featureId),
|
|
166
|
+
worktreePathResolver: (featureId: string) => this.kernel.worktreePath(featureId),
|
|
167
|
+
validateDiff: async (featureId: string, parsedDiff: unknown) =>
|
|
168
|
+
await this.kernel.validatePatchDiff(featureId, parsedDiff),
|
|
169
|
+
watchdog: this.worktreeWatchdogService,
|
|
170
|
+
provider: this.provider,
|
|
171
|
+
readState: (featureId: string) => this.kernel.readState(featureId),
|
|
172
|
+
updateState: async (featureId, expectedVersion, updater) =>
|
|
173
|
+
await this.kernel.updateState(featureId, expectedVersion, updater),
|
|
174
|
+
config: this.interactiveConfig,
|
|
175
|
+
});
|
|
123
176
|
const runId = options.run_id ?? `run:${Date.now()}`;
|
|
124
177
|
const ownerInstanceId =
|
|
125
178
|
options.owner_instance_id ?? `supervisor:${process.pid}:${crypto.randomUUID()}`;
|
|
@@ -228,6 +281,13 @@ export class SupervisorRuntime
|
|
|
228
281
|
activityMonitor,
|
|
229
282
|
repoRoot: this.kernel.getRepoRoot(),
|
|
230
283
|
runId: () => this.state.runId,
|
|
284
|
+
resolveExecutionMode: async (featureId: string) => await this.resolveExecutionMode(featureId),
|
|
285
|
+
resolveInteractiveConfig: () => this.interactiveConfig,
|
|
286
|
+
watchdog: this.worktreeWatchdogService,
|
|
287
|
+
checkpointService: this.checkpointService,
|
|
288
|
+
resolveWorktreePath: (featureId: string) => this.kernel.worktreePath(featureId),
|
|
289
|
+
resolveRoleSessionId: (role, featureId) =>
|
|
290
|
+
this.resolveRoleSessionIdByFeature(role, featureId),
|
|
231
291
|
});
|
|
232
292
|
|
|
233
293
|
this.planningWaveExecutor = new PlanningWaveExecutor({
|
|
@@ -548,6 +608,52 @@ export class SupervisorRuntime
|
|
|
548
608
|
}
|
|
549
609
|
}
|
|
550
610
|
|
|
611
|
+
private resolveRoleSessionIdByFeature(role: RuntimeRole, featureId: string): string | null {
|
|
612
|
+
return this.resolveRoleSessionId(role, { feature_id: featureId });
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
private resolveInteractiveExecutionConfig(): InteractiveExecutionConfig {
|
|
616
|
+
const runtime = this.kernel.getAgentsConfig().runtime;
|
|
617
|
+
const interactive =
|
|
618
|
+
runtime &&
|
|
619
|
+
typeof runtime === 'object' &&
|
|
620
|
+
runtime.interactive &&
|
|
621
|
+
typeof runtime.interactive === 'object'
|
|
622
|
+
? (runtime.interactive as Record<string, unknown>)
|
|
623
|
+
: {};
|
|
624
|
+
return {
|
|
625
|
+
checkpointIntervalMs: asPositiveInteger(interactive['checkpoint_interval_ms'], 30_000),
|
|
626
|
+
watchdogPollIntervalMs: asPositiveInteger(interactive['watchdog_poll_interval_ms'], 2_000),
|
|
627
|
+
maxUncommittedChanges: asPositiveInteger(interactive['max_uncommitted_changes'], 50),
|
|
628
|
+
validationOnCheckpoint: asBoolean(interactive['validation_on_checkpoint'], true),
|
|
629
|
+
revertOnViolation: asBoolean(interactive['revert_on_violation'], false),
|
|
630
|
+
violationSeverity: asSeverity(interactive['violation_severity'], 'warning'),
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
async resolveExecutionMode(featureId: string): Promise<ExecutionMode> {
|
|
635
|
+
if (this.cliExecutionMode) {
|
|
636
|
+
return this.cliExecutionMode;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
try {
|
|
640
|
+
const state = await this.kernel.readState(featureId);
|
|
641
|
+
const fromState = asExecutionMode(state.frontMatter['execution_mode']);
|
|
642
|
+
if (fromState) {
|
|
643
|
+
return fromState;
|
|
644
|
+
}
|
|
645
|
+
} catch {
|
|
646
|
+
// Ignore state read failures and continue to runtime defaults.
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
const fromRuntime = asExecutionMode(this.kernel.getAgentsConfig().runtime?.execution_mode);
|
|
650
|
+
if (fromRuntime) {
|
|
651
|
+
return fromRuntime;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
return 'deterministic';
|
|
655
|
+
}
|
|
656
|
+
|
|
551
657
|
async callTool<TData = Record<string, unknown>, TToolName extends string = string>(
|
|
552
658
|
role: RuntimeRole,
|
|
553
659
|
toolName: TToolName,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { AgentsConfigSnapshot } from '../core/kernel.js';
|
|
2
2
|
import type { FeatureStatePayload } from '../core/tool-caller.js';
|
|
3
3
|
import type { BudgetCheckResult } from '../application/services/cost-tracking-service.js';
|
|
4
|
+
import type { ExecutionMode } from '../providers/providers.js';
|
|
5
|
+
import type { PatchValidationResult } from '../application/services/patch-service.js';
|
|
4
6
|
export type {
|
|
5
7
|
FeatureStateFrontMatter,
|
|
6
8
|
FeatureStatePayload,
|
|
@@ -21,6 +23,7 @@ export interface SupervisorOptions {
|
|
|
21
23
|
run_id?: string;
|
|
22
24
|
owner_instance_id?: string;
|
|
23
25
|
takeover_stale_run?: boolean;
|
|
26
|
+
execution_mode?: ExecutionMode;
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
export interface FeatureInput {
|
|
@@ -119,6 +122,12 @@ export interface FeatureOrchestrationPort {
|
|
|
119
122
|
ownerInstanceId: string,
|
|
120
123
|
): Promise<{ data: { lease_expires_at: string } }>;
|
|
121
124
|
repoDiff(featureId: string, options?: string[]): Promise<{ data: Record<string, unknown> }>;
|
|
125
|
+
worktreePath(featureId: string): string;
|
|
126
|
+
featurePath(featureId: string): string;
|
|
127
|
+
readState(
|
|
128
|
+
featureId: string,
|
|
129
|
+
): Promise<{ frontMatter: Record<string, unknown>; body: string; raw?: string }>;
|
|
130
|
+
validatePatchDiff(featureId: string, parsedDiff: unknown): Promise<PatchValidationResult>;
|
|
122
131
|
updateState(
|
|
123
132
|
featureId: string,
|
|
124
133
|
expectedVersion: number | null,
|