agentic-qe 2.8.0 → 2.8.2
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/CHANGELOG.md +148 -0
- package/README.md +1 -1
- package/dist/agents/BaseAgent.d.ts +329 -0
- package/dist/agents/BaseAgent.d.ts.map +1 -1
- package/dist/agents/BaseAgent.js +657 -0
- package/dist/agents/BaseAgent.js.map +1 -1
- package/dist/cli/commands/supabase/index.d.ts +20 -0
- package/dist/cli/commands/supabase/index.d.ts.map +1 -0
- package/dist/cli/commands/supabase/index.js +632 -0
- package/dist/cli/commands/supabase/index.js.map +1 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/code-intelligence/embeddings/EmbeddingCacheFactory.d.ts +135 -0
- package/dist/code-intelligence/embeddings/EmbeddingCacheFactory.d.ts.map +1 -0
- package/dist/code-intelligence/embeddings/EmbeddingCacheFactory.js +301 -0
- package/dist/code-intelligence/embeddings/EmbeddingCacheFactory.js.map +1 -0
- package/dist/code-intelligence/embeddings/NomicEmbedder.d.ts +78 -6
- package/dist/code-intelligence/embeddings/NomicEmbedder.d.ts.map +1 -1
- package/dist/code-intelligence/embeddings/NomicEmbedder.js +162 -21
- package/dist/code-intelligence/embeddings/NomicEmbedder.js.map +1 -1
- package/dist/code-intelligence/embeddings/backends/MemoryBackend.d.ts +59 -0
- package/dist/code-intelligence/embeddings/backends/MemoryBackend.d.ts.map +1 -0
- package/dist/code-intelligence/embeddings/backends/MemoryBackend.js +173 -0
- package/dist/code-intelligence/embeddings/backends/MemoryBackend.js.map +1 -0
- package/dist/code-intelligence/embeddings/backends/RedisBackend.d.ts +50 -0
- package/dist/code-intelligence/embeddings/backends/RedisBackend.d.ts.map +1 -0
- package/dist/code-intelligence/embeddings/backends/RedisBackend.js +279 -0
- package/dist/code-intelligence/embeddings/backends/RedisBackend.js.map +1 -0
- package/dist/code-intelligence/embeddings/backends/SQLiteBackend.d.ts +64 -0
- package/dist/code-intelligence/embeddings/backends/SQLiteBackend.d.ts.map +1 -0
- package/dist/code-intelligence/embeddings/backends/SQLiteBackend.js +314 -0
- package/dist/code-intelligence/embeddings/backends/SQLiteBackend.js.map +1 -0
- package/dist/code-intelligence/embeddings/backends/index.d.ts +16 -0
- package/dist/code-intelligence/embeddings/backends/index.d.ts.map +1 -0
- package/dist/code-intelligence/embeddings/backends/index.js +28 -0
- package/dist/code-intelligence/embeddings/backends/index.js.map +1 -0
- package/dist/code-intelligence/embeddings/backends/types.d.ts +177 -0
- package/dist/code-intelligence/embeddings/backends/types.d.ts.map +1 -0
- package/dist/code-intelligence/embeddings/backends/types.js +30 -0
- package/dist/code-intelligence/embeddings/backends/types.js.map +1 -0
- package/dist/code-intelligence/embeddings/index.d.ts +7 -0
- package/dist/code-intelligence/embeddings/index.d.ts.map +1 -1
- package/dist/code-intelligence/embeddings/index.js +16 -1
- package/dist/code-intelligence/embeddings/index.js.map +1 -1
- package/dist/core/memory/HNSWVectorMemory.js +1 -1
- package/dist/infrastructure/index.d.ts +15 -0
- package/dist/infrastructure/index.d.ts.map +1 -0
- package/dist/infrastructure/index.js +44 -0
- package/dist/infrastructure/index.js.map +1 -0
- package/dist/infrastructure/network/AgentRateLimiter.d.ts +59 -0
- package/dist/infrastructure/network/AgentRateLimiter.d.ts.map +1 -0
- package/dist/infrastructure/network/AgentRateLimiter.js +186 -0
- package/dist/infrastructure/network/AgentRateLimiter.js.map +1 -0
- package/dist/infrastructure/network/AuditLogger.d.ts +102 -0
- package/dist/infrastructure/network/AuditLogger.d.ts.map +1 -0
- package/dist/infrastructure/network/AuditLogger.js +284 -0
- package/dist/infrastructure/network/AuditLogger.js.map +1 -0
- package/dist/infrastructure/network/DomainWhitelist.d.ts +111 -0
- package/dist/infrastructure/network/DomainWhitelist.d.ts.map +1 -0
- package/dist/infrastructure/network/DomainWhitelist.js +216 -0
- package/dist/infrastructure/network/DomainWhitelist.js.map +1 -0
- package/dist/infrastructure/network/NetworkPolicyManager.d.ts +97 -0
- package/dist/infrastructure/network/NetworkPolicyManager.d.ts.map +1 -0
- package/dist/infrastructure/network/NetworkPolicyManager.js +309 -0
- package/dist/infrastructure/network/NetworkPolicyManager.js.map +1 -0
- package/dist/infrastructure/network/index.d.ts +19 -0
- package/dist/infrastructure/network/index.d.ts.map +1 -0
- package/dist/infrastructure/network/index.js +46 -0
- package/dist/infrastructure/network/index.js.map +1 -0
- package/dist/infrastructure/network/policies/default-policies.d.ts +78 -0
- package/dist/infrastructure/network/policies/default-policies.d.ts.map +1 -0
- package/dist/infrastructure/network/policies/default-policies.js +312 -0
- package/dist/infrastructure/network/policies/default-policies.js.map +1 -0
- package/dist/infrastructure/network/types.d.ts +214 -0
- package/dist/infrastructure/network/types.d.ts.map +1 -0
- package/dist/infrastructure/network/types.js +25 -0
- package/dist/infrastructure/network/types.js.map +1 -0
- package/dist/infrastructure/sandbox/ResourceMonitor.d.ts +124 -0
- package/dist/infrastructure/sandbox/ResourceMonitor.d.ts.map +1 -0
- package/dist/infrastructure/sandbox/ResourceMonitor.js +305 -0
- package/dist/infrastructure/sandbox/ResourceMonitor.js.map +1 -0
- package/dist/infrastructure/sandbox/SandboxManager.d.ts +122 -0
- package/dist/infrastructure/sandbox/SandboxManager.d.ts.map +1 -0
- package/dist/infrastructure/sandbox/SandboxManager.js +527 -0
- package/dist/infrastructure/sandbox/SandboxManager.js.map +1 -0
- package/dist/infrastructure/sandbox/index.d.ts +18 -0
- package/dist/infrastructure/sandbox/index.d.ts.map +1 -0
- package/dist/infrastructure/sandbox/index.js +38 -0
- package/dist/infrastructure/sandbox/index.js.map +1 -0
- package/dist/infrastructure/sandbox/profiles/agent-profiles.d.ts +53 -0
- package/dist/infrastructure/sandbox/profiles/agent-profiles.d.ts.map +1 -0
- package/dist/infrastructure/sandbox/profiles/agent-profiles.js +433 -0
- package/dist/infrastructure/sandbox/profiles/agent-profiles.js.map +1 -0
- package/dist/infrastructure/sandbox/types.d.ts +227 -0
- package/dist/infrastructure/sandbox/types.d.ts.map +1 -0
- package/dist/infrastructure/sandbox/types.js +63 -0
- package/dist/infrastructure/sandbox/types.js.map +1 -0
- package/dist/mcp/handlers/NewDomainToolsHandler.d.ts +8 -8
- package/dist/mcp/handlers/NewDomainToolsHandler.d.ts.map +1 -1
- package/dist/mcp/handlers/NewDomainToolsHandler.js.map +1 -1
- package/dist/mcp/handlers/ruvector/RuVectorHandler.d.ts +54 -0
- package/dist/mcp/handlers/ruvector/RuVectorHandler.d.ts.map +1 -0
- package/dist/mcp/handlers/ruvector/RuVectorHandler.js +325 -0
- package/dist/mcp/handlers/ruvector/RuVectorHandler.js.map +1 -0
- package/dist/mcp/handlers/ruvector/index.d.ts +5 -0
- package/dist/mcp/handlers/ruvector/index.d.ts.map +1 -0
- package/dist/mcp/handlers/ruvector/index.js +9 -0
- package/dist/mcp/handlers/ruvector/index.js.map +1 -0
- package/dist/mcp/server-instructions.d.ts +1 -1
- package/dist/mcp/server-instructions.js +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +100 -22
- package/dist/mcp/server.js.map +1 -1
- package/dist/nervous-system/adapters/BTSPAdapter.d.ts +342 -0
- package/dist/nervous-system/adapters/BTSPAdapter.d.ts.map +1 -0
- package/dist/nervous-system/adapters/BTSPAdapter.js +494 -0
- package/dist/nervous-system/adapters/BTSPAdapter.js.map +1 -0
- package/dist/nervous-system/adapters/CircadianController.d.ts +560 -0
- package/dist/nervous-system/adapters/CircadianController.d.ts.map +1 -0
- package/dist/nervous-system/adapters/CircadianController.js +882 -0
- package/dist/nervous-system/adapters/CircadianController.js.map +1 -0
- package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.d.ts +337 -0
- package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.d.ts.map +1 -0
- package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.js +532 -0
- package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.js.map +1 -0
- package/dist/nervous-system/adapters/HdcMemoryAdapter.d.ts +444 -0
- package/dist/nervous-system/adapters/HdcMemoryAdapter.d.ts.map +1 -0
- package/dist/nervous-system/adapters/HdcMemoryAdapter.js +715 -0
- package/dist/nervous-system/adapters/HdcMemoryAdapter.js.map +1 -0
- package/dist/nervous-system/adapters/ReflexLayer.d.ts +231 -0
- package/dist/nervous-system/adapters/ReflexLayer.d.ts.map +1 -0
- package/dist/nervous-system/adapters/ReflexLayer.js +309 -0
- package/dist/nervous-system/adapters/ReflexLayer.js.map +1 -0
- package/dist/nervous-system/index.d.ts +25 -0
- package/dist/nervous-system/index.d.ts.map +1 -0
- package/dist/nervous-system/index.js +80 -0
- package/dist/nervous-system/index.js.map +1 -0
- package/dist/nervous-system/integration/BTSPLearningEngine.d.ts +266 -0
- package/dist/nervous-system/integration/BTSPLearningEngine.d.ts.map +1 -0
- package/dist/nervous-system/integration/BTSPLearningEngine.js +587 -0
- package/dist/nervous-system/integration/BTSPLearningEngine.js.map +1 -0
- package/dist/nervous-system/integration/CircadianAgent.d.ts +389 -0
- package/dist/nervous-system/integration/CircadianAgent.d.ts.map +1 -0
- package/dist/nervous-system/integration/CircadianAgent.js +696 -0
- package/dist/nervous-system/integration/CircadianAgent.js.map +1 -0
- package/dist/nervous-system/integration/HybridPatternStore.d.ts +244 -0
- package/dist/nervous-system/integration/HybridPatternStore.d.ts.map +1 -0
- package/dist/nervous-system/integration/HybridPatternStore.js +622 -0
- package/dist/nervous-system/integration/HybridPatternStore.js.map +1 -0
- package/dist/nervous-system/integration/NervousSystemEnhancement.d.ts +459 -0
- package/dist/nervous-system/integration/NervousSystemEnhancement.d.ts.map +1 -0
- package/dist/nervous-system/integration/NervousSystemEnhancement.js +921 -0
- package/dist/nervous-system/integration/NervousSystemEnhancement.js.map +1 -0
- package/dist/nervous-system/integration/WorkspaceAgent.d.ts +398 -0
- package/dist/nervous-system/integration/WorkspaceAgent.d.ts.map +1 -0
- package/dist/nervous-system/integration/WorkspaceAgent.js +722 -0
- package/dist/nervous-system/integration/WorkspaceAgent.js.map +1 -0
- package/dist/nervous-system/integration/index.d.ts +22 -0
- package/dist/nervous-system/integration/index.d.ts.map +1 -0
- package/dist/nervous-system/integration/index.js +44 -0
- package/dist/nervous-system/integration/index.js.map +1 -0
- package/dist/nervous-system/persistence/BTSPSerializer.d.ts +96 -0
- package/dist/nervous-system/persistence/BTSPSerializer.d.ts.map +1 -0
- package/dist/nervous-system/persistence/BTSPSerializer.js +223 -0
- package/dist/nervous-system/persistence/BTSPSerializer.js.map +1 -0
- package/dist/nervous-system/persistence/CircadianSerializer.d.ts +90 -0
- package/dist/nervous-system/persistence/CircadianSerializer.d.ts.map +1 -0
- package/dist/nervous-system/persistence/CircadianSerializer.js +239 -0
- package/dist/nervous-system/persistence/CircadianSerializer.js.map +1 -0
- package/dist/nervous-system/persistence/HdcSerializer.d.ts +100 -0
- package/dist/nervous-system/persistence/HdcSerializer.d.ts.map +1 -0
- package/dist/nervous-system/persistence/HdcSerializer.js +259 -0
- package/dist/nervous-system/persistence/HdcSerializer.js.map +1 -0
- package/dist/nervous-system/persistence/INervousSystemStore.d.ts +208 -0
- package/dist/nervous-system/persistence/INervousSystemStore.d.ts.map +1 -0
- package/dist/nervous-system/persistence/INervousSystemStore.js +11 -0
- package/dist/nervous-system/persistence/INervousSystemStore.js.map +1 -0
- package/dist/nervous-system/persistence/NervousSystemPersistenceManager.d.ts +187 -0
- package/dist/nervous-system/persistence/NervousSystemPersistenceManager.d.ts.map +1 -0
- package/dist/nervous-system/persistence/NervousSystemPersistenceManager.js +411 -0
- package/dist/nervous-system/persistence/NervousSystemPersistenceManager.js.map +1 -0
- package/dist/nervous-system/persistence/SQLiteNervousSystemStore.d.ts +98 -0
- package/dist/nervous-system/persistence/SQLiteNervousSystemStore.d.ts.map +1 -0
- package/dist/nervous-system/persistence/SQLiteNervousSystemStore.js +510 -0
- package/dist/nervous-system/persistence/SQLiteNervousSystemStore.js.map +1 -0
- package/dist/nervous-system/persistence/index.d.ts +22 -0
- package/dist/nervous-system/persistence/index.d.ts.map +1 -0
- package/dist/nervous-system/persistence/index.js +45 -0
- package/dist/nervous-system/persistence/index.js.map +1 -0
- package/dist/nervous-system/wasm-loader.d.ts +52 -0
- package/dist/nervous-system/wasm-loader.d.ts.map +1 -0
- package/dist/nervous-system/wasm-loader.js +188 -0
- package/dist/nervous-system/wasm-loader.js.map +1 -0
- package/dist/persistence/HybridPersistenceProvider.d.ts +184 -0
- package/dist/persistence/HybridPersistenceProvider.d.ts.map +1 -0
- package/dist/persistence/HybridPersistenceProvider.js +1086 -0
- package/dist/persistence/HybridPersistenceProvider.js.map +1 -0
- package/dist/persistence/IPersistenceProvider.d.ts +657 -0
- package/dist/persistence/IPersistenceProvider.d.ts.map +1 -0
- package/dist/persistence/IPersistenceProvider.js +11 -0
- package/dist/persistence/IPersistenceProvider.js.map +1 -0
- package/dist/persistence/SupabaseConfig.d.ts +176 -0
- package/dist/persistence/SupabaseConfig.d.ts.map +1 -0
- package/dist/persistence/SupabaseConfig.js +277 -0
- package/dist/persistence/SupabaseConfig.js.map +1 -0
- package/dist/persistence/SupabasePersistenceProvider.d.ts +143 -0
- package/dist/persistence/SupabasePersistenceProvider.d.ts.map +1 -0
- package/dist/persistence/SupabasePersistenceProvider.js +959 -0
- package/dist/persistence/SupabasePersistenceProvider.js.map +1 -0
- package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.d.ts +213 -0
- package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.d.ts.map +1 -0
- package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.js +468 -0
- package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.js.map +1 -0
- package/dist/persistence/adapters/MemorySyncAdapter.d.ts +115 -0
- package/dist/persistence/adapters/MemorySyncAdapter.d.ts.map +1 -0
- package/dist/persistence/adapters/MemorySyncAdapter.js +291 -0
- package/dist/persistence/adapters/MemorySyncAdapter.js.map +1 -0
- package/dist/persistence/adapters/index.d.ts +11 -0
- package/dist/persistence/adapters/index.d.ts.map +1 -0
- package/dist/persistence/adapters/index.js +20 -0
- package/dist/persistence/adapters/index.js.map +1 -0
- package/dist/persistence/index.d.ts +14 -0
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +36 -1
- package/dist/persistence/index.js.map +1 -1
- package/package.json +7 -1
|
@@ -0,0 +1,696 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CircadianAgentManager - Bio-inspired duty cycling for QE agent lifecycle management
|
|
4
|
+
*
|
|
5
|
+
* Integrates CircadianController with BaseAgent lifecycle to achieve 5-50x compute
|
|
6
|
+
* cost reduction by intelligently cycling agents between active and rest phases.
|
|
7
|
+
*
|
|
8
|
+
* ## Agent Lifecycle Phases
|
|
9
|
+
* - **ACTIVE**: Full compute, agents process all tasks, run tests, make decisions
|
|
10
|
+
* - **DAWN**: Ramping up, agents pre-warm caches, prepare for active period
|
|
11
|
+
* - **DUSK**: Ramping down, agents process backlog, batch operations
|
|
12
|
+
* - **REST**: Memory consolidation, minimal compute, only critical events handled
|
|
13
|
+
*
|
|
14
|
+
* ## Compute Savings
|
|
15
|
+
* - Active phase: 100% compute usage
|
|
16
|
+
* - Dawn phase: 60% compute usage
|
|
17
|
+
* - Dusk phase: 40% compute usage
|
|
18
|
+
* - Rest phase: 10% compute usage (5-10x reduction)
|
|
19
|
+
*
|
|
20
|
+
* @module nervous-system/integration/CircadianAgent
|
|
21
|
+
* @version 1.0.0
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.CircadianAgentManager = void 0;
|
|
25
|
+
const events_1 = require("events");
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Implementation
|
|
28
|
+
// ============================================================================
|
|
29
|
+
/**
|
|
30
|
+
* CircadianAgentManager integrates bio-inspired duty cycling with QE agent lifecycle
|
|
31
|
+
*
|
|
32
|
+
* Manages agent active/rest states based on circadian phases to achieve
|
|
33
|
+
* significant compute cost reduction while maintaining responsiveness for
|
|
34
|
+
* critical operations.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* import { CircadianController } from '../adapters/CircadianController.js';
|
|
39
|
+
* import { CircadianAgentManager, AgentPhaseConfig } from './CircadianAgent.js';
|
|
40
|
+
*
|
|
41
|
+
* // Create controller with 1-hour cycles for demo
|
|
42
|
+
* const controller = new CircadianController({ cyclePeriodMs: 60 * 60 * 1000 });
|
|
43
|
+
*
|
|
44
|
+
* // Create manager
|
|
45
|
+
* const manager = new CircadianAgentManager({ controller });
|
|
46
|
+
*
|
|
47
|
+
* // Register agents
|
|
48
|
+
* const testAgent = await TestGeneratorAgent.create();
|
|
49
|
+
* await manager.registerAgent(testAgent, {
|
|
50
|
+
* agentId: testAgent.getAgentId().id,
|
|
51
|
+
* agentType: 'test-generator',
|
|
52
|
+
* criticalityLevel: 'medium',
|
|
53
|
+
* minActiveHours: 4,
|
|
54
|
+
* canRest: true,
|
|
55
|
+
* });
|
|
56
|
+
*
|
|
57
|
+
* // Listen for phase transitions
|
|
58
|
+
* manager.on('phase-transition', (event) => {
|
|
59
|
+
* console.log(`Agent ${event.agentId} transitioned to ${event.toPhase}`);
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* // Start the manager
|
|
63
|
+
* manager.start();
|
|
64
|
+
*
|
|
65
|
+
* // Check energy savings
|
|
66
|
+
* const savings = manager.getEnergySavings();
|
|
67
|
+
* console.log(`Saved ${savings.savingsPercentage}% compute`);
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
class CircadianAgentManager extends events_1.EventEmitter {
|
|
71
|
+
/**
|
|
72
|
+
* Create a new CircadianAgentManager
|
|
73
|
+
*
|
|
74
|
+
* @param config - Manager configuration
|
|
75
|
+
*/
|
|
76
|
+
constructor(config) {
|
|
77
|
+
super();
|
|
78
|
+
// Tracking state
|
|
79
|
+
this.checkInterval = null;
|
|
80
|
+
this.totalComputeCycles = 0;
|
|
81
|
+
this.savedComputeCycles = 0;
|
|
82
|
+
this.lastSavingsMilestone = 0;
|
|
83
|
+
this.startTime = 0;
|
|
84
|
+
this.isRunning = false;
|
|
85
|
+
this.controller = config.controller;
|
|
86
|
+
this.agents = new Map();
|
|
87
|
+
this.defaultCriticality = config.defaultCriticality ?? 'medium';
|
|
88
|
+
this.checkIntervalMs = config.checkIntervalMs ?? 1000;
|
|
89
|
+
this.debug = config.debug ?? false;
|
|
90
|
+
this.lastPhase = this.controller.getPhase();
|
|
91
|
+
}
|
|
92
|
+
// ============================================================================
|
|
93
|
+
// Agent Registration
|
|
94
|
+
// ============================================================================
|
|
95
|
+
/**
|
|
96
|
+
* Register an agent for circadian management
|
|
97
|
+
*
|
|
98
|
+
* Agents must be registered before they can be managed. Critical agents
|
|
99
|
+
* will never enter rest phase; low criticality agents rest first.
|
|
100
|
+
*
|
|
101
|
+
* @param agent - The BaseAgent instance to manage
|
|
102
|
+
* @param config - Phase configuration for this agent
|
|
103
|
+
*/
|
|
104
|
+
async registerAgent(agent, config) {
|
|
105
|
+
const agentId = config.agentId;
|
|
106
|
+
if (this.agents.has(agentId)) {
|
|
107
|
+
throw new Error(`Agent ${agentId} is already registered`);
|
|
108
|
+
}
|
|
109
|
+
// Validate config
|
|
110
|
+
if (config.minActiveHours < 0 || config.minActiveHours > 24) {
|
|
111
|
+
throw new Error(`minActiveHours must be between 0 and 24, got ${config.minActiveHours}`);
|
|
112
|
+
}
|
|
113
|
+
if (config.criticalityLevel === 'critical' && config.canRest) {
|
|
114
|
+
this.log(`Warning: Critical agent ${agentId} should not have canRest=true, overriding to false`);
|
|
115
|
+
config.canRest = false;
|
|
116
|
+
}
|
|
117
|
+
// Initialize agent state
|
|
118
|
+
const initialState = {
|
|
119
|
+
phase: this.controller.getPhase(),
|
|
120
|
+
isActive: true,
|
|
121
|
+
timeInState: 0,
|
|
122
|
+
activeTimeInCycle: 0,
|
|
123
|
+
tasksProcessed: 0,
|
|
124
|
+
lastActivity: Date.now(),
|
|
125
|
+
isSleeping: false,
|
|
126
|
+
};
|
|
127
|
+
this.agents.set(agentId, { agent, config, state: initialState });
|
|
128
|
+
this.log(`Registered agent ${agentId} (${config.agentType}) with criticality ${config.criticalityLevel}`);
|
|
129
|
+
// If manager is already running, apply current phase
|
|
130
|
+
if (this.isRunning) {
|
|
131
|
+
await this.applyPhaseToAgent(agentId);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Unregister an agent from circadian management
|
|
136
|
+
*
|
|
137
|
+
* @param agentId - ID of agent to unregister
|
|
138
|
+
*/
|
|
139
|
+
async unregisterAgent(agentId) {
|
|
140
|
+
const entry = this.agents.get(agentId);
|
|
141
|
+
if (!entry) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// Wake agent if sleeping before unregistering
|
|
145
|
+
if (entry.state.isSleeping) {
|
|
146
|
+
await this.wakeAgent(agentId, 'unregistering');
|
|
147
|
+
}
|
|
148
|
+
this.agents.delete(agentId);
|
|
149
|
+
this.log(`Unregistered agent ${agentId}`);
|
|
150
|
+
}
|
|
151
|
+
// ============================================================================
|
|
152
|
+
// Phase Management
|
|
153
|
+
// ============================================================================
|
|
154
|
+
/**
|
|
155
|
+
* Check if an agent should be active in the current phase
|
|
156
|
+
*
|
|
157
|
+
* Takes into account:
|
|
158
|
+
* - Current circadian phase
|
|
159
|
+
* - Agent criticality level
|
|
160
|
+
* - Minimum active hours requirement
|
|
161
|
+
* - Custom duty factor overrides
|
|
162
|
+
*
|
|
163
|
+
* @param agentId - ID of agent to check
|
|
164
|
+
* @returns true if agent should be active
|
|
165
|
+
*/
|
|
166
|
+
shouldBeActive(agentId) {
|
|
167
|
+
const entry = this.agents.get(agentId);
|
|
168
|
+
if (!entry) {
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
const { config, state } = entry;
|
|
172
|
+
const currentPhase = this.controller.getPhase();
|
|
173
|
+
// Critical agents are always active
|
|
174
|
+
if (config.criticalityLevel === 'critical') {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
// Check if agent can rest
|
|
178
|
+
if (!config.canRest) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
// Phase-based activity rules
|
|
182
|
+
switch (currentPhase) {
|
|
183
|
+
case 'Active':
|
|
184
|
+
// All agents active during Active phase
|
|
185
|
+
return true;
|
|
186
|
+
case 'Dawn':
|
|
187
|
+
// High agents active during Dawn (critical already handled above)
|
|
188
|
+
return config.criticalityLevel === 'high';
|
|
189
|
+
case 'Dusk':
|
|
190
|
+
// High agents stay active during Dusk (critical already handled above)
|
|
191
|
+
// Medium/low agents active if min active hours not met
|
|
192
|
+
if (config.criticalityLevel === 'high') {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
return this.needsMoreActiveTime(agentId);
|
|
196
|
+
case 'Rest':
|
|
197
|
+
// High agents check if they need more active time (critical handled above)
|
|
198
|
+
// Medium/low agents rest
|
|
199
|
+
if (config.criticalityLevel === 'high') {
|
|
200
|
+
return this.needsMoreActiveTime(agentId);
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
default:
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Check if agent needs more active time to meet minimum requirement
|
|
209
|
+
*/
|
|
210
|
+
needsMoreActiveTime(agentId) {
|
|
211
|
+
const entry = this.agents.get(agentId);
|
|
212
|
+
if (!entry) {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
const { config, state } = entry;
|
|
216
|
+
const cyclePeriodMs = this.controller.getConfig().cyclePeriodMs;
|
|
217
|
+
const minActiveMs = config.minActiveHours * 60 * 60 * 1000;
|
|
218
|
+
const minActiveFraction = minActiveMs / cyclePeriodMs;
|
|
219
|
+
// Calculate how much of cycle has passed
|
|
220
|
+
const cycleState = this.controller.getState();
|
|
221
|
+
const cycleFraction = cycleState.cycleTime / cyclePeriodMs;
|
|
222
|
+
// Calculate minimum active time needed by this point in cycle
|
|
223
|
+
const expectedActiveTimeMs = minActiveFraction * cycleState.cycleTime;
|
|
224
|
+
return state.activeTimeInCycle < expectedActiveTimeMs;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Enter rest phase - put eligible agents to sleep
|
|
228
|
+
*
|
|
229
|
+
* Agents are put to sleep in order of criticality (low first).
|
|
230
|
+
* Critical agents never sleep.
|
|
231
|
+
*/
|
|
232
|
+
async enterRestPhase() {
|
|
233
|
+
this.log('Entering rest phase - putting eligible agents to sleep');
|
|
234
|
+
// Sort agents by criticality (low first)
|
|
235
|
+
const sortedAgents = this.getSortedAgentsByCriticality('ascending');
|
|
236
|
+
for (const agentId of sortedAgents) {
|
|
237
|
+
const entry = this.agents.get(agentId);
|
|
238
|
+
if (!entry)
|
|
239
|
+
continue;
|
|
240
|
+
if (!this.shouldBeActive(agentId) && !entry.state.isSleeping) {
|
|
241
|
+
await this.sleepAgent(agentId);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// Emit fleet rest event if all eligible agents are sleeping
|
|
245
|
+
const sleepingCount = this.getAgentsByState('sleeping').length;
|
|
246
|
+
this.emit('fleet-rest', {
|
|
247
|
+
timestamp: Date.now(),
|
|
248
|
+
agentCount: sleepingCount,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Enter active phase - wake all agents
|
|
253
|
+
*/
|
|
254
|
+
async enterActivePhase() {
|
|
255
|
+
this.log('Entering active phase - waking all agents');
|
|
256
|
+
// Wake agents in reverse criticality order (high first)
|
|
257
|
+
const sortedAgents = this.getSortedAgentsByCriticality('descending');
|
|
258
|
+
for (const agentId of sortedAgents) {
|
|
259
|
+
const entry = this.agents.get(agentId);
|
|
260
|
+
if (!entry)
|
|
261
|
+
continue;
|
|
262
|
+
if (entry.state.isSleeping) {
|
|
263
|
+
await this.wakeAgent(agentId, 'entering active phase');
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Emit fleet wake event
|
|
267
|
+
const activeCount = this.getAgentsByState('active').length;
|
|
268
|
+
this.emit('fleet-wake', {
|
|
269
|
+
timestamp: Date.now(),
|
|
270
|
+
agentCount: activeCount,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Force a specific phase transition for the fleet
|
|
275
|
+
*
|
|
276
|
+
* @param phase - Phase to transition to
|
|
277
|
+
*/
|
|
278
|
+
async forcePhaseTransition(phase) {
|
|
279
|
+
this.controller.modulate({
|
|
280
|
+
forcePhase: phase,
|
|
281
|
+
reason: 'manual override',
|
|
282
|
+
});
|
|
283
|
+
await this.handlePhaseChange(this.lastPhase, phase);
|
|
284
|
+
this.lastPhase = phase;
|
|
285
|
+
}
|
|
286
|
+
// ============================================================================
|
|
287
|
+
// Agent Sleep/Wake
|
|
288
|
+
// ============================================================================
|
|
289
|
+
/**
|
|
290
|
+
* Put an agent to sleep
|
|
291
|
+
*/
|
|
292
|
+
async sleepAgent(agentId) {
|
|
293
|
+
const entry = this.agents.get(agentId);
|
|
294
|
+
if (!entry || entry.state.isSleeping) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
const { agent, config, state } = entry;
|
|
298
|
+
// Calculate expected sleep duration based on phase
|
|
299
|
+
const cycleState = this.controller.getState();
|
|
300
|
+
const expectedDuration = cycleState.timeToNextPhase;
|
|
301
|
+
// Update state before transition
|
|
302
|
+
state.isSleeping = true;
|
|
303
|
+
state.isActive = false;
|
|
304
|
+
state.timeInState = 0;
|
|
305
|
+
// Emit sleep event
|
|
306
|
+
this.emit('agent-sleep', {
|
|
307
|
+
agentId,
|
|
308
|
+
isSleeping: true,
|
|
309
|
+
phase: state.phase,
|
|
310
|
+
timestamp: Date.now(),
|
|
311
|
+
expectedDuration,
|
|
312
|
+
});
|
|
313
|
+
this.log(`Agent ${agentId} entering sleep (expected: ${expectedDuration}ms)`);
|
|
314
|
+
// Track compute savings
|
|
315
|
+
this.updateComputeSavings(config.customDutyFactor ?? this.controller.getDutyFactor());
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Wake an agent from sleep
|
|
319
|
+
*/
|
|
320
|
+
async wakeAgent(agentId, reason) {
|
|
321
|
+
const entry = this.agents.get(agentId);
|
|
322
|
+
if (!entry || !entry.state.isSleeping) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const { agent, state } = entry;
|
|
326
|
+
// Update state
|
|
327
|
+
state.isSleeping = false;
|
|
328
|
+
state.isActive = true;
|
|
329
|
+
state.timeInState = 0;
|
|
330
|
+
state.lastActivity = Date.now();
|
|
331
|
+
// Emit wake event
|
|
332
|
+
this.emit('agent-sleep', {
|
|
333
|
+
agentId,
|
|
334
|
+
isSleeping: false,
|
|
335
|
+
phase: state.phase,
|
|
336
|
+
timestamp: Date.now(),
|
|
337
|
+
expectedDuration: 0,
|
|
338
|
+
});
|
|
339
|
+
this.log(`Agent ${agentId} waking (reason: ${reason})`);
|
|
340
|
+
}
|
|
341
|
+
// ============================================================================
|
|
342
|
+
// State Queries
|
|
343
|
+
// ============================================================================
|
|
344
|
+
/**
|
|
345
|
+
* Get current state of all managed agents
|
|
346
|
+
*
|
|
347
|
+
* @returns Map of agent IDs to their current states
|
|
348
|
+
*/
|
|
349
|
+
getAgentStates() {
|
|
350
|
+
const states = new Map();
|
|
351
|
+
for (const [agentId, entry] of this.agents) {
|
|
352
|
+
states.set(agentId, {
|
|
353
|
+
phase: entry.state.phase,
|
|
354
|
+
isActive: entry.state.isActive,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
return states;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Get detailed state for a specific agent
|
|
361
|
+
*/
|
|
362
|
+
getAgentState(agentId) {
|
|
363
|
+
const entry = this.agents.get(agentId);
|
|
364
|
+
return entry ? { ...entry.state } : null;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Get agents by their current state
|
|
368
|
+
*/
|
|
369
|
+
getAgentsByState(state) {
|
|
370
|
+
const result = [];
|
|
371
|
+
for (const [agentId, entry] of this.agents) {
|
|
372
|
+
if (state === 'sleeping' && entry.state.isSleeping) {
|
|
373
|
+
result.push(agentId);
|
|
374
|
+
}
|
|
375
|
+
else if (state === 'active' && entry.state.isActive) {
|
|
376
|
+
result.push(agentId);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
return result;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Get agents sorted by criticality
|
|
383
|
+
*/
|
|
384
|
+
getSortedAgentsByCriticality(order) {
|
|
385
|
+
const criticalityOrder = {
|
|
386
|
+
low: 1,
|
|
387
|
+
medium: 2,
|
|
388
|
+
high: 3,
|
|
389
|
+
critical: 4,
|
|
390
|
+
};
|
|
391
|
+
const agents = Array.from(this.agents.entries());
|
|
392
|
+
agents.sort((a, b) => {
|
|
393
|
+
const aLevel = criticalityOrder[a[1].config.criticalityLevel];
|
|
394
|
+
const bLevel = criticalityOrder[b[1].config.criticalityLevel];
|
|
395
|
+
return order === 'ascending' ? aLevel - bLevel : bLevel - aLevel;
|
|
396
|
+
});
|
|
397
|
+
return agents.map(([agentId]) => agentId);
|
|
398
|
+
}
|
|
399
|
+
// ============================================================================
|
|
400
|
+
// Energy Savings
|
|
401
|
+
// ============================================================================
|
|
402
|
+
/**
|
|
403
|
+
* Calculate compute savings achieved by circadian cycling
|
|
404
|
+
*
|
|
405
|
+
* @returns Energy savings report with cycles saved and percentages
|
|
406
|
+
*/
|
|
407
|
+
getEnergySavings() {
|
|
408
|
+
const metrics = this.controller.getMetrics();
|
|
409
|
+
const totalTime = metrics.phaseTime.Active + metrics.phaseTime.Dawn + metrics.phaseTime.Dusk + metrics.phaseTime.Rest;
|
|
410
|
+
if (totalTime === 0) {
|
|
411
|
+
return {
|
|
412
|
+
savedCycles: 0,
|
|
413
|
+
savingsPercentage: 0,
|
|
414
|
+
totalRestTime: 0,
|
|
415
|
+
totalActiveTime: 0,
|
|
416
|
+
averageDutyFactor: 1,
|
|
417
|
+
costReductionFactor: 1,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
const averageDutyFactor = metrics.averageDutyFactor;
|
|
421
|
+
const savingsPercentage = (1 - averageDutyFactor) * 100;
|
|
422
|
+
const costReductionFactor = averageDutyFactor > 0 ? 1 / averageDutyFactor : 1;
|
|
423
|
+
return {
|
|
424
|
+
savedCycles: this.savedComputeCycles,
|
|
425
|
+
savingsPercentage: Math.round(savingsPercentage * 10) / 10,
|
|
426
|
+
totalRestTime: metrics.phaseTime.Rest,
|
|
427
|
+
totalActiveTime: metrics.phaseTime.Active,
|
|
428
|
+
averageDutyFactor: Math.round(averageDutyFactor * 1000) / 1000,
|
|
429
|
+
costReductionFactor: Math.round(costReductionFactor * 10) / 10,
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Update compute savings tracking
|
|
434
|
+
*/
|
|
435
|
+
updateComputeSavings(dutyFactor) {
|
|
436
|
+
this.totalComputeCycles++;
|
|
437
|
+
this.savedComputeCycles += 1 - dutyFactor;
|
|
438
|
+
// Check for savings milestones (every 10%)
|
|
439
|
+
const savings = this.getEnergySavings();
|
|
440
|
+
const milestone = Math.floor(savings.savingsPercentage / 10) * 10;
|
|
441
|
+
if (milestone > this.lastSavingsMilestone && milestone >= 10) {
|
|
442
|
+
this.lastSavingsMilestone = milestone;
|
|
443
|
+
this.emit('savings-milestone', {
|
|
444
|
+
savingsPercentage: savings.savingsPercentage,
|
|
445
|
+
savedCycles: savings.savedCycles,
|
|
446
|
+
timestamp: Date.now(),
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
// ============================================================================
|
|
451
|
+
// Lifecycle Management
|
|
452
|
+
// ============================================================================
|
|
453
|
+
/**
|
|
454
|
+
* Start the circadian manager
|
|
455
|
+
*
|
|
456
|
+
* Begins periodic phase checks and applies current phase to all agents.
|
|
457
|
+
*/
|
|
458
|
+
start() {
|
|
459
|
+
if (this.isRunning) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
this.isRunning = true;
|
|
463
|
+
this.startTime = Date.now();
|
|
464
|
+
this.lastPhase = this.controller.getPhase();
|
|
465
|
+
// Apply current phase to all agents
|
|
466
|
+
for (const agentId of this.agents.keys()) {
|
|
467
|
+
this.applyPhaseToAgent(agentId).catch((err) => {
|
|
468
|
+
this.log(`Error applying phase to agent ${agentId}: ${err.message}`);
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
// Start periodic phase check
|
|
472
|
+
this.checkInterval = setInterval(() => {
|
|
473
|
+
this.checkPhaseTransition();
|
|
474
|
+
}, this.checkIntervalMs);
|
|
475
|
+
this.log(`CircadianAgentManager started with ${this.agents.size} agents`);
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Stop the circadian manager
|
|
479
|
+
*
|
|
480
|
+
* Stops phase checks and wakes all sleeping agents.
|
|
481
|
+
*/
|
|
482
|
+
async stop() {
|
|
483
|
+
if (!this.isRunning) {
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
this.isRunning = false;
|
|
487
|
+
// Stop periodic check
|
|
488
|
+
if (this.checkInterval) {
|
|
489
|
+
clearInterval(this.checkInterval);
|
|
490
|
+
this.checkInterval = null;
|
|
491
|
+
}
|
|
492
|
+
// Wake all sleeping agents
|
|
493
|
+
for (const agentId of this.agents.keys()) {
|
|
494
|
+
const entry = this.agents.get(agentId);
|
|
495
|
+
if (entry?.state.isSleeping) {
|
|
496
|
+
await this.wakeAgent(agentId, 'manager stopping');
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
this.log('CircadianAgentManager stopped');
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Advance the circadian controller time
|
|
503
|
+
*
|
|
504
|
+
* Call this to advance simulation time. In production, time advances
|
|
505
|
+
* automatically based on wall clock.
|
|
506
|
+
*
|
|
507
|
+
* @param dt - Time to advance in milliseconds
|
|
508
|
+
*/
|
|
509
|
+
advance(dt) {
|
|
510
|
+
this.controller.advance(dt);
|
|
511
|
+
// Update agent state times
|
|
512
|
+
for (const [, entry] of this.agents) {
|
|
513
|
+
entry.state.timeInState += dt;
|
|
514
|
+
if (entry.state.isActive) {
|
|
515
|
+
entry.state.activeTimeInCycle += dt;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
// Check for phase transition
|
|
519
|
+
this.checkPhaseTransition();
|
|
520
|
+
}
|
|
521
|
+
// ============================================================================
|
|
522
|
+
// Phase Transition Handling
|
|
523
|
+
// ============================================================================
|
|
524
|
+
/**
|
|
525
|
+
* Check for and handle phase transitions
|
|
526
|
+
*/
|
|
527
|
+
checkPhaseTransition() {
|
|
528
|
+
const currentPhase = this.controller.getPhase();
|
|
529
|
+
if (currentPhase !== this.lastPhase) {
|
|
530
|
+
this.handlePhaseChange(this.lastPhase, currentPhase).catch((err) => {
|
|
531
|
+
this.log(`Error handling phase change: ${err.message}`);
|
|
532
|
+
});
|
|
533
|
+
this.lastPhase = currentPhase;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Handle a phase change
|
|
538
|
+
*/
|
|
539
|
+
async handlePhaseChange(fromPhase, toPhase) {
|
|
540
|
+
this.log(`Phase transition: ${fromPhase} -> ${toPhase}`);
|
|
541
|
+
// Emit fleet phase change event
|
|
542
|
+
this.emit('fleet-phase-change', {
|
|
543
|
+
fromPhase,
|
|
544
|
+
toPhase,
|
|
545
|
+
timestamp: Date.now(),
|
|
546
|
+
});
|
|
547
|
+
// Apply phase to all agents
|
|
548
|
+
for (const agentId of this.agents.keys()) {
|
|
549
|
+
await this.applyPhaseToAgent(agentId, fromPhase, toPhase);
|
|
550
|
+
}
|
|
551
|
+
// Phase-specific handling
|
|
552
|
+
switch (toPhase) {
|
|
553
|
+
case 'Rest':
|
|
554
|
+
await this.enterRestPhase();
|
|
555
|
+
break;
|
|
556
|
+
case 'Active':
|
|
557
|
+
await this.enterActivePhase();
|
|
558
|
+
break;
|
|
559
|
+
case 'Dawn':
|
|
560
|
+
await this.handleDawnPhase();
|
|
561
|
+
break;
|
|
562
|
+
case 'Dusk':
|
|
563
|
+
await this.handleDuskPhase();
|
|
564
|
+
break;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Apply current phase to a specific agent
|
|
569
|
+
*/
|
|
570
|
+
async applyPhaseToAgent(agentId, fromPhase, toPhase) {
|
|
571
|
+
const entry = this.agents.get(agentId);
|
|
572
|
+
if (!entry) {
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
const currentPhase = toPhase ?? this.controller.getPhase();
|
|
576
|
+
const previousPhase = fromPhase ?? entry.state.phase;
|
|
577
|
+
// Update agent state
|
|
578
|
+
entry.state.phase = currentPhase;
|
|
579
|
+
// Emit phase transition event
|
|
580
|
+
if (previousPhase !== currentPhase) {
|
|
581
|
+
this.emit('phase-transition', {
|
|
582
|
+
agentId,
|
|
583
|
+
fromPhase: previousPhase,
|
|
584
|
+
toPhase: currentPhase,
|
|
585
|
+
timestamp: Date.now(),
|
|
586
|
+
reason: 'circadian cycle',
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
// Apply sleep/wake based on new phase
|
|
590
|
+
const shouldBeActive = this.shouldBeActive(agentId);
|
|
591
|
+
if (shouldBeActive && entry.state.isSleeping) {
|
|
592
|
+
await this.wakeAgent(agentId, `phase transition to ${currentPhase}`);
|
|
593
|
+
}
|
|
594
|
+
else if (!shouldBeActive && !entry.state.isSleeping) {
|
|
595
|
+
await this.sleepAgent(agentId);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Handle dawn phase - prepare agents for active period
|
|
600
|
+
*/
|
|
601
|
+
async handleDawnPhase() {
|
|
602
|
+
// Wake high-criticality agents during dawn
|
|
603
|
+
const sortedAgents = this.getSortedAgentsByCriticality('descending');
|
|
604
|
+
for (const agentId of sortedAgents) {
|
|
605
|
+
const entry = this.agents.get(agentId);
|
|
606
|
+
if (!entry)
|
|
607
|
+
continue;
|
|
608
|
+
if (this.shouldBeActive(agentId) && entry.state.isSleeping) {
|
|
609
|
+
await this.wakeAgent(agentId, 'dawn phase preparation');
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Handle dusk phase - start ramping down
|
|
615
|
+
*/
|
|
616
|
+
async handleDuskPhase() {
|
|
617
|
+
// Low-criticality agents start sleeping during dusk
|
|
618
|
+
const sortedAgents = this.getSortedAgentsByCriticality('ascending');
|
|
619
|
+
for (const agentId of sortedAgents) {
|
|
620
|
+
const entry = this.agents.get(agentId);
|
|
621
|
+
if (!entry)
|
|
622
|
+
continue;
|
|
623
|
+
if (!this.shouldBeActive(agentId) && !entry.state.isSleeping) {
|
|
624
|
+
await this.sleepAgent(agentId);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
// ============================================================================
|
|
629
|
+
// Metrics and Reporting
|
|
630
|
+
// ============================================================================
|
|
631
|
+
/**
|
|
632
|
+
* Get circadian controller metrics
|
|
633
|
+
*/
|
|
634
|
+
getControllerMetrics() {
|
|
635
|
+
return this.controller.getMetrics();
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Get circadian controller state
|
|
639
|
+
*/
|
|
640
|
+
getControllerState() {
|
|
641
|
+
return this.controller.getState();
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Get manager statistics
|
|
645
|
+
*/
|
|
646
|
+
getStats() {
|
|
647
|
+
const activeAgents = this.getAgentsByState('active').length;
|
|
648
|
+
const sleepingAgents = this.getAgentsByState('sleeping').length;
|
|
649
|
+
return {
|
|
650
|
+
totalAgents: this.agents.size,
|
|
651
|
+
activeAgents,
|
|
652
|
+
sleepingAgents,
|
|
653
|
+
currentPhase: this.controller.getPhase(),
|
|
654
|
+
uptime: this.isRunning ? Date.now() - this.startTime : 0,
|
|
655
|
+
savings: this.getEnergySavings(),
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
// ============================================================================
|
|
659
|
+
// Utility
|
|
660
|
+
// ============================================================================
|
|
661
|
+
/**
|
|
662
|
+
* Log message if debug is enabled
|
|
663
|
+
*/
|
|
664
|
+
log(message) {
|
|
665
|
+
if (this.debug) {
|
|
666
|
+
console.log(`[CircadianAgentManager] ${message}`);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Record a task completion for an agent
|
|
671
|
+
*
|
|
672
|
+
* Call this when an agent completes a task to track activity.
|
|
673
|
+
*/
|
|
674
|
+
recordTaskCompletion(agentId) {
|
|
675
|
+
const entry = this.agents.get(agentId);
|
|
676
|
+
if (entry) {
|
|
677
|
+
entry.state.tasksProcessed++;
|
|
678
|
+
entry.state.lastActivity = Date.now();
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* Get the number of registered agents
|
|
683
|
+
*/
|
|
684
|
+
get agentCount() {
|
|
685
|
+
return this.agents.size;
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Check if manager is currently running
|
|
689
|
+
*/
|
|
690
|
+
get running() {
|
|
691
|
+
return this.isRunning;
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
exports.CircadianAgentManager = CircadianAgentManager;
|
|
695
|
+
exports.default = CircadianAgentManager;
|
|
696
|
+
//# sourceMappingURL=CircadianAgent.js.map
|