agentic-qe 2.8.0 → 2.8.1
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 +105 -0
- package/README.md +1 -1
- package/dist/agents/BaseAgent.d.ts +128 -0
- package/dist/agents/BaseAgent.d.ts.map +1 -1
- package/dist/agents/BaseAgent.js +256 -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/core/memory/HNSWVectorMemory.js +1 -1
- 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 +955 -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 +3 -1
|
@@ -0,0 +1,722 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WorkspaceAgentCoordinator - Attention-Based Agent Coordination
|
|
4
|
+
*
|
|
5
|
+
* Integrates GlobalWorkspaceAdapter with QE agent coordination for
|
|
6
|
+
* attention-based agent management following Global Workspace Theory.
|
|
7
|
+
*
|
|
8
|
+
* Key Features:
|
|
9
|
+
* - Attention bottleneck for agent coordination (Miller's Law: 7+/-2 items)
|
|
10
|
+
* - Broadcasting important items to all registered agents
|
|
11
|
+
* - Competition for workspace access based on relevance/salience
|
|
12
|
+
* - Conscious vs unconscious processing management
|
|
13
|
+
*
|
|
14
|
+
* @see Baars, B.J. (1988) A Cognitive Theory of Consciousness
|
|
15
|
+
* @module nervous-system/integration/WorkspaceAgent
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.WorkspaceAgentCoordinator = void 0;
|
|
19
|
+
exports.createWorkspaceCoordinator = createWorkspaceCoordinator;
|
|
20
|
+
exports.createFocusedCoordinator = createFocusedCoordinator;
|
|
21
|
+
exports.createExpandedCoordinator = createExpandedCoordinator;
|
|
22
|
+
const events_1 = require("events");
|
|
23
|
+
const GlobalWorkspaceAdapter_js_1 = require("../adapters/GlobalWorkspaceAdapter.js");
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Implementation
|
|
26
|
+
// ============================================================================
|
|
27
|
+
/**
|
|
28
|
+
* WorkspaceAgentCoordinator
|
|
29
|
+
*
|
|
30
|
+
* Coordinates QE agents through a global workspace based on Global Workspace Theory.
|
|
31
|
+
* Implements attention bottleneck (Miller's Law: 7+/-2 items) to prevent information
|
|
32
|
+
* overload while ensuring high-priority items receive processing.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Create coordinator
|
|
37
|
+
* const coordinator = await WorkspaceAgentCoordinator.create();
|
|
38
|
+
*
|
|
39
|
+
* // Register agents
|
|
40
|
+
* await coordinator.registerAgent(testGeneratorAgent);
|
|
41
|
+
* await coordinator.registerAgent(coverageAnalyzerAgent);
|
|
42
|
+
*
|
|
43
|
+
* // Agent broadcasts to workspace
|
|
44
|
+
* const accepted = await coordinator.agentBroadcast('test-gen-1', {
|
|
45
|
+
* id: 'item-1',
|
|
46
|
+
* agentId: 'test-gen-1',
|
|
47
|
+
* agentType: 'test-generator',
|
|
48
|
+
* content: { tests: [...] },
|
|
49
|
+
* priority: 0.8,
|
|
50
|
+
* relevance: 0.9,
|
|
51
|
+
* timestamp: Date.now()
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* // Check if agent has attention
|
|
55
|
+
* if (await coordinator.hasAttention('test-gen-1')) {
|
|
56
|
+
* // Agent can proceed with full processing
|
|
57
|
+
* }
|
|
58
|
+
*
|
|
59
|
+
* // Coordinate task across multiple agents
|
|
60
|
+
* const result = await coordinator.coordinateTask({
|
|
61
|
+
* taskId: 'task-1',
|
|
62
|
+
* type: 'comprehensive-testing',
|
|
63
|
+
* payload: { sourceFile: 'app.ts' },
|
|
64
|
+
* requiredAgents: [QEAgentType.TEST_GENERATOR, QEAgentType.COVERAGE_ANALYZER],
|
|
65
|
+
* priority: 0.9
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
class WorkspaceAgentCoordinator extends events_1.EventEmitter {
|
|
70
|
+
/**
|
|
71
|
+
* Private constructor - use create() factory method
|
|
72
|
+
*/
|
|
73
|
+
constructor(config = {}) {
|
|
74
|
+
super();
|
|
75
|
+
this.initialized = false;
|
|
76
|
+
this.registeredAgents = new Map();
|
|
77
|
+
this.itemToAgentMap = new Map();
|
|
78
|
+
this.config = {
|
|
79
|
+
workspaceConfig: config.workspaceConfig ?? {},
|
|
80
|
+
autoCompete: config.autoCompete ?? true,
|
|
81
|
+
competitionInterval: config.competitionInterval ?? 0,
|
|
82
|
+
defaultTtl: config.defaultTtl ?? 30000,
|
|
83
|
+
debug: config.debug ?? false,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Factory method to create an initialized WorkspaceAgentCoordinator
|
|
88
|
+
*
|
|
89
|
+
* @param config - Configuration options
|
|
90
|
+
* @returns Initialized coordinator instance
|
|
91
|
+
*/
|
|
92
|
+
static async create(config = {}) {
|
|
93
|
+
const coordinator = new WorkspaceAgentCoordinator(config);
|
|
94
|
+
await coordinator.initialize();
|
|
95
|
+
return coordinator;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Initialize the coordinator and underlying workspace
|
|
99
|
+
*/
|
|
100
|
+
async initialize() {
|
|
101
|
+
if (this.initialized) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// Create global workspace adapter
|
|
105
|
+
this.workspace = await GlobalWorkspaceAdapter_js_1.GlobalWorkspaceAdapter.create(this.config.workspaceConfig);
|
|
106
|
+
// Start periodic competition if configured
|
|
107
|
+
if (this.config.competitionInterval > 0) {
|
|
108
|
+
this.competitionTimer = setInterval(() => {
|
|
109
|
+
this.runCompetition();
|
|
110
|
+
}, this.config.competitionInterval);
|
|
111
|
+
}
|
|
112
|
+
this.initialized = true;
|
|
113
|
+
this.log('WorkspaceAgentCoordinator initialized');
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Register an agent for workspace participation
|
|
117
|
+
*
|
|
118
|
+
* @param agent - The BaseAgent instance to register
|
|
119
|
+
* @param subscriptions - Optional subscription filters
|
|
120
|
+
*/
|
|
121
|
+
async registerAgent(agent, subscriptions) {
|
|
122
|
+
const agentId = agent.getAgentId();
|
|
123
|
+
if (this.registeredAgents.has(agentId.id)) {
|
|
124
|
+
this.log(`Agent ${agentId.id} already registered, updating registration`);
|
|
125
|
+
}
|
|
126
|
+
const info = {
|
|
127
|
+
agent,
|
|
128
|
+
currentSalience: 0,
|
|
129
|
+
hasAttention: false,
|
|
130
|
+
lastBroadcast: 0,
|
|
131
|
+
subscriptions: subscriptions ?? {},
|
|
132
|
+
};
|
|
133
|
+
this.registeredAgents.set(agentId.id, info);
|
|
134
|
+
this.emit('agent:registered', {
|
|
135
|
+
agentId: agentId.id,
|
|
136
|
+
agentType: agentId.type,
|
|
137
|
+
});
|
|
138
|
+
this.log(`Agent registered: ${agentId.id} (${agentId.type})`);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Unregister an agent from workspace participation
|
|
142
|
+
*
|
|
143
|
+
* @param agentId - ID of agent to unregister
|
|
144
|
+
*/
|
|
145
|
+
async unregisterAgent(agentId) {
|
|
146
|
+
if (!this.registeredAgents.has(agentId)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.registeredAgents.delete(agentId);
|
|
150
|
+
// Clear any workspace items from this agent
|
|
151
|
+
for (const [itemId, ownerAgentId] of this.itemToAgentMap.entries()) {
|
|
152
|
+
if (ownerAgentId === agentId) {
|
|
153
|
+
this.itemToAgentMap.delete(itemId);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
this.emit('agent:unregistered', { agentId });
|
|
157
|
+
this.log(`Agent unregistered: ${agentId}`);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Agent broadcasts an item to the global workspace
|
|
161
|
+
*
|
|
162
|
+
* The item competes for one of the limited attention slots (7+/-2).
|
|
163
|
+
* High-priority/relevance items are more likely to win attention.
|
|
164
|
+
*
|
|
165
|
+
* @param agentId - ID of the broadcasting agent
|
|
166
|
+
* @param item - The workspace item to broadcast
|
|
167
|
+
* @returns True if item was accepted into workspace
|
|
168
|
+
*/
|
|
169
|
+
async agentBroadcast(agentId, item) {
|
|
170
|
+
const agentInfo = this.registeredAgents.get(agentId);
|
|
171
|
+
if (!agentInfo) {
|
|
172
|
+
this.log(`Broadcast rejected: agent ${agentId} not registered`);
|
|
173
|
+
this.emit('broadcast:rejected', { item, reason: 'Agent not registered' });
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
// Create agent representation for workspace
|
|
177
|
+
// Convert content to embedding vector (simplified: use priority and relevance)
|
|
178
|
+
const contentVector = this.createContentVector(item);
|
|
179
|
+
// Calculate salience from priority and relevance
|
|
180
|
+
const salience = this.calculateSalience(item);
|
|
181
|
+
const representation = {
|
|
182
|
+
agentId: agentId,
|
|
183
|
+
content: contentVector,
|
|
184
|
+
salience,
|
|
185
|
+
timestamp: item.timestamp,
|
|
186
|
+
};
|
|
187
|
+
// Broadcast to workspace
|
|
188
|
+
const accepted = this.workspace.broadcast(representation);
|
|
189
|
+
if (accepted) {
|
|
190
|
+
// Track item-to-agent mapping
|
|
191
|
+
this.itemToAgentMap.set(item.id, agentId);
|
|
192
|
+
// Update agent info
|
|
193
|
+
agentInfo.currentSalience = salience;
|
|
194
|
+
agentInfo.lastBroadcast = item.timestamp;
|
|
195
|
+
this.emit('broadcast:accepted', { item });
|
|
196
|
+
this.log(`Broadcast accepted: ${item.id} from ${agentId} (salience: ${salience.toFixed(3)})`);
|
|
197
|
+
// Notify relevant agents about the broadcast
|
|
198
|
+
await this.notifyRelevantAgents(item);
|
|
199
|
+
// Auto-compete if enabled
|
|
200
|
+
if (this.config.autoCompete) {
|
|
201
|
+
await this.runCompetition();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
this.emit('broadcast:rejected', { item, reason: 'Workspace full or low salience' });
|
|
206
|
+
this.log(`Broadcast rejected: ${item.id} from ${agentId} (salience: ${salience.toFixed(3)})`);
|
|
207
|
+
}
|
|
208
|
+
return accepted;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Get items relevant to a specific agent type
|
|
212
|
+
*
|
|
213
|
+
* Filters workspace items based on agent type subscriptions and metadata.
|
|
214
|
+
*
|
|
215
|
+
* @param agentType - The agent type to filter for
|
|
216
|
+
* @returns Array of relevant workspace items
|
|
217
|
+
*/
|
|
218
|
+
async getRelevantItems(agentType) {
|
|
219
|
+
// Get all current attention winners
|
|
220
|
+
const occupancy = this.workspace.getOccupancy();
|
|
221
|
+
const winners = this.workspace.retrieveTopK(occupancy.current);
|
|
222
|
+
const relevantItems = [];
|
|
223
|
+
for (const winner of winners) {
|
|
224
|
+
const itemAgentId = winner.agentId;
|
|
225
|
+
const agentInfo = this.registeredAgents.get(itemAgentId);
|
|
226
|
+
if (!agentInfo) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
// Reconstruct workspace item from winner
|
|
230
|
+
// In a full implementation, we would store items separately
|
|
231
|
+
const item = {
|
|
232
|
+
id: `${itemAgentId}-${winner.rank}`,
|
|
233
|
+
agentId: itemAgentId,
|
|
234
|
+
agentType: agentInfo.agent.getAgentId().type,
|
|
235
|
+
content: winner.content,
|
|
236
|
+
priority: winner.salience,
|
|
237
|
+
relevance: winner.salience,
|
|
238
|
+
timestamp: Date.now(), // Would be stored with item
|
|
239
|
+
};
|
|
240
|
+
// Check if item is relevant to requesting agent type
|
|
241
|
+
if (this.isItemRelevantToType(item, agentType)) {
|
|
242
|
+
relevantItems.push(item);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return relevantItems;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Coordinate a task across multiple agents using the workspace
|
|
249
|
+
*
|
|
250
|
+
* Allocates attention to involved agents and manages their collaboration.
|
|
251
|
+
*
|
|
252
|
+
* @param task - Task coordination request
|
|
253
|
+
* @returns Coordination result with agent outcomes
|
|
254
|
+
*/
|
|
255
|
+
async coordinateTask(task) {
|
|
256
|
+
const startTime = Date.now();
|
|
257
|
+
const participatingAgents = [];
|
|
258
|
+
const agentResults = new Map();
|
|
259
|
+
const errors = [];
|
|
260
|
+
// Find agents that match required types
|
|
261
|
+
const matchingAgents = [];
|
|
262
|
+
for (const [agentId, info] of this.registeredAgents.entries()) {
|
|
263
|
+
const agentType = info.agent.getAgentId().type;
|
|
264
|
+
if (task.requiredAgents.includes(agentType)) {
|
|
265
|
+
matchingAgents.push({ id: agentId, info });
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Also include specific agent IDs if provided
|
|
269
|
+
if (task.involvedAgentIds) {
|
|
270
|
+
for (const agentId of task.involvedAgentIds) {
|
|
271
|
+
if (this.registeredAgents.has(agentId) && !matchingAgents.find(a => a.id === agentId)) {
|
|
272
|
+
matchingAgents.push({
|
|
273
|
+
id: agentId,
|
|
274
|
+
info: this.registeredAgents.get(agentId),
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (matchingAgents.length === 0) {
|
|
280
|
+
return {
|
|
281
|
+
taskId: task.taskId,
|
|
282
|
+
success: false,
|
|
283
|
+
participatingAgents: [],
|
|
284
|
+
agentResults,
|
|
285
|
+
duration: Date.now() - startTime,
|
|
286
|
+
errors: [{ agentId: 'coordinator', error: 'No matching agents found' }],
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
this.emit('coordination:started', {
|
|
290
|
+
taskId: task.taskId,
|
|
291
|
+
agents: matchingAgents.map(a => a.id),
|
|
292
|
+
});
|
|
293
|
+
// Broadcast task to workspace with high priority
|
|
294
|
+
for (const { id: agentId, info } of matchingAgents) {
|
|
295
|
+
const taskItem = {
|
|
296
|
+
id: `${task.taskId}-${agentId}`,
|
|
297
|
+
agentId,
|
|
298
|
+
agentType: info.agent.getAgentId().type,
|
|
299
|
+
content: {
|
|
300
|
+
taskId: task.taskId,
|
|
301
|
+
type: task.type,
|
|
302
|
+
payload: task.payload,
|
|
303
|
+
coordination: true,
|
|
304
|
+
},
|
|
305
|
+
priority: task.priority,
|
|
306
|
+
relevance: task.priority,
|
|
307
|
+
timestamp: Date.now(),
|
|
308
|
+
metadata: {
|
|
309
|
+
taskId: task.taskId,
|
|
310
|
+
category: 'coordination',
|
|
311
|
+
targetTypes: task.requiredAgents,
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
const accepted = await this.agentBroadcast(agentId, taskItem);
|
|
315
|
+
if (accepted) {
|
|
316
|
+
participatingAgents.push(agentId);
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
errors.push({ agentId, error: 'Failed to broadcast task item' });
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
// Run competition to allocate attention
|
|
323
|
+
await this.runCompetition();
|
|
324
|
+
// Execute based on strategy
|
|
325
|
+
switch (task.strategy) {
|
|
326
|
+
case 'sequential':
|
|
327
|
+
await this.executeSequential(participatingAgents, task, agentResults, errors);
|
|
328
|
+
break;
|
|
329
|
+
case 'consensus':
|
|
330
|
+
await this.executeConsensus(participatingAgents, task, agentResults, errors);
|
|
331
|
+
break;
|
|
332
|
+
case 'parallel':
|
|
333
|
+
default:
|
|
334
|
+
await this.executeParallel(participatingAgents, task, agentResults, errors);
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
const result = {
|
|
338
|
+
taskId: task.taskId,
|
|
339
|
+
success: errors.length === 0,
|
|
340
|
+
participatingAgents,
|
|
341
|
+
agentResults,
|
|
342
|
+
duration: Date.now() - startTime,
|
|
343
|
+
errors: errors.length > 0 ? errors : undefined,
|
|
344
|
+
};
|
|
345
|
+
this.emit('coordination:completed', { result });
|
|
346
|
+
return result;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Check if an agent currently has attention
|
|
350
|
+
*
|
|
351
|
+
* Agents should check this before performing expensive operations.
|
|
352
|
+
* If they don't have attention, they should defer to higher-priority agents.
|
|
353
|
+
*
|
|
354
|
+
* @param agentId - Agent ID to check
|
|
355
|
+
* @returns True if agent has attention slot
|
|
356
|
+
*/
|
|
357
|
+
async hasAttention(agentId) {
|
|
358
|
+
const agentInfo = this.registeredAgents.get(agentId);
|
|
359
|
+
if (!agentInfo) {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
const hasWorkspaceAttention = this.workspace.hasAttention(agentId);
|
|
363
|
+
// Update cached state
|
|
364
|
+
const previousState = agentInfo.hasAttention;
|
|
365
|
+
agentInfo.hasAttention = hasWorkspaceAttention;
|
|
366
|
+
// Emit events on state change
|
|
367
|
+
if (hasWorkspaceAttention && !previousState) {
|
|
368
|
+
this.emit('attention:granted', {
|
|
369
|
+
agentId,
|
|
370
|
+
item: {
|
|
371
|
+
id: `${agentId}-attention`,
|
|
372
|
+
agentId,
|
|
373
|
+
agentType: agentInfo.agent.getAgentId().type,
|
|
374
|
+
content: null,
|
|
375
|
+
priority: agentInfo.currentSalience,
|
|
376
|
+
relevance: agentInfo.currentSalience,
|
|
377
|
+
timestamp: Date.now(),
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
else if (!hasWorkspaceAttention && previousState) {
|
|
382
|
+
this.emit('attention:lost', { agentId });
|
|
383
|
+
}
|
|
384
|
+
return hasWorkspaceAttention;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Run competition for attention slots
|
|
388
|
+
*
|
|
389
|
+
* Triggers salience decay and reorders attention hierarchy.
|
|
390
|
+
*/
|
|
391
|
+
async runCompetition() {
|
|
392
|
+
this.workspace.compete();
|
|
393
|
+
const occupancy = this.workspace.getOccupancy();
|
|
394
|
+
const winners = this.workspace.retrieveTopK(occupancy.current);
|
|
395
|
+
// Update agent attention states
|
|
396
|
+
for (const [agentId, info] of this.registeredAgents.entries()) {
|
|
397
|
+
const isWinner = winners.some(w => w.agentId === agentId);
|
|
398
|
+
const previousState = info.hasAttention;
|
|
399
|
+
if (isWinner) {
|
|
400
|
+
const winnerInfo = winners.find(w => w.agentId === agentId);
|
|
401
|
+
info.currentSalience = winnerInfo?.salience ?? 0;
|
|
402
|
+
info.hasAttention = true;
|
|
403
|
+
if (!previousState) {
|
|
404
|
+
this.emit('attention:granted', {
|
|
405
|
+
agentId,
|
|
406
|
+
item: {
|
|
407
|
+
id: `${agentId}-competition`,
|
|
408
|
+
agentId,
|
|
409
|
+
agentType: info.agent.getAgentId().type,
|
|
410
|
+
content: null,
|
|
411
|
+
priority: info.currentSalience,
|
|
412
|
+
relevance: info.currentSalience,
|
|
413
|
+
timestamp: Date.now(),
|
|
414
|
+
},
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
info.hasAttention = false;
|
|
420
|
+
if (previousState) {
|
|
421
|
+
this.emit('attention:lost', { agentId });
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
this.emit('competition:complete', { winners });
|
|
426
|
+
this.log(`Competition complete: ${winners.length} attention slots filled`);
|
|
427
|
+
return winners;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Get current workspace occupancy
|
|
431
|
+
*/
|
|
432
|
+
getOccupancy() {
|
|
433
|
+
return this.workspace.getOccupancy();
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Get synchronization metrics
|
|
437
|
+
*/
|
|
438
|
+
getSynchronization() {
|
|
439
|
+
return this.workspace.getSynchronization();
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Get attention winners (agents with attention)
|
|
443
|
+
*
|
|
444
|
+
* @param k - Number of top agents to return (default: all)
|
|
445
|
+
*/
|
|
446
|
+
getAttentionWinners(k) {
|
|
447
|
+
const occupancy = this.workspace.getOccupancy();
|
|
448
|
+
return this.workspace.retrieveTopK(k ?? occupancy.current);
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Get registered agent count
|
|
452
|
+
*/
|
|
453
|
+
getAgentCount() {
|
|
454
|
+
return this.registeredAgents.size;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Get agent info for debugging
|
|
458
|
+
*/
|
|
459
|
+
getAgentInfo(agentId) {
|
|
460
|
+
const info = this.registeredAgents.get(agentId);
|
|
461
|
+
if (!info) {
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
agentType: info.agent.getAgentId().type,
|
|
466
|
+
currentSalience: info.currentSalience,
|
|
467
|
+
hasAttention: info.hasAttention,
|
|
468
|
+
lastBroadcast: info.lastBroadcast,
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Clear workspace and reset all agent states
|
|
473
|
+
*/
|
|
474
|
+
clear() {
|
|
475
|
+
this.workspace.clear();
|
|
476
|
+
this.itemToAgentMap.clear();
|
|
477
|
+
for (const info of this.registeredAgents.values()) {
|
|
478
|
+
info.currentSalience = 0;
|
|
479
|
+
info.hasAttention = false;
|
|
480
|
+
}
|
|
481
|
+
this.log('Workspace cleared');
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Dispose of coordinator resources
|
|
485
|
+
*/
|
|
486
|
+
dispose() {
|
|
487
|
+
if (this.competitionTimer) {
|
|
488
|
+
clearInterval(this.competitionTimer);
|
|
489
|
+
this.competitionTimer = undefined;
|
|
490
|
+
}
|
|
491
|
+
this.workspace.dispose();
|
|
492
|
+
this.registeredAgents.clear();
|
|
493
|
+
this.itemToAgentMap.clear();
|
|
494
|
+
this.removeAllListeners();
|
|
495
|
+
this.initialized = false;
|
|
496
|
+
this.log('WorkspaceAgentCoordinator disposed');
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Get coordinator statistics
|
|
500
|
+
*/
|
|
501
|
+
getStats() {
|
|
502
|
+
const agentStates = Array.from(this.registeredAgents.entries()).map(([id, info]) => ({
|
|
503
|
+
agentId: id,
|
|
504
|
+
agentType: info.agent.getAgentId().type,
|
|
505
|
+
hasAttention: info.hasAttention,
|
|
506
|
+
salience: info.currentSalience,
|
|
507
|
+
}));
|
|
508
|
+
return {
|
|
509
|
+
initialized: this.initialized,
|
|
510
|
+
registeredAgents: this.registeredAgents.size,
|
|
511
|
+
workspaceOccupancy: this.workspace.getOccupancy(),
|
|
512
|
+
synchronization: this.workspace.getSynchronization(),
|
|
513
|
+
agentStates,
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
// ============================================================================
|
|
517
|
+
// Private Helper Methods
|
|
518
|
+
// ============================================================================
|
|
519
|
+
/**
|
|
520
|
+
* Create a content vector from workspace item
|
|
521
|
+
*/
|
|
522
|
+
createContentVector(item) {
|
|
523
|
+
// Create a simple feature vector from item properties
|
|
524
|
+
// In a production system, this would use embeddings
|
|
525
|
+
const features = [
|
|
526
|
+
item.priority,
|
|
527
|
+
item.relevance,
|
|
528
|
+
// Normalize timestamp to 0-1 range (last 24 hours)
|
|
529
|
+
Math.min(1, (Date.now() - item.timestamp) / (24 * 60 * 60 * 1000)),
|
|
530
|
+
// Category encoding
|
|
531
|
+
this.encodeCategoryFeature(item.metadata?.category),
|
|
532
|
+
// Agent type hash (simplified)
|
|
533
|
+
this.hashString(item.agentType) % 1000 / 1000,
|
|
534
|
+
];
|
|
535
|
+
return new Float32Array(features);
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Calculate salience from item properties
|
|
539
|
+
*/
|
|
540
|
+
calculateSalience(item) {
|
|
541
|
+
// Combine priority and relevance with weights
|
|
542
|
+
const baseSalience = item.priority * 0.6 + item.relevance * 0.4;
|
|
543
|
+
// Apply time decay (items lose salience over time)
|
|
544
|
+
const age = Date.now() - item.timestamp;
|
|
545
|
+
const ttl = item.metadata?.ttl ?? this.config.defaultTtl;
|
|
546
|
+
const timeDecay = Math.max(0, 1 - age / ttl);
|
|
547
|
+
// Final salience
|
|
548
|
+
return Math.max(0, Math.min(1, baseSalience * timeDecay));
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Encode category to numeric feature
|
|
552
|
+
*/
|
|
553
|
+
encodeCategoryFeature(category) {
|
|
554
|
+
const categoryMap = {
|
|
555
|
+
task: 0.9,
|
|
556
|
+
result: 0.8,
|
|
557
|
+
request: 0.7,
|
|
558
|
+
notification: 0.5,
|
|
559
|
+
coordination: 1.0,
|
|
560
|
+
};
|
|
561
|
+
return categoryMap[category ?? 'notification'] ?? 0.5;
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Simple string hash for feature encoding
|
|
565
|
+
*/
|
|
566
|
+
hashString(str) {
|
|
567
|
+
let hash = 0;
|
|
568
|
+
for (let i = 0; i < str.length; i++) {
|
|
569
|
+
const char = str.charCodeAt(i);
|
|
570
|
+
hash = (hash << 5) - hash + char;
|
|
571
|
+
hash = hash & hash;
|
|
572
|
+
}
|
|
573
|
+
return Math.abs(hash);
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Check if item is relevant to a specific agent type
|
|
577
|
+
*/
|
|
578
|
+
isItemRelevantToType(item, targetType) {
|
|
579
|
+
// If item specifies target types, check if target is included
|
|
580
|
+
if (item.metadata?.targetTypes && item.metadata.targetTypes.length > 0) {
|
|
581
|
+
return item.metadata.targetTypes.includes(targetType);
|
|
582
|
+
}
|
|
583
|
+
// If no target types specified, item is relevant to all
|
|
584
|
+
return true;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Notify agents that have subscriptions matching the broadcast item
|
|
588
|
+
*/
|
|
589
|
+
async notifyRelevantAgents(item) {
|
|
590
|
+
for (const [agentId, info] of this.registeredAgents.entries()) {
|
|
591
|
+
// Skip the broadcasting agent
|
|
592
|
+
if (agentId === item.agentId) {
|
|
593
|
+
continue;
|
|
594
|
+
}
|
|
595
|
+
// Check subscriptions
|
|
596
|
+
const subscriptions = info.subscriptions;
|
|
597
|
+
let matches = true;
|
|
598
|
+
// Check category filter
|
|
599
|
+
if (subscriptions.categories && subscriptions.categories.length > 0) {
|
|
600
|
+
if (!item.metadata?.category || !subscriptions.categories.includes(item.metadata.category)) {
|
|
601
|
+
matches = false;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
// Check task ID filter
|
|
605
|
+
if (matches && subscriptions.taskIds && subscriptions.taskIds.length > 0) {
|
|
606
|
+
if (!item.metadata?.taskId || !subscriptions.taskIds.includes(item.metadata.taskId)) {
|
|
607
|
+
matches = false;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
// Check source type filter
|
|
611
|
+
if (matches && subscriptions.sourceTypes && subscriptions.sourceTypes.length > 0) {
|
|
612
|
+
if (!subscriptions.sourceTypes.includes(item.agentType)) {
|
|
613
|
+
matches = false;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (matches) {
|
|
617
|
+
// Emit notification to agent (they can listen on their event bus)
|
|
618
|
+
info.agent.emit('workspace:item', item);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Execute task coordination in parallel
|
|
624
|
+
*/
|
|
625
|
+
async executeParallel(agents, _task, results, errors) {
|
|
626
|
+
const promises = agents.map(async (agentId) => {
|
|
627
|
+
try {
|
|
628
|
+
const hasAtt = await this.hasAttention(agentId);
|
|
629
|
+
results.set(agentId, { hasAttention: hasAtt, processed: true });
|
|
630
|
+
}
|
|
631
|
+
catch (error) {
|
|
632
|
+
errors.push({ agentId, error: error.message });
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
await Promise.all(promises);
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Execute task coordination sequentially
|
|
639
|
+
*/
|
|
640
|
+
async executeSequential(agents, _task, results, errors) {
|
|
641
|
+
for (const agentId of agents) {
|
|
642
|
+
try {
|
|
643
|
+
const hasAtt = await this.hasAttention(agentId);
|
|
644
|
+
results.set(agentId, { hasAttention: hasAtt, processed: true });
|
|
645
|
+
}
|
|
646
|
+
catch (error) {
|
|
647
|
+
errors.push({ agentId, error: error.message });
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Execute task coordination with consensus
|
|
653
|
+
*/
|
|
654
|
+
async executeConsensus(agents, _task, results, errors) {
|
|
655
|
+
// Run all agents in parallel
|
|
656
|
+
await this.executeParallel(agents, _task, results, errors);
|
|
657
|
+
// Calculate consensus (simplified: majority with attention wins)
|
|
658
|
+
let withAttention = 0;
|
|
659
|
+
for (const result of results.values()) {
|
|
660
|
+
if (result.hasAttention) {
|
|
661
|
+
withAttention++;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
const consensusReached = withAttention >= Math.ceil(agents.length / 2);
|
|
665
|
+
results.set('__consensus__', {
|
|
666
|
+
reached: consensusReached,
|
|
667
|
+
agentsWithAttention: withAttention,
|
|
668
|
+
totalAgents: agents.length,
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
/**
|
|
672
|
+
* Debug logging
|
|
673
|
+
*/
|
|
674
|
+
log(message) {
|
|
675
|
+
if (this.config.debug) {
|
|
676
|
+
console.log(`[WorkspaceAgentCoordinator] ${message}`);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
exports.WorkspaceAgentCoordinator = WorkspaceAgentCoordinator;
|
|
681
|
+
// ============================================================================
|
|
682
|
+
// Utility Functions
|
|
683
|
+
// ============================================================================
|
|
684
|
+
/**
|
|
685
|
+
* Create a default WorkspaceAgentCoordinator with standard settings
|
|
686
|
+
*/
|
|
687
|
+
async function createWorkspaceCoordinator() {
|
|
688
|
+
return WorkspaceAgentCoordinator.create({
|
|
689
|
+
workspaceConfig: { capacity: 7 }, // Miller's Law
|
|
690
|
+
autoCompete: true,
|
|
691
|
+
defaultTtl: 30000,
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Create a focused WorkspaceAgentCoordinator (4 attention slots)
|
|
696
|
+
*/
|
|
697
|
+
async function createFocusedCoordinator() {
|
|
698
|
+
return WorkspaceAgentCoordinator.create({
|
|
699
|
+
workspaceConfig: {
|
|
700
|
+
capacity: 4,
|
|
701
|
+
threshold: 0.2,
|
|
702
|
+
decayRate: 0.08,
|
|
703
|
+
},
|
|
704
|
+
autoCompete: true,
|
|
705
|
+
defaultTtl: 15000,
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Create an expanded WorkspaceAgentCoordinator (9 attention slots)
|
|
710
|
+
*/
|
|
711
|
+
async function createExpandedCoordinator() {
|
|
712
|
+
return WorkspaceAgentCoordinator.create({
|
|
713
|
+
workspaceConfig: {
|
|
714
|
+
capacity: 9,
|
|
715
|
+
threshold: 0.05,
|
|
716
|
+
decayRate: 0.03,
|
|
717
|
+
},
|
|
718
|
+
autoCompete: true,
|
|
719
|
+
defaultTtl: 60000,
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
//# sourceMappingURL=WorkspaceAgent.js.map
|