@sesamespace/hivemind 0.10.0 → 0.11.0
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/.pnpmrc.json +1 -0
- package/AUTO-DEBUG-DESIGN.md +267 -0
- package/AUTOMATIC-MEMORY-MANAGEMENT.md +109 -0
- package/DASHBOARD-PLAN.md +206 -0
- package/MEMORY-ENHANCEMENT-PLAN.md +211 -0
- package/TOOL-USE-DESIGN.md +173 -0
- package/dist/{chunk-FBQBBAPZ.js → chunk-4C6B2AMB.js} +2 -2
- package/dist/{chunk-FK6WYXRM.js → chunk-4YXOQGQC.js} +2 -2
- package/dist/{chunk-IXBIAX76.js → chunk-K6KL2VD6.js} +2 -2
- package/dist/{chunk-BHCDOHSK.js → chunk-LYL5GG2F.js} +3 -3
- package/dist/{chunk-M3A2WRXM.js → chunk-OB6OXLPC.js} +430 -2
- package/dist/chunk-OB6OXLPC.js.map +1 -0
- package/dist/{chunk-DPLCEMEC.js → chunk-ZA4NWNS6.js} +2 -2
- package/dist/commands/fleet.js +3 -3
- package/dist/commands/init.js +3 -3
- package/dist/commands/start.js +3 -3
- package/dist/commands/watchdog.js +3 -3
- package/dist/dashboard.html +100 -60
- package/dist/index.js +2 -2
- package/dist/main.js +6 -6
- package/dist/start.js +1 -1
- package/docs/TOOL-PARITY-PLAN.md +191 -0
- package/package.json +23 -24
- package/src/memory/dashboard-integration.ts +295 -0
- package/src/memory/index.ts +187 -0
- package/src/memory/performance-test.ts +208 -0
- package/src/memory/processors/agent-sync.ts +312 -0
- package/src/memory/processors/command-learner.ts +298 -0
- package/src/memory/processors/memory-api-client.ts +105 -0
- package/src/memory/processors/message-flow-integration.ts +168 -0
- package/src/memory/processors/research-digester.ts +204 -0
- package/test-caitlin-access.md +11 -0
- package/dist/chunk-M3A2WRXM.js.map +0 -1
- package/install.sh +0 -162
- package/packages/memory/Cargo.lock +0 -6480
- package/packages/memory/Cargo.toml +0 -21
- package/packages/memory/src/src/context.rs +0 -179
- package/packages/memory/src/src/embeddings.rs +0 -51
- package/packages/memory/src/src/main.rs +0 -887
- package/packages/memory/src/src/promotion.rs +0 -808
- package/packages/memory/src/src/scoring.rs +0 -142
- package/packages/memory/src/src/store.rs +0 -460
- package/packages/memory/src/src/tasks.rs +0 -321
- /package/dist/{chunk-FBQBBAPZ.js.map → chunk-4C6B2AMB.js.map} +0 -0
- /package/dist/{chunk-FK6WYXRM.js.map → chunk-4YXOQGQC.js.map} +0 -0
- /package/dist/{chunk-IXBIAX76.js.map → chunk-K6KL2VD6.js.map} +0 -0
- /package/dist/{chunk-BHCDOHSK.js.map → chunk-LYL5GG2F.js.map} +0 -0
- /package/dist/{chunk-DPLCEMEC.js.map → chunk-ZA4NWNS6.js.map} +0 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Integration - Exposes memory system state to the Hivemind dashboard
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
import express from 'express';
|
|
7
|
+
import { MessageFlowIntegration } from './processors/message-flow-integration';
|
|
8
|
+
import { ResearchDigester } from './processors/research-digester';
|
|
9
|
+
import { CommandLearner } from './processors/command-learner';
|
|
10
|
+
import { AgentSync } from './processors/agent-sync';
|
|
11
|
+
|
|
12
|
+
export interface DashboardConfig {
|
|
13
|
+
port?: number;
|
|
14
|
+
messageFlow: MessageFlowIntegration;
|
|
15
|
+
researchDigester?: ResearchDigester;
|
|
16
|
+
commandLearner?: CommandLearner;
|
|
17
|
+
agentSync?: AgentSync;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export class DashboardIntegration extends EventEmitter {
|
|
21
|
+
private app: express.Application;
|
|
22
|
+
private messageFlow: MessageFlowIntegration;
|
|
23
|
+
private researchDigester?: ResearchDigester;
|
|
24
|
+
private commandLearner?: CommandLearner;
|
|
25
|
+
private agentSync?: AgentSync;
|
|
26
|
+
|
|
27
|
+
constructor(config: DashboardConfig) {
|
|
28
|
+
super();
|
|
29
|
+
|
|
30
|
+
this.messageFlow = config.messageFlow;
|
|
31
|
+
this.researchDigester = config.researchDigester;
|
|
32
|
+
this.commandLearner = config.commandLearner;
|
|
33
|
+
this.agentSync = config.agentSync;
|
|
34
|
+
|
|
35
|
+
this.app = express();
|
|
36
|
+
this.setupRoutes();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private setupRoutes(): void {
|
|
40
|
+
this.app.use(express.json());
|
|
41
|
+
|
|
42
|
+
// Memory system overview
|
|
43
|
+
this.app.get('/api/memory/overview', async (req, res) => {
|
|
44
|
+
try {
|
|
45
|
+
const state = await this.messageFlow.getState();
|
|
46
|
+
const overview = {
|
|
47
|
+
...state,
|
|
48
|
+
research: this.researchDigester ? {
|
|
49
|
+
entries: (await this.researchDigester['research']).size,
|
|
50
|
+
topics: Array.from(this.researchDigester['topicIndex'].keys())
|
|
51
|
+
} : null,
|
|
52
|
+
commands: this.commandLearner ? {
|
|
53
|
+
patterns: this.commandLearner['patterns'].size,
|
|
54
|
+
categories: Array.from(this.commandLearner['categoryIndex'].keys())
|
|
55
|
+
} : null,
|
|
56
|
+
agents: this.agentSync ? {
|
|
57
|
+
known: (await this.agentSync.getAgentKnowledge()).length,
|
|
58
|
+
sharedTasks: (await this.agentSync.getSharedTasks()).length
|
|
59
|
+
} : null
|
|
60
|
+
};
|
|
61
|
+
res.json(overview);
|
|
62
|
+
} catch (error) {
|
|
63
|
+
res.status(500).json({ error: error.message });
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Working set - currently active code files
|
|
68
|
+
this.app.get('/api/memory/working-set', async (req, res) => {
|
|
69
|
+
try {
|
|
70
|
+
const state = await this.messageFlow.getState();
|
|
71
|
+
res.json({
|
|
72
|
+
files: state.workingSet,
|
|
73
|
+
totalFiles: state.workingSet.length
|
|
74
|
+
});
|
|
75
|
+
} catch (error) {
|
|
76
|
+
res.status(500).json({ error: error.message });
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Active tasks
|
|
81
|
+
this.app.get('/api/memory/tasks', async (req, res) => {
|
|
82
|
+
try {
|
|
83
|
+
const state = await this.messageFlow.getState();
|
|
84
|
+
const sharedTasks = this.agentSync ? await this.agentSync.getSharedTasks() : [];
|
|
85
|
+
|
|
86
|
+
res.json({
|
|
87
|
+
localTasks: state.tasks,
|
|
88
|
+
sharedTasks: sharedTasks,
|
|
89
|
+
total: state.tasks.length + sharedTasks.length
|
|
90
|
+
});
|
|
91
|
+
} catch (error) {
|
|
92
|
+
res.status(500).json({ error: error.message });
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Research entries
|
|
97
|
+
this.app.get('/api/memory/research', async (req, res) => {
|
|
98
|
+
if (!this.researchDigester) {
|
|
99
|
+
return res.json({ entries: [], topics: [] });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
const recent = await this.researchDigester.getRecent(20);
|
|
104
|
+
res.json({
|
|
105
|
+
entries: recent,
|
|
106
|
+
topics: Array.from(this.researchDigester['topicIndex'].keys())
|
|
107
|
+
});
|
|
108
|
+
} catch (error) {
|
|
109
|
+
res.status(500).json({ error: error.message });
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Search research
|
|
114
|
+
this.app.get('/api/memory/research/search', async (req, res) => {
|
|
115
|
+
if (!this.researchDigester) {
|
|
116
|
+
return res.json({ results: [] });
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
const { q } = req.query;
|
|
121
|
+
const results = await this.researchDigester.search(q as string);
|
|
122
|
+
res.json({ results });
|
|
123
|
+
} catch (error) {
|
|
124
|
+
res.status(500).json({ error: error.message });
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Command patterns
|
|
129
|
+
this.app.get('/api/memory/commands', async (req, res) => {
|
|
130
|
+
if (!this.commandLearner) {
|
|
131
|
+
return res.json({ patterns: [], categories: [] });
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
const patterns = Array.from(this.commandLearner['patterns'].values());
|
|
136
|
+
const categories = Array.from(this.commandLearner['categoryIndex'].keys());
|
|
137
|
+
|
|
138
|
+
res.json({
|
|
139
|
+
patterns: patterns.sort((a, b) => b.usageCount - a.usageCount),
|
|
140
|
+
categories
|
|
141
|
+
});
|
|
142
|
+
} catch (error) {
|
|
143
|
+
res.status(500).json({ error: error.message });
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Command suggestions
|
|
148
|
+
this.app.get('/api/memory/commands/suggest', async (req, res) => {
|
|
149
|
+
if (!this.commandLearner) {
|
|
150
|
+
return res.json({ suggestions: [] });
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
const { context, category } = req.query;
|
|
155
|
+
const suggestions = await this.commandLearner.getSuggestions(
|
|
156
|
+
context as string || '',
|
|
157
|
+
category as string
|
|
158
|
+
);
|
|
159
|
+
res.json({ suggestions });
|
|
160
|
+
} catch (error) {
|
|
161
|
+
res.status(500).json({ error: error.message });
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Agent knowledge
|
|
166
|
+
this.app.get('/api/memory/agents', async (req, res) => {
|
|
167
|
+
if (!this.agentSync) {
|
|
168
|
+
return res.json({ agents: [] });
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
const agents = await this.agentSync.getAgentKnowledge();
|
|
173
|
+
res.json({ agents });
|
|
174
|
+
} catch (error) {
|
|
175
|
+
res.status(500).json({ error: error.message });
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Memory timeline - recent activity
|
|
180
|
+
this.app.get('/api/memory/timeline', async (req, res) => {
|
|
181
|
+
try {
|
|
182
|
+
const timeline = [];
|
|
183
|
+
|
|
184
|
+
// Add recent tasks
|
|
185
|
+
const state = await this.messageFlow.getState();
|
|
186
|
+
for (const task of state.tasks) {
|
|
187
|
+
timeline.push({
|
|
188
|
+
type: 'task',
|
|
189
|
+
timestamp: task.lastUpdate,
|
|
190
|
+
description: task.description,
|
|
191
|
+
metadata: { state: task.state }
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Add recent research
|
|
196
|
+
if (this.researchDigester) {
|
|
197
|
+
const research = await this.researchDigester.getRecent(5);
|
|
198
|
+
for (const entry of research) {
|
|
199
|
+
timeline.push({
|
|
200
|
+
type: 'research',
|
|
201
|
+
timestamp: entry.timestamp,
|
|
202
|
+
description: entry.title,
|
|
203
|
+
metadata: { url: entry.url, topics: entry.relatedTopics }
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Add recent commands
|
|
209
|
+
if (this.commandLearner) {
|
|
210
|
+
const patterns = Array.from(this.commandLearner['patterns'].values())
|
|
211
|
+
.sort((a, b) => b.lastUsed.getTime() - a.lastUsed.getTime())
|
|
212
|
+
.slice(0, 5);
|
|
213
|
+
|
|
214
|
+
for (const pattern of patterns) {
|
|
215
|
+
timeline.push({
|
|
216
|
+
type: 'command',
|
|
217
|
+
timestamp: pattern.lastUsed,
|
|
218
|
+
description: pattern.description,
|
|
219
|
+
metadata: { pattern: pattern.pattern, category: pattern.category }
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Sort by timestamp
|
|
225
|
+
timeline.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
226
|
+
|
|
227
|
+
res.json({ timeline: timeline.slice(0, 50) });
|
|
228
|
+
} catch (error) {
|
|
229
|
+
res.status(500).json({ error: error.message });
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Context preview - what would be included in next request
|
|
234
|
+
this.app.post('/api/memory/context-preview', async (req, res) => {
|
|
235
|
+
try {
|
|
236
|
+
const { message } = req.body;
|
|
237
|
+
const context = await this.messageFlow.processMessage({
|
|
238
|
+
role: 'user',
|
|
239
|
+
content: message,
|
|
240
|
+
timestamp: new Date()
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
res.json({
|
|
244
|
+
context,
|
|
245
|
+
length: context.length,
|
|
246
|
+
sections: this.analyzeContextSections(context)
|
|
247
|
+
});
|
|
248
|
+
} catch (error) {
|
|
249
|
+
res.status(500).json({ error: error.message });
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
private analyzeContextSections(context: string): any[] {
|
|
255
|
+
const sections = [];
|
|
256
|
+
const lines = context.split('\n');
|
|
257
|
+
let currentSection = null;
|
|
258
|
+
let currentContent = [];
|
|
259
|
+
|
|
260
|
+
for (const line of lines) {
|
|
261
|
+
if (line.startsWith('## ')) {
|
|
262
|
+
if (currentSection) {
|
|
263
|
+
sections.push({
|
|
264
|
+
title: currentSection,
|
|
265
|
+
lines: currentContent.length,
|
|
266
|
+
characters: currentContent.join('\n').length
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
currentSection = line.substring(3);
|
|
270
|
+
currentContent = [];
|
|
271
|
+
} else {
|
|
272
|
+
currentContent.push(line);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (currentSection) {
|
|
277
|
+
sections.push({
|
|
278
|
+
title: currentSection,
|
|
279
|
+
lines: currentContent.length,
|
|
280
|
+
characters: currentContent.join('\n').length
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return sections;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async start(port: number = 9486): Promise<void> {
|
|
288
|
+
return new Promise((resolve) => {
|
|
289
|
+
this.app.listen(port, () => {
|
|
290
|
+
this.emit('started', { port });
|
|
291
|
+
resolve();
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hivemind Memory System - Automatic context management for all agents
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { MessageFlowIntegration, MessageFlowConfig } from './processors/message-flow-integration';
|
|
6
|
+
import { ResearchDigester } from './processors/research-digester';
|
|
7
|
+
import { CommandLearner } from './processors/command-learner';
|
|
8
|
+
import { AgentSync } from './processors/agent-sync';
|
|
9
|
+
import { DashboardIntegration } from './dashboard-integration';
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
11
|
+
|
|
12
|
+
export interface MemorySystemConfig {
|
|
13
|
+
agentId: string;
|
|
14
|
+
agentName: string;
|
|
15
|
+
workspaceRoot: string;
|
|
16
|
+
memoryURL?: string;
|
|
17
|
+
context?: string;
|
|
18
|
+
maxContextTokens?: number;
|
|
19
|
+
dashboardPort?: number;
|
|
20
|
+
syncEndpoints?: Map<string, string>; // Other agents to sync with
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class MemorySystem extends EventEmitter {
|
|
24
|
+
private messageFlow: MessageFlowIntegration;
|
|
25
|
+
private researchDigester: ResearchDigester;
|
|
26
|
+
private commandLearner: CommandLearner;
|
|
27
|
+
private agentSync: AgentSync;
|
|
28
|
+
private dashboard?: DashboardIntegration;
|
|
29
|
+
private config: MemorySystemConfig;
|
|
30
|
+
|
|
31
|
+
constructor(config: MemorySystemConfig) {
|
|
32
|
+
super();
|
|
33
|
+
this.config = config;
|
|
34
|
+
|
|
35
|
+
// Initialize core message flow
|
|
36
|
+
this.messageFlow = new MessageFlowIntegration({
|
|
37
|
+
workspaceRoot: config.workspaceRoot,
|
|
38
|
+
memoryURL: config.memoryURL,
|
|
39
|
+
context: config.context,
|
|
40
|
+
maxContextTokens: config.maxContextTokens
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Initialize processors
|
|
44
|
+
this.researchDigester = new ResearchDigester();
|
|
45
|
+
this.commandLearner = new CommandLearner();
|
|
46
|
+
this.agentSync = new AgentSync(config.agentId, config.agentName);
|
|
47
|
+
|
|
48
|
+
// Register processors with message flow
|
|
49
|
+
this.messageFlow['processManager'].register('research-digester', this.researchDigester);
|
|
50
|
+
this.messageFlow['processManager'].register('command-learner', this.commandLearner);
|
|
51
|
+
this.messageFlow['processManager'].register('agent-sync', this.agentSync);
|
|
52
|
+
|
|
53
|
+
// Set up event forwarding
|
|
54
|
+
this.setupEventForwarding();
|
|
55
|
+
|
|
56
|
+
// Register sync endpoints if provided
|
|
57
|
+
if (config.syncEndpoints) {
|
|
58
|
+
for (const [agentId, endpoint] of config.syncEndpoints) {
|
|
59
|
+
this.agentSync.registerAgent(agentId, agentId, endpoint);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private setupEventForwarding(): void {
|
|
65
|
+
// Forward errors
|
|
66
|
+
this.messageFlow.on('error', (error) => this.emit('error', error));
|
|
67
|
+
this.researchDigester.on('error', (error) => this.emit('error', { source: 'research', error }));
|
|
68
|
+
this.commandLearner.on('error', (error) => this.emit('error', { source: 'commands', error }));
|
|
69
|
+
this.agentSync.on('error', (error) => this.emit('error', { source: 'sync', error }));
|
|
70
|
+
|
|
71
|
+
// Forward interesting events
|
|
72
|
+
this.messageFlow.on('context-built', (data) => this.emit('context-built', data));
|
|
73
|
+
this.researchDigester.on('research-digested', (entry) => this.emit('research-added', entry));
|
|
74
|
+
this.commandLearner.on('patterns-updated', (stats) => this.emit('commands-updated', stats));
|
|
75
|
+
this.agentSync.on('handoff-received', (handoff) => this.emit('task-handoff', handoff));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Start the memory system
|
|
80
|
+
*/
|
|
81
|
+
async start(): Promise<void> {
|
|
82
|
+
// Start message flow (which starts all processors)
|
|
83
|
+
await this.messageFlow.start();
|
|
84
|
+
|
|
85
|
+
// Start dashboard if port specified
|
|
86
|
+
if (this.config.dashboardPort) {
|
|
87
|
+
this.dashboard = new DashboardIntegration({
|
|
88
|
+
port: this.config.dashboardPort,
|
|
89
|
+
messageFlow: this.messageFlow,
|
|
90
|
+
researchDigester: this.researchDigester,
|
|
91
|
+
commandLearner: this.commandLearner,
|
|
92
|
+
agentSync: this.agentSync
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
await this.dashboard.start(this.config.dashboardPort);
|
|
96
|
+
this.emit('dashboard-started', { port: this.config.dashboardPort });
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
this.emit('started');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Stop the memory system
|
|
104
|
+
*/
|
|
105
|
+
async stop(): Promise<void> {
|
|
106
|
+
await this.messageFlow.stop();
|
|
107
|
+
this.emit('stopped');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Process a message and get enriched context
|
|
112
|
+
*/
|
|
113
|
+
async processMessage(message: {
|
|
114
|
+
role: 'user' | 'assistant';
|
|
115
|
+
content: string;
|
|
116
|
+
metadata?: Record<string, any>;
|
|
117
|
+
}): Promise<string> {
|
|
118
|
+
return this.messageFlow.processMessage({
|
|
119
|
+
...message,
|
|
120
|
+
timestamp: new Date(),
|
|
121
|
+
context: this.config.context
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Add research content (from web pages, PDFs, etc.)
|
|
127
|
+
*/
|
|
128
|
+
async addResearch(content: string, metadata?: {
|
|
129
|
+
url?: string;
|
|
130
|
+
title?: string;
|
|
131
|
+
sourceType?: 'web' | 'pdf' | 'markdown' | 'other';
|
|
132
|
+
}): Promise<void> {
|
|
133
|
+
await this.researchDigester.addContent(content, metadata);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Track a command execution
|
|
138
|
+
*/
|
|
139
|
+
async trackCommand(command: string, context: string, output?: string, success: boolean = true): Promise<void> {
|
|
140
|
+
await this.commandLearner.trackCommand(command, context, output, success);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Share a task with other agents
|
|
145
|
+
*/
|
|
146
|
+
async shareTask(task: {
|
|
147
|
+
description: string;
|
|
148
|
+
status: 'active' | 'completed' | 'blocked';
|
|
149
|
+
dependencies?: string[];
|
|
150
|
+
progress?: number;
|
|
151
|
+
notes?: string[];
|
|
152
|
+
}): Promise<string> {
|
|
153
|
+
return this.agentSync.shareTask({
|
|
154
|
+
...task,
|
|
155
|
+
assignedTo: this.config.agentName,
|
|
156
|
+
dependencies: task.dependencies || [],
|
|
157
|
+
progress: task.progress || 0,
|
|
158
|
+
notes: task.notes || []
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Share an insight
|
|
164
|
+
*/
|
|
165
|
+
async shareInsight(insight: string, context?: string): Promise<void> {
|
|
166
|
+
await this.agentSync.shareInsight(insight, context);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Get current system state
|
|
171
|
+
*/
|
|
172
|
+
async getState(): Promise<any> {
|
|
173
|
+
return this.messageFlow.getState();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Export all components for advanced usage
|
|
178
|
+
export { MessageFlowIntegration } from './processors/message-flow-integration';
|
|
179
|
+
export { BackgroundProcessor, ProcessManager } from './processors/background-processor';
|
|
180
|
+
export { CodeIndexer } from './processors/code-indexer';
|
|
181
|
+
export { TaskTracker } from './processors/task-tracker';
|
|
182
|
+
export { ResearchDigester } from './processors/research-digester';
|
|
183
|
+
export { CommandLearner } from './processors/command-learner';
|
|
184
|
+
export { AgentSync } from './processors/agent-sync';
|
|
185
|
+
export { ContextManager } from './processors/context-manager';
|
|
186
|
+
export { MemoryAPIClient } from './processors/memory-api-client';
|
|
187
|
+
export { DashboardIntegration } from './dashboard-integration';
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance test for the memory management system
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { MemorySystem } from './index';
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
|
|
9
|
+
async function runPerformanceTest() {
|
|
10
|
+
console.log('🧪 Starting Hivemind Memory System Performance Test\n');
|
|
11
|
+
|
|
12
|
+
const startTime = Date.now();
|
|
13
|
+
const workspaceRoot = path.join(__dirname, '../../test-workspace');
|
|
14
|
+
|
|
15
|
+
// Create test workspace
|
|
16
|
+
if (!fs.existsSync(workspaceRoot)) {
|
|
17
|
+
fs.mkdirSync(workspaceRoot, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Initialize memory system
|
|
21
|
+
const memory = new MemorySystem({
|
|
22
|
+
agentId: 'test-agent-001',
|
|
23
|
+
agentName: 'TestAgent',
|
|
24
|
+
workspaceRoot,
|
|
25
|
+
memoryURL: 'http://localhost:3434',
|
|
26
|
+
context: 'performance-test',
|
|
27
|
+
maxContextTokens: 8000,
|
|
28
|
+
dashboardPort: 9487
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Track metrics
|
|
32
|
+
const metrics = {
|
|
33
|
+
messagesProcessed: 0,
|
|
34
|
+
contextBuildTime: [] as number[],
|
|
35
|
+
memoryUsage: [] as number[],
|
|
36
|
+
errors: 0
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Set up event listeners
|
|
40
|
+
memory.on('error', (error) => {
|
|
41
|
+
console.error('❌ Error:', error);
|
|
42
|
+
metrics.errors++;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
memory.on('context-built', (data) => {
|
|
46
|
+
console.log(`📝 Context built: ${data.contextLength} chars, ${data.sections} sections`);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
memory.on('started', () => {
|
|
50
|
+
console.log('✅ Memory system started\n');
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
memory.on('dashboard-started', ({ port }) => {
|
|
54
|
+
console.log(`🌐 Dashboard available at http://localhost:${port}\n`);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
// Start the system
|
|
59
|
+
await memory.start();
|
|
60
|
+
|
|
61
|
+
// Test 1: Message processing
|
|
62
|
+
console.log('📊 Test 1: Message Processing');
|
|
63
|
+
const messages = [
|
|
64
|
+
{ role: 'user' as const, content: 'Can you help me debug the authentication system in src/auth/login.ts?' },
|
|
65
|
+
{ role: 'assistant' as const, content: 'I\'ll help you debug the authentication system. Let me look at src/auth/login.ts...' },
|
|
66
|
+
{ role: 'user' as const, content: 'The error happens when users try to login with OAuth' },
|
|
67
|
+
{ role: 'assistant' as const, content: 'I see. Let me check the OAuth configuration in src/auth/oauth.ts and src/config/oauth.json' }
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
for (const message of messages) {
|
|
71
|
+
const startContext = Date.now();
|
|
72
|
+
const context = await memory.processMessage(message);
|
|
73
|
+
const contextTime = Date.now() - startContext;
|
|
74
|
+
|
|
75
|
+
metrics.contextBuildTime.push(contextTime);
|
|
76
|
+
metrics.messagesProcessed++;
|
|
77
|
+
|
|
78
|
+
console.log(` - Processed ${message.role} message in ${contextTime}ms (context: ${context.length} chars)`);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Test 2: Research ingestion
|
|
82
|
+
console.log('\n📊 Test 2: Research Ingestion');
|
|
83
|
+
const researchContent = `
|
|
84
|
+
# Understanding TypeScript Decorators
|
|
85
|
+
|
|
86
|
+
Decorators are a powerful feature in TypeScript that allow you to modify classes and their members.
|
|
87
|
+
|
|
88
|
+
## Key Points
|
|
89
|
+
- Decorators use the @ symbol
|
|
90
|
+
- They can be applied to classes, methods, properties, and parameters
|
|
91
|
+
- Decorators are executed at runtime
|
|
92
|
+
- Multiple decorators can be composed
|
|
93
|
+
|
|
94
|
+
## Common Use Cases
|
|
95
|
+
- Logging and monitoring
|
|
96
|
+
- Validation
|
|
97
|
+
- Dependency injection
|
|
98
|
+
- Route handling in web frameworks
|
|
99
|
+
|
|
100
|
+
## Example
|
|
101
|
+
\`\`\`typescript
|
|
102
|
+
@Injectable()
|
|
103
|
+
class UserService {
|
|
104
|
+
@Log()
|
|
105
|
+
async getUser(id: string) {
|
|
106
|
+
return this.db.findUser(id);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
\`\`\`
|
|
110
|
+
`;
|
|
111
|
+
|
|
112
|
+
await memory.addResearch(researchContent, {
|
|
113
|
+
title: 'TypeScript Decorators Guide',
|
|
114
|
+
sourceType: 'markdown'
|
|
115
|
+
});
|
|
116
|
+
console.log(' - Added research document');
|
|
117
|
+
|
|
118
|
+
// Test 3: Command tracking
|
|
119
|
+
console.log('\n📊 Test 3: Command Tracking');
|
|
120
|
+
const commands = [
|
|
121
|
+
{ cmd: 'git status', output: 'On branch main\nnothing to commit', success: true },
|
|
122
|
+
{ cmd: 'git pull origin main', output: 'Already up to date.', success: true },
|
|
123
|
+
{ cmd: 'npm test', output: 'Test suite failed', success: false },
|
|
124
|
+
{ cmd: 'npm test -- --fix', output: 'All tests passed', success: true }
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
for (const { cmd, output, success } of commands) {
|
|
128
|
+
await memory.trackCommand(cmd, 'debugging auth system', output, success);
|
|
129
|
+
console.log(` - Tracked command: ${cmd} (${success ? '✓' : '✗'})`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Test 4: Task sharing
|
|
133
|
+
console.log('\n📊 Test 4: Task Management');
|
|
134
|
+
const taskId = await memory.shareTask({
|
|
135
|
+
description: 'Fix OAuth authentication bug',
|
|
136
|
+
status: 'active',
|
|
137
|
+
progress: 45,
|
|
138
|
+
notes: ['Users report 401 errors', 'Might be related to token expiration']
|
|
139
|
+
});
|
|
140
|
+
console.log(` - Created shared task: ${taskId}`);
|
|
141
|
+
|
|
142
|
+
// Test 5: Insight sharing
|
|
143
|
+
await memory.shareInsight('OAuth tokens need refresh logic to handle expiration gracefully');
|
|
144
|
+
console.log(' - Shared insight about OAuth tokens');
|
|
145
|
+
|
|
146
|
+
// Test 6: Memory usage
|
|
147
|
+
console.log('\n📊 Test 6: Memory Usage');
|
|
148
|
+
for (let i = 0; i < 5; i++) {
|
|
149
|
+
const usage = process.memoryUsage();
|
|
150
|
+
metrics.memoryUsage.push(usage.heapUsed);
|
|
151
|
+
console.log(` - Heap used: ${(usage.heapUsed / 1024 / 1024).toFixed(2)} MB`);
|
|
152
|
+
|
|
153
|
+
// Process more messages to see memory growth
|
|
154
|
+
await memory.processMessage({
|
|
155
|
+
role: 'user',
|
|
156
|
+
content: `Test message ${i}: Working on feature ${i}`
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Test 7: Context building performance with large content
|
|
163
|
+
console.log('\n📊 Test 7: Large Context Performance');
|
|
164
|
+
const largeMessage = 'x'.repeat(1000) + ' Can you analyze this large codebase?';
|
|
165
|
+
const largeStart = Date.now();
|
|
166
|
+
const largeContext = await memory.processMessage({
|
|
167
|
+
role: 'user',
|
|
168
|
+
content: largeMessage
|
|
169
|
+
});
|
|
170
|
+
const largeTime = Date.now() - largeStart;
|
|
171
|
+
console.log(` - Large message processed in ${largeTime}ms (context: ${largeContext.length} chars)`);
|
|
172
|
+
|
|
173
|
+
// Get final state
|
|
174
|
+
const state = await memory.getState();
|
|
175
|
+
console.log('\n📊 Final System State:');
|
|
176
|
+
console.log(` - Memory episodes: ${state.memory?.episodes || 0}`);
|
|
177
|
+
console.log(` - Active tasks: ${state.tasks?.length || 0}`);
|
|
178
|
+
console.log(` - Working set files: ${state.workingSet?.length || 0}`);
|
|
179
|
+
console.log(` - Background processors: ${state.processors || 0}`);
|
|
180
|
+
|
|
181
|
+
// Calculate statistics
|
|
182
|
+
const avgContextTime = metrics.contextBuildTime.reduce((a, b) => a + b, 0) / metrics.contextBuildTime.length;
|
|
183
|
+
const maxMemory = Math.max(...metrics.memoryUsage);
|
|
184
|
+
const minMemory = Math.min(...metrics.memoryUsage);
|
|
185
|
+
|
|
186
|
+
console.log('\n📈 Performance Summary:');
|
|
187
|
+
console.log(` - Total runtime: ${((Date.now() - startTime) / 1000).toFixed(2)}s`);
|
|
188
|
+
console.log(` - Messages processed: ${metrics.messagesProcessed}`);
|
|
189
|
+
console.log(` - Avg context build time: ${avgContextTime.toFixed(2)}ms`);
|
|
190
|
+
console.log(` - Memory usage: ${(minMemory / 1024 / 1024).toFixed(2)} - ${(maxMemory / 1024 / 1024).toFixed(2)} MB`);
|
|
191
|
+
console.log(` - Errors encountered: ${metrics.errors}`);
|
|
192
|
+
|
|
193
|
+
// Stop the system
|
|
194
|
+
await memory.stop();
|
|
195
|
+
console.log('\n✅ Memory system stopped successfully');
|
|
196
|
+
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error('\n❌ Test failed:', error);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Clean up test workspace
|
|
203
|
+
fs.rmSync(workspaceRoot, { recursive: true, force: true });
|
|
204
|
+
console.log('\n🧹 Cleaned up test workspace');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Run the test
|
|
208
|
+
runPerformanceTest().catch(console.error);
|