agentic-orchestrator 0.1.25 → 0.1.26
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/agentic/orchestrator/defaults/policy.defaults.yaml +1 -0
- package/agentic/orchestrator/policy.yaml +1 -0
- package/agentic/orchestrator/schemas/policy.schema.json +4 -0
- package/agentic/orchestrator/schemas/policy.user.schema.json +4 -0
- package/apps/control-plane/src/application/services/activity-monitor-service.ts +42 -0
- package/apps/control-plane/src/application/services/collision-queue-service.ts +48 -0
- package/apps/control-plane/src/application/services/cost-tracking-service.ts +80 -0
- package/apps/control-plane/src/application/services/feature-deletion-service.ts +57 -0
- package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +65 -0
- package/apps/control-plane/src/application/services/feature-state-service.ts +87 -0
- package/apps/control-plane/src/application/services/gate-selection-service.ts +28 -0
- package/apps/control-plane/src/application/services/gate-service.ts +148 -0
- package/apps/control-plane/src/application/services/issue-tracker-service.ts +28 -0
- package/apps/control-plane/src/application/services/lock-service.ts +88 -0
- package/apps/control-plane/src/application/services/merge-service.ts +63 -0
- package/apps/control-plane/src/application/services/notifier-service.ts +70 -0
- package/apps/control-plane/src/application/services/patch-service.ts +95 -0
- package/apps/control-plane/src/application/services/performance-analytics-service.ts +90 -0
- package/apps/control-plane/src/application/services/plan-service.ts +184 -0
- package/apps/control-plane/src/application/services/pr-monitor-service.ts +58 -0
- package/apps/control-plane/src/application/services/qa-index-service.ts +68 -0
- package/apps/control-plane/src/application/services/reactions-service.ts +77 -0
- package/apps/control-plane/src/application/services/reporting-service.ts +79 -0
- package/apps/control-plane/src/application/services/run-lease-service.ts +79 -0
- package/apps/control-plane/src/application/tools/tool-router.ts +76 -0
- package/apps/control-plane/src/mcp/tool-runtime.ts +4 -0
- package/apps/control-plane/src/providers/providers.ts +96 -0
- package/apps/control-plane/src/providers/worker-provider-factory.ts +4 -0
- package/apps/control-plane/src/supervisor/build-wave-executor.ts +4 -0
- package/apps/control-plane/src/supervisor/planning-wave-executor.ts +4 -0
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +4 -0
- package/apps/control-plane/src/supervisor/run-coordinator.ts +4 -0
- package/apps/control-plane/src/supervisor/runtime.ts +4 -0
- package/apps/control-plane/src/supervisor/session-orchestrator.ts +4 -0
- package/apps/control-plane/test/dashboard-api.integration.spec.ts +310 -1
- package/apps/control-plane/test/dashboard-client.spec.ts +136 -1
- package/apps/control-plane/test/dashboard-live-feed.spec.ts +153 -0
- package/apps/control-plane/test/dashboard-ui-utils.spec.ts +132 -0
- package/apps/control-plane/test/mcp.spec.ts +96 -0
- package/apps/control-plane/test/tool-runtime.spec.ts +68 -0
- package/config/agentic/orchestrator/policy.yaml +1 -0
- package/dist/apps/control-plane/application/services/activity-monitor-service.d.ts +42 -0
- package/dist/apps/control-plane/application/services/activity-monitor-service.js +42 -0
- package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/collision-queue-service.d.ts +48 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.js +48 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/cost-tracking-service.d.ts +79 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.js +76 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +57 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.js +57 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.d.ts +64 -0
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +61 -0
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-state-service.d.ts +86 -0
- package/dist/apps/control-plane/application/services/feature-state-service.js +83 -0
- package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-selection-service.d.ts +28 -0
- package/dist/apps/control-plane/application/services/gate-selection-service.js +28 -0
- package/dist/apps/control-plane/application/services/gate-selection-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-service.d.ts +148 -0
- package/dist/apps/control-plane/application/services/gate-service.js +120 -0
- package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/issue-tracker-service.d.ts +28 -0
- package/dist/apps/control-plane/application/services/issue-tracker-service.js +28 -0
- package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/lock-service.d.ts +88 -0
- package/dist/apps/control-plane/application/services/lock-service.js +64 -0
- package/dist/apps/control-plane/application/services/lock-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/merge-service.d.ts +62 -0
- package/dist/apps/control-plane/application/services/merge-service.js +59 -0
- package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/notifier-service.d.ts +70 -0
- package/dist/apps/control-plane/application/services/notifier-service.js +70 -0
- package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/patch-service.d.ts +94 -0
- package/dist/apps/control-plane/application/services/patch-service.js +91 -0
- package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/performance-analytics-service.d.ts +89 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.js +86 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/plan-service.d.ts +287 -0
- package/dist/apps/control-plane/application/services/plan-service.js +207 -0
- package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/pr-monitor-service.d.ts +58 -0
- package/dist/apps/control-plane/application/services/pr-monitor-service.js +58 -0
- package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/qa-index-service.d.ts +67 -0
- package/dist/apps/control-plane/application/services/qa-index-service.js +64 -0
- package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/reactions-service.d.ts +76 -0
- package/dist/apps/control-plane/application/services/reactions-service.js +73 -0
- package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/reporting-service.d.ts +78 -0
- package/dist/apps/control-plane/application/services/reporting-service.js +75 -0
- package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/run-lease-service.d.ts +79 -0
- package/dist/apps/control-plane/application/services/run-lease-service.js +79 -0
- package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
- package/dist/apps/control-plane/application/tools/tool-router.d.ts +76 -0
- package/dist/apps/control-plane/application/tools/tool-router.js +62 -0
- package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-runtime.d.ts +3 -0
- package/dist/apps/control-plane/mcp/tool-runtime.js +3 -0
- package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
- package/dist/apps/control-plane/providers/providers.d.ts +88 -0
- package/dist/apps/control-plane/providers/providers.js.map +1 -1
- package/dist/apps/control-plane/providers/worker-provider-factory.d.ts +3 -0
- package/dist/apps/control-plane/providers/worker-provider-factory.js.map +1 -1
- package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +3 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/planning-wave-executor.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js +3 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +3 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.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 +3 -0
- package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/runtime.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/runtime.js +3 -0
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
- package/dist/apps/control-plane/supervisor/session-orchestrator.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/session-orchestrator.js +3 -0
- package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
- package/package.json +1 -1
- package/packages/web-dashboard/src/app/analytics/page.tsx +451 -0
- package/packages/web-dashboard/src/app/api/analytics/route.ts +62 -0
- package/packages/web-dashboard/src/app/api/collisions/route.ts +63 -0
- package/packages/web-dashboard/src/app/api/features/[id]/cost/route.ts +29 -0
- package/packages/web-dashboard/src/app/api/features/[id]/review-brief/route.ts +31 -0
- package/packages/web-dashboard/src/app/api/features/[id]/route.ts +5 -8
- package/packages/web-dashboard/src/app/api/features/[id]/test-index/route.ts +31 -0
- package/packages/web-dashboard/src/app/api/flaky/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/policy/budget/route.ts +31 -0
- package/packages/web-dashboard/src/app/api/run/route.ts +162 -0
- package/packages/web-dashboard/src/app/api/status/route.ts +2 -5
- package/packages/web-dashboard/src/app/feature/[id]/page.tsx +112 -0
- package/packages/web-dashboard/src/app/page.tsx +379 -77
- package/packages/web-dashboard/src/components/agent-pipeline-stepper.tsx +100 -0
- package/packages/web-dashboard/src/components/dependency-chains.tsx +58 -0
- package/packages/web-dashboard/src/components/detail-panel.tsx +215 -5
- package/packages/web-dashboard/src/components/feature-card.tsx +5 -0
- package/packages/web-dashboard/src/components/feature-cost-panel.tsx +66 -0
- package/packages/web-dashboard/src/components/feature-list-view.tsx +336 -0
- package/packages/web-dashboard/src/components/gate-step-drilldown.tsx +92 -0
- package/packages/web-dashboard/src/components/kanban-board.tsx +3 -0
- package/packages/web-dashboard/src/components/live-event-feed.tsx +60 -0
- package/packages/web-dashboard/src/components/lock-resource-map.tsx +73 -0
- package/packages/web-dashboard/src/components/plan-revision-timeline.tsx +55 -0
- package/packages/web-dashboard/src/components/plan-risk-annotations.tsx +63 -0
- package/packages/web-dashboard/src/components/plan-scope-tree.tsx +285 -0
- package/packages/web-dashboard/src/components/qa-coverage-map.tsx +174 -0
- package/packages/web-dashboard/src/components/quick-launch-panel.tsx +70 -0
- package/packages/web-dashboard/src/components/review-brief-panel.tsx +75 -0
- package/packages/web-dashboard/src/components/run-health-panel.tsx +85 -0
- package/packages/web-dashboard/src/components/summary-bar.tsx +59 -2
- package/packages/web-dashboard/src/components/verification-signals.tsx +167 -0
- package/packages/web-dashboard/src/lib/analytics-utils.ts +3 -0
- package/packages/web-dashboard/src/lib/aop-client.ts +510 -11
- package/packages/web-dashboard/src/lib/api-envelope.ts +48 -0
- package/packages/web-dashboard/src/lib/authz-adapter.ts +33 -0
- package/packages/web-dashboard/src/lib/dashboard-utils.ts +304 -0
- package/packages/web-dashboard/src/lib/live-feed.ts +218 -0
- package/packages/web-dashboard/src/lib/policy-reader.ts +22 -0
- package/packages/web-dashboard/src/lib/types.ts +114 -0
- package/packages/web-dashboard/src/styles/dashboard.module.css +341 -1
- package/spec-files/{outstanding → completed}/agentic_orchestrator_dashboard_advanced_ux_spec.md +1 -1
- package/spec-files/outstanding/agentic_orchestrator_evidence_integrity_doctor_spec.md +561 -0
- package/spec-files/outstanding/agentic_orchestrator_kernel_simplification_spec.md +834 -0
- package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +12 -5
- package/spec-files/outstanding/agentic_orchestrator_observability_replay_spec.md +442 -0
- package/spec-files/progress.md +174 -1
|
@@ -2,11 +2,58 @@ import { atomicWriteJson, readJson, stableHash } from '../../core/fs.js';
|
|
|
2
2
|
import { applyQaUpdates, summarizeQaIndex } from '../../core/qa-index.js';
|
|
3
3
|
import { ERROR_CODES } from '../../core/error-codes.js';
|
|
4
4
|
import { fail } from '../../core/response.js';
|
|
5
|
+
/**
|
|
6
|
+
* Manages QA test obligation tracking.
|
|
7
|
+
*
|
|
8
|
+
* ## Responsibilities
|
|
9
|
+
* - Create qa_test_index.json from diff hunks
|
|
10
|
+
* - Track test status per hunk (pending/covered/skipped)
|
|
11
|
+
* - Link evidence to test obligations
|
|
12
|
+
* - Validate all obligations are resolved
|
|
13
|
+
*
|
|
14
|
+
* ## Dependencies
|
|
15
|
+
* Depends on {@link QaIndexServicePort} for:
|
|
16
|
+
* - QA index file path resolution
|
|
17
|
+
* - Schema validation
|
|
18
|
+
*
|
|
19
|
+
* ## Key Methods
|
|
20
|
+
* - `qaTestIndexGet()` - retrieve test index
|
|
21
|
+
* - `qaTestIndexUpdate()` - update hunk statuses with evidence
|
|
22
|
+
*
|
|
23
|
+
* ## Error Conditions
|
|
24
|
+
* - FILE_NOT_FOUND - index file does not exist
|
|
25
|
+
* - VERSION_CONFLICT - concurrent index update
|
|
26
|
+
* - SCHEMA_VALIDATION_FAILED - invalid index structure
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const qaService = new QaIndexService(port);
|
|
31
|
+
* const index = await qaService.qaTestIndexGet('my_feature');
|
|
32
|
+
* await qaService.qaTestIndexUpdate('my_feature', updates, 1);
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* ## Index Format
|
|
36
|
+
* Each hunk has: path, line range, required tests, status, evidence refs
|
|
37
|
+
*/
|
|
5
38
|
export class QaIndexService {
|
|
6
39
|
port;
|
|
7
40
|
constructor(port) {
|
|
8
41
|
this.port = port;
|
|
9
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Retrieves QA test index for a feature.
|
|
45
|
+
*
|
|
46
|
+
* @param featureId - feature identifier
|
|
47
|
+
* @returns Test index with hunk obligations and pending summary
|
|
48
|
+
* @throws FILE_NOT_FOUND - index does not exist
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const index = await qaService.qaTestIndexGet('my_feature');
|
|
53
|
+
* console.log(index.data.items);
|
|
54
|
+
* console.log(index.data.pending_obligations);
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
10
57
|
async qaTestIndexGet(featureId) {
|
|
11
58
|
const index = await readJson(this.port.qaIndexPath(featureId), {
|
|
12
59
|
feature_id: featureId,
|
|
@@ -33,6 +80,23 @@ export class QaIndexService {
|
|
|
33
80
|
},
|
|
34
81
|
};
|
|
35
82
|
}
|
|
83
|
+
/**
|
|
84
|
+
* Updates hunk statuses with evidence references and version guard.
|
|
85
|
+
*
|
|
86
|
+
* @param featureId - feature identifier
|
|
87
|
+
* @param updates - hunk status updates with evidence refs
|
|
88
|
+
* @param expectedVersion - expected index version
|
|
89
|
+
* @returns Updated index
|
|
90
|
+
* @throws VERSION_CONFLICT - version mismatch
|
|
91
|
+
* @throws SCHEMA_VALIDATION_FAILED - invalid updates
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```typescript
|
|
95
|
+
* await qaService.qaTestIndexUpdate('my_feature', {
|
|
96
|
+
* items: [{ path: 'file.ts', status: 'covered', evidence_refs: ['gate_123'] }]
|
|
97
|
+
* }, 1);
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
36
100
|
async qaTestIndexUpdate(featureId, expectedVersion, updates, evidenceRefs) {
|
|
37
101
|
const current = await readJson(this.port.qaIndexPath(featureId), null);
|
|
38
102
|
if (!current) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qa-index-service.js","sourceRoot":"","sources":["../../../../../apps/control-plane/src/application/services/qa-index-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"qa-index-service.js","sourceRoot":"","sources":["../../../../../apps/control-plane/src/application/services/qa-index-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ToolCaller as SupervisorToolCaller } from '../../core/tool-caller.js';
|
|
2
2
|
import type { NotifierService } from './notifier-service.js';
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Event-driven reactions and retry policy service.
|
|
5
|
+
*/
|
|
3
6
|
export interface GateFailedReaction {
|
|
4
7
|
enabled: boolean;
|
|
5
8
|
max_retries: number;
|
|
@@ -51,6 +54,47 @@ export interface ReactionsServiceDependencies {
|
|
|
51
54
|
notifier?: NotifierService;
|
|
52
55
|
policy?: ReactionsPolicy;
|
|
53
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Manages event-driven reactions and retry policies.
|
|
59
|
+
*
|
|
60
|
+
* ## Responsibilities
|
|
61
|
+
* - Execute reactions for events (gate_failed, agent_stuck, collision_detected, etc.)
|
|
62
|
+
* - Enforce retry limits and backoff
|
|
63
|
+
* - Trigger escalation when limits exceeded
|
|
64
|
+
* - Record reaction outcomes
|
|
65
|
+
*
|
|
66
|
+
* ## Dependencies
|
|
67
|
+
* Depends on:
|
|
68
|
+
* - {@link SupervisorToolCaller} - for tool invocation
|
|
69
|
+
* - {@link NotifierService} - for escalation notifications
|
|
70
|
+
* - Policy reactions configuration
|
|
71
|
+
*
|
|
72
|
+
* ## Key Methods
|
|
73
|
+
* - `shouldRetry()` - determine if retry is allowed
|
|
74
|
+
* - `waitBeforeRetry()` - apply retry delay
|
|
75
|
+
* - `recordRetry()` - log retry attempt
|
|
76
|
+
* - `notifyEscalation()` - escalate to human
|
|
77
|
+
*
|
|
78
|
+
* ## Error Conditions
|
|
79
|
+
* - RETRY_LIMIT_EXCEEDED - max retries reached
|
|
80
|
+
* - REACTION_NOT_CONFIGURED - no reaction defined for event
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const reactionsService = new ReactionsService({ toolCaller, notifier, policy });
|
|
85
|
+
* if (reactionsService.shouldRetry('my_feature', 1)) {
|
|
86
|
+
* await reactionsService.waitBeforeRetry();
|
|
87
|
+
* await reactionsService.recordRetry('my_feature', 2);
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* ## Supported Events
|
|
92
|
+
* - gate_failed: retry with feedback
|
|
93
|
+
* - agent_stuck: restart or escalate
|
|
94
|
+
* - collision_detected: re-drive queue
|
|
95
|
+
* - ready_to_merge: notify reviewers
|
|
96
|
+
* - changes_requested: restart QA phase
|
|
97
|
+
*/
|
|
54
98
|
export declare class ReactionsService {
|
|
55
99
|
private readonly toolCaller;
|
|
56
100
|
private readonly notifier;
|
|
@@ -59,9 +103,41 @@ export declare class ReactionsService {
|
|
|
59
103
|
shouldRetry(_featureId: string, retryCount: number): boolean;
|
|
60
104
|
retryDelayMs(): number;
|
|
61
105
|
maxRetries(): number;
|
|
106
|
+
/**
|
|
107
|
+
* Waits for retry delay before next attempt.
|
|
108
|
+
*
|
|
109
|
+
* @returns Promise that resolves after delay
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* await reactionsService.waitBeforeRetry();
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
62
116
|
waitBeforeRetry(): Promise<void>;
|
|
63
117
|
buildRepairPrompt(ctx: GateRepairContext): string;
|
|
118
|
+
/**
|
|
119
|
+
* Records retry attempt in feature state.
|
|
120
|
+
*
|
|
121
|
+
* @param featureId - feature identifier
|
|
122
|
+
* @param retryCount - current retry count
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* await reactionsService.recordRetry('my_feature', 2);
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
64
129
|
recordRetry(featureId: string, retryCount: number): Promise<void>;
|
|
65
130
|
shouldEscalate(retryCount: number): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Notifies escalation when retry limit exceeded.
|
|
133
|
+
*
|
|
134
|
+
* @param featureId - feature identifier
|
|
135
|
+
* @param ctx - gate repair context with failure details
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* await reactionsService.notifyEscalation('my_feature', context);
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
66
142
|
notifyEscalation(featureId: string, ctx: GateRepairContext): Promise<void>;
|
|
67
143
|
}
|
|
@@ -6,6 +6,47 @@ const DEFAULT_GATE_FAILED_REACTION = {
|
|
|
6
6
|
escalate_after: 2,
|
|
7
7
|
retry_delay_ms: 30000,
|
|
8
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Manages event-driven reactions and retry policies.
|
|
11
|
+
*
|
|
12
|
+
* ## Responsibilities
|
|
13
|
+
* - Execute reactions for events (gate_failed, agent_stuck, collision_detected, etc.)
|
|
14
|
+
* - Enforce retry limits and backoff
|
|
15
|
+
* - Trigger escalation when limits exceeded
|
|
16
|
+
* - Record reaction outcomes
|
|
17
|
+
*
|
|
18
|
+
* ## Dependencies
|
|
19
|
+
* Depends on:
|
|
20
|
+
* - {@link SupervisorToolCaller} - for tool invocation
|
|
21
|
+
* - {@link NotifierService} - for escalation notifications
|
|
22
|
+
* - Policy reactions configuration
|
|
23
|
+
*
|
|
24
|
+
* ## Key Methods
|
|
25
|
+
* - `shouldRetry()` - determine if retry is allowed
|
|
26
|
+
* - `waitBeforeRetry()` - apply retry delay
|
|
27
|
+
* - `recordRetry()` - log retry attempt
|
|
28
|
+
* - `notifyEscalation()` - escalate to human
|
|
29
|
+
*
|
|
30
|
+
* ## Error Conditions
|
|
31
|
+
* - RETRY_LIMIT_EXCEEDED - max retries reached
|
|
32
|
+
* - REACTION_NOT_CONFIGURED - no reaction defined for event
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* const reactionsService = new ReactionsService({ toolCaller, notifier, policy });
|
|
37
|
+
* if (reactionsService.shouldRetry('my_feature', 1)) {
|
|
38
|
+
* await reactionsService.waitBeforeRetry();
|
|
39
|
+
* await reactionsService.recordRetry('my_feature', 2);
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* ## Supported Events
|
|
44
|
+
* - gate_failed: retry with feedback
|
|
45
|
+
* - agent_stuck: restart or escalate
|
|
46
|
+
* - collision_detected: re-drive queue
|
|
47
|
+
* - ready_to_merge: notify reviewers
|
|
48
|
+
* - changes_requested: restart QA phase
|
|
49
|
+
*/
|
|
9
50
|
export class ReactionsService {
|
|
10
51
|
toolCaller;
|
|
11
52
|
notifier;
|
|
@@ -43,6 +84,16 @@ export class ReactionsService {
|
|
|
43
84
|
}
|
|
44
85
|
return DEFAULT_GATE_FAILED_REACTION.max_retries;
|
|
45
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Waits for retry delay before next attempt.
|
|
89
|
+
*
|
|
90
|
+
* @returns Promise that resolves after delay
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* await reactionsService.waitBeforeRetry();
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
46
97
|
async waitBeforeRetry() {
|
|
47
98
|
const delayMs = this.retryDelayMs();
|
|
48
99
|
if (delayMs <= 0) {
|
|
@@ -78,6 +129,17 @@ export class ReactionsService {
|
|
|
78
129
|
failureSummary,
|
|
79
130
|
].join('\n');
|
|
80
131
|
}
|
|
132
|
+
/**
|
|
133
|
+
* Records retry attempt in feature state.
|
|
134
|
+
*
|
|
135
|
+
* @param featureId - feature identifier
|
|
136
|
+
* @param retryCount - current retry count
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* await reactionsService.recordRetry('my_feature', 2);
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
81
143
|
async recordRetry(featureId, retryCount) {
|
|
82
144
|
const current = await this.toolCaller.callTool('orchestrator', TOOLS.FEATURE_STATE_GET, { feature_id: featureId });
|
|
83
145
|
await this.toolCaller.callTool('orchestrator', TOOLS.FEATURE_STATE_PATCH, {
|
|
@@ -95,6 +157,17 @@ export class ReactionsService {
|
|
|
95
157
|
const reaction = this.policy.gate_failed ?? DEFAULT_GATE_FAILED_REACTION;
|
|
96
158
|
return retryCount >= reaction.escalate_after;
|
|
97
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Notifies escalation when retry limit exceeded.
|
|
162
|
+
*
|
|
163
|
+
* @param featureId - feature identifier
|
|
164
|
+
* @param ctx - gate repair context with failure details
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ```typescript
|
|
168
|
+
* await reactionsService.notifyEscalation('my_feature', context);
|
|
169
|
+
* ```
|
|
170
|
+
*/
|
|
98
171
|
async notifyEscalation(featureId, ctx) {
|
|
99
172
|
if (!this.notifier) {
|
|
100
173
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactions-service.js","sourceRoot":"","sources":["../../../../../apps/control-plane/src/application/services/reactions-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"reactions-service.js","sourceRoot":"","sources":["../../../../../apps/control-plane/src/application/services/reactions-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
type AnyRecord = Record<string, any>;
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Dashboard and feature summary reporting service.
|
|
4
|
+
*/
|
|
2
5
|
export interface ReportingServicePort {
|
|
3
6
|
collectAcceptedPlans(excludeFeatureId?: string | null): Promise<AnyRecord[]>;
|
|
4
7
|
getPolicySnapshot(): AnyRecord;
|
|
@@ -20,20 +23,95 @@ export interface ReportingServicePort {
|
|
|
20
23
|
data: AnyRecord;
|
|
21
24
|
}>;
|
|
22
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Manages dashboard and feature summary generation.
|
|
28
|
+
*
|
|
29
|
+
* ## Responsibilities
|
|
30
|
+
* - Generate report.dashboard with global index snapshot
|
|
31
|
+
* - Generate report.feature_summary with per-feature details
|
|
32
|
+
* - Aggregate cost and PR metadata
|
|
33
|
+
* - Provide gate profile summaries
|
|
34
|
+
*
|
|
35
|
+
* ## Dependencies
|
|
36
|
+
* Depends on {@link ReportingServicePort} for:
|
|
37
|
+
* - Index and state access
|
|
38
|
+
* - Cost and analytics data
|
|
39
|
+
* - PR monitor integration
|
|
40
|
+
* - Collision detection
|
|
41
|
+
*
|
|
42
|
+
* ## Key Methods
|
|
43
|
+
* - `reportDashboard()` - generate global dashboard
|
|
44
|
+
* - `reportFeatureSummary()` - generate per-feature summary
|
|
45
|
+
* - `collisionsScan()` - detect collisions across features
|
|
46
|
+
*
|
|
47
|
+
* ## Error Conditions
|
|
48
|
+
* - FILE_NOT_FOUND - feature state or index missing
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const reportingService = new ReportingService(port);
|
|
53
|
+
* const dashboard = await reportingService.reportDashboard();
|
|
54
|
+
* const summary = await reportingService.reportFeatureSummary('my_feature');
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* ## Dashboard Contents
|
|
58
|
+
* - Active/blocked/merged feature counts
|
|
59
|
+
* - Lock ownership
|
|
60
|
+
* - Runtime session metadata
|
|
61
|
+
* - Cost analytics
|
|
62
|
+
* - PR status (if integrated)
|
|
63
|
+
*/
|
|
23
64
|
export declare class ReportingService {
|
|
24
65
|
private readonly port;
|
|
25
66
|
constructor(port: ReportingServicePort);
|
|
67
|
+
/**
|
|
68
|
+
* Detects collisions across all accepted plans.
|
|
69
|
+
*
|
|
70
|
+
* @returns Collision matrix with conflicts by feature
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const collisions = await reportingService.collisionsScan();
|
|
75
|
+
* console.log(collisions.data.has_collisions);
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
26
78
|
collisionsScan(): Promise<{
|
|
27
79
|
data: {
|
|
28
80
|
collisions: any[];
|
|
29
81
|
};
|
|
30
82
|
}>;
|
|
83
|
+
/**
|
|
84
|
+
* Generates global orchestration dashboard.
|
|
85
|
+
*
|
|
86
|
+
* @returns Dashboard with active/blocked/merged features, locks, costs, PR metadata
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const dashboard = await reportingService.reportDashboard();
|
|
91
|
+
* console.log(dashboard.data.active);
|
|
92
|
+
* console.log(dashboard.data.locks);
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
31
95
|
reportDashboard(): Promise<{
|
|
32
96
|
data: {
|
|
33
97
|
index: AnyRecord;
|
|
34
98
|
features: any[];
|
|
35
99
|
};
|
|
36
100
|
}>;
|
|
101
|
+
/**
|
|
102
|
+
* Generates per-feature summary report.
|
|
103
|
+
*
|
|
104
|
+
* @param featureId - feature identifier
|
|
105
|
+
* @returns Feature summary with state, diff, evidence, costs, QA index
|
|
106
|
+
* @throws FILE_NOT_FOUND - feature does not exist
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* const summary = await reportingService.reportFeatureSummary('my_feature');
|
|
111
|
+
* console.log(summary.data.state);
|
|
112
|
+
* console.log(summary.data.diff);
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
37
115
|
reportFeatureSummary(featureId: string | null): Promise<{
|
|
38
116
|
data: {
|
|
39
117
|
feature_id: string;
|
|
@@ -11,11 +11,60 @@ function readHeldLocks(frontMatter) {
|
|
|
11
11
|
function createCollisionFingerprint(collisions) {
|
|
12
12
|
return stableHash(JSON.stringify(collisions));
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Manages dashboard and feature summary generation.
|
|
16
|
+
*
|
|
17
|
+
* ## Responsibilities
|
|
18
|
+
* - Generate report.dashboard with global index snapshot
|
|
19
|
+
* - Generate report.feature_summary with per-feature details
|
|
20
|
+
* - Aggregate cost and PR metadata
|
|
21
|
+
* - Provide gate profile summaries
|
|
22
|
+
*
|
|
23
|
+
* ## Dependencies
|
|
24
|
+
* Depends on {@link ReportingServicePort} for:
|
|
25
|
+
* - Index and state access
|
|
26
|
+
* - Cost and analytics data
|
|
27
|
+
* - PR monitor integration
|
|
28
|
+
* - Collision detection
|
|
29
|
+
*
|
|
30
|
+
* ## Key Methods
|
|
31
|
+
* - `reportDashboard()` - generate global dashboard
|
|
32
|
+
* - `reportFeatureSummary()` - generate per-feature summary
|
|
33
|
+
* - `collisionsScan()` - detect collisions across features
|
|
34
|
+
*
|
|
35
|
+
* ## Error Conditions
|
|
36
|
+
* - FILE_NOT_FOUND - feature state or index missing
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const reportingService = new ReportingService(port);
|
|
41
|
+
* const dashboard = await reportingService.reportDashboard();
|
|
42
|
+
* const summary = await reportingService.reportFeatureSummary('my_feature');
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* ## Dashboard Contents
|
|
46
|
+
* - Active/blocked/merged feature counts
|
|
47
|
+
* - Lock ownership
|
|
48
|
+
* - Runtime session metadata
|
|
49
|
+
* - Cost analytics
|
|
50
|
+
* - PR status (if integrated)
|
|
51
|
+
*/
|
|
14
52
|
export class ReportingService {
|
|
15
53
|
port;
|
|
16
54
|
constructor(port) {
|
|
17
55
|
this.port = port;
|
|
18
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Detects collisions across all accepted plans.
|
|
59
|
+
*
|
|
60
|
+
* @returns Collision matrix with conflicts by feature
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const collisions = await reportingService.collisionsScan();
|
|
65
|
+
* console.log(collisions.data.has_collisions);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
19
68
|
async collisionsScan() {
|
|
20
69
|
const plans = await this.port.collectAcceptedPlans();
|
|
21
70
|
const matrix = [];
|
|
@@ -40,6 +89,18 @@ export class ReportingService {
|
|
|
40
89
|
},
|
|
41
90
|
};
|
|
42
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Generates global orchestration dashboard.
|
|
94
|
+
*
|
|
95
|
+
* @returns Dashboard with active/blocked/merged features, locks, costs, PR metadata
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const dashboard = await reportingService.reportDashboard();
|
|
100
|
+
* console.log(dashboard.data.active);
|
|
101
|
+
* console.log(dashboard.data.locks);
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
43
104
|
async reportDashboard() {
|
|
44
105
|
const index = await this.port.readIndex();
|
|
45
106
|
const featureIds = normalizeSet([
|
|
@@ -84,6 +145,20 @@ export class ReportingService {
|
|
|
84
145
|
},
|
|
85
146
|
};
|
|
86
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* Generates per-feature summary report.
|
|
150
|
+
*
|
|
151
|
+
* @param featureId - feature identifier
|
|
152
|
+
* @returns Feature summary with state, diff, evidence, costs, QA index
|
|
153
|
+
* @throws FILE_NOT_FOUND - feature does not exist
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const summary = await reportingService.reportFeatureSummary('my_feature');
|
|
158
|
+
* console.log(summary.data.state);
|
|
159
|
+
* console.log(summary.data.diff);
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
87
162
|
async reportFeatureSummary(featureId) {
|
|
88
163
|
const state = await this.port.featureStateGet(featureId);
|
|
89
164
|
const bundle = await this.port.repoDiffBundle(featureId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporting-service.js","sourceRoot":"","sources":["../../../../../apps/control-plane/src/application/services/reporting-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKpE,SAAS,YAAY,CAAC,KAAe;IACnC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,aAAa,CAAC,WAAsB;IAC3C,MAAM,KAAK,GACT,WAAW,EAAE,KAAK,IAAI,OAAO,WAAW,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACvF,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACzD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,IAAa,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,0BAA0B,CAAC,UAAmB;IACrD,OAAO,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;AAChD,CAAC;
|
|
1
|
+
{"version":3,"file":"reporting-service.js","sourceRoot":"","sources":["../../../../../apps/control-plane/src/application/services/reporting-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,9 +32,64 @@ export interface RunLeaseServicePort {
|
|
|
32
32
|
isRunLeaseFresh(runtimeSessions: RuntimeSessionsSnapshot): boolean;
|
|
33
33
|
emptyRuntimeSessions(at?: string): RuntimeSessionsSnapshot;
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Manages run lease acquisition, renewal, and release.
|
|
37
|
+
*
|
|
38
|
+
* ## Responsibilities
|
|
39
|
+
* - Acquire exclusive run lease for orchestrator instance
|
|
40
|
+
* - Renew lease heartbeat to prevent staleness
|
|
41
|
+
* - Release lease on shutdown
|
|
42
|
+
* - Track orchestrator and feature session assignments
|
|
43
|
+
* - Prune stale session assignments
|
|
44
|
+
*
|
|
45
|
+
* ## Dependencies
|
|
46
|
+
* Depends on {@link RunLeaseServicePort} for:
|
|
47
|
+
* - Run lease file operations
|
|
48
|
+
* - Index operations
|
|
49
|
+
* - Lease TTL configuration
|
|
50
|
+
*
|
|
51
|
+
* ## Key Methods
|
|
52
|
+
* - `acquireRunLease()` - acquire exclusive run lease
|
|
53
|
+
* - `renewRunLease()` - renew lease heartbeat
|
|
54
|
+
* - `releaseRunLease()` - release lease
|
|
55
|
+
* - `updateOrchestratorSession()` - update orchestrator session metadata
|
|
56
|
+
* - `updateFeatureSessionAssignment()` - assign feature to sessions
|
|
57
|
+
* - `pruneFeatureSessionAssignments()` - remove stale assignments
|
|
58
|
+
*
|
|
59
|
+
* ## Error Conditions
|
|
60
|
+
* - RUN_ALREADY_ACTIVE - another instance holds fresh lease
|
|
61
|
+
* - STALE_LEASE - lease expired (can be taken over)
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const leaseService = new RunLeaseService(port);
|
|
66
|
+
* const lease = await leaseService.acquireRunLease({
|
|
67
|
+
* run_id: 'run_123',
|
|
68
|
+
* owner_instance_id: 'instance_abc',
|
|
69
|
+
* takeover_stale: false
|
|
70
|
+
* });
|
|
71
|
+
* await leaseService.renewRunLease(lease.data.run_id, lease.data.owner_instance_id);
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
35
74
|
export declare class RunLeaseService {
|
|
36
75
|
private readonly port;
|
|
37
76
|
constructor(port: RunLeaseServicePort);
|
|
77
|
+
/**
|
|
78
|
+
* Acquires exclusive run lease for orchestrator instance.
|
|
79
|
+
*
|
|
80
|
+
* @param input - acquisition parameters (run_id, owner_instance_id, takeover_stale)
|
|
81
|
+
* @returns Lease acquisition result
|
|
82
|
+
* @throws RUN_ALREADY_ACTIVE - another instance holds fresh lease
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const lease = await leaseService.acquireRunLease({
|
|
87
|
+
* run_id: 'run_123',
|
|
88
|
+
* owner_instance_id: 'instance_abc',
|
|
89
|
+
* takeover_stale: false
|
|
90
|
+
* });
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
38
93
|
acquireRunLease(input: AcquireRunLeaseInput): Promise<{
|
|
39
94
|
data: {
|
|
40
95
|
runtime_sessions: RuntimeSessionsSnapshot;
|
|
@@ -42,11 +97,35 @@ export declare class RunLeaseService {
|
|
|
42
97
|
reused_existing_owner: boolean;
|
|
43
98
|
};
|
|
44
99
|
}>;
|
|
100
|
+
/**
|
|
101
|
+
* Renews run lease heartbeat to prevent staleness.
|
|
102
|
+
*
|
|
103
|
+
* @param runId - run identifier
|
|
104
|
+
* @param ownerInstanceId - instance identifier
|
|
105
|
+
* @returns Renewal result
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* await leaseService.renewRunLease('run_123', 'instance_abc');
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
45
112
|
renewRunLease(runId: string, ownerInstanceId: string): Promise<{
|
|
46
113
|
data: {
|
|
47
114
|
lease_expires_at: string;
|
|
48
115
|
};
|
|
49
116
|
}>;
|
|
117
|
+
/**
|
|
118
|
+
* Releases run lease on shutdown.
|
|
119
|
+
*
|
|
120
|
+
* @param runId - run identifier
|
|
121
|
+
* @param ownerInstanceId - instance identifier
|
|
122
|
+
* @returns Release result
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* await leaseService.releaseRunLease('run_123', 'instance_abc');
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
50
129
|
releaseRunLease(runId: string, ownerInstanceId: string): Promise<{
|
|
51
130
|
data: {
|
|
52
131
|
released: boolean;
|