agentic-qe 3.8.10 → 3.8.12
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/.claude/skills/skills-manifest.json +1 -1
- package/CHANGELOG.md +40 -0
- package/dist/cli/bundle.js +1345 -1003
- package/dist/cli/command-registry.js +5 -1
- package/dist/cli/commands/pipeline.d.ts +16 -0
- package/dist/cli/commands/pipeline.js +314 -0
- package/dist/cli/commands/ruvector-commands.js +17 -0
- package/dist/cli/commands/token-usage.js +24 -1
- package/dist/cli/handlers/heartbeat-handler.d.ts +26 -0
- package/dist/cli/handlers/heartbeat-handler.js +382 -0
- package/dist/cli/handlers/index.d.ts +2 -0
- package/dist/cli/handlers/index.js +2 -0
- package/dist/cli/handlers/routing-handler.d.ts +22 -0
- package/dist/cli/handlers/routing-handler.js +227 -0
- package/dist/cli/index.js +2 -0
- package/dist/coordination/deterministic-actions.d.ts +36 -0
- package/dist/coordination/deterministic-actions.js +257 -0
- package/dist/coordination/workflow-orchestrator.d.ts +18 -1
- package/dist/coordination/workflow-orchestrator.js +113 -3
- package/dist/coordination/workflow-types.d.ts +19 -1
- package/dist/coordination/workflow-types.js +3 -0
- package/dist/coordination/yaml-pipeline-loader.d.ts +1 -0
- package/dist/coordination/yaml-pipeline-loader.js +34 -0
- package/dist/domains/code-intelligence/coordinator-gnn.d.ts +21 -0
- package/dist/domains/code-intelligence/coordinator-gnn.js +102 -0
- package/dist/domains/contract-testing/coordinator.js +13 -0
- package/dist/domains/coverage-analysis/coordinator.js +5 -0
- package/dist/domains/defect-intelligence/coordinator.d.ts +1 -0
- package/dist/domains/defect-intelligence/coordinator.js +43 -0
- package/dist/domains/quality-assessment/coordinator.js +26 -0
- package/dist/domains/test-generation/coordinator.js +14 -0
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts +11 -0
- package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js +44 -1
- package/dist/integrations/rl-suite/algorithms/eprop.d.ts +79 -0
- package/dist/integrations/rl-suite/algorithms/eprop.js +284 -0
- package/dist/integrations/rl-suite/algorithms/index.d.ts +2 -1
- package/dist/integrations/rl-suite/algorithms/index.js +2 -1
- package/dist/integrations/rl-suite/index.d.ts +2 -2
- package/dist/integrations/rl-suite/index.js +2 -2
- package/dist/integrations/rl-suite/interfaces.d.ts +3 -3
- package/dist/integrations/rl-suite/interfaces.js +1 -1
- package/dist/integrations/rl-suite/orchestrator.d.ts +2 -2
- package/dist/integrations/rl-suite/orchestrator.js +3 -2
- package/dist/integrations/rl-suite/reward-signals.d.ts +1 -1
- package/dist/integrations/rl-suite/reward-signals.js +1 -1
- package/dist/integrations/ruvector/coherence-gate-cohomology.d.ts +41 -0
- package/dist/integrations/ruvector/coherence-gate-cohomology.js +47 -0
- package/dist/integrations/ruvector/coherence-gate-core.d.ts +200 -0
- package/dist/integrations/ruvector/coherence-gate-core.js +294 -0
- package/dist/integrations/ruvector/coherence-gate-energy.d.ts +136 -0
- package/dist/integrations/ruvector/coherence-gate-energy.js +373 -0
- package/dist/integrations/ruvector/coherence-gate-vector.d.ts +38 -0
- package/dist/integrations/ruvector/coherence-gate-vector.js +76 -0
- package/dist/integrations/ruvector/coherence-gate.d.ts +10 -311
- package/dist/integrations/ruvector/coherence-gate.js +10 -652
- package/dist/integrations/ruvector/cold-tier-trainer.d.ts +103 -0
- package/dist/integrations/ruvector/cold-tier-trainer.js +377 -0
- package/dist/integrations/ruvector/cusum-detector.d.ts +70 -0
- package/dist/integrations/ruvector/cusum-detector.js +142 -0
- package/dist/integrations/ruvector/delta-tracker.d.ts +122 -0
- package/dist/integrations/ruvector/delta-tracker.js +311 -0
- package/dist/integrations/ruvector/domain-transfer.d.ts +79 -1
- package/dist/integrations/ruvector/domain-transfer.js +158 -2
- package/dist/integrations/ruvector/eprop-learner.d.ts +135 -0
- package/dist/integrations/ruvector/eprop-learner.js +351 -0
- package/dist/integrations/ruvector/feature-flags.d.ts +177 -0
- package/dist/integrations/ruvector/feature-flags.js +145 -0
- package/dist/integrations/ruvector/graphmae-encoder.d.ts +88 -0
- package/dist/integrations/ruvector/graphmae-encoder.js +360 -0
- package/dist/integrations/ruvector/hdc-fingerprint.d.ts +127 -0
- package/dist/integrations/ruvector/hdc-fingerprint.js +222 -0
- package/dist/integrations/ruvector/hopfield-memory.d.ts +97 -0
- package/dist/integrations/ruvector/hopfield-memory.js +238 -0
- package/dist/integrations/ruvector/index.d.ts +13 -2
- package/dist/integrations/ruvector/index.js +46 -2
- package/dist/integrations/ruvector/mincut-wrapper.d.ts +7 -0
- package/dist/integrations/ruvector/mincut-wrapper.js +54 -2
- package/dist/integrations/ruvector/reservoir-replay.d.ts +172 -0
- package/dist/integrations/ruvector/reservoir-replay.js +335 -0
- package/dist/integrations/ruvector/solver-adapter.d.ts +93 -0
- package/dist/integrations/ruvector/solver-adapter.js +299 -0
- package/dist/integrations/ruvector/sona-persistence.d.ts +33 -0
- package/dist/integrations/ruvector/sona-persistence.js +47 -0
- package/dist/integrations/ruvector/spectral-sparsifier.d.ts +154 -0
- package/dist/integrations/ruvector/spectral-sparsifier.js +389 -0
- package/dist/integrations/ruvector/temporal-causality.d.ts +63 -0
- package/dist/integrations/ruvector/temporal-causality.js +317 -0
- package/dist/learning/pattern-promotion.d.ts +63 -0
- package/dist/learning/pattern-promotion.js +235 -1
- package/dist/learning/pattern-store.d.ts +2 -0
- package/dist/learning/pattern-store.js +187 -1
- package/dist/learning/sqlite-persistence.d.ts +2 -0
- package/dist/learning/sqlite-persistence.js +4 -0
- package/dist/mcp/bundle.js +477 -380
- package/dist/mcp/handlers/heartbeat-handlers.d.ts +67 -0
- package/dist/mcp/handlers/heartbeat-handlers.js +180 -0
- package/dist/mcp/handlers/index.d.ts +2 -1
- package/dist/mcp/handlers/index.js +5 -1
- package/dist/mcp/handlers/task-handlers.d.ts +28 -0
- package/dist/mcp/handlers/task-handlers.js +39 -0
- package/dist/mcp/protocol-server.js +45 -1
- package/dist/mcp/server.js +41 -1
- package/dist/optimization/index.d.ts +2 -0
- package/dist/optimization/index.js +1 -0
- package/dist/optimization/session-cache.d.ts +80 -0
- package/dist/optimization/session-cache.js +227 -0
- package/dist/optimization/token-optimizer-service.d.ts +10 -0
- package/dist/optimization/token-optimizer-service.js +51 -0
- package/dist/routing/economic-routing.d.ts +126 -0
- package/dist/routing/economic-routing.js +290 -0
- package/dist/routing/index.d.ts +2 -0
- package/dist/routing/index.js +2 -0
- package/dist/routing/routing-feedback.d.ts +29 -0
- package/dist/routing/routing-feedback.js +75 -0
- package/dist/shared/utils/index.d.ts +1 -0
- package/dist/shared/utils/index.js +1 -0
- package/dist/shared/utils/xorshift128.d.ts +24 -0
- package/dist/shared/utils/xorshift128.js +50 -0
- package/package.json +1 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic Step Actions (Imp-9)
|
|
3
|
+
*
|
|
4
|
+
* Built-in actions that execute WITHOUT LLM tokens. Each action maps to a
|
|
5
|
+
* domain + action pair and is automatically wired into the WorkflowOrchestrator
|
|
6
|
+
* as a fallback before domain service delegation.
|
|
7
|
+
*
|
|
8
|
+
* When the caller supplies explicit input values they are used directly.
|
|
9
|
+
* When inputs are omitted, the actions query the unified SQLite database
|
|
10
|
+
* for live metrics — keeping execution fully deterministic (SQL-only).
|
|
11
|
+
*/
|
|
12
|
+
import { Result, DomainName } from '../shared/types/index.js';
|
|
13
|
+
import type { WorkflowContext } from './workflow-types.js';
|
|
14
|
+
/**
|
|
15
|
+
* A deterministic action that runs without any LLM tokens.
|
|
16
|
+
*/
|
|
17
|
+
export interface DeterministicAction {
|
|
18
|
+
/** Unique action identifier */
|
|
19
|
+
id: string;
|
|
20
|
+
/** Target domain */
|
|
21
|
+
domain: DomainName;
|
|
22
|
+
/** Action name within the domain */
|
|
23
|
+
action: string;
|
|
24
|
+
/** Execute the action with the given input */
|
|
25
|
+
execute(input: Record<string, unknown>, context: WorkflowContext): Promise<Result<Record<string, unknown>, Error>>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Look up a deterministic action by domain + action.
|
|
29
|
+
* Returns undefined if no built-in action matches.
|
|
30
|
+
*/
|
|
31
|
+
export declare function findDeterministicAction(domain: DomainName, action: string): DeterministicAction | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Get all registered deterministic actions.
|
|
34
|
+
*/
|
|
35
|
+
export declare function getAllDeterministicActions(): readonly DeterministicAction[];
|
|
36
|
+
//# sourceMappingURL=deterministic-actions.d.ts.map
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic Step Actions (Imp-9)
|
|
3
|
+
*
|
|
4
|
+
* Built-in actions that execute WITHOUT LLM tokens. Each action maps to a
|
|
5
|
+
* domain + action pair and is automatically wired into the WorkflowOrchestrator
|
|
6
|
+
* as a fallback before domain service delegation.
|
|
7
|
+
*
|
|
8
|
+
* When the caller supplies explicit input values they are used directly.
|
|
9
|
+
* When inputs are omitted, the actions query the unified SQLite database
|
|
10
|
+
* for live metrics — keeping execution fully deterministic (SQL-only).
|
|
11
|
+
*/
|
|
12
|
+
import { ok } from '../shared/types/index.js';
|
|
13
|
+
function tryGetDb() {
|
|
14
|
+
try {
|
|
15
|
+
// Dynamic import to avoid hard dependency — the module may not be initialised
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
17
|
+
const { getUnifiedMemory } = require('../kernel/unified-memory.js');
|
|
18
|
+
const um = getUnifiedMemory();
|
|
19
|
+
if (!um.isInitialized())
|
|
20
|
+
return null;
|
|
21
|
+
return um.getDatabase();
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// ============================================================================
|
|
28
|
+
// Quality Gate Check
|
|
29
|
+
// ============================================================================
|
|
30
|
+
const qualityGateCheck = {
|
|
31
|
+
id: 'quality-gate-check',
|
|
32
|
+
domain: 'quality-assessment',
|
|
33
|
+
action: 'gate-check',
|
|
34
|
+
async execute(input) {
|
|
35
|
+
const coverageMin = typeof input.coverageMin === 'number' ? input.coverageMin : 80;
|
|
36
|
+
const testsPassingMin = typeof input.testsPassingMin === 'number' ? input.testsPassingMin : 90;
|
|
37
|
+
const maxBugs = typeof input.maxBugs === 'number' ? input.maxBugs : 5;
|
|
38
|
+
// ----- Fetch live data from DB when not supplied by caller -----
|
|
39
|
+
let currentCoverage = typeof input.currentCoverage === 'number' ? input.currentCoverage : null;
|
|
40
|
+
let currentTestsPassingRate = typeof input.currentTestsPassingRate === 'number' ? input.currentTestsPassingRate : null;
|
|
41
|
+
let currentBugs = typeof input.currentBugs === 'number' ? input.currentBugs : null;
|
|
42
|
+
if (currentCoverage === null || currentTestsPassingRate === null || currentBugs === null) {
|
|
43
|
+
const db = tryGetDb();
|
|
44
|
+
if (db) {
|
|
45
|
+
try {
|
|
46
|
+
// Latest coverage from coverage_sessions
|
|
47
|
+
if (currentCoverage === null) {
|
|
48
|
+
const row = db.prepare(`SELECT after_lines FROM coverage_sessions ORDER BY created_at DESC LIMIT 1`).get();
|
|
49
|
+
currentCoverage = row?.after_lines ?? 0;
|
|
50
|
+
}
|
|
51
|
+
// Test pass rate from recent test_outcomes
|
|
52
|
+
if (currentTestsPassingRate === null) {
|
|
53
|
+
const row = db.prepare(`SELECT COUNT(*) as total,
|
|
54
|
+
SUM(CASE WHEN passed = 1 THEN 1 ELSE 0 END) as passed
|
|
55
|
+
FROM test_outcomes
|
|
56
|
+
WHERE created_at > datetime('now', '-7 days')`).get();
|
|
57
|
+
currentTestsPassingRate =
|
|
58
|
+
row && row.total > 0 ? (row.passed / row.total) * 100 : 0;
|
|
59
|
+
}
|
|
60
|
+
// Bug count: failed non-flaky tests in the last 7 days
|
|
61
|
+
if (currentBugs === null) {
|
|
62
|
+
const row = db.prepare(`SELECT COUNT(*) as bugs FROM test_outcomes
|
|
63
|
+
WHERE passed = 0 AND flaky = 0
|
|
64
|
+
AND created_at > datetime('now', '-7 days')`).get();
|
|
65
|
+
currentBugs = row?.bugs ?? 0;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// Graceful degradation — fall through to defaults
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Apply defaults for anything still null
|
|
74
|
+
currentCoverage = currentCoverage ?? 0;
|
|
75
|
+
currentTestsPassingRate = currentTestsPassingRate ?? 0;
|
|
76
|
+
currentBugs = currentBugs ?? 0;
|
|
77
|
+
const coveragePassed = currentCoverage >= coverageMin;
|
|
78
|
+
const testsPassed = currentTestsPassingRate >= testsPassingMin;
|
|
79
|
+
const bugsPassed = currentBugs <= maxBugs;
|
|
80
|
+
const passed = coveragePassed && testsPassed && bugsPassed;
|
|
81
|
+
// Score is a normalized 0-1 value
|
|
82
|
+
const coverageScore = Math.min(currentCoverage / coverageMin, 1);
|
|
83
|
+
const testsScore = Math.min(currentTestsPassingRate / testsPassingMin, 1);
|
|
84
|
+
const bugsScore = maxBugs > 0 ? Math.max(0, 1 - currentBugs / maxBugs) : (currentBugs === 0 ? 1 : 0);
|
|
85
|
+
const score = (coverageScore + testsScore + bugsScore) / 3;
|
|
86
|
+
return ok({
|
|
87
|
+
passed,
|
|
88
|
+
score: Math.round(score * 100) / 100,
|
|
89
|
+
source: typeof input.currentCoverage === 'number' ? 'input' : 'database',
|
|
90
|
+
details: {
|
|
91
|
+
coverage: { current: currentCoverage, threshold: coverageMin, passed: coveragePassed },
|
|
92
|
+
testsPassing: { current: currentTestsPassingRate, threshold: testsPassingMin, passed: testsPassed },
|
|
93
|
+
bugs: { current: currentBugs, threshold: maxBugs, passed: bugsPassed },
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
// ============================================================================
|
|
99
|
+
// Coverage Threshold Check
|
|
100
|
+
// ============================================================================
|
|
101
|
+
const coverageThresholdCheck = {
|
|
102
|
+
id: 'coverage-threshold',
|
|
103
|
+
domain: 'coverage-analysis',
|
|
104
|
+
action: 'threshold-check',
|
|
105
|
+
async execute(input) {
|
|
106
|
+
const minCoverage = typeof input.minCoverage === 'number' ? input.minCoverage : 80;
|
|
107
|
+
// ----- Fetch from DB when not supplied -----
|
|
108
|
+
let currentCoverage = typeof input.currentCoverage === 'number' ? input.currentCoverage : null;
|
|
109
|
+
let source = 'input';
|
|
110
|
+
if (currentCoverage === null) {
|
|
111
|
+
source = 'database';
|
|
112
|
+
const db = tryGetDb();
|
|
113
|
+
if (db) {
|
|
114
|
+
try {
|
|
115
|
+
const row = db.prepare(`SELECT after_lines FROM coverage_sessions ORDER BY created_at DESC LIMIT 1`).get();
|
|
116
|
+
currentCoverage = row?.after_lines ?? 0;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
currentCoverage = 0;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
currentCoverage = 0;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
const passed = currentCoverage >= minCoverage;
|
|
127
|
+
const gap = passed ? 0 : Math.round((minCoverage - currentCoverage) * 100) / 100;
|
|
128
|
+
return ok({
|
|
129
|
+
currentCoverage,
|
|
130
|
+
passed,
|
|
131
|
+
gap,
|
|
132
|
+
minCoverage,
|
|
133
|
+
source,
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
// ============================================================================
|
|
138
|
+
// Pattern Health Check
|
|
139
|
+
// ============================================================================
|
|
140
|
+
const patternHealthCheck = {
|
|
141
|
+
id: 'pattern-health',
|
|
142
|
+
domain: 'learning-optimization',
|
|
143
|
+
action: 'health-check',
|
|
144
|
+
async execute(input) {
|
|
145
|
+
// ----- Fetch from DB when not supplied -----
|
|
146
|
+
let totalPatterns = typeof input.totalPatterns === 'number' ? input.totalPatterns : null;
|
|
147
|
+
let activePatterns = typeof input.activePatterns === 'number' ? input.activePatterns : null;
|
|
148
|
+
let avgConfidence = typeof input.avgConfidence === 'number' ? input.avgConfidence : null;
|
|
149
|
+
let source = 'input';
|
|
150
|
+
if (totalPatterns === null || activePatterns === null || avgConfidence === null) {
|
|
151
|
+
source = 'database';
|
|
152
|
+
const db = tryGetDb();
|
|
153
|
+
if (db) {
|
|
154
|
+
try {
|
|
155
|
+
const row = db.prepare(`
|
|
156
|
+
SELECT COUNT(*) as total,
|
|
157
|
+
SUM(CASE WHEN deprecated_at IS NULL AND confidence >= 0.3 THEN 1 ELSE 0 END) as active,
|
|
158
|
+
AVG(confidence) as avg_conf
|
|
159
|
+
FROM qe_patterns
|
|
160
|
+
`).get();
|
|
161
|
+
totalPatterns = totalPatterns ?? (row?.total ?? 0);
|
|
162
|
+
activePatterns = activePatterns ?? (row?.active ?? 0);
|
|
163
|
+
avgConfidence = avgConfidence ?? (row?.avg_conf ?? 0);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// Graceful degradation
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Apply defaults for anything still null
|
|
171
|
+
totalPatterns = totalPatterns ?? 0;
|
|
172
|
+
activePatterns = activePatterns ?? 0;
|
|
173
|
+
avgConfidence = avgConfidence ?? 0;
|
|
174
|
+
// Health score: weighted combination of volume, activity ratio, and confidence
|
|
175
|
+
const volumeScore = Math.min(totalPatterns / 100, 1); // 100 patterns = max volume
|
|
176
|
+
const activityRatio = totalPatterns > 0 ? activePatterns / totalPatterns : 0;
|
|
177
|
+
const healthScore = Math.round((volumeScore * 0.3 + activityRatio * 0.3 + avgConfidence * 0.4) * 100) / 100;
|
|
178
|
+
return ok({
|
|
179
|
+
totalPatterns,
|
|
180
|
+
activePatterns,
|
|
181
|
+
avgConfidence,
|
|
182
|
+
healthScore,
|
|
183
|
+
source,
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
// ============================================================================
|
|
188
|
+
// Routing Accuracy Check
|
|
189
|
+
// ============================================================================
|
|
190
|
+
const routingAccuracyCheck = {
|
|
191
|
+
id: 'routing-accuracy',
|
|
192
|
+
domain: 'learning-optimization',
|
|
193
|
+
action: 'routing-check',
|
|
194
|
+
async execute(input) {
|
|
195
|
+
// ----- Fetch from DB when not supplied -----
|
|
196
|
+
let totalOutcomes = typeof input.totalOutcomes === 'number' ? input.totalOutcomes : null;
|
|
197
|
+
let successfulOutcomes = typeof input.successfulOutcomes === 'number' ? input.successfulOutcomes : null;
|
|
198
|
+
let confidenceCorrelation = typeof input.confidenceCorrelation === 'number' ? input.confidenceCorrelation : null;
|
|
199
|
+
let source = 'input';
|
|
200
|
+
if (totalOutcomes === null || successfulOutcomes === null) {
|
|
201
|
+
source = 'database';
|
|
202
|
+
const db = tryGetDb();
|
|
203
|
+
if (db) {
|
|
204
|
+
try {
|
|
205
|
+
const row = db.prepare(`
|
|
206
|
+
SELECT COUNT(*) as total,
|
|
207
|
+
SUM(CASE WHEN success = 1 THEN 1 ELSE 0 END) as successful
|
|
208
|
+
FROM routing_outcomes
|
|
209
|
+
`).get();
|
|
210
|
+
totalOutcomes = totalOutcomes ?? (row?.total ?? 0);
|
|
211
|
+
successfulOutcomes = successfulOutcomes ?? (row?.successful ?? 0);
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
// Graceful degradation
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Apply defaults
|
|
219
|
+
totalOutcomes = totalOutcomes ?? 0;
|
|
220
|
+
successfulOutcomes = successfulOutcomes ?? 0;
|
|
221
|
+
confidenceCorrelation = confidenceCorrelation ?? 0;
|
|
222
|
+
const successRate = totalOutcomes > 0
|
|
223
|
+
? Math.round((successfulOutcomes / totalOutcomes) * 10000) / 100
|
|
224
|
+
: 0;
|
|
225
|
+
return ok({
|
|
226
|
+
successRate,
|
|
227
|
+
totalOutcomes,
|
|
228
|
+
successfulOutcomes,
|
|
229
|
+
confidenceCorrelation,
|
|
230
|
+
source,
|
|
231
|
+
});
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
// ============================================================================
|
|
235
|
+
// Registry
|
|
236
|
+
// ============================================================================
|
|
237
|
+
/** All built-in deterministic actions */
|
|
238
|
+
const DETERMINISTIC_ACTIONS = [
|
|
239
|
+
qualityGateCheck,
|
|
240
|
+
coverageThresholdCheck,
|
|
241
|
+
patternHealthCheck,
|
|
242
|
+
routingAccuracyCheck,
|
|
243
|
+
];
|
|
244
|
+
/**
|
|
245
|
+
* Look up a deterministic action by domain + action.
|
|
246
|
+
* Returns undefined if no built-in action matches.
|
|
247
|
+
*/
|
|
248
|
+
export function findDeterministicAction(domain, action) {
|
|
249
|
+
return DETERMINISTIC_ACTIONS.find((a) => a.domain === domain && a.action === action);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Get all registered deterministic actions.
|
|
253
|
+
*/
|
|
254
|
+
export function getAllDeterministicActions() {
|
|
255
|
+
return DETERMINISTIC_ACTIONS;
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=deterministic-actions.js.map
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { Result, DomainName } from '../shared/types/index.js';
|
|
11
11
|
import { EventBus, MemoryBackend, AgentCoordinator } from '../kernel/interfaces.js';
|
|
12
12
|
import type { BehaviorNode } from './behavior-tree/nodes.js';
|
|
13
|
-
export type { StepExecutionMode, StepStatus, WorkflowStatus, ConditionOperator, StepCondition, WorkflowStepDefinition, WorkflowDefinition, WorkflowTrigger, StepExecutionResult, WorkflowContext, WorkflowExecutionStatus, WorkflowListItem, WorkflowStartedPayload, WorkflowCompletedPayload, WorkflowFailedPayload, StepEventPayload, IWorkflowOrchestrator, DomainAction, DomainActionRegistry, WorkflowOrchestratorConfig, } from './workflow-types.js';
|
|
13
|
+
export type { StepExecutionMode, StepStatus, WorkflowStatus, ConditionOperator, StepCondition, WorkflowStepDefinition, WorkflowDefinition, WorkflowTrigger, StepExecutionResult, WorkflowContext, WorkflowExecutionStatus, WorkflowListItem, WorkflowStartedPayload, WorkflowCompletedPayload, WorkflowFailedPayload, StepEventPayload, StepAwaitingApprovalPayload, IWorkflowOrchestrator, DomainAction, DomainActionRegistry, WorkflowOrchestratorConfig, } from './workflow-types.js';
|
|
14
14
|
export { WorkflowEvents, DEFAULT_WORKFLOW_CONFIG, } from './workflow-types.js';
|
|
15
15
|
import type { WorkflowDefinition, WorkflowExecutionStatus, WorkflowListItem, IWorkflowOrchestrator, DomainAction, WorkflowOrchestratorConfig } from './workflow-types.js';
|
|
16
16
|
export declare class WorkflowOrchestrator implements IWorkflowOrchestrator {
|
|
@@ -22,6 +22,8 @@ export declare class WorkflowOrchestrator implements IWorkflowOrchestrator {
|
|
|
22
22
|
private readonly executions;
|
|
23
23
|
private readonly actionRegistry;
|
|
24
24
|
private readonly eventSubscriptions;
|
|
25
|
+
/** Pending approval gates: Map<`${executionId}:${stepId}`, gate> */
|
|
26
|
+
private readonly approvalGates;
|
|
25
27
|
private initialized;
|
|
26
28
|
constructor(eventBus: EventBus, memory: MemoryBackend, agentCoordinator: AgentCoordinator, config?: Partial<WorkflowOrchestratorConfig>);
|
|
27
29
|
initialize(): Promise<void>;
|
|
@@ -36,6 +38,16 @@ export declare class WorkflowOrchestrator implements IWorkflowOrchestrator {
|
|
|
36
38
|
listWorkflows(): WorkflowListItem[];
|
|
37
39
|
getActiveExecutions(): WorkflowExecutionStatus[];
|
|
38
40
|
getWorkflow(workflowId: string): WorkflowDefinition | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Approve a step that is awaiting approval. Returns true if the step
|
|
43
|
+
* was found and approved, false otherwise.
|
|
44
|
+
*/
|
|
45
|
+
approveStep(executionId: string, stepId: string): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Reject a step that is awaiting approval. Returns true if the step
|
|
48
|
+
* was found and rejected, false otherwise.
|
|
49
|
+
*/
|
|
50
|
+
rejectStep(executionId: string, stepId: string, reason?: string): boolean;
|
|
39
51
|
isActionRegistered(domain: DomainName, action: string): boolean;
|
|
40
52
|
getRegisteredActions(domain: DomainName): string[];
|
|
41
53
|
getDomainsWithActions(): DomainName[];
|
|
@@ -81,6 +93,11 @@ export declare class WorkflowOrchestrator implements IWorkflowOrchestrator {
|
|
|
81
93
|
private loadPersistedWorkflows;
|
|
82
94
|
private persistWorkflows;
|
|
83
95
|
private persistExecution;
|
|
96
|
+
/**
|
|
97
|
+
* Wait for external approval (or auto-approve after timeout).
|
|
98
|
+
* Returns an object with approved status and optional rejection reason.
|
|
99
|
+
*/
|
|
100
|
+
private waitForApproval;
|
|
84
101
|
private delay;
|
|
85
102
|
}
|
|
86
103
|
export declare function createWorkflowOrchestrator(eventBus: EventBus, memory: MemoryBackend, agentCoordinator: AgentCoordinator, config?: Partial<WorkflowOrchestratorConfig>): IWorkflowOrchestrator;
|
|
@@ -13,6 +13,8 @@ import { createEvent } from '../shared/events/domain-events.js';
|
|
|
13
13
|
import { toError, toErrorMessage } from '../shared/error-utils.js';
|
|
14
14
|
export { WorkflowEvents, DEFAULT_WORKFLOW_CONFIG, } from './workflow-types.js';
|
|
15
15
|
import { WorkflowEvents, DEFAULT_WORKFLOW_CONFIG } from './workflow-types.js';
|
|
16
|
+
// Import deterministic actions
|
|
17
|
+
import { findDeterministicAction } from './deterministic-actions.js';
|
|
16
18
|
// Import built-in workflows
|
|
17
19
|
import { getBuiltInWorkflows, BUILTIN_WORKFLOW_IDS } from './workflow-builtin.js';
|
|
18
20
|
// ============================================================================
|
|
@@ -27,6 +29,8 @@ export class WorkflowOrchestrator {
|
|
|
27
29
|
executions = new Map();
|
|
28
30
|
actionRegistry = {};
|
|
29
31
|
eventSubscriptions = [];
|
|
32
|
+
/** Pending approval gates: Map<`${executionId}:${stepId}`, gate> */
|
|
33
|
+
approvalGates = new Map();
|
|
30
34
|
initialized = false;
|
|
31
35
|
constructor(eventBus, memory, agentCoordinator, config = {}) {
|
|
32
36
|
this.eventBus = eventBus;
|
|
@@ -127,6 +131,13 @@ export class WorkflowOrchestrator {
|
|
|
127
131
|
execution.status = 'cancelled';
|
|
128
132
|
execution.completedAt = new Date();
|
|
129
133
|
execution.duration = execution.completedAt.getTime() - execution.startedAt.getTime();
|
|
134
|
+
// Clean up any pending approval gates for this execution to prevent timer leaks
|
|
135
|
+
for (const [key, gate] of this.approvalGates.entries()) {
|
|
136
|
+
if (key.startsWith(`${executionId}:`)) {
|
|
137
|
+
gate.resolve({ approved: false, reason: 'Workflow cancelled' });
|
|
138
|
+
this.approvalGates.delete(key);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
130
141
|
await this.publishEvent(WorkflowEvents.WorkflowCancelled, {
|
|
131
142
|
executionId, workflowId: execution.workflowId, workflowName: execution.workflowName,
|
|
132
143
|
}, execution.context.metadata.correlationId);
|
|
@@ -171,6 +182,35 @@ export class WorkflowOrchestrator {
|
|
|
171
182
|
return this.workflows.get(workflowId);
|
|
172
183
|
}
|
|
173
184
|
// ============================================================================
|
|
185
|
+
// Approval Gate Methods
|
|
186
|
+
// ============================================================================
|
|
187
|
+
/**
|
|
188
|
+
* Approve a step that is awaiting approval. Returns true if the step
|
|
189
|
+
* was found and approved, false otherwise.
|
|
190
|
+
*/
|
|
191
|
+
approveStep(executionId, stepId) {
|
|
192
|
+
const key = `${executionId}:${stepId}`;
|
|
193
|
+
const gate = this.approvalGates.get(key);
|
|
194
|
+
if (!gate)
|
|
195
|
+
return false;
|
|
196
|
+
gate.resolve({ approved: true });
|
|
197
|
+
this.approvalGates.delete(key);
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Reject a step that is awaiting approval. Returns true if the step
|
|
202
|
+
* was found and rejected, false otherwise.
|
|
203
|
+
*/
|
|
204
|
+
rejectStep(executionId, stepId, reason) {
|
|
205
|
+
const key = `${executionId}:${stepId}`;
|
|
206
|
+
const gate = this.approvalGates.get(key);
|
|
207
|
+
if (!gate)
|
|
208
|
+
return false;
|
|
209
|
+
gate.resolve({ approved: false, reason });
|
|
210
|
+
this.approvalGates.delete(key);
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
// ============================================================================
|
|
174
214
|
// Public Utility Methods
|
|
175
215
|
// ============================================================================
|
|
176
216
|
isActionRegistered(domain, action) {
|
|
@@ -402,6 +442,20 @@ export class WorkflowOrchestrator {
|
|
|
402
442
|
const stepTimeout = step.timeout || this.config.defaultStepTimeout;
|
|
403
443
|
const output = await this.executeStepAction(step, input, execution.context, stepTimeout);
|
|
404
444
|
this.mapStepOutput(step, output, execution.context);
|
|
445
|
+
// Handle approval gate if configured
|
|
446
|
+
if (step.approval) {
|
|
447
|
+
const approvalResult = await this.waitForApproval(step, execution);
|
|
448
|
+
if (!approvalResult.approved) {
|
|
449
|
+
result.status = 'failed';
|
|
450
|
+
result.error = approvalResult.reason || 'Step rejected at approval gate';
|
|
451
|
+
result.output = output;
|
|
452
|
+
result.completedAt = new Date();
|
|
453
|
+
result.duration = result.completedAt.getTime() - startedAt.getTime();
|
|
454
|
+
execution.stepResults.set(step.id, result);
|
|
455
|
+
await this.publishStepFailed(execution, step, result.error);
|
|
456
|
+
return result;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
405
459
|
result.status = 'completed';
|
|
406
460
|
result.output = output;
|
|
407
461
|
result.completedAt = new Date();
|
|
@@ -439,11 +493,20 @@ export class WorkflowOrchestrator {
|
|
|
439
493
|
}
|
|
440
494
|
}
|
|
441
495
|
async executeStepAction(step, input, context, timeout) {
|
|
496
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
497
|
+
setTimeout(() => reject(new Error(`Step timeout after ${timeout}ms`)), timeout);
|
|
498
|
+
});
|
|
499
|
+
// Check for a deterministic action first (zero LLM tokens)
|
|
500
|
+
const deterministicAction = findDeterministicAction(step.domain, step.action);
|
|
501
|
+
if (deterministicAction) {
|
|
502
|
+
const actionResult = await Promise.race([deterministicAction.execute(input, context), timeoutPromise]);
|
|
503
|
+
if (!actionResult.success)
|
|
504
|
+
throw actionResult.error;
|
|
505
|
+
return actionResult.value;
|
|
506
|
+
}
|
|
507
|
+
// Fall back to registered domain actions
|
|
442
508
|
const domainActions = this.actionRegistry[step.domain];
|
|
443
509
|
if (domainActions?.[step.action]) {
|
|
444
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
445
|
-
setTimeout(() => reject(new Error(`Step timeout after ${timeout}ms`)), timeout);
|
|
446
|
-
});
|
|
447
510
|
const actionResult = await Promise.race([domainActions[step.action](input, context), timeoutPromise]);
|
|
448
511
|
if (!actionResult.success)
|
|
449
512
|
throw actionResult.error;
|
|
@@ -751,6 +814,53 @@ export class WorkflowOrchestrator {
|
|
|
751
814
|
}
|
|
752
815
|
}
|
|
753
816
|
// ============================================================================
|
|
817
|
+
// Private Methods - Approval Gates
|
|
818
|
+
// ============================================================================
|
|
819
|
+
/**
|
|
820
|
+
* Wait for external approval (or auto-approve after timeout).
|
|
821
|
+
* Returns an object with approved status and optional rejection reason.
|
|
822
|
+
*/
|
|
823
|
+
async waitForApproval(step, execution) {
|
|
824
|
+
const approvalConfig = typeof step.approval === 'object' ? step.approval : {};
|
|
825
|
+
const autoApproveAfter = approvalConfig.autoApproveAfter ?? 300000; // 5 min default
|
|
826
|
+
const message = approvalConfig.message ?? `Awaiting approval for step: ${step.name}`;
|
|
827
|
+
// Update step result status
|
|
828
|
+
const stepResult = execution.stepResults.get(step.id);
|
|
829
|
+
if (stepResult)
|
|
830
|
+
stepResult.status = 'awaiting_approval';
|
|
831
|
+
// Emit StepAwaitingApproval event
|
|
832
|
+
await this.publishEvent(WorkflowEvents.StepAwaitingApproval, {
|
|
833
|
+
executionId: execution.executionId,
|
|
834
|
+
workflowId: execution.workflowId,
|
|
835
|
+
stepId: step.id,
|
|
836
|
+
stepName: step.name,
|
|
837
|
+
domain: step.domain,
|
|
838
|
+
message,
|
|
839
|
+
autoApproveAfter: autoApproveAfter > 0 ? autoApproveAfter : undefined,
|
|
840
|
+
}, execution.context.metadata.correlationId);
|
|
841
|
+
const key = `${execution.executionId}:${step.id}`;
|
|
842
|
+
return new Promise((resolve) => {
|
|
843
|
+
// Store the gate so approveStep/rejectStep can resolve it
|
|
844
|
+
const gate = { resolve };
|
|
845
|
+
this.approvalGates.set(key, gate);
|
|
846
|
+
// Auto-approve timer (0 = never auto-approve)
|
|
847
|
+
if (autoApproveAfter > 0) {
|
|
848
|
+
const timer = setTimeout(() => {
|
|
849
|
+
if (this.approvalGates.has(key)) {
|
|
850
|
+
this.approvalGates.delete(key);
|
|
851
|
+
resolve({ approved: true }); // auto-approve on timeout
|
|
852
|
+
}
|
|
853
|
+
}, autoApproveAfter);
|
|
854
|
+
// Wrap resolve to also clear the timer
|
|
855
|
+
const originalResolve = gate.resolve;
|
|
856
|
+
gate.resolve = (result) => {
|
|
857
|
+
clearTimeout(timer);
|
|
858
|
+
originalResolve(result);
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
// ============================================================================
|
|
754
864
|
// Private Methods - Utilities
|
|
755
865
|
// ============================================================================
|
|
756
866
|
delay(ms) {
|
|
@@ -12,7 +12,7 @@ export type StepExecutionMode = 'sequential' | 'parallel';
|
|
|
12
12
|
/**
|
|
13
13
|
* Step status
|
|
14
14
|
*/
|
|
15
|
-
export type StepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped';
|
|
15
|
+
export type StepStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped' | 'awaiting_approval';
|
|
16
16
|
/**
|
|
17
17
|
* Workflow status
|
|
18
18
|
*/
|
|
@@ -70,6 +70,13 @@ export interface WorkflowStepDefinition {
|
|
|
70
70
|
};
|
|
71
71
|
/** Continue workflow on failure */
|
|
72
72
|
continueOnFailure?: boolean;
|
|
73
|
+
/** Approval gate configuration */
|
|
74
|
+
approval?: boolean | {
|
|
75
|
+
/** Auto-approve after this many ms (0 = never auto-approve) */
|
|
76
|
+
autoApproveAfter?: number;
|
|
77
|
+
/** Approval prompt message */
|
|
78
|
+
message?: string;
|
|
79
|
+
};
|
|
73
80
|
}
|
|
74
81
|
/**
|
|
75
82
|
* Workflow definition
|
|
@@ -178,6 +185,9 @@ export declare const WorkflowEvents: {
|
|
|
178
185
|
readonly StepCompleted: "workflow.StepCompleted";
|
|
179
186
|
readonly StepFailed: "workflow.StepFailed";
|
|
180
187
|
readonly StepSkipped: "workflow.StepSkipped";
|
|
188
|
+
readonly StepAwaitingApproval: "workflow.StepAwaitingApproval";
|
|
189
|
+
readonly StepApproved: "workflow.StepApproved";
|
|
190
|
+
readonly StepRejected: "workflow.StepRejected";
|
|
181
191
|
};
|
|
182
192
|
export interface WorkflowStartedPayload {
|
|
183
193
|
executionId: string;
|
|
@@ -207,6 +217,10 @@ export interface StepEventPayload {
|
|
|
207
217
|
stepName: string;
|
|
208
218
|
domain: DomainName;
|
|
209
219
|
}
|
|
220
|
+
export interface StepAwaitingApprovalPayload extends StepEventPayload {
|
|
221
|
+
message?: string;
|
|
222
|
+
autoApproveAfter?: number;
|
|
223
|
+
}
|
|
210
224
|
export interface IWorkflowOrchestrator {
|
|
211
225
|
/** Initialize the orchestrator */
|
|
212
226
|
initialize(): Promise<void>;
|
|
@@ -232,6 +246,10 @@ export interface IWorkflowOrchestrator {
|
|
|
232
246
|
getActiveExecutions(): WorkflowExecutionStatus[];
|
|
233
247
|
/** Get workflow definition */
|
|
234
248
|
getWorkflow(workflowId: string): WorkflowDefinition | undefined;
|
|
249
|
+
/** Approve a step that is awaiting approval */
|
|
250
|
+
approveStep(executionId: string, stepId: string): boolean;
|
|
251
|
+
/** Reject a step that is awaiting approval */
|
|
252
|
+
rejectStep(executionId: string, stepId: string, reason?: string): boolean;
|
|
235
253
|
}
|
|
236
254
|
export type DomainAction = (input: Record<string, unknown>, context: WorkflowContext) => Promise<Result<unknown, Error>>;
|
|
237
255
|
export interface DomainActionRegistry {
|
|
@@ -16,6 +16,9 @@ export const WorkflowEvents = {
|
|
|
16
16
|
StepCompleted: 'workflow.StepCompleted',
|
|
17
17
|
StepFailed: 'workflow.StepFailed',
|
|
18
18
|
StepSkipped: 'workflow.StepSkipped',
|
|
19
|
+
StepAwaitingApproval: 'workflow.StepAwaitingApproval',
|
|
20
|
+
StepApproved: 'workflow.StepApproved',
|
|
21
|
+
StepRejected: 'workflow.StepRejected',
|
|
19
22
|
};
|
|
20
23
|
export const DEFAULT_WORKFLOW_CONFIG = {
|
|
21
24
|
maxConcurrentWorkflows: 10,
|
|
@@ -22,6 +22,7 @@ export declare class YamlPipelineLoader {
|
|
|
22
22
|
private validateTriggers;
|
|
23
23
|
private validateRetry;
|
|
24
24
|
private validateRollback;
|
|
25
|
+
private validateApproval;
|
|
25
26
|
/** Validate that a value is Record<string, string>, undefined, or return an Error. */
|
|
26
27
|
private validateStringRecord;
|
|
27
28
|
/** Resolve a dot-path variable (e.g. "foo.bar") from a variables map. */
|
|
@@ -211,6 +211,14 @@ export class YamlPipelineLoader {
|
|
|
211
211
|
const continueOnFailure = typeof s.continueOnFailure === 'boolean'
|
|
212
212
|
? s.continueOnFailure
|
|
213
213
|
: undefined;
|
|
214
|
+
// Validate approval gate configuration
|
|
215
|
+
let approval;
|
|
216
|
+
if (s.approval !== undefined) {
|
|
217
|
+
const approvalResult = this.validateApproval(s.approval, s.id);
|
|
218
|
+
if (!approvalResult.success)
|
|
219
|
+
return approvalResult;
|
|
220
|
+
approval = approvalResult.value;
|
|
221
|
+
}
|
|
214
222
|
const step = {
|
|
215
223
|
id: s.id,
|
|
216
224
|
name: s.name,
|
|
@@ -225,6 +233,7 @@ export class YamlPipelineLoader {
|
|
|
225
233
|
...(retry !== undefined && { retry }),
|
|
226
234
|
...(rollback !== undefined && { rollback }),
|
|
227
235
|
...(continueOnFailure !== undefined && { continueOnFailure }),
|
|
236
|
+
...(approval !== undefined && { approval }),
|
|
228
237
|
};
|
|
229
238
|
steps.push(step);
|
|
230
239
|
}
|
|
@@ -325,6 +334,31 @@ export class YamlPipelineLoader {
|
|
|
325
334
|
...(r.input !== undefined && typeof r.input === 'object' && { input: r.input }),
|
|
326
335
|
});
|
|
327
336
|
}
|
|
337
|
+
validateApproval(raw, stepId) {
|
|
338
|
+
// Simple boolean form: approval: true
|
|
339
|
+
if (typeof raw === 'boolean') {
|
|
340
|
+
return ok(raw);
|
|
341
|
+
}
|
|
342
|
+
// Object form: approval: { autoApproveAfter, message }
|
|
343
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
344
|
+
return err(new Error(`Step '${stepId}': 'approval' must be a boolean or object`));
|
|
345
|
+
}
|
|
346
|
+
const a = raw;
|
|
347
|
+
const result = {};
|
|
348
|
+
if (a.autoApproveAfter !== undefined) {
|
|
349
|
+
if (typeof a.autoApproveAfter !== 'number' || a.autoApproveAfter < 0) {
|
|
350
|
+
return err(new Error(`Step '${stepId}': approval.autoApproveAfter must be a non-negative number`));
|
|
351
|
+
}
|
|
352
|
+
result.autoApproveAfter = a.autoApproveAfter;
|
|
353
|
+
}
|
|
354
|
+
if (a.message !== undefined) {
|
|
355
|
+
if (typeof a.message !== 'string') {
|
|
356
|
+
return err(new Error(`Step '${stepId}': approval.message must be a string`));
|
|
357
|
+
}
|
|
358
|
+
result.message = a.message;
|
|
359
|
+
}
|
|
360
|
+
return ok(result);
|
|
361
|
+
}
|
|
328
362
|
/** Validate that a value is Record<string, string>, undefined, or return an Error. */
|
|
329
363
|
validateStringRecord(value, label) {
|
|
330
364
|
if (value === undefined || value === null)
|
|
@@ -12,6 +12,13 @@ export declare function initializeGNNIndex(domainKey: string): QEGNNEmbeddingInd
|
|
|
12
12
|
* Index code embeddings in GNN for fast similarity search
|
|
13
13
|
*/
|
|
14
14
|
export declare function indexCodeEmbeddings(gnnIndex: QEGNNEmbeddingIndex, fileReader: FileReader, paths: string[]): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* R4: Generate graph-aware embeddings for a set of files using GraphMAE.
|
|
17
|
+
* Builds a dependency graph from import relationships and uses masked
|
|
18
|
+
* autoencoders to produce structure-aware embeddings.
|
|
19
|
+
* Falls back to feature-hash embeddings when GraphMAE is disabled.
|
|
20
|
+
*/
|
|
21
|
+
export declare function generateGraphMAEEmbeddings(fileReader: FileReader, paths: string[]): Promise<Map<string, number[]>>;
|
|
15
22
|
/**
|
|
16
23
|
* Generate code embedding using semantic features
|
|
17
24
|
*/
|
|
@@ -34,6 +41,20 @@ export declare function mergeSearchResults(semanticResults: SearchResult[], gnnR
|
|
|
34
41
|
file: string;
|
|
35
42
|
similarity: number;
|
|
36
43
|
}>): SearchResult[];
|
|
44
|
+
/**
|
|
45
|
+
* R6: Train GNN embeddings with memory-bounded cold-tier training.
|
|
46
|
+
* Uses LRU hotset caching when the graph exceeds hotsetSize, falling
|
|
47
|
+
* back to full in-memory training for small graphs.
|
|
48
|
+
*/
|
|
49
|
+
export declare function trainWithColdTier(nodeFeatures: Map<number, Float32Array>, adjacency: Map<number, number[]>, options?: {
|
|
50
|
+
hotsetSize?: number;
|
|
51
|
+
epochs?: number;
|
|
52
|
+
hiddenDim?: number;
|
|
53
|
+
}): {
|
|
54
|
+
embeddings: Map<number, Float32Array>;
|
|
55
|
+
loss: number;
|
|
56
|
+
usedColdTier: boolean;
|
|
57
|
+
};
|
|
37
58
|
/**
|
|
38
59
|
* Simple hash function for strings
|
|
39
60
|
*/
|