claude-flow 2.7.44 → 2.7.45

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.
@@ -1,399 +1,480 @@
1
- import { EventEmitter } from 'node:events';
2
- import { Logger } from '../core/logger.js';
3
- import { MemoryManager } from './manager.js';
4
- import { EventBus } from '../core/event-bus.js';
5
- import { generateId } from '../utils/helpers.js';
6
- import * as fs from 'node:fs/promises';
7
- import * as path from 'node:path';
8
- export class SwarmMemoryManager extends EventEmitter {
9
- logger;
10
- config;
11
- baseMemory;
12
- entries;
13
- knowledgeBases;
14
- agentMemories;
15
- syncTimer;
16
- isInitialized = false;
17
- constructor(config = {}){
18
- super();
19
- this.logger = new Logger('SwarmMemoryManager');
20
- this.config = {
21
- namespace: 'swarm',
22
- enableDistribution: true,
23
- enableReplication: true,
24
- syncInterval: 10000,
25
- maxEntries: 10000,
26
- compressionThreshold: 1000,
27
- enableKnowledgeBase: true,
28
- enableCrossAgentSharing: true,
29
- persistencePath: './swarm-memory',
30
- ...config
31
- };
32
- this.entries = new Map();
33
- this.knowledgeBases = new Map();
34
- this.agentMemories = new Map();
35
- const eventBus = EventBus.getInstance();
36
- this.baseMemory = new MemoryManager({
37
- backend: 'sqlite',
38
- namespace: this.config.namespace,
39
- cacheSizeMB: 50,
40
- syncOnExit: true,
41
- maxEntries: this.config.maxEntries,
42
- ttlMinutes: 60
43
- }, eventBus, this.logger);
1
+ import { SharedMemory } from './shared-memory.js';
2
+ const SWARM_NAMESPACES = {
3
+ AGENTS: 'swarm:agents',
4
+ TASKS: 'swarm:tasks',
5
+ COMMUNICATIONS: 'swarm:communications',
6
+ CONSENSUS: 'swarm:consensus',
7
+ PATTERNS: 'swarm:patterns',
8
+ METRICS: 'swarm:metrics',
9
+ COORDINATION: 'swarm:coordination'
10
+ };
11
+ export class SwarmMemory extends SharedMemory {
12
+ constructor(options = {}){
13
+ super({
14
+ directory: options.directory || '.swarm',
15
+ filename: options.filename || 'swarm-memory.db',
16
+ ...options
17
+ });
18
+ this.swarmId = options.swarmId || 'default';
19
+ this.mcpMode = options.mcpMode !== false;
20
+ this.agentCache = new Map();
21
+ this.taskCache = new Map();
22
+ this.patternCache = new Map();
44
23
  }
45
24
  async initialize() {
46
- if (this.isInitialized) return;
47
- this.logger.info('Initializing swarm memory manager...');
48
- await this.baseMemory.initialize();
49
- await fs.mkdir(this.config.persistencePath, {
50
- recursive: true
25
+ await super.initialize();
26
+ await this._initializeSwarmNamespaces();
27
+ await this._loadSwarmState();
28
+ this.emit('swarm:initialized', {
29
+ swarmId: this.swarmId
51
30
  });
52
- await this.loadMemoryState();
53
- if (this.config.syncInterval > 0) {
54
- this.syncTimer = setInterval(()=>{
55
- this.syncMemoryState();
56
- }, this.config.syncInterval);
57
- }
58
- this.isInitialized = true;
59
- this.emit('memory:initialized');
60
31
  }
61
- async shutdown() {
62
- if (!this.isInitialized) return;
63
- this.logger.info('Shutting down swarm memory manager...');
64
- if (this.syncTimer) {
65
- clearInterval(this.syncTimer);
66
- this.syncTimer = undefined;
67
- }
68
- await this.saveMemoryState();
69
- this.isInitialized = false;
70
- this.emit('memory:shutdown');
71
- }
72
- async remember(agentId, type, content, metadata = {}) {
73
- const entryId = generateId('mem');
74
- const entry = {
75
- id: entryId,
76
- agentId,
77
- type,
78
- content,
79
- timestamp: new Date(),
32
+ async storeAgent(agentId, agentData) {
33
+ const key = `agent:${agentId}`;
34
+ const enrichedData = {
35
+ ...agentData,
36
+ swarmId: this.swarmId,
37
+ lastUpdated: new Date().toISOString()
38
+ };
39
+ await this.store(key, enrichedData, {
40
+ namespace: SWARM_NAMESPACES.AGENTS,
41
+ tags: [
42
+ 'agent',
43
+ agentData.type,
44
+ agentData.status
45
+ ],
80
46
  metadata: {
81
- shareLevel: 'team',
82
- priority: 1,
83
- ...metadata
47
+ swarmId: this.swarmId,
48
+ agentType: agentData.type
84
49
  }
50
+ });
51
+ this.agentCache.set(agentId, enrichedData);
52
+ this.emit('swarm:agentStored', {
53
+ agentId,
54
+ type: agentData.type
55
+ });
56
+ return {
57
+ agentId,
58
+ stored: true
85
59
  };
86
- this.entries.set(entryId, entry);
87
- if (!this.agentMemories.has(agentId)) {
88
- this.agentMemories.set(agentId, new Set());
60
+ }
61
+ async getAgent(agentId) {
62
+ if (this.agentCache.has(agentId)) {
63
+ return this.agentCache.get(agentId);
89
64
  }
90
- this.agentMemories.get(agentId).add(entryId);
91
- await this.baseMemory.remember({
92
- namespace: this.config.namespace,
93
- key: `entry:${entryId}`,
94
- content: JSON.stringify(entry),
65
+ const key = `agent:${agentId}`;
66
+ const agent = await this.retrieve(key, SWARM_NAMESPACES.AGENTS);
67
+ if (agent) {
68
+ this.agentCache.set(agentId, agent);
69
+ }
70
+ return agent;
71
+ }
72
+ async listAgents(filter = {}) {
73
+ const agents = await this.list(SWARM_NAMESPACES.AGENTS, {
74
+ limit: filter.limit || 100
75
+ });
76
+ return agents.map((entry)=>entry.value).filter((agent)=>{
77
+ if (filter.type && agent.type !== filter.type) return false;
78
+ if (filter.status && agent.status !== filter.status) return false;
79
+ if (filter.swarmId && agent.swarmId !== filter.swarmId) return false;
80
+ return true;
81
+ });
82
+ }
83
+ async storeTask(taskId, taskData) {
84
+ const key = `task:${taskId}`;
85
+ const enrichedData = {
86
+ ...taskData,
87
+ swarmId: this.swarmId,
88
+ createdAt: taskData.createdAt || new Date().toISOString(),
89
+ updatedAt: new Date().toISOString()
90
+ };
91
+ await this.store(key, enrichedData, {
92
+ namespace: SWARM_NAMESPACES.TASKS,
93
+ tags: [
94
+ 'task',
95
+ taskData.status,
96
+ taskData.priority
97
+ ],
95
98
  metadata: {
96
- type: 'swarm-memory',
97
- agentId,
98
- entryType: type,
99
- shareLevel: entry.metadata.shareLevel
99
+ swarmId: this.swarmId,
100
+ assignedAgents: taskData.assignedAgents || []
100
101
  }
101
102
  });
102
- this.logger.debug(`Agent ${agentId} remembered: ${type} - ${entryId}`);
103
- this.emit('memory:added', entry);
104
- if (type === 'knowledge' && this.config.enableKnowledgeBase) {
105
- await this.updateKnowledgeBase(entry);
106
- }
107
- await this.enforceMemoryLimits();
108
- return entryId;
103
+ this.taskCache.set(taskId, enrichedData);
104
+ this.emit('swarm:taskStored', {
105
+ taskId,
106
+ status: taskData.status
107
+ });
108
+ return {
109
+ taskId,
110
+ stored: true
111
+ };
109
112
  }
110
- async recall(query) {
111
- let results = Array.from(this.entries.values());
112
- if (query.agentId) {
113
- results = results.filter((e)=>e.agentId === query.agentId);
114
- }
115
- if (query.type) {
116
- results = results.filter((e)=>e.type === query.type);
117
- }
118
- if (query.taskId) {
119
- results = results.filter((e)=>e.metadata.taskId === query.taskId);
113
+ async updateTaskStatus(taskId, status, result = null) {
114
+ const task = await this.getTask(taskId);
115
+ if (!task) {
116
+ throw new Error(`Task ${taskId} not found`);
120
117
  }
121
- if (query.objectiveId) {
122
- results = results.filter((e)=>e.metadata.objectiveId === query.objectiveId);
118
+ task.status = status;
119
+ task.updatedAt = new Date().toISOString();
120
+ if (result) {
121
+ task.result = result;
123
122
  }
124
- if (query.tags && query.tags.length > 0) {
125
- results = results.filter((e)=>e.metadata.tags && query.tags.some((tag)=>e.metadata.tags.includes(tag)));
123
+ if (status === 'completed') {
124
+ task.completedAt = new Date().toISOString();
126
125
  }
127
- if (query.since) {
128
- results = results.filter((e)=>e.timestamp >= query.since);
129
- }
130
- if (query.before) {
131
- results = results.filter((e)=>e.timestamp <= query.before);
132
- }
133
- if (query.shareLevel) {
134
- results = results.filter((e)=>e.metadata.shareLevel === query.shareLevel);
135
- }
136
- results.sort((a, b)=>b.timestamp.getTime() - a.timestamp.getTime());
137
- if (query.limit) {
138
- results = results.slice(0, query.limit);
139
- }
140
- this.logger.debug(`Recalled ${results.length} memories for query`);
141
- return results;
126
+ await this.storeTask(taskId, task);
127
+ this.emit('swarm:taskStatusUpdated', {
128
+ taskId,
129
+ status
130
+ });
131
+ return {
132
+ taskId,
133
+ status,
134
+ updated: true
135
+ };
142
136
  }
143
- async shareMemory(entryId, targetAgentId) {
144
- const entry = this.entries.get(entryId);
145
- if (!entry) {
146
- throw new Error('Memory entry not found');
147
- }
148
- if (!this.config.enableCrossAgentSharing) {
149
- throw new Error('Cross-agent sharing is disabled');
137
+ async getTask(taskId) {
138
+ if (this.taskCache.has(taskId)) {
139
+ return this.taskCache.get(taskId);
150
140
  }
151
- if (entry.metadata.shareLevel === 'private') {
152
- throw new Error('Memory entry is private and cannot be shared');
141
+ const key = `task:${taskId}`;
142
+ const task = await this.retrieve(key, SWARM_NAMESPACES.TASKS);
143
+ if (task) {
144
+ this.taskCache.set(taskId, task);
153
145
  }
154
- const sharedEntry = {
155
- ...entry,
156
- id: generateId('mem'),
146
+ return task;
147
+ }
148
+ async storeCommunication(fromAgent, toAgent, message) {
149
+ const commId = `comm:${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
150
+ const communication = {
151
+ id: commId,
152
+ fromAgent,
153
+ toAgent,
154
+ message,
155
+ swarmId: this.swarmId,
156
+ timestamp: new Date().toISOString()
157
+ };
158
+ await this.store(commId, communication, {
159
+ namespace: SWARM_NAMESPACES.COMMUNICATIONS,
160
+ ttl: 86400,
161
+ tags: [
162
+ 'communication',
163
+ message.type
164
+ ],
157
165
  metadata: {
158
- ...entry.metadata,
159
- originalId: entryId,
160
- sharedFrom: entry.agentId,
161
- sharedTo: targetAgentId,
162
- sharedAt: new Date()
166
+ fromAgent,
167
+ toAgent,
168
+ messageType: message.type
163
169
  }
164
- };
165
- this.entries.set(sharedEntry.id, sharedEntry);
166
- if (!this.agentMemories.has(targetAgentId)) {
167
- this.agentMemories.set(targetAgentId, new Set());
168
- }
169
- this.agentMemories.get(targetAgentId).add(sharedEntry.id);
170
- this.logger.info(`Shared memory ${entryId} from ${entry.agentId} to ${targetAgentId}`);
171
- this.emit('memory:shared', {
172
- original: entry,
173
- shared: sharedEntry
174
170
  });
171
+ this.emit('swarm:communication', {
172
+ fromAgent,
173
+ toAgent,
174
+ type: message.type
175
+ });
176
+ return {
177
+ id: commId,
178
+ stored: true
179
+ };
175
180
  }
176
- async broadcastMemory(entryId, agentIds) {
177
- const entry = this.entries.get(entryId);
178
- if (!entry) {
179
- throw new Error('Memory entry not found');
180
- }
181
- if (entry.metadata.shareLevel === 'private') {
182
- throw new Error('Cannot broadcast private memory');
183
- }
184
- const targets = agentIds || Array.from(this.agentMemories.keys()).filter((id)=>id !== entry.agentId);
185
- for (const targetId of targets){
186
- try {
187
- await this.shareMemory(entryId, targetId);
188
- } catch (error) {
189
- this.logger.warn(`Failed to share memory to ${targetId}:`, error);
181
+ async storeConsensus(consensusId, decision) {
182
+ const key = `consensus:${consensusId}`;
183
+ const consensusData = {
184
+ ...decision,
185
+ swarmId: this.swarmId,
186
+ timestamp: new Date().toISOString()
187
+ };
188
+ await this.store(key, consensusData, {
189
+ namespace: SWARM_NAMESPACES.CONSENSUS,
190
+ tags: [
191
+ 'consensus',
192
+ decision.status
193
+ ],
194
+ metadata: {
195
+ swarmId: this.swarmId,
196
+ taskId: decision.taskId,
197
+ threshold: decision.threshold
190
198
  }
191
- }
192
- this.logger.info(`Broadcasted memory ${entryId} to ${targets.length} agents`);
199
+ });
200
+ this.emit('swarm:consensus', {
201
+ consensusId,
202
+ status: decision.status
203
+ });
204
+ return {
205
+ consensusId,
206
+ stored: true
207
+ };
193
208
  }
194
- async createKnowledgeBase(name, description, domain, expertise) {
195
- const kbId = generateId('kb');
196
- const knowledgeBase = {
197
- id: kbId,
198
- name,
199
- description,
200
- entries: [],
209
+ async storePattern(patternId, pattern) {
210
+ const key = `pattern:${patternId}`;
211
+ const patternData = {
212
+ ...pattern,
213
+ swarmId: this.swarmId,
214
+ createdAt: new Date().toISOString(),
215
+ usageCount: 0,
216
+ successRate: 0
217
+ };
218
+ await this.store(key, patternData, {
219
+ namespace: SWARM_NAMESPACES.PATTERNS,
220
+ tags: [
221
+ 'pattern',
222
+ pattern.type
223
+ ],
201
224
  metadata: {
202
- domain,
203
- expertise,
204
- contributors: [],
205
- lastUpdated: new Date()
225
+ swarmId: this.swarmId,
226
+ patternType: pattern.type,
227
+ confidence: pattern.confidence || 0
206
228
  }
229
+ });
230
+ if (pattern.type === 'coordination' || pattern.type === 'optimization') {
231
+ this.patternCache.set(patternId, patternData);
232
+ }
233
+ this.emit('swarm:patternStored', {
234
+ patternId,
235
+ type: pattern.type
236
+ });
237
+ return {
238
+ patternId,
239
+ stored: true
207
240
  };
208
- this.knowledgeBases.set(kbId, knowledgeBase);
209
- this.logger.info(`Created knowledge base: ${name} (${kbId})`);
210
- this.emit('knowledgebase:created', knowledgeBase);
211
- return kbId;
212
241
  }
213
- async updateKnowledgeBase(entry) {
214
- if (!this.config.enableKnowledgeBase) return;
215
- const relevantKBs = Array.from(this.knowledgeBases.values()).filter((kb)=>{
216
- const tags = entry.metadata.tags || [];
217
- return tags.some((tag)=>kb.metadata.expertise.some((exp)=>exp.toLowerCase().includes(tag.toLowerCase()) || tag.toLowerCase().includes(exp.toLowerCase())));
218
- });
219
- for (const kb of relevantKBs){
220
- kb.entries.push(entry);
221
- kb.metadata.lastUpdated = new Date();
222
- if (!kb.metadata.contributors.includes(entry.agentId)) {
223
- kb.metadata.contributors.push(entry.agentId);
224
- }
225
- this.logger.debug(`Updated knowledge base ${kb.id} with entry ${entry.id}`);
242
+ async updatePatternMetrics(patternId, success = true) {
243
+ const pattern = await this.getPattern(patternId);
244
+ if (!pattern) {
245
+ throw new Error(`Pattern ${patternId} not found`);
226
246
  }
247
+ pattern.usageCount++;
248
+ pattern.lastUsedAt = new Date().toISOString();
249
+ const alpha = 0.1;
250
+ const currentSuccess = success ? 1 : 0;
251
+ pattern.successRate = alpha * currentSuccess + (1 - alpha) * (pattern.successRate || 0);
252
+ await this.storePattern(patternId, pattern);
253
+ return {
254
+ patternId,
255
+ usageCount: pattern.usageCount,
256
+ successRate: pattern.successRate
257
+ };
227
258
  }
228
- async searchKnowledge(query, domain, expertise) {
229
- const allEntries = [];
230
- for (const kb of this.knowledgeBases.values()){
231
- if (domain && kb.metadata.domain !== domain) continue;
232
- if (expertise && !expertise.some((exp)=>kb.metadata.expertise.includes(exp))) {
233
- continue;
234
- }
235
- allEntries.push(...kb.entries);
259
+ async getPattern(patternId) {
260
+ if (this.patternCache.has(patternId)) {
261
+ return this.patternCache.get(patternId);
236
262
  }
237
- const queryLower = query.toLowerCase();
238
- const results = allEntries.filter((entry)=>{
239
- const contentStr = JSON.stringify(entry.content).toLowerCase();
240
- return contentStr.includes(queryLower);
263
+ const key = `pattern:${patternId}`;
264
+ return await this.retrieve(key, SWARM_NAMESPACES.PATTERNS);
265
+ }
266
+ async findBestPatterns(context, limit = 5) {
267
+ const patterns = await this.search({
268
+ namespace: SWARM_NAMESPACES.PATTERNS,
269
+ tags: context.tags,
270
+ limit: 100
271
+ });
272
+ const scored = patterns.map((entry)=>{
273
+ const pattern = entry.value;
274
+ const score = pattern.successRate * 0.7 + (pattern.confidence || 0) * 0.2 + (pattern.usageCount > 0 ? 0.1 : 0);
275
+ return {
276
+ ...pattern,
277
+ score
278
+ };
241
279
  });
242
- return results.slice(0, 50);
280
+ return scored.sort((a, b)=>b.score - a.score).slice(0, limit);
243
281
  }
244
- async getAgentMemorySnapshot(agentId) {
245
- const agentEntryIds = this.agentMemories.get(agentId) || new Set();
246
- const agentEntries = Array.from(agentEntryIds).map((id)=>this.entries.get(id)).filter(Boolean);
247
- const recentEntries = agentEntries.sort((a, b)=>b.timestamp.getTime() - a.timestamp.getTime()).slice(0, 10);
248
- const knowledgeContributions = agentEntries.filter((e)=>e.type === 'knowledge').length;
249
- const sharedEntries = agentEntries.filter((e)=>e.metadata.shareLevel === 'public' || e.metadata.shareLevel === 'team').length;
282
+ async storeCoordination(key, state) {
283
+ await this.store(key, state, {
284
+ namespace: SWARM_NAMESPACES.COORDINATION,
285
+ ttl: 3600,
286
+ metadata: {
287
+ swarmId: this.swarmId,
288
+ timestamp: new Date().toISOString()
289
+ }
290
+ });
250
291
  return {
251
- totalEntries: agentEntries.length,
252
- recentEntries,
253
- knowledgeContributions,
254
- sharedEntries
292
+ key,
293
+ stored: true
255
294
  };
256
295
  }
257
- async loadMemoryState() {
258
- try {
259
- const entriesFile = path.join(this.config.persistencePath, 'entries.json');
260
- try {
261
- const entriesData = await fs.readFile(entriesFile, 'utf-8');
262
- const entriesArray = JSON.parse(entriesData);
263
- for (const entry of entriesArray){
264
- this.entries.set(entry.id, {
265
- ...entry,
266
- timestamp: new Date(entry.timestamp)
267
- });
268
- if (!this.agentMemories.has(entry.agentId)) {
269
- this.agentMemories.set(entry.agentId, new Set());
270
- }
271
- this.agentMemories.get(entry.agentId).add(entry.id);
272
- }
273
- this.logger.info(`Loaded ${entriesArray.length} memory entries`);
274
- } catch (error) {
275
- this.logger.warn('No existing memory entries found');
276
- }
277
- const kbFile = path.join(this.config.persistencePath, 'knowledge-bases.json');
278
- try {
279
- const kbData = await fs.readFile(kbFile, 'utf-8');
280
- const kbArray = JSON.parse(kbData);
281
- for (const kb of kbArray){
282
- this.knowledgeBases.set(kb.id, {
283
- ...kb,
284
- metadata: {
285
- ...kb.metadata,
286
- lastUpdated: new Date(kb.metadata.lastUpdated)
287
- },
288
- entries: kb.entries.map((e)=>({
289
- ...e,
290
- timestamp: new Date(e.timestamp)
291
- }))
292
- });
293
- }
294
- this.logger.info(`Loaded ${kbArray.length} knowledge bases`);
295
- } catch (error) {
296
- this.logger.warn('No existing knowledge bases found');
296
+ async getCoordination(key) {
297
+ return await this.retrieve(key, SWARM_NAMESPACES.COORDINATION);
298
+ }
299
+ async storeMetrics(metricsId, metrics) {
300
+ const key = `metrics:${metricsId}`;
301
+ await this.store(key, metrics, {
302
+ namespace: SWARM_NAMESPACES.METRICS,
303
+ ttl: 86400 * 7,
304
+ tags: [
305
+ 'metrics',
306
+ metrics.type
307
+ ],
308
+ metadata: {
309
+ swarmId: this.swarmId,
310
+ agentId: metrics.agentId,
311
+ timestamp: new Date().toISOString()
297
312
  }
298
- } catch (error) {
299
- this.logger.error('Error loading memory state:', error);
300
- }
313
+ });
314
+ this.emit('swarm:metricsStored', {
315
+ metricsId,
316
+ type: metrics.type
317
+ });
318
+ return {
319
+ metricsId,
320
+ stored: true
321
+ };
301
322
  }
302
- async saveMemoryState() {
303
- try {
304
- const entriesArray = Array.from(this.entries.values());
305
- const entriesFile = path.join(this.config.persistencePath, 'entries.json');
306
- await fs.writeFile(entriesFile, JSON.stringify(entriesArray, null, 2));
307
- const kbArray = Array.from(this.knowledgeBases.values());
308
- const kbFile = path.join(this.config.persistencePath, 'knowledge-bases.json');
309
- await fs.writeFile(kbFile, JSON.stringify(kbArray, null, 2));
310
- this.logger.debug('Saved memory state to disk');
311
- } catch (error) {
312
- this.logger.error('Error saving memory state:', error);
313
- }
323
+ async getSwarmStats() {
324
+ const baseStats = await this.getStats();
325
+ const agentCount = await this._countNamespace(SWARM_NAMESPACES.AGENTS);
326
+ const taskCount = await this._countNamespace(SWARM_NAMESPACES.TASKS);
327
+ const patternCount = await this._countNamespace(SWARM_NAMESPACES.PATTERNS);
328
+ const activeAgents = Array.from(this.agentCache.values()).filter((agent)=>agent.status === 'active' || agent.status === 'busy').length;
329
+ const tasks = Array.from(this.taskCache.values());
330
+ const taskStats = {
331
+ total: tasks.length,
332
+ pending: tasks.filter((t)=>t.status === 'pending').length,
333
+ inProgress: tasks.filter((t)=>t.status === 'in_progress').length,
334
+ completed: tasks.filter((t)=>t.status === 'completed').length,
335
+ failed: tasks.filter((t)=>t.status === 'failed').length
336
+ };
337
+ return {
338
+ ...baseStats,
339
+ swarm: {
340
+ swarmId: this.swarmId,
341
+ agents: {
342
+ total: agentCount,
343
+ active: activeAgents,
344
+ cached: this.agentCache.size
345
+ },
346
+ tasks: taskStats,
347
+ patterns: {
348
+ total: patternCount,
349
+ cached: this.patternCache.size
350
+ },
351
+ namespaces: Object.values(SWARM_NAMESPACES)
352
+ }
353
+ };
314
354
  }
315
- async syncMemoryState() {
316
- try {
317
- await this.saveMemoryState();
318
- this.emit('memory:synced');
319
- } catch (error) {
320
- this.logger.error('Error syncing memory state:', error);
355
+ async cleanupSwarmData(options = {}) {
356
+ const { maxAge = 86400 * 7, keepPatterns = true, keepConsensus = true } = options;
357
+ const cutoffTime = Date.now() - maxAge * 1000;
358
+ let cleaned = 0;
359
+ const comms = await this.list(SWARM_NAMESPACES.COMMUNICATIONS);
360
+ for (const comm of comms){
361
+ if (new Date(comm.value.timestamp).getTime() < cutoffTime) {
362
+ await this.delete(comm.key, SWARM_NAMESPACES.COMMUNICATIONS);
363
+ cleaned++;
364
+ }
321
365
  }
322
- }
323
- async enforceMemoryLimits() {
324
- if (this.entries.size <= this.config.maxEntries) return;
325
- this.logger.info('Enforcing memory limits...');
326
- const entries = Array.from(this.entries.values()).filter((e)=>(e.metadata.priority || 1) <= 1).sort((a, b)=>a.timestamp.getTime() - b.timestamp.getTime());
327
- const toRemove = entries.slice(0, this.entries.size - this.config.maxEntries);
328
- for (const entry of toRemove){
329
- this.entries.delete(entry.id);
330
- const agentEntries = this.agentMemories.get(entry.agentId);
331
- if (agentEntries) {
332
- agentEntries.delete(entry.id);
366
+ const tasks = await this.list(SWARM_NAMESPACES.TASKS);
367
+ for (const task of tasks){
368
+ if (task.value.status === 'completed' && new Date(task.value.completedAt).getTime() < cutoffTime) {
369
+ await this.delete(task.key, SWARM_NAMESPACES.TASKS);
370
+ this.taskCache.delete(task.value.id);
371
+ cleaned++;
333
372
  }
334
- this.logger.debug(`Removed old memory entry: ${entry.id}`);
335
373
  }
336
- this.emit('memory:cleaned', toRemove.length);
337
- }
338
- getMemoryStats() {
339
- const entries = Array.from(this.entries.values());
340
- const entriesByType = {};
341
- const entriesByAgent = {};
342
- for (const entry of entries){
343
- entriesByType[entry.type] = (entriesByType[entry.type] || 0) + 1;
344
- entriesByAgent[entry.agentId] = (entriesByAgent[entry.agentId] || 0) + 1;
374
+ const metrics = await this.list(SWARM_NAMESPACES.METRICS);
375
+ for (const metric of metrics){
376
+ if (new Date(metric.createdAt).getTime() < cutoffTime) {
377
+ await this.delete(metric.key, SWARM_NAMESPACES.METRICS);
378
+ cleaned++;
379
+ }
345
380
  }
346
- const memoryUsage = JSON.stringify(entries).length;
381
+ this.emit('swarm:cleanup', {
382
+ cleaned,
383
+ maxAge
384
+ });
347
385
  return {
348
- totalEntries: entries.length,
349
- entriesByType,
350
- entriesByAgent,
351
- knowledgeBases: this.knowledgeBases.size,
352
- memoryUsage
386
+ cleaned
353
387
  };
354
388
  }
355
- async exportMemory(agentId) {
356
- const entries = agentId ? await this.recall({
357
- agentId
358
- }) : Array.from(this.entries.values());
389
+ async exportSwarmState() {
390
+ const agents = await this.listAgents();
391
+ const tasks = Array.from(this.taskCache.values());
392
+ const patterns = await this.list(SWARM_NAMESPACES.PATTERNS);
359
393
  return {
360
- entries,
361
- knowledgeBases: agentId ? Array.from(this.knowledgeBases.values()).filter((kb)=>kb.metadata.contributors.includes(agentId)) : Array.from(this.knowledgeBases.values()),
362
- exportedAt: new Date(),
363
- stats: this.getMemoryStats()
394
+ swarmId: this.swarmId,
395
+ exportedAt: new Date().toISOString(),
396
+ agents: agents,
397
+ tasks: tasks,
398
+ patterns: patterns.map((p)=>p.value),
399
+ statistics: await this.getSwarmStats()
364
400
  };
365
401
  }
366
- async clearMemory(agentId) {
367
- if (agentId) {
368
- const entryIds = this.agentMemories.get(agentId) || new Set();
369
- for (const entryId of entryIds){
370
- this.entries.delete(entryId);
402
+ async importSwarmState(state) {
403
+ let imported = {
404
+ agents: 0,
405
+ tasks: 0,
406
+ patterns: 0
407
+ };
408
+ if (state.agents) {
409
+ for (const agent of state.agents){
410
+ await this.storeAgent(agent.id, agent);
411
+ imported.agents++;
412
+ }
413
+ }
414
+ if (state.tasks) {
415
+ for (const task of state.tasks){
416
+ await this.storeTask(task.id, task);
417
+ imported.tasks++;
418
+ }
419
+ }
420
+ if (state.patterns) {
421
+ for (const pattern of state.patterns){
422
+ await this.storePattern(pattern.id, pattern);
423
+ imported.patterns++;
371
424
  }
372
- this.agentMemories.delete(agentId);
373
- this.logger.info(`Cleared memory for agent ${agentId}`);
374
- } else {
375
- this.entries.clear();
376
- this.agentMemories.clear();
377
- this.knowledgeBases.clear();
378
- this.logger.info('Cleared all swarm memory');
379
425
  }
380
- this.emit('memory:cleared', {
381
- agentId
426
+ this.emit('swarm:imported', imported);
427
+ return imported;
428
+ }
429
+ async _initializeSwarmNamespaces() {
430
+ await this.store('swarm:metadata', {
431
+ swarmId: this.swarmId,
432
+ createdAt: new Date().toISOString(),
433
+ version: '1.0.0',
434
+ namespaces: Object.values(SWARM_NAMESPACES)
435
+ }, {
436
+ namespace: 'swarm:system'
382
437
  });
383
438
  }
384
- async store(key, value) {
385
- const parts = key.split('/');
386
- const type = parts[0] || 'state';
387
- const agentId = parts[1] || 'system';
388
- await this.remember(agentId, type, value, {
439
+ async _loadSwarmState() {
440
+ const agents = await this.list(SWARM_NAMESPACES.AGENTS, {
441
+ limit: 100
442
+ });
443
+ for (const entry of agents){
444
+ if (entry.value.status === 'active' || entry.value.status === 'busy') {
445
+ this.agentCache.set(entry.value.id, entry.value);
446
+ }
447
+ }
448
+ const tasks = await this.search({
449
+ namespace: SWARM_NAMESPACES.TASKS,
389
450
  tags: [
390
- parts[0],
391
- parts[1]
392
- ].filter(Boolean),
393
- shareLevel: 'team'
451
+ 'in_progress'
452
+ ],
453
+ limit: 100
454
+ });
455
+ for (const entry of tasks){
456
+ this.taskCache.set(entry.value.id, entry.value);
457
+ }
458
+ const patterns = await this.list(SWARM_NAMESPACES.PATTERNS, {
459
+ limit: 50
394
460
  });
461
+ for (const entry of patterns){
462
+ if (entry.value.confidence > 0.7 || entry.value.successRate > 0.8) {
463
+ this.patternCache.set(entry.value.id, entry.value);
464
+ }
465
+ }
466
+ }
467
+ async _countNamespace(namespace) {
468
+ const stats = await this.getStats();
469
+ return stats.namespaces[namespace]?.count || 0;
395
470
  }
396
- async search(pattern, limit = 10) {
471
+ }
472
+ export function createSwarmMemory(options = {}) {
473
+ return new SwarmMemory(options);
474
+ }
475
+ export default SwarmMemory;
476
+
477
+ //# sourceMappingURL=swarm-memory.js.maptern, limit = 10) {
397
478
  const results = [];
398
479
  for (const entry of this.entries.values()){
399
480
  const entryString = JSON.stringify(entry);