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.
Files changed (119) hide show
  1. package/.claude/skills/skills-manifest.json +1 -1
  2. package/CHANGELOG.md +40 -0
  3. package/dist/cli/bundle.js +1345 -1003
  4. package/dist/cli/command-registry.js +5 -1
  5. package/dist/cli/commands/pipeline.d.ts +16 -0
  6. package/dist/cli/commands/pipeline.js +314 -0
  7. package/dist/cli/commands/ruvector-commands.js +17 -0
  8. package/dist/cli/commands/token-usage.js +24 -1
  9. package/dist/cli/handlers/heartbeat-handler.d.ts +26 -0
  10. package/dist/cli/handlers/heartbeat-handler.js +382 -0
  11. package/dist/cli/handlers/index.d.ts +2 -0
  12. package/dist/cli/handlers/index.js +2 -0
  13. package/dist/cli/handlers/routing-handler.d.ts +22 -0
  14. package/dist/cli/handlers/routing-handler.js +227 -0
  15. package/dist/cli/index.js +2 -0
  16. package/dist/coordination/deterministic-actions.d.ts +36 -0
  17. package/dist/coordination/deterministic-actions.js +257 -0
  18. package/dist/coordination/workflow-orchestrator.d.ts +18 -1
  19. package/dist/coordination/workflow-orchestrator.js +113 -3
  20. package/dist/coordination/workflow-types.d.ts +19 -1
  21. package/dist/coordination/workflow-types.js +3 -0
  22. package/dist/coordination/yaml-pipeline-loader.d.ts +1 -0
  23. package/dist/coordination/yaml-pipeline-loader.js +34 -0
  24. package/dist/domains/code-intelligence/coordinator-gnn.d.ts +21 -0
  25. package/dist/domains/code-intelligence/coordinator-gnn.js +102 -0
  26. package/dist/domains/contract-testing/coordinator.js +13 -0
  27. package/dist/domains/coverage-analysis/coordinator.js +5 -0
  28. package/dist/domains/defect-intelligence/coordinator.d.ts +1 -0
  29. package/dist/domains/defect-intelligence/coordinator.js +43 -0
  30. package/dist/domains/quality-assessment/coordinator.js +26 -0
  31. package/dist/domains/test-generation/coordinator.js +14 -0
  32. package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts +11 -0
  33. package/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js +44 -1
  34. package/dist/integrations/rl-suite/algorithms/eprop.d.ts +79 -0
  35. package/dist/integrations/rl-suite/algorithms/eprop.js +284 -0
  36. package/dist/integrations/rl-suite/algorithms/index.d.ts +2 -1
  37. package/dist/integrations/rl-suite/algorithms/index.js +2 -1
  38. package/dist/integrations/rl-suite/index.d.ts +2 -2
  39. package/dist/integrations/rl-suite/index.js +2 -2
  40. package/dist/integrations/rl-suite/interfaces.d.ts +3 -3
  41. package/dist/integrations/rl-suite/interfaces.js +1 -1
  42. package/dist/integrations/rl-suite/orchestrator.d.ts +2 -2
  43. package/dist/integrations/rl-suite/orchestrator.js +3 -2
  44. package/dist/integrations/rl-suite/reward-signals.d.ts +1 -1
  45. package/dist/integrations/rl-suite/reward-signals.js +1 -1
  46. package/dist/integrations/ruvector/coherence-gate-cohomology.d.ts +41 -0
  47. package/dist/integrations/ruvector/coherence-gate-cohomology.js +47 -0
  48. package/dist/integrations/ruvector/coherence-gate-core.d.ts +200 -0
  49. package/dist/integrations/ruvector/coherence-gate-core.js +294 -0
  50. package/dist/integrations/ruvector/coherence-gate-energy.d.ts +136 -0
  51. package/dist/integrations/ruvector/coherence-gate-energy.js +373 -0
  52. package/dist/integrations/ruvector/coherence-gate-vector.d.ts +38 -0
  53. package/dist/integrations/ruvector/coherence-gate-vector.js +76 -0
  54. package/dist/integrations/ruvector/coherence-gate.d.ts +10 -311
  55. package/dist/integrations/ruvector/coherence-gate.js +10 -652
  56. package/dist/integrations/ruvector/cold-tier-trainer.d.ts +103 -0
  57. package/dist/integrations/ruvector/cold-tier-trainer.js +377 -0
  58. package/dist/integrations/ruvector/cusum-detector.d.ts +70 -0
  59. package/dist/integrations/ruvector/cusum-detector.js +142 -0
  60. package/dist/integrations/ruvector/delta-tracker.d.ts +122 -0
  61. package/dist/integrations/ruvector/delta-tracker.js +311 -0
  62. package/dist/integrations/ruvector/domain-transfer.d.ts +79 -1
  63. package/dist/integrations/ruvector/domain-transfer.js +158 -2
  64. package/dist/integrations/ruvector/eprop-learner.d.ts +135 -0
  65. package/dist/integrations/ruvector/eprop-learner.js +351 -0
  66. package/dist/integrations/ruvector/feature-flags.d.ts +177 -0
  67. package/dist/integrations/ruvector/feature-flags.js +145 -0
  68. package/dist/integrations/ruvector/graphmae-encoder.d.ts +88 -0
  69. package/dist/integrations/ruvector/graphmae-encoder.js +360 -0
  70. package/dist/integrations/ruvector/hdc-fingerprint.d.ts +127 -0
  71. package/dist/integrations/ruvector/hdc-fingerprint.js +222 -0
  72. package/dist/integrations/ruvector/hopfield-memory.d.ts +97 -0
  73. package/dist/integrations/ruvector/hopfield-memory.js +238 -0
  74. package/dist/integrations/ruvector/index.d.ts +13 -2
  75. package/dist/integrations/ruvector/index.js +46 -2
  76. package/dist/integrations/ruvector/mincut-wrapper.d.ts +7 -0
  77. package/dist/integrations/ruvector/mincut-wrapper.js +54 -2
  78. package/dist/integrations/ruvector/reservoir-replay.d.ts +172 -0
  79. package/dist/integrations/ruvector/reservoir-replay.js +335 -0
  80. package/dist/integrations/ruvector/solver-adapter.d.ts +93 -0
  81. package/dist/integrations/ruvector/solver-adapter.js +299 -0
  82. package/dist/integrations/ruvector/sona-persistence.d.ts +33 -0
  83. package/dist/integrations/ruvector/sona-persistence.js +47 -0
  84. package/dist/integrations/ruvector/spectral-sparsifier.d.ts +154 -0
  85. package/dist/integrations/ruvector/spectral-sparsifier.js +389 -0
  86. package/dist/integrations/ruvector/temporal-causality.d.ts +63 -0
  87. package/dist/integrations/ruvector/temporal-causality.js +317 -0
  88. package/dist/learning/pattern-promotion.d.ts +63 -0
  89. package/dist/learning/pattern-promotion.js +235 -1
  90. package/dist/learning/pattern-store.d.ts +2 -0
  91. package/dist/learning/pattern-store.js +187 -1
  92. package/dist/learning/sqlite-persistence.d.ts +2 -0
  93. package/dist/learning/sqlite-persistence.js +4 -0
  94. package/dist/mcp/bundle.js +477 -380
  95. package/dist/mcp/handlers/heartbeat-handlers.d.ts +67 -0
  96. package/dist/mcp/handlers/heartbeat-handlers.js +180 -0
  97. package/dist/mcp/handlers/index.d.ts +2 -1
  98. package/dist/mcp/handlers/index.js +5 -1
  99. package/dist/mcp/handlers/task-handlers.d.ts +28 -0
  100. package/dist/mcp/handlers/task-handlers.js +39 -0
  101. package/dist/mcp/protocol-server.js +45 -1
  102. package/dist/mcp/server.js +41 -1
  103. package/dist/optimization/index.d.ts +2 -0
  104. package/dist/optimization/index.js +1 -0
  105. package/dist/optimization/session-cache.d.ts +80 -0
  106. package/dist/optimization/session-cache.js +227 -0
  107. package/dist/optimization/token-optimizer-service.d.ts +10 -0
  108. package/dist/optimization/token-optimizer-service.js +51 -0
  109. package/dist/routing/economic-routing.d.ts +126 -0
  110. package/dist/routing/economic-routing.js +290 -0
  111. package/dist/routing/index.d.ts +2 -0
  112. package/dist/routing/index.js +2 -0
  113. package/dist/routing/routing-feedback.d.ts +29 -0
  114. package/dist/routing/routing-feedback.js +75 -0
  115. package/dist/shared/utils/index.d.ts +1 -0
  116. package/dist/shared/utils/index.js +1 -0
  117. package/dist/shared/utils/xorshift128.d.ts +24 -0
  118. package/dist/shared/utils/xorshift128.js +50 -0
  119. package/package.json +1 -1
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Heartbeat MCP Handlers (Imp-10)
3
+ *
4
+ * Exposes the token-free heartbeat scheduler through MCP tools:
5
+ * - heartbeat_status: Returns current heartbeat health and metrics
6
+ * - heartbeat_trigger: Triggers an immediate heartbeat cycle
7
+ * - heartbeat_log: Returns daily log entries for a given date
8
+ */
9
+ import type { ToolResult } from '../types.js';
10
+ export type HeartbeatStatusParams = Record<string, never>;
11
+ export interface HeartbeatStatusResult {
12
+ status: string;
13
+ healthScore: number;
14
+ totalExecutions: number;
15
+ successfulExecutions: number;
16
+ failedExecutions: number;
17
+ avgDurationMs: number;
18
+ lastRunAt: string | null;
19
+ nextRunAt: string | null;
20
+ lastResult: {
21
+ success: boolean;
22
+ durationMs: number;
23
+ healthScore: number;
24
+ trend: string;
25
+ domainMetrics: Record<string, number | string>;
26
+ } | null;
27
+ }
28
+ export interface HeartbeatTriggerParams {
29
+ /** Optional: timeout in milliseconds (default: 60000) */
30
+ timeout?: number;
31
+ }
32
+ export interface HeartbeatTriggerResult {
33
+ success: boolean;
34
+ durationMs: number;
35
+ healthScore: number;
36
+ trend: string;
37
+ promoted: number;
38
+ deprecated: number;
39
+ decayed: number;
40
+ pendingExperiences: number;
41
+ avgConfidence: number;
42
+ findingsCount: number;
43
+ recommendationsCount: number;
44
+ }
45
+ export interface HeartbeatLogParams {
46
+ /** Date in YYYY-MM-DD format (defaults to today) */
47
+ date?: string;
48
+ }
49
+ export interface HeartbeatLogResult {
50
+ date: string;
51
+ exists: boolean;
52
+ content: string;
53
+ lineCount: number;
54
+ }
55
+ /**
56
+ * Get the current heartbeat scheduler status and health metrics.
57
+ */
58
+ export declare function handleHeartbeatStatus(_params: HeartbeatStatusParams): Promise<ToolResult<HeartbeatStatusResult>>;
59
+ /**
60
+ * Trigger an immediate heartbeat cycle and return the result.
61
+ */
62
+ export declare function handleHeartbeatTrigger(params: HeartbeatTriggerParams): Promise<ToolResult<HeartbeatTriggerResult>>;
63
+ /**
64
+ * Read the daily log for a given date (defaults to today).
65
+ */
66
+ export declare function handleHeartbeatLog(params: HeartbeatLogParams): Promise<ToolResult<HeartbeatLogResult>>;
67
+ //# sourceMappingURL=heartbeat-handlers.d.ts.map
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Heartbeat MCP Handlers (Imp-10)
3
+ *
4
+ * Exposes the token-free heartbeat scheduler through MCP tools:
5
+ * - heartbeat_status: Returns current heartbeat health and metrics
6
+ * - heartbeat_trigger: Triggers an immediate heartbeat cycle
7
+ * - heartbeat_log: Returns daily log entries for a given date
8
+ */
9
+ import * as fs from 'fs';
10
+ import * as path from 'path';
11
+ import { HeartbeatSchedulerWorker } from '../../workers/workers/heartbeat-scheduler.js';
12
+ import { toErrorMessage } from '../../shared/error-utils.js';
13
+ import { findProjectRoot } from '../../kernel/unified-memory.js';
14
+ // ============================================================================
15
+ // Shared State
16
+ // ============================================================================
17
+ let sharedWorker = null;
18
+ function getWorker() {
19
+ if (!sharedWorker) {
20
+ sharedWorker = new HeartbeatSchedulerWorker();
21
+ }
22
+ return sharedWorker;
23
+ }
24
+ // ============================================================================
25
+ // Handlers
26
+ // ============================================================================
27
+ /**
28
+ * Get the current heartbeat scheduler status and health metrics.
29
+ */
30
+ export async function handleHeartbeatStatus(_params) {
31
+ try {
32
+ const worker = getWorker();
33
+ await worker.initialize();
34
+ const health = worker.getHealth();
35
+ const lastResult = worker.lastResult;
36
+ return {
37
+ success: true,
38
+ data: {
39
+ status: health.status,
40
+ healthScore: health.healthScore,
41
+ totalExecutions: health.totalExecutions,
42
+ successfulExecutions: health.successfulExecutions,
43
+ failedExecutions: health.failedExecutions,
44
+ avgDurationMs: health.avgDurationMs,
45
+ lastRunAt: worker.lastRunAt?.toISOString() ?? null,
46
+ nextRunAt: worker.nextRunAt?.toISOString() ?? null,
47
+ lastResult: lastResult
48
+ ? {
49
+ success: lastResult.success,
50
+ durationMs: lastResult.durationMs,
51
+ healthScore: lastResult.metrics.healthScore,
52
+ trend: lastResult.metrics.trend,
53
+ domainMetrics: lastResult.metrics.domainMetrics,
54
+ }
55
+ : null,
56
+ },
57
+ };
58
+ }
59
+ catch (error) {
60
+ return {
61
+ success: false,
62
+ error: `Failed to get heartbeat status: ${toErrorMessage(error)}`,
63
+ };
64
+ }
65
+ }
66
+ /**
67
+ * Trigger an immediate heartbeat cycle and return the result.
68
+ */
69
+ export async function handleHeartbeatTrigger(params) {
70
+ try {
71
+ const worker = getWorker();
72
+ await worker.initialize();
73
+ const abortController = new AbortController();
74
+ // The worker already enforces its own 60s timeout via BaseWorker.executeWithTimeout().
75
+ // Only add an external abort if the caller explicitly requests a *shorter* timeout.
76
+ const userTimeout = params.timeout && params.timeout > 0 ? params.timeout : null;
77
+ const timeoutHandle = userTimeout
78
+ ? setTimeout(() => abortController.abort(), userTimeout)
79
+ : null;
80
+ let result;
81
+ try {
82
+ result = await worker.execute({
83
+ eventBus: { publish: async () => { } },
84
+ memory: {
85
+ get: async () => undefined,
86
+ set: async () => { },
87
+ search: async () => [],
88
+ },
89
+ logger: {
90
+ debug: () => { },
91
+ info: () => { },
92
+ warn: () => { },
93
+ error: () => { },
94
+ },
95
+ domains: {
96
+ getDomainAPI: () => undefined,
97
+ getDomainHealth: () => ({ status: 'healthy', errors: [] }),
98
+ },
99
+ signal: abortController.signal,
100
+ });
101
+ }
102
+ finally {
103
+ if (timeoutHandle)
104
+ clearTimeout(timeoutHandle);
105
+ }
106
+ const dm = result.metrics.domainMetrics;
107
+ return {
108
+ success: true,
109
+ data: {
110
+ success: result.success,
111
+ durationMs: result.durationMs,
112
+ healthScore: result.metrics.healthScore,
113
+ trend: result.metrics.trend,
114
+ promoted: Number(dm.promoted ?? 0),
115
+ deprecated: Number(dm.deprecated ?? 0),
116
+ decayed: Number(dm.decayed ?? 0),
117
+ pendingExperiences: Number(dm.pendingExperiences ?? 0),
118
+ avgConfidence: Number(dm.avgConfidence ?? 0),
119
+ findingsCount: result.findings.length,
120
+ recommendationsCount: result.recommendations.length,
121
+ },
122
+ };
123
+ }
124
+ catch (error) {
125
+ const msg = toErrorMessage(error);
126
+ const isTimeout = msg.includes('aborted') || msg.includes('abort') || msg.includes('timed out');
127
+ return {
128
+ success: false,
129
+ error: isTimeout
130
+ ? `Heartbeat timed out after ${params.timeout ?? 60000}ms`
131
+ : `Failed to trigger heartbeat: ${msg}`,
132
+ };
133
+ }
134
+ }
135
+ /**
136
+ * Read the daily log for a given date (defaults to today).
137
+ */
138
+ export async function handleHeartbeatLog(params) {
139
+ try {
140
+ const targetDate = params.date || new Date().toISOString().split('T')[0];
141
+ // Validate date format
142
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(targetDate)) {
143
+ return {
144
+ success: false,
145
+ error: "Invalid date format. Use YYYY-MM-DD (e.g., '2026-03-27').",
146
+ };
147
+ }
148
+ const logDir = path.join(findProjectRoot(), '.agentic-qe', 'logs');
149
+ const logPath = path.join(logDir, `${targetDate}.md`);
150
+ if (!fs.existsSync(logPath)) {
151
+ return {
152
+ success: true,
153
+ data: {
154
+ date: targetDate,
155
+ exists: false,
156
+ content: '',
157
+ lineCount: 0,
158
+ },
159
+ };
160
+ }
161
+ const content = fs.readFileSync(logPath, 'utf-8');
162
+ const lineCount = content.split('\n').filter((l) => l.trim()).length;
163
+ return {
164
+ success: true,
165
+ data: {
166
+ date: targetDate,
167
+ exists: true,
168
+ content,
169
+ lineCount,
170
+ },
171
+ };
172
+ }
173
+ catch (error) {
174
+ return {
175
+ success: false,
176
+ error: `Failed to read heartbeat log: ${toErrorMessage(error)}`,
177
+ };
178
+ }
179
+ }
180
+ //# sourceMappingURL=heartbeat-handlers.js.map
@@ -3,7 +3,7 @@
3
3
  * Exports all MCP tool handlers
4
4
  */
5
5
  export { handleFleetInit, handleFleetStatus, handleFleetHealth, handleAQEHealth, getFleetState, isFleetInitialized, disposeFleet, } from './core-handlers';
6
- export { handleTaskSubmit, handleTaskList, handleTaskStatus, handleTaskCancel, handleTaskOrchestrate, handleModelRoute, handleRoutingMetrics, type TaskOrchestrateResult, type ModelRouteParams, type ModelRouteResult, type RoutingMetricsParams, type RoutingMetricsResult, } from './task-handlers';
6
+ export { handleTaskSubmit, handleTaskList, handleTaskStatus, handleTaskCancel, handleTaskOrchestrate, handleModelRoute, handleRoutingMetrics, handleRoutingEconomics, type TaskOrchestrateResult, type ModelRouteParams, type ModelRouteResult, type RoutingMetricsParams, type RoutingMetricsResult, } from './task-handlers';
7
7
  export { handleAgentList, handleAgentSpawn, handleAgentMetrics, handleAgentStatus, } from './agent-handlers';
8
8
  export { handleTestGenerate, handleTestExecute, handleCoverageAnalyze, handleQualityAssess, handleSecurityScan, handleContractValidate, handleAccessibilityTest, handleChaosTest, handleDefectPredict, handleRequirementsValidate, handleCodeIndex, resetTaskExecutor, } from './wrapped-domain-handlers.js';
9
9
  export { handleInfraHealingStatus, handleInfraHealingFeedOutput, handleInfraHealingRecover, setInfraHealingOrchestrator, } from './domain-handlers';
@@ -12,5 +12,6 @@ export { handleMemoryStore, handleMemoryRetrieve, handleMemoryQuery, handleMemor
12
12
  export { handlePipelineLoad, handlePipelineRun, handlePipelineList, handlePipelineValidate, getPipelineRegistry, getPipelineLoader, type PipelineLoadParams, type PipelineLoadResult, type PipelineRunParams, type PipelineRunResult, type PipelineListParams, type PipelineListResult, type PipelineValidateParams, type PipelineValidateResult, } from './pipeline-handlers.js';
13
13
  export { handleValidationPipeline, type ValidationPipelineParams, type ValidationPipelineResult, } from './validation-pipeline-handler.js';
14
14
  export { handleHypergraphQuery, type HypergraphQueryParams, type HypergraphQueryResult, } from './hypergraph-handler.js';
15
+ export { handleHeartbeatStatus, handleHeartbeatTrigger, handleHeartbeatLog, type HeartbeatStatusParams, type HeartbeatStatusResult, type HeartbeatTriggerParams, type HeartbeatTriggerResult, type HeartbeatLogParams, type HeartbeatLogResult, } from './heartbeat-handlers.js';
15
16
  export { handleCrossPhaseStore, handleCrossPhaseQuery, handleAgentComplete, handlePhaseStart, handlePhaseEnd, handleCrossPhaseStats, handleFormatSignals, handleCrossPhaseCleanup, resetCrossPhaseHandlers, type StoreSignalParams, type StoreSignalResult, type QuerySignalsParams, type QuerySignalsResult, type AgentCompleteParams, type AgentCompleteResult, type PhaseEventParams, type PhaseStartResult, type PhaseEndResult, type CrossPhaseStatsResult, type FormatSignalsParams, type FormatSignalsResult, } from './cross-phase-handlers';
16
17
  //# sourceMappingURL=index.d.ts.map
@@ -7,7 +7,9 @@ export { handleFleetInit, handleFleetStatus, handleFleetHealth, handleAQEHealth,
7
7
  // Task handlers
8
8
  export { handleTaskSubmit, handleTaskList, handleTaskStatus, handleTaskCancel, handleTaskOrchestrate,
9
9
  // ADR-051: Model routing handlers
10
- handleModelRoute, handleRoutingMetrics, } from './task-handlers';
10
+ handleModelRoute, handleRoutingMetrics,
11
+ // Imp-18: Economic routing handler
12
+ handleRoutingEconomics, } from './task-handlers';
11
13
  // Agent handlers
12
14
  export { handleAgentList, handleAgentSpawn, handleAgentMetrics, handleAgentStatus, } from './agent-handlers';
13
15
  // Domain handlers (wrapped with experience capture - ADR-051)
@@ -24,6 +26,8 @@ export { handlePipelineLoad, handlePipelineRun, handlePipelineList, handlePipeli
24
26
  export { handleValidationPipeline, } from './validation-pipeline-handler.js';
25
27
  // Hypergraph query handler
26
28
  export { handleHypergraphQuery, } from './hypergraph-handler.js';
29
+ // Heartbeat handlers (Imp-10: Token-Free Heartbeat Scheduler)
30
+ export { handleHeartbeatStatus, handleHeartbeatTrigger, handleHeartbeatLog, } from './heartbeat-handlers.js';
27
31
  // Cross-phase handlers
28
32
  export { handleCrossPhaseStore, handleCrossPhaseQuery, handleAgentComplete, handlePhaseStart, handlePhaseEnd, handleCrossPhaseStats, handleFormatSignals, handleCrossPhaseCleanup, resetCrossPhaseHandlers, } from './cross-phase-handlers';
29
33
  //# sourceMappingURL=index.js.map
@@ -126,6 +126,34 @@ export interface RoutingMetricsResult {
126
126
  * Handle routing metrics query
127
127
  */
128
128
  export declare function handleRoutingMetrics(params: RoutingMetricsParams): Promise<ToolResult<RoutingMetricsResult>>;
129
+ export interface RoutingEconomicsParams {
130
+ /** Task complexity score 0-1 for tier scoring (default: 0.5) */
131
+ taskComplexity?: number;
132
+ }
133
+ export interface RoutingEconomicsResult {
134
+ tierEfficiency: Array<{
135
+ tier: string;
136
+ qualityScore: number;
137
+ estimatedCostUsd: number;
138
+ qualityPerDollar: number | string;
139
+ economicScore: number;
140
+ }>;
141
+ currentHourlyCostUsd: number;
142
+ currentDailyCostUsd: number;
143
+ budgetRemaining: {
144
+ hourly: number | null;
145
+ daily: number | null;
146
+ };
147
+ recommendation: string;
148
+ savingsOpportunity: {
149
+ usd: number;
150
+ description: string;
151
+ } | null;
152
+ }
153
+ /**
154
+ * Handle economic routing report query
155
+ */
156
+ export declare function handleRoutingEconomics(params: RoutingEconomicsParams): Promise<ToolResult<RoutingEconomicsResult>>;
129
157
  export interface TaskOutcomeRecordParams {
130
158
  /** Task ID */
131
159
  taskId: string;
@@ -466,6 +466,45 @@ export async function handleRoutingMetrics(params) {
466
466
  };
467
467
  }
468
468
  }
469
+ /**
470
+ * Handle economic routing report query
471
+ */
472
+ export async function handleRoutingEconomics(params) {
473
+ try {
474
+ const { createRoutingFeedbackCollector } = await import('../../routing/routing-feedback.js');
475
+ const { getGlobalCostTracker } = await import('../../shared/llm/cost-tracker.js');
476
+ // Create collector, initialize to load persisted state from DB, then enable economic routing
477
+ const collector = createRoutingFeedbackCollector(100);
478
+ await collector.initialize();
479
+ collector.enableEconomicRouting({ ...(params.taskComplexity != null ? {} : {}) }, getGlobalCostTracker());
480
+ const report = collector.getEconomicReport();
481
+ if (!report) {
482
+ return { success: false, error: 'Economic routing is not available' };
483
+ }
484
+ // Convert Infinity to string for JSON serialization
485
+ const tierEfficiency = report.tierEfficiency.map(t => ({
486
+ ...t,
487
+ qualityPerDollar: isFinite(t.qualityPerDollar) ? t.qualityPerDollar : 'Infinity',
488
+ }));
489
+ return {
490
+ success: true,
491
+ data: {
492
+ tierEfficiency,
493
+ currentHourlyCostUsd: report.currentHourlyCostUsd,
494
+ currentDailyCostUsd: report.currentDailyCostUsd,
495
+ budgetRemaining: report.budgetRemaining,
496
+ recommendation: report.recommendation,
497
+ savingsOpportunity: report.savingsOpportunity,
498
+ },
499
+ };
500
+ }
501
+ catch (error) {
502
+ return {
503
+ success: false,
504
+ error: `Failed to get economic routing report: ${toErrorMessage(error)}`,
505
+ };
506
+ }
507
+ }
469
508
  // ============================================================================
470
509
  // Helper Functions
471
510
  // ============================================================================
@@ -11,7 +11,9 @@ import { createToolRegistry } from './tool-registry';
11
11
  import { createEventAdapter, } from '../adapters/ag-ui/index.js';
12
12
  import { handleFleetInit, handleFleetStatus, handleFleetHealth, handleAQEHealth, disposeFleet, handleTaskSubmit, handleTaskList, handleTaskStatus, handleTaskCancel, handleTaskOrchestrate,
13
13
  // ADR-051: Model routing handlers
14
- handleModelRoute, handleRoutingMetrics, handleAgentList, handleAgentSpawn, handleAgentMetrics, handleAgentStatus, handleTestGenerate, handleTestExecute, handleCoverageAnalyze, handleQualityAssess, handleSecurityScan, handleContractValidate, handleAccessibilityTest, handleChaosTest, handleDefectPredict, handleRequirementsValidate, handleCodeIndex, handleMemoryStore, handleMemoryRetrieve, handleMemoryQuery, handleMemoryDelete, handleMemoryUsage, handleMemoryShare,
14
+ handleModelRoute, handleRoutingMetrics,
15
+ // Imp-18: Economic routing handler
16
+ handleRoutingEconomics, handleAgentList, handleAgentSpawn, handleAgentMetrics, handleAgentStatus, handleTestGenerate, handleTestExecute, handleCoverageAnalyze, handleQualityAssess, handleSecurityScan, handleContractValidate, handleAccessibilityTest, handleChaosTest, handleDefectPredict, handleRequirementsValidate, handleCodeIndex, handleMemoryStore, handleMemoryRetrieve, handleMemoryQuery, handleMemoryDelete, handleMemoryUsage, handleMemoryShare,
15
17
  // ADR-057: Infrastructure self-healing handlers
16
18
  handleInfraHealingStatus, handleInfraHealingFeedOutput, handleInfraHealingRecover,
17
19
  // ADR-064: Team handlers
@@ -809,6 +811,17 @@ export class MCPProtocolServer {
809
811
  },
810
812
  handler: (params) => handleRoutingMetrics(params),
811
813
  });
814
+ this.registerTool({
815
+ definition: {
816
+ name: 'routing_economics',
817
+ description: 'Get economic routing report: tier efficiency, budget status, cost-per-quality analysis, and savings opportunities. Example: routing_economics({ taskComplexity: 0.5 })',
818
+ category: 'routing',
819
+ parameters: [
820
+ { name: 'taskComplexity', type: 'number', description: 'Task complexity score 0-1 for tier scoring (default: 0.5)', default: 0.5 },
821
+ ],
822
+ },
823
+ handler: (params) => handleRoutingEconomics(params),
824
+ });
812
825
  // ADR-057: Infrastructure self-healing tools
813
826
  this.registerTool({
814
827
  definition: {
@@ -1005,6 +1018,37 @@ export class MCPProtocolServer {
1005
1018
  handler: (params) => handlePipelineValidate(params),
1006
1019
  });
1007
1020
  // =========================================================================
1021
+ // Imp-15: Session Cache Stats
1022
+ // =========================================================================
1023
+ this.registerTool({
1024
+ definition: {
1025
+ name: 'session_cache_stats',
1026
+ description: 'Get session operation cache statistics: hit rate, cache size, tokens saved via O(1) fingerprint reuse. Example: session_cache_stats({})',
1027
+ category: 'learning',
1028
+ parameters: [],
1029
+ },
1030
+ handler: async () => {
1031
+ try {
1032
+ const { getSessionCache } = await import('../optimization/session-cache.js');
1033
+ const stats = getSessionCache().getStats();
1034
+ return {
1035
+ success: true,
1036
+ data: {
1037
+ ...stats,
1038
+ hitRatePercent: `${(stats.hitRate * 100).toFixed(1)}%`,
1039
+ description: 'Session cache provides O(1) exact-match lookups before HNSW similarity search',
1040
+ },
1041
+ };
1042
+ }
1043
+ catch (err) {
1044
+ return {
1045
+ success: false,
1046
+ error: `Failed to get session cache stats: ${err instanceof Error ? err.message : String(err)}`,
1047
+ };
1048
+ }
1049
+ },
1050
+ });
1051
+ // =========================================================================
1008
1052
  // OpenCode Integration: Health Endpoint
1009
1053
  // =========================================================================
1010
1054
  this.registerTool({
@@ -21,7 +21,9 @@ handleCrossPhaseStore, handleCrossPhaseQuery, handleAgentComplete, handlePhaseSt
21
21
  // Pipeline handlers (Imp-9: YAML Deterministic Pipelines)
22
22
  handlePipelineLoad, handlePipelineRun, handlePipelineList, handlePipelineValidate,
23
23
  // Validation Pipeline handler (BMAD-003)
24
- handleValidationPipeline, } from './handlers';
24
+ handleValidationPipeline,
25
+ // Heartbeat handlers (Imp-10: Token-Free Heartbeat Scheduler)
26
+ handleHeartbeatStatus, handleHeartbeatTrigger, handleHeartbeatLog, } from './handlers';
25
27
  // ============================================================================
26
28
  // Tool Definitions
27
29
  // ============================================================================
@@ -672,6 +674,43 @@ const PIPELINE_TOOLS = [
672
674
  handler: handlePipelineValidate,
673
675
  },
674
676
  ];
677
+ // Imp-10: Token-Free Heartbeat Scheduler
678
+ const HEARTBEAT_TOOLS = [
679
+ // Heartbeat Status
680
+ {
681
+ definition: {
682
+ name: 'mcp__agentic_qe__heartbeat_status',
683
+ description: 'Get heartbeat scheduler status, health metrics, and last result',
684
+ category: 'core',
685
+ parameters: [],
686
+ },
687
+ handler: handleHeartbeatStatus,
688
+ },
689
+ // Heartbeat Trigger
690
+ {
691
+ definition: {
692
+ name: 'mcp__agentic_qe__heartbeat_trigger',
693
+ description: 'Trigger an immediate heartbeat maintenance cycle (SQL-only, zero tokens)',
694
+ category: 'core',
695
+ parameters: [
696
+ { name: 'timeout', type: 'number', description: 'Timeout in milliseconds (default: 60000)' },
697
+ ],
698
+ },
699
+ handler: handleHeartbeatTrigger,
700
+ },
701
+ // Heartbeat Log
702
+ {
703
+ definition: {
704
+ name: 'mcp__agentic_qe__heartbeat_log',
705
+ description: 'Read the daily heartbeat log for a specific date',
706
+ category: 'core',
707
+ parameters: [
708
+ { name: 'date', type: 'string', description: 'Date in YYYY-MM-DD format (defaults to today)' },
709
+ ],
710
+ },
711
+ handler: handleHeartbeatLog,
712
+ },
713
+ ];
675
714
  // ============================================================================
676
715
  export class MCPServer {
677
716
  registry;
@@ -695,6 +734,7 @@ export class MCPServer {
695
734
  ...MEMORY_TOOLS,
696
735
  ...CROSS_PHASE_TOOLS,
697
736
  ...PIPELINE_TOOLS,
737
+ ...HEARTBEAT_TOOLS,
698
738
  ];
699
739
  this.registry.registerAll(allTools);
700
740
  this.initialized = true;
@@ -17,4 +17,6 @@ export type { EarlyExitConfig as TokenEarlyExitConfig, EarlyExitResult as TokenE
17
17
  export { EarlyExitTokenOptimizer, createEarlyExitTokenOptimizer, createAggressiveTokenOptimizer, createConservativeTokenOptimizer, DEFAULT_EARLY_EXIT_CONFIG, AGGRESSIVE_EARLY_EXIT_CONFIG, CONSERVATIVE_EARLY_EXIT_CONFIG, } from './early-exit-token-optimizer.js';
18
18
  export type { TokenOptimizerServiceConfig, } from './token-optimizer-service.js';
19
19
  export { TokenOptimizerService, initializeTokenOptimizer, } from './token-optimizer-service.js';
20
+ export type { CachedOperation, SessionCacheConfig, SessionCacheStats, } from './session-cache.js';
21
+ export { SessionOperationCache, DEFAULT_SESSION_CACHE_CONFIG, getSessionCache, resetSessionCache, } from './session-cache.js';
20
22
  //# sourceMappingURL=index.d.ts.map
@@ -13,4 +13,5 @@ export { AQEAutoTuner, createAutoTuner, DefaultParameterApplicatorRegistry, crea
13
13
  export { QE_OPTIMIZATION_WORKER_CONFIGS, PatternConsolidatorWorker, DreamConsolidatorWorker, CoverageGapScannerWorker, FlakyTestDetectorWorker, RoutingAccuracyMonitorWorker, createPatternConsolidatorWorker, createDreamConsolidatorWorker, createCoverageGapScannerWorker, createFlakyTestDetectorWorker, createRoutingAccuracyMonitorWorker, } from './qe-workers.js';
14
14
  export { EarlyExitTokenOptimizer, createEarlyExitTokenOptimizer, createAggressiveTokenOptimizer, createConservativeTokenOptimizer, DEFAULT_EARLY_EXIT_CONFIG, AGGRESSIVE_EARLY_EXIT_CONFIG, CONSERVATIVE_EARLY_EXIT_CONFIG, } from './early-exit-token-optimizer.js';
15
15
  export { TokenOptimizerService, initializeTokenOptimizer, } from './token-optimizer-service.js';
16
+ export { SessionOperationCache, DEFAULT_SESSION_CACHE_CONFIG, getSessionCache, resetSessionCache, } from './session-cache.js';
16
17
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Agentic QE v3 - Session Operation Cache
3
+ * Imp-15: Session Reuse for Repeated Operations
4
+ *
5
+ * Lightweight fingerprint-based cache for operation results that provides
6
+ * O(1) exact-match lookups before falling back to HNSW similarity search.
7
+ * Supplements (does not replace) the EarlyExitTokenOptimizer.
8
+ *
9
+ * Architecture:
10
+ * - SHA-256 fingerprint from canonicalized (domain + action + input)
11
+ * - In-memory Map for O(1) lookups
12
+ * - Optional SQLite persistence via kv_store (namespace: 'session_cache')
13
+ * - TTL-based expiry, LRU-ish eviction at capacity
14
+ */
15
+ export interface CachedOperation {
16
+ fingerprint: string;
17
+ domain: string;
18
+ action: string;
19
+ result: Record<string, unknown>;
20
+ tokensSaved: number;
21
+ cachedAt: number;
22
+ hitCount: number;
23
+ lastHitAt: number;
24
+ }
25
+ export interface SessionCacheConfig {
26
+ /** Enable the cache (default: true) */
27
+ enabled: boolean;
28
+ /** Maximum entries in memory (default: 500) */
29
+ maxEntries: number;
30
+ /** TTL in milliseconds (default: 1 hour) */
31
+ ttlMs: number;
32
+ /** Persist across sessions via SQLite kv_store (default: true) */
33
+ persistToDb: boolean;
34
+ }
35
+ export interface SessionCacheStats {
36
+ size: number;
37
+ hits: number;
38
+ misses: number;
39
+ hitRate: number;
40
+ estimatedTokensSaved: number;
41
+ }
42
+ export declare const DEFAULT_SESSION_CACHE_CONFIG: SessionCacheConfig;
43
+ export declare class SessionOperationCache {
44
+ private cache;
45
+ private config;
46
+ private hits;
47
+ private misses;
48
+ constructor(config?: Partial<SessionCacheConfig>);
49
+ /**
50
+ * Compute a deterministic fingerprint from domain + action + input.
51
+ * Uses SHA-256 of the canonicalized JSON (recursively sorted keys), truncated to 16 hex chars.
52
+ */
53
+ computeFingerprint(domain: string, action: string, input: Record<string, unknown>): string;
54
+ /**
55
+ * Look up a cached result by fingerprint.
56
+ * Returns null on miss or expired entry.
57
+ */
58
+ get(fingerprint: string): CachedOperation | null;
59
+ /**
60
+ * Store an operation result in the cache.
61
+ */
62
+ set(fingerprint: string, domain: string, action: string, result: Record<string, unknown>, estimatedTokens: number): void;
63
+ /**
64
+ * Load persisted cache entries from SQLite kv_store.
65
+ * Called on service initialization. Gracefully degrades if DB unavailable.
66
+ */
67
+ loadFromDb(): void;
68
+ /** Get cache statistics */
69
+ getStats(): SessionCacheStats;
70
+ /** Clear all cache entries and reset counters */
71
+ clear(): void;
72
+ /** Evict the oldest entry by cachedAt */
73
+ private evictOldest;
74
+ /** Persist a single entry to kv_store */
75
+ private persistEntry;
76
+ }
77
+ export declare function getSessionCache(config?: Partial<SessionCacheConfig>): SessionOperationCache;
78
+ /** Reset the singleton (for testing) */
79
+ export declare function resetSessionCache(): void;
80
+ //# sourceMappingURL=session-cache.d.ts.map