network-ai 3.0.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/LICENSE +21 -0
- package/QUICKSTART.md +260 -0
- package/README.md +604 -0
- package/SKILL.md +568 -0
- package/dist/adapters/adapter-registry.d.ts +94 -0
- package/dist/adapters/adapter-registry.d.ts.map +1 -0
- package/dist/adapters/adapter-registry.js +355 -0
- package/dist/adapters/adapter-registry.js.map +1 -0
- package/dist/adapters/agno-adapter.d.ts +112 -0
- package/dist/adapters/agno-adapter.d.ts.map +1 -0
- package/dist/adapters/agno-adapter.js +140 -0
- package/dist/adapters/agno-adapter.js.map +1 -0
- package/dist/adapters/autogen-adapter.d.ts +67 -0
- package/dist/adapters/autogen-adapter.d.ts.map +1 -0
- package/dist/adapters/autogen-adapter.js +141 -0
- package/dist/adapters/autogen-adapter.js.map +1 -0
- package/dist/adapters/base-adapter.d.ts +51 -0
- package/dist/adapters/base-adapter.d.ts.map +1 -0
- package/dist/adapters/base-adapter.js +103 -0
- package/dist/adapters/base-adapter.js.map +1 -0
- package/dist/adapters/crewai-adapter.d.ts +72 -0
- package/dist/adapters/crewai-adapter.d.ts.map +1 -0
- package/dist/adapters/crewai-adapter.js +148 -0
- package/dist/adapters/crewai-adapter.js.map +1 -0
- package/dist/adapters/custom-adapter.d.ts +74 -0
- package/dist/adapters/custom-adapter.d.ts.map +1 -0
- package/dist/adapters/custom-adapter.js +142 -0
- package/dist/adapters/custom-adapter.js.map +1 -0
- package/dist/adapters/dspy-adapter.d.ts +70 -0
- package/dist/adapters/dspy-adapter.d.ts.map +1 -0
- package/dist/adapters/dspy-adapter.js +127 -0
- package/dist/adapters/dspy-adapter.js.map +1 -0
- package/dist/adapters/haystack-adapter.d.ts +83 -0
- package/dist/adapters/haystack-adapter.d.ts.map +1 -0
- package/dist/adapters/haystack-adapter.js +149 -0
- package/dist/adapters/haystack-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +47 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +56 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/langchain-adapter.d.ts +51 -0
- package/dist/adapters/langchain-adapter.d.ts.map +1 -0
- package/dist/adapters/langchain-adapter.js +134 -0
- package/dist/adapters/langchain-adapter.js.map +1 -0
- package/dist/adapters/llamaindex-adapter.d.ts +89 -0
- package/dist/adapters/llamaindex-adapter.d.ts.map +1 -0
- package/dist/adapters/llamaindex-adapter.js +135 -0
- package/dist/adapters/llamaindex-adapter.js.map +1 -0
- package/dist/adapters/mcp-adapter.d.ts +90 -0
- package/dist/adapters/mcp-adapter.d.ts.map +1 -0
- package/dist/adapters/mcp-adapter.js +200 -0
- package/dist/adapters/mcp-adapter.js.map +1 -0
- package/dist/adapters/openai-assistants-adapter.d.ts +94 -0
- package/dist/adapters/openai-assistants-adapter.d.ts.map +1 -0
- package/dist/adapters/openai-assistants-adapter.js +130 -0
- package/dist/adapters/openai-assistants-adapter.js.map +1 -0
- package/dist/adapters/openclaw-adapter.d.ts +21 -0
- package/dist/adapters/openclaw-adapter.d.ts.map +1 -0
- package/dist/adapters/openclaw-adapter.js +140 -0
- package/dist/adapters/openclaw-adapter.js.map +1 -0
- package/dist/adapters/semantic-kernel-adapter.d.ts +73 -0
- package/dist/adapters/semantic-kernel-adapter.d.ts.map +1 -0
- package/dist/adapters/semantic-kernel-adapter.js +123 -0
- package/dist/adapters/semantic-kernel-adapter.js.map +1 -0
- package/dist/index.d.ts +379 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1428 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/blackboard-validator.d.ts +205 -0
- package/dist/lib/blackboard-validator.d.ts.map +1 -0
- package/dist/lib/blackboard-validator.js +756 -0
- package/dist/lib/blackboard-validator.js.map +1 -0
- package/dist/lib/locked-blackboard.d.ts +174 -0
- package/dist/lib/locked-blackboard.d.ts.map +1 -0
- package/dist/lib/locked-blackboard.js +654 -0
- package/dist/lib/locked-blackboard.js.map +1 -0
- package/dist/lib/swarm-utils.d.ts +136 -0
- package/dist/lib/swarm-utils.d.ts.map +1 -0
- package/dist/lib/swarm-utils.js +510 -0
- package/dist/lib/swarm-utils.js.map +1 -0
- package/dist/security.d.ts +269 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +713 -0
- package/dist/security.js.map +1 -0
- package/package.json +84 -0
- package/scripts/blackboard.py +819 -0
- package/scripts/check_permission.py +331 -0
- package/scripts/revoke_token.py +243 -0
- package/scripts/swarm_guard.py +1140 -0
- package/scripts/validate_token.py +97 -0
- package/types/agent-adapter.d.ts +244 -0
- package/types/openclaw-core.d.ts +52 -0
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LockedBlackboard - Atomic Commitment Layer for Multi-Agent Coordination
|
|
4
|
+
*
|
|
5
|
+
* This module provides file-system mutex locks to ensure atomic writes to the
|
|
6
|
+
* swarm-blackboard.md, preventing split-brain scenarios when multiple agents
|
|
7
|
+
* attempt concurrent updates.
|
|
8
|
+
*
|
|
9
|
+
* FEATURES:
|
|
10
|
+
* - File-system mutexes (cross-platform)
|
|
11
|
+
* - Atomic propose → validate → commit workflow
|
|
12
|
+
* - Deadlock prevention with lock timeouts
|
|
13
|
+
* - Split-brain detection and recovery
|
|
14
|
+
*
|
|
15
|
+
* @module LockedBlackboard
|
|
16
|
+
* @version 1.0.0
|
|
17
|
+
* @license MIT
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.LockedBlackboard = exports.FileLock = void 0;
|
|
21
|
+
const fs_1 = require("fs");
|
|
22
|
+
const path_1 = require("path");
|
|
23
|
+
const crypto_1 = require("crypto");
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// CONFIGURATION
|
|
26
|
+
// ============================================================================
|
|
27
|
+
const CONFIG = {
|
|
28
|
+
lockTimeoutMs: 10000, // 10 second lock timeout
|
|
29
|
+
lockRetryIntervalMs: 100, // Retry every 100ms
|
|
30
|
+
staleLockThresholdMs: 30000, // Consider lock stale after 30s
|
|
31
|
+
maxPendingChanges: 100, // Prevent memory bloat
|
|
32
|
+
};
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// FILE LOCK IMPLEMENTATION
|
|
35
|
+
// ============================================================================
|
|
36
|
+
/**
|
|
37
|
+
* Cross-platform file lock using lock files.
|
|
38
|
+
* Works on Windows, Linux, and macOS.
|
|
39
|
+
*/
|
|
40
|
+
class FileLock {
|
|
41
|
+
lockPath;
|
|
42
|
+
lockHolder = null;
|
|
43
|
+
lockFd = null;
|
|
44
|
+
constructor(lockPath) {
|
|
45
|
+
this.lockPath = lockPath;
|
|
46
|
+
this.ensureDir();
|
|
47
|
+
}
|
|
48
|
+
ensureDir() {
|
|
49
|
+
const dir = (0, path_1.dirname)(this.lockPath);
|
|
50
|
+
if (!(0, fs_1.existsSync)(dir)) {
|
|
51
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Attempt to acquire the lock with timeout.
|
|
56
|
+
* @param holderId Unique identifier for the lock holder
|
|
57
|
+
* @param timeoutMs Maximum time to wait for lock (default: CONFIG.lockTimeoutMs)
|
|
58
|
+
* @returns true if lock acquired, false if timeout
|
|
59
|
+
*/
|
|
60
|
+
acquire(holderId, timeoutMs = CONFIG.lockTimeoutMs) {
|
|
61
|
+
const startTime = Date.now();
|
|
62
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
63
|
+
// Check for stale lock
|
|
64
|
+
if ((0, fs_1.existsSync)(this.lockPath)) {
|
|
65
|
+
try {
|
|
66
|
+
const lockData = JSON.parse((0, fs_1.readFileSync)(this.lockPath, 'utf-8'));
|
|
67
|
+
const lockAge = Date.now() - new Date(lockData.acquired_at).getTime();
|
|
68
|
+
// If lock is stale, force release it
|
|
69
|
+
if (lockAge > CONFIG.staleLockThresholdMs) {
|
|
70
|
+
console.warn(`[FileLock] Stale lock detected (${lockAge}ms old), force releasing`);
|
|
71
|
+
this.forceRelease();
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// Lock is held by someone else, wait and retry
|
|
75
|
+
this.sleep(CONFIG.lockRetryIntervalMs);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Corrupted lock file, remove it
|
|
81
|
+
this.forceRelease();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Try to create lock file atomically
|
|
85
|
+
try {
|
|
86
|
+
// Use exclusive flag to prevent race conditions
|
|
87
|
+
this.lockFd = (0, fs_1.openSync)(this.lockPath, 'wx');
|
|
88
|
+
const lockData = {
|
|
89
|
+
holder: holderId,
|
|
90
|
+
acquired_at: new Date().toISOString(),
|
|
91
|
+
timeout_at: new Date(Date.now() + CONFIG.lockTimeoutMs).toISOString(),
|
|
92
|
+
pid: process.pid
|
|
93
|
+
};
|
|
94
|
+
(0, fs_1.writeFileSync)(this.lockPath, JSON.stringify(lockData, null, 2));
|
|
95
|
+
this.lockHolder = holderId;
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (error.code === 'EEXIST') {
|
|
100
|
+
// Lock file already exists, retry
|
|
101
|
+
this.sleep(CONFIG.lockRetryIntervalMs);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return false; // Timeout
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Release the lock if we hold it.
|
|
111
|
+
*/
|
|
112
|
+
release() {
|
|
113
|
+
if (!this.lockHolder) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
if (this.lockFd !== null) {
|
|
118
|
+
(0, fs_1.closeSync)(this.lockFd);
|
|
119
|
+
this.lockFd = null;
|
|
120
|
+
}
|
|
121
|
+
if ((0, fs_1.existsSync)(this.lockPath)) {
|
|
122
|
+
(0, fs_1.unlinkSync)(this.lockPath);
|
|
123
|
+
}
|
|
124
|
+
this.lockHolder = null;
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.error('[FileLock] Failed to release lock:', error);
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Force release a stale lock (use with caution).
|
|
134
|
+
*/
|
|
135
|
+
forceRelease() {
|
|
136
|
+
try {
|
|
137
|
+
if ((0, fs_1.existsSync)(this.lockPath)) {
|
|
138
|
+
(0, fs_1.unlinkSync)(this.lockPath);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// Ignore errors during force release
|
|
143
|
+
}
|
|
144
|
+
this.lockHolder = null;
|
|
145
|
+
this.lockFd = null;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Check current lock status.
|
|
149
|
+
*/
|
|
150
|
+
getStatus() {
|
|
151
|
+
if (!(0, fs_1.existsSync)(this.lockPath)) {
|
|
152
|
+
return { locked: false };
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const lockData = JSON.parse((0, fs_1.readFileSync)(this.lockPath, 'utf-8'));
|
|
156
|
+
return {
|
|
157
|
+
locked: true,
|
|
158
|
+
holder: lockData.holder,
|
|
159
|
+
acquired_at: lockData.acquired_at,
|
|
160
|
+
timeout_at: lockData.timeout_at
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return { locked: false };
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Check if we hold the lock.
|
|
169
|
+
*/
|
|
170
|
+
isHeldByMe() {
|
|
171
|
+
return this.lockHolder !== null;
|
|
172
|
+
}
|
|
173
|
+
sleep(ms) {
|
|
174
|
+
const end = Date.now() + ms;
|
|
175
|
+
while (Date.now() < end) {
|
|
176
|
+
// Busy wait (Node.js doesn't have sync sleep)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
exports.FileLock = FileLock;
|
|
181
|
+
// ============================================================================
|
|
182
|
+
// LOCKED BLACKBOARD IMPLEMENTATION
|
|
183
|
+
// ============================================================================
|
|
184
|
+
/**
|
|
185
|
+
* LockedBlackboard - Thread-safe blackboard with atomic commits.
|
|
186
|
+
*
|
|
187
|
+
* Usage:
|
|
188
|
+
* ```typescript
|
|
189
|
+
* const blackboard = new LockedBlackboard('./');
|
|
190
|
+
*
|
|
191
|
+
* // Atomic write workflow
|
|
192
|
+
* const changeId = blackboard.propose('task:123', { status: 'done' }, 'agent-1');
|
|
193
|
+
* const isValid = blackboard.validate(changeId, 'orchestrator');
|
|
194
|
+
* if (isValid) {
|
|
195
|
+
* blackboard.commit(changeId);
|
|
196
|
+
* } else {
|
|
197
|
+
* blackboard.abort(changeId);
|
|
198
|
+
* }
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
class LockedBlackboard {
|
|
202
|
+
basePath;
|
|
203
|
+
blackboardPath;
|
|
204
|
+
lockPath;
|
|
205
|
+
pendingDir;
|
|
206
|
+
lock;
|
|
207
|
+
cache = new Map();
|
|
208
|
+
pendingChanges = new Map();
|
|
209
|
+
constructor(basePath = '.') {
|
|
210
|
+
this.basePath = basePath;
|
|
211
|
+
this.blackboardPath = (0, path_1.join)(basePath, 'swarm-blackboard.md');
|
|
212
|
+
this.lockPath = (0, path_1.join)(basePath, 'data', '.blackboard.lock');
|
|
213
|
+
this.pendingDir = (0, path_1.join)(basePath, 'data', 'pending_changes');
|
|
214
|
+
this.lock = new FileLock(this.lockPath);
|
|
215
|
+
this.initialize();
|
|
216
|
+
}
|
|
217
|
+
initialize() {
|
|
218
|
+
// Ensure directories exist
|
|
219
|
+
if (!(0, fs_1.existsSync)((0, path_1.dirname)(this.blackboardPath))) {
|
|
220
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(this.blackboardPath), { recursive: true });
|
|
221
|
+
}
|
|
222
|
+
if (!(0, fs_1.existsSync)(this.pendingDir)) {
|
|
223
|
+
(0, fs_1.mkdirSync)(this.pendingDir, { recursive: true });
|
|
224
|
+
}
|
|
225
|
+
// Initialize blackboard file if needed
|
|
226
|
+
if (!(0, fs_1.existsSync)(this.blackboardPath)) {
|
|
227
|
+
this.writeInitialBlackboard();
|
|
228
|
+
}
|
|
229
|
+
// Load existing data
|
|
230
|
+
this.loadFromDisk();
|
|
231
|
+
this.loadPendingChanges();
|
|
232
|
+
}
|
|
233
|
+
writeInitialBlackboard() {
|
|
234
|
+
const content = `# Swarm Blackboard
|
|
235
|
+
Last Updated: ${new Date().toISOString()}
|
|
236
|
+
Content Hash: ${this.computeHash('')}
|
|
237
|
+
|
|
238
|
+
## Active Tasks
|
|
239
|
+
| TaskID | Agent | Status | Started | Description |
|
|
240
|
+
|--------|-------|--------|---------|-------------|
|
|
241
|
+
|
|
242
|
+
## Knowledge Cache
|
|
243
|
+
<!-- Cached results from agent operations -->
|
|
244
|
+
|
|
245
|
+
## Coordination Signals
|
|
246
|
+
<!-- Agent availability status -->
|
|
247
|
+
|
|
248
|
+
## Execution History
|
|
249
|
+
<!-- Chronological log of completed tasks -->
|
|
250
|
+
`;
|
|
251
|
+
(0, fs_1.writeFileSync)(this.blackboardPath, content, 'utf-8');
|
|
252
|
+
}
|
|
253
|
+
computeHash(content) {
|
|
254
|
+
return (0, crypto_1.createHash)('sha256').update(content).digest('hex').substring(0, 16);
|
|
255
|
+
}
|
|
256
|
+
loadFromDisk() {
|
|
257
|
+
try {
|
|
258
|
+
const content = (0, fs_1.readFileSync)(this.blackboardPath, 'utf-8');
|
|
259
|
+
const cacheSection = content.match(/## Knowledge Cache\n([\s\S]*?)(?=\n## |$)/);
|
|
260
|
+
if (cacheSection) {
|
|
261
|
+
const entries = Array.from(cacheSection[1].matchAll(/### (\S+)\n```json\n([\s\S]*?)\n```/g));
|
|
262
|
+
for (const entry of entries) {
|
|
263
|
+
const key = entry[1];
|
|
264
|
+
try {
|
|
265
|
+
const data = JSON.parse(entry[2]);
|
|
266
|
+
this.cache.set(key, data);
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
// Skip malformed entries
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
console.error('[LockedBlackboard] Failed to load from disk:', error);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
loadPendingChanges() {
|
|
279
|
+
try {
|
|
280
|
+
if (!(0, fs_1.existsSync)(this.pendingDir))
|
|
281
|
+
return;
|
|
282
|
+
const files = (0, fs_1.readdirSync)(this.pendingDir);
|
|
283
|
+
for (const file of files) {
|
|
284
|
+
if (!file.endsWith('.json') || file.includes('.committed') || file.includes('.aborted')) {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
try {
|
|
288
|
+
const content = (0, fs_1.readFileSync)((0, path_1.join)(this.pendingDir, file), 'utf-8');
|
|
289
|
+
const change = JSON.parse(content);
|
|
290
|
+
if (change.status === 'pending' || change.status === 'validated') {
|
|
291
|
+
this.pendingChanges.set(change.change_id, change);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
catch {
|
|
295
|
+
// Skip corrupted files
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
// Enforce max pending changes limit
|
|
299
|
+
if (this.pendingChanges.size > CONFIG.maxPendingChanges) {
|
|
300
|
+
console.warn(`[LockedBlackboard] Too many pending changes (${this.pendingChanges.size}), cleaning up old ones`);
|
|
301
|
+
this.cleanupOldPendingChanges();
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
console.error('[LockedBlackboard] Failed to load pending changes:', error);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
cleanupOldPendingChanges() {
|
|
309
|
+
const sorted = Array.from(this.pendingChanges.entries())
|
|
310
|
+
.sort((a, b) => new Date(a[1].proposed_at).getTime() - new Date(b[1].proposed_at).getTime());
|
|
311
|
+
// Keep only the newest half
|
|
312
|
+
const toRemove = sorted.slice(0, Math.floor(sorted.length / 2));
|
|
313
|
+
for (const [changeId] of toRemove) {
|
|
314
|
+
this.abort(changeId);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
persistToDisk() {
|
|
318
|
+
const holderId = `writer-${(0, crypto_1.randomUUID)().substring(0, 8)}`;
|
|
319
|
+
if (!this.lock.acquire(holderId)) {
|
|
320
|
+
throw new Error('Failed to acquire lock for writing to blackboard');
|
|
321
|
+
}
|
|
322
|
+
try {
|
|
323
|
+
const cacheContent = Array.from(this.cache.entries())
|
|
324
|
+
.filter(([, entry]) => !this.isExpired(entry))
|
|
325
|
+
.map(([key, entry]) => `### ${key}\n\`\`\`json\n${JSON.stringify(entry, null, 2)}\n\`\`\``)
|
|
326
|
+
.join('\n\n');
|
|
327
|
+
const content = `# Swarm Blackboard
|
|
328
|
+
Last Updated: ${new Date().toISOString()}
|
|
329
|
+
Content Hash: ${this.computeHash(cacheContent)}
|
|
330
|
+
|
|
331
|
+
## Active Tasks
|
|
332
|
+
| TaskID | Agent | Status | Started | Description |
|
|
333
|
+
|--------|-------|--------|---------|-------------|
|
|
334
|
+
|
|
335
|
+
## Knowledge Cache
|
|
336
|
+
${cacheContent}
|
|
337
|
+
|
|
338
|
+
## Coordination Signals
|
|
339
|
+
<!-- Agent availability status -->
|
|
340
|
+
|
|
341
|
+
## Execution History
|
|
342
|
+
<!-- Chronological log of completed tasks -->
|
|
343
|
+
`;
|
|
344
|
+
(0, fs_1.writeFileSync)(this.blackboardPath, content, 'utf-8');
|
|
345
|
+
}
|
|
346
|
+
finally {
|
|
347
|
+
this.lock.release();
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
isExpired(entry) {
|
|
351
|
+
if (!entry.ttl)
|
|
352
|
+
return false;
|
|
353
|
+
const expiresAt = new Date(entry.timestamp).getTime() + entry.ttl * 1000;
|
|
354
|
+
return Date.now() > expiresAt;
|
|
355
|
+
}
|
|
356
|
+
savePendingChange(change) {
|
|
357
|
+
const filePath = (0, path_1.join)(this.pendingDir, `${change.change_id}.json`);
|
|
358
|
+
(0, fs_1.writeFileSync)(filePath, JSON.stringify(change, null, 2));
|
|
359
|
+
}
|
|
360
|
+
archivePendingChange(change) {
|
|
361
|
+
const archiveDir = (0, path_1.join)(this.pendingDir, 'archive');
|
|
362
|
+
if (!(0, fs_1.existsSync)(archiveDir)) {
|
|
363
|
+
(0, fs_1.mkdirSync)(archiveDir, { recursive: true });
|
|
364
|
+
}
|
|
365
|
+
const sourcePath = (0, path_1.join)(this.pendingDir, `${change.change_id}.json`);
|
|
366
|
+
const archivePath = (0, path_1.join)(archiveDir, `${change.change_id}.${change.status}.json`);
|
|
367
|
+
try {
|
|
368
|
+
if ((0, fs_1.existsSync)(sourcePath)) {
|
|
369
|
+
(0, fs_1.writeFileSync)(archivePath, JSON.stringify(change, null, 2));
|
|
370
|
+
(0, fs_1.unlinkSync)(sourcePath);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
console.error('[LockedBlackboard] Failed to archive change:', error);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// ==========================================================================
|
|
378
|
+
// PUBLIC API: ATOMIC COMMIT WORKFLOW
|
|
379
|
+
// ==========================================================================
|
|
380
|
+
/**
|
|
381
|
+
* STEP 1: Propose a change (does NOT modify blackboard yet).
|
|
382
|
+
* @returns change_id for use in validate/commit/abort
|
|
383
|
+
*/
|
|
384
|
+
propose(key, value, sourceAgent, ttl) {
|
|
385
|
+
const changeId = `chg_${(0, crypto_1.randomUUID)().substring(0, 8)}`;
|
|
386
|
+
// Get current hash for conflict detection
|
|
387
|
+
const currentEntry = this.cache.get(key);
|
|
388
|
+
const previousHash = currentEntry
|
|
389
|
+
? this.computeHash(JSON.stringify(currentEntry))
|
|
390
|
+
: null;
|
|
391
|
+
const change = {
|
|
392
|
+
change_id: changeId,
|
|
393
|
+
key,
|
|
394
|
+
value,
|
|
395
|
+
source_agent: sourceAgent,
|
|
396
|
+
proposed_at: new Date().toISOString(),
|
|
397
|
+
ttl: ttl ?? null,
|
|
398
|
+
status: 'pending',
|
|
399
|
+
previous_hash: previousHash
|
|
400
|
+
};
|
|
401
|
+
this.pendingChanges.set(changeId, change);
|
|
402
|
+
this.savePendingChange(change);
|
|
403
|
+
return changeId;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* STEP 2: Validate a proposed change (check for conflicts).
|
|
407
|
+
* Typically called by the orchestrator before committing.
|
|
408
|
+
* @returns true if change can be safely committed
|
|
409
|
+
*/
|
|
410
|
+
validate(changeId, validatorAgent) {
|
|
411
|
+
const change = this.pendingChanges.get(changeId);
|
|
412
|
+
if (!change) {
|
|
413
|
+
console.error(`[LockedBlackboard] Change ${changeId} not found`);
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
if (change.status !== 'pending') {
|
|
417
|
+
console.error(`[LockedBlackboard] Change ${changeId} is ${change.status}, cannot validate`);
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
// Check for conflicts (has the key been modified since proposal?)
|
|
421
|
+
const currentEntry = this.cache.get(change.key);
|
|
422
|
+
const currentHash = currentEntry
|
|
423
|
+
? this.computeHash(JSON.stringify(currentEntry))
|
|
424
|
+
: null;
|
|
425
|
+
if (change.previous_hash !== currentHash) {
|
|
426
|
+
console.warn(`[LockedBlackboard] CONFLICT DETECTED for ${change.key}: ` +
|
|
427
|
+
`expected hash ${change.previous_hash}, got ${currentHash}`);
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
// Mark as validated
|
|
431
|
+
change.status = 'validated';
|
|
432
|
+
change.validation = {
|
|
433
|
+
validated_at: new Date().toISOString(),
|
|
434
|
+
validated_by: validatorAgent
|
|
435
|
+
};
|
|
436
|
+
this.savePendingChange(change);
|
|
437
|
+
return true;
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* STEP 3a: Commit a validated change (applies to blackboard).
|
|
441
|
+
* @returns CommitResult with success status
|
|
442
|
+
*/
|
|
443
|
+
commit(changeId) {
|
|
444
|
+
const change = this.pendingChanges.get(changeId);
|
|
445
|
+
if (!change) {
|
|
446
|
+
return {
|
|
447
|
+
success: false,
|
|
448
|
+
change_id: changeId,
|
|
449
|
+
message: `Change ${changeId} not found`
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
if (change.status !== 'validated') {
|
|
453
|
+
return {
|
|
454
|
+
success: false,
|
|
455
|
+
change_id: changeId,
|
|
456
|
+
message: `Change ${changeId} is ${change.status}, must be validated first`
|
|
457
|
+
};
|
|
458
|
+
}
|
|
459
|
+
// Acquire lock and apply change atomically
|
|
460
|
+
const holderId = `commit-${changeId}`;
|
|
461
|
+
if (!this.lock.acquire(holderId)) {
|
|
462
|
+
return {
|
|
463
|
+
success: false,
|
|
464
|
+
change_id: changeId,
|
|
465
|
+
message: 'Failed to acquire lock for commit'
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
try {
|
|
469
|
+
// Double-check for conflicts under lock
|
|
470
|
+
const currentEntry = this.cache.get(change.key);
|
|
471
|
+
const currentHash = currentEntry
|
|
472
|
+
? this.computeHash(JSON.stringify(currentEntry))
|
|
473
|
+
: null;
|
|
474
|
+
if (change.previous_hash !== currentHash) {
|
|
475
|
+
change.status = 'aborted';
|
|
476
|
+
this.savePendingChange(change);
|
|
477
|
+
this.archivePendingChange(change);
|
|
478
|
+
this.pendingChanges.delete(changeId);
|
|
479
|
+
return {
|
|
480
|
+
success: false,
|
|
481
|
+
change_id: changeId,
|
|
482
|
+
message: `CONFLICT: Key ${change.key} was modified since validation`
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
// Apply the change
|
|
486
|
+
const newVersion = (currentEntry?.version ?? 0) + 1;
|
|
487
|
+
const entry = {
|
|
488
|
+
key: change.key,
|
|
489
|
+
value: change.value,
|
|
490
|
+
source_agent: change.source_agent,
|
|
491
|
+
timestamp: new Date().toISOString(),
|
|
492
|
+
ttl: change.ttl,
|
|
493
|
+
version: newVersion
|
|
494
|
+
};
|
|
495
|
+
this.cache.set(change.key, entry);
|
|
496
|
+
change.status = 'committed';
|
|
497
|
+
// Persist to disk (still under lock)
|
|
498
|
+
this.persistToDiskInternal();
|
|
499
|
+
// Archive the change
|
|
500
|
+
this.archivePendingChange(change);
|
|
501
|
+
this.pendingChanges.delete(changeId);
|
|
502
|
+
return {
|
|
503
|
+
success: true,
|
|
504
|
+
change_id: changeId,
|
|
505
|
+
message: `Successfully committed ${change.key} (v${newVersion})`,
|
|
506
|
+
entry
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
finally {
|
|
510
|
+
this.lock.release();
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* STEP 3b: Abort a proposed/validated change.
|
|
515
|
+
*/
|
|
516
|
+
abort(changeId) {
|
|
517
|
+
const change = this.pendingChanges.get(changeId);
|
|
518
|
+
if (!change) {
|
|
519
|
+
return false;
|
|
520
|
+
}
|
|
521
|
+
change.status = 'aborted';
|
|
522
|
+
this.archivePendingChange(change);
|
|
523
|
+
this.pendingChanges.delete(changeId);
|
|
524
|
+
return true;
|
|
525
|
+
}
|
|
526
|
+
// Internal persist without acquiring lock (called when already holding lock)
|
|
527
|
+
persistToDiskInternal() {
|
|
528
|
+
const cacheContent = Array.from(this.cache.entries())
|
|
529
|
+
.filter(([, entry]) => !this.isExpired(entry))
|
|
530
|
+
.map(([key, entry]) => `### ${key}\n\`\`\`json\n${JSON.stringify(entry, null, 2)}\n\`\`\``)
|
|
531
|
+
.join('\n\n');
|
|
532
|
+
const content = `# Swarm Blackboard
|
|
533
|
+
Last Updated: ${new Date().toISOString()}
|
|
534
|
+
Content Hash: ${this.computeHash(cacheContent)}
|
|
535
|
+
|
|
536
|
+
## Active Tasks
|
|
537
|
+
| TaskID | Agent | Status | Started | Description |
|
|
538
|
+
|--------|-------|--------|---------|-------------|
|
|
539
|
+
|
|
540
|
+
## Knowledge Cache
|
|
541
|
+
${cacheContent}
|
|
542
|
+
|
|
543
|
+
## Coordination Signals
|
|
544
|
+
<!-- Agent availability status -->
|
|
545
|
+
|
|
546
|
+
## Execution History
|
|
547
|
+
<!-- Chronological log of completed tasks -->
|
|
548
|
+
`;
|
|
549
|
+
(0, fs_1.writeFileSync)(this.blackboardPath, content, 'utf-8');
|
|
550
|
+
}
|
|
551
|
+
// ==========================================================================
|
|
552
|
+
// PUBLIC API: SIMPLE READ/WRITE (with automatic locking)
|
|
553
|
+
// ==========================================================================
|
|
554
|
+
/**
|
|
555
|
+
* Read a value from the blackboard.
|
|
556
|
+
*/
|
|
557
|
+
read(key) {
|
|
558
|
+
const entry = this.cache.get(key);
|
|
559
|
+
if (!entry)
|
|
560
|
+
return null;
|
|
561
|
+
if (this.isExpired(entry)) {
|
|
562
|
+
this.cache.delete(key);
|
|
563
|
+
this.persistToDisk();
|
|
564
|
+
return null;
|
|
565
|
+
}
|
|
566
|
+
return entry;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Direct write with automatic locking (use propose/validate/commit for multi-agent safety).
|
|
570
|
+
*/
|
|
571
|
+
write(key, value, sourceAgent, ttl) {
|
|
572
|
+
const holderId = `write-${(0, crypto_1.randomUUID)().substring(0, 8)}`;
|
|
573
|
+
if (!this.lock.acquire(holderId)) {
|
|
574
|
+
throw new Error('Failed to acquire lock for write');
|
|
575
|
+
}
|
|
576
|
+
try {
|
|
577
|
+
const currentEntry = this.cache.get(key);
|
|
578
|
+
const newVersion = (currentEntry?.version ?? 0) + 1;
|
|
579
|
+
const entry = {
|
|
580
|
+
key,
|
|
581
|
+
value,
|
|
582
|
+
source_agent: sourceAgent,
|
|
583
|
+
timestamp: new Date().toISOString(),
|
|
584
|
+
ttl: ttl ?? null,
|
|
585
|
+
version: newVersion
|
|
586
|
+
};
|
|
587
|
+
this.cache.set(key, entry);
|
|
588
|
+
this.persistToDiskInternal();
|
|
589
|
+
return entry;
|
|
590
|
+
}
|
|
591
|
+
finally {
|
|
592
|
+
this.lock.release();
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Delete a key from the blackboard.
|
|
597
|
+
*/
|
|
598
|
+
delete(key) {
|
|
599
|
+
const holderId = `delete-${(0, crypto_1.randomUUID)().substring(0, 8)}`;
|
|
600
|
+
if (!this.lock.acquire(holderId)) {
|
|
601
|
+
throw new Error('Failed to acquire lock for delete');
|
|
602
|
+
}
|
|
603
|
+
try {
|
|
604
|
+
if (this.cache.has(key)) {
|
|
605
|
+
this.cache.delete(key);
|
|
606
|
+
this.persistToDiskInternal();
|
|
607
|
+
return true;
|
|
608
|
+
}
|
|
609
|
+
return false;
|
|
610
|
+
}
|
|
611
|
+
finally {
|
|
612
|
+
this.lock.release();
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* List all valid keys.
|
|
617
|
+
*/
|
|
618
|
+
listKeys() {
|
|
619
|
+
return Array.from(this.cache.keys()).filter(key => {
|
|
620
|
+
const entry = this.cache.get(key);
|
|
621
|
+
return entry && !this.isExpired(entry);
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Get full snapshot of blackboard state.
|
|
626
|
+
*/
|
|
627
|
+
getSnapshot() {
|
|
628
|
+
const snapshot = {};
|
|
629
|
+
for (const [key, entry] of Array.from(this.cache.entries())) {
|
|
630
|
+
if (!this.isExpired(entry)) {
|
|
631
|
+
snapshot[key] = entry;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
return snapshot;
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* List all pending changes.
|
|
638
|
+
*/
|
|
639
|
+
listPendingChanges() {
|
|
640
|
+
return Array.from(this.pendingChanges.values());
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Get lock status.
|
|
644
|
+
*/
|
|
645
|
+
getLockStatus() {
|
|
646
|
+
return this.lock.getStatus();
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
exports.LockedBlackboard = LockedBlackboard;
|
|
650
|
+
// ============================================================================
|
|
651
|
+
// EXPORTS
|
|
652
|
+
// ============================================================================
|
|
653
|
+
exports.default = LockedBlackboard;
|
|
654
|
+
//# sourceMappingURL=locked-blackboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locked-blackboard.js","sourceRoot":"","sources":["../../lib/locked-blackboard.ts"],"names":[],"mappings":"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"}
|