@sesamespace/hivemind 0.1.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.
Files changed (110) hide show
  1. package/README.md +86 -0
  2. package/config/TEAM-CHARTER.md +87 -0
  3. package/config/default.toml +39 -0
  4. package/dist/__tests__/fleet-integration.test.d.ts +9 -0
  5. package/dist/__tests__/fleet-integration.test.d.ts.map +1 -0
  6. package/dist/__tests__/fleet-integration.test.js +201 -0
  7. package/dist/__tests__/fleet-integration.test.js.map +1 -0
  8. package/dist/__tests__/fleet.test.d.ts +7 -0
  9. package/dist/__tests__/fleet.test.d.ts.map +1 -0
  10. package/dist/__tests__/fleet.test.js +171 -0
  11. package/dist/__tests__/fleet.test.js.map +1 -0
  12. package/dist/__tests__/integration.test.d.ts +2 -0
  13. package/dist/__tests__/integration.test.d.ts.map +1 -0
  14. package/dist/__tests__/integration.test.js +348 -0
  15. package/dist/__tests__/integration.test.js.map +1 -0
  16. package/dist/agent.d.ts +27 -0
  17. package/dist/agent.d.ts.map +1 -0
  18. package/dist/agent.js +217 -0
  19. package/dist/agent.js.map +1 -0
  20. package/dist/commands/fleet.d.ts +13 -0
  21. package/dist/commands/fleet.d.ts.map +1 -0
  22. package/dist/commands/fleet.js +193 -0
  23. package/dist/commands/fleet.js.map +1 -0
  24. package/dist/commands/init.d.ts +2 -0
  25. package/dist/commands/init.d.ts.map +1 -0
  26. package/dist/commands/init.js +170 -0
  27. package/dist/commands/init.js.map +1 -0
  28. package/dist/commands/start.d.ts +2 -0
  29. package/dist/commands/start.d.ts.map +1 -0
  30. package/dist/commands/start.js +39 -0
  31. package/dist/commands/start.js.map +1 -0
  32. package/dist/config.d.ts +44 -0
  33. package/dist/config.d.ts.map +1 -0
  34. package/dist/config.js +73 -0
  35. package/dist/config.js.map +1 -0
  36. package/dist/context.d.ts +50 -0
  37. package/dist/context.d.ts.map +1 -0
  38. package/dist/context.js +153 -0
  39. package/dist/context.js.map +1 -0
  40. package/dist/fleet/fleet-manager.d.ts +86 -0
  41. package/dist/fleet/fleet-manager.d.ts.map +1 -0
  42. package/dist/fleet/fleet-manager.js +298 -0
  43. package/dist/fleet/fleet-manager.js.map +1 -0
  44. package/dist/fleet/memory-sync.d.ts +91 -0
  45. package/dist/fleet/memory-sync.d.ts.map +1 -0
  46. package/dist/fleet/memory-sync.js +292 -0
  47. package/dist/fleet/memory-sync.js.map +1 -0
  48. package/dist/fleet/primary-client.d.ts +49 -0
  49. package/dist/fleet/primary-client.d.ts.map +1 -0
  50. package/dist/fleet/primary-client.js +222 -0
  51. package/dist/fleet/primary-client.js.map +1 -0
  52. package/dist/fleet/worker-protocol.d.ts +125 -0
  53. package/dist/fleet/worker-protocol.d.ts.map +1 -0
  54. package/dist/fleet/worker-protocol.js +27 -0
  55. package/dist/fleet/worker-protocol.js.map +1 -0
  56. package/dist/fleet/worker-server.d.ts +53 -0
  57. package/dist/fleet/worker-server.d.ts.map +1 -0
  58. package/dist/fleet/worker-server.js +191 -0
  59. package/dist/fleet/worker-server.js.map +1 -0
  60. package/dist/index.d.ts +26 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +16 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/llm-client.d.ts +24 -0
  65. package/dist/llm-client.d.ts.map +1 -0
  66. package/dist/llm-client.js +40 -0
  67. package/dist/llm-client.js.map +1 -0
  68. package/dist/main.d.ts +3 -0
  69. package/dist/main.d.ts.map +1 -0
  70. package/dist/main.js +41 -0
  71. package/dist/main.js.map +1 -0
  72. package/dist/memory-client.d.ts +88 -0
  73. package/dist/memory-client.d.ts.map +1 -0
  74. package/dist/memory-client.js +185 -0
  75. package/dist/memory-client.js.map +1 -0
  76. package/dist/pipeline.d.ts +2 -0
  77. package/dist/pipeline.d.ts.map +1 -0
  78. package/dist/pipeline.js +125 -0
  79. package/dist/pipeline.js.map +1 -0
  80. package/dist/prompt.d.ts +6 -0
  81. package/dist/prompt.d.ts.map +1 -0
  82. package/dist/prompt.js +75 -0
  83. package/dist/prompt.js.map +1 -0
  84. package/dist/sesame.d.ts +33 -0
  85. package/dist/sesame.d.ts.map +1 -0
  86. package/dist/sesame.js +67 -0
  87. package/dist/sesame.js.map +1 -0
  88. package/dist/start.d.ts +3 -0
  89. package/dist/start.d.ts.map +1 -0
  90. package/dist/start.js +20 -0
  91. package/dist/start.js.map +1 -0
  92. package/dist/task-engine.d.ts +32 -0
  93. package/dist/task-engine.d.ts.map +1 -0
  94. package/dist/task-engine.js +80 -0
  95. package/dist/task-engine.js.map +1 -0
  96. package/dist/worker.d.ts +73 -0
  97. package/dist/worker.d.ts.map +1 -0
  98. package/dist/worker.js +279 -0
  99. package/dist/worker.js.map +1 -0
  100. package/install.sh +186 -0
  101. package/package.json +36 -0
  102. package/packages/memory/Cargo.lock +6480 -0
  103. package/packages/memory/Cargo.toml +21 -0
  104. package/packages/memory/src/src/context.rs +179 -0
  105. package/packages/memory/src/src/embeddings.rs +51 -0
  106. package/packages/memory/src/src/main.rs +626 -0
  107. package/packages/memory/src/src/promotion.rs +637 -0
  108. package/packages/memory/src/src/scoring.rs +131 -0
  109. package/packages/memory/src/src/store.rs +460 -0
  110. package/packages/memory/src/src/tasks.rs +321 -0
@@ -0,0 +1,292 @@
1
+ /**
2
+ * Cross-machine memory sync.
3
+ *
4
+ * Workers periodically push key L3 knowledge back to the Primary.
5
+ * Primary can push Global context updates (L3 + L2 episodes) to workers.
6
+ *
7
+ * Conflict resolution:
8
+ * - L3: last-write-wins (compared by updated_at timestamp)
9
+ * - L2: append-only (episodes are never overwritten, only added)
10
+ *
11
+ * Sync protocol:
12
+ * POST /sync/pull — Worker sends L3 knowledge to Primary
13
+ * POST /sync/push — Primary sends Global context updates to Worker
14
+ */
15
+ import { DEFAULT_SYNC_INTERVAL_MS, HEALTH_TIMEOUT_MS, PRIMARY_ROUTES } from "./worker-protocol.js";
16
+ // --- Helpers ---
17
+ function l3ToSync(entry) {
18
+ return {
19
+ id: entry.id,
20
+ source_episode_id: entry.source_episode_id,
21
+ context_name: entry.context_name,
22
+ content: entry.content,
23
+ promoted_at: entry.promoted_at,
24
+ access_count: entry.access_count,
25
+ connection_density: entry.connection_density,
26
+ updated_at: entry.promoted_at,
27
+ };
28
+ }
29
+ function episodeToSync(ep) {
30
+ return {
31
+ id: ep.id,
32
+ timestamp: ep.timestamp,
33
+ context_name: ep.context_name,
34
+ role: ep.role,
35
+ content: ep.content,
36
+ };
37
+ }
38
+ /**
39
+ * Worker-side memory sync. Periodically sends L3 knowledge from assigned
40
+ * contexts back to the Primary, and accepts Global context pushes.
41
+ */
42
+ export class WorkerMemorySync {
43
+ workerId;
44
+ primaryUrl;
45
+ memory;
46
+ syncTimer = null;
47
+ syncIntervalMs;
48
+ knownL2Ids = new Set();
49
+ knownL3Ids = new Map(); // id -> updated_at
50
+ constructor(opts) {
51
+ this.workerId = opts.workerId;
52
+ this.primaryUrl = opts.primaryUrl;
53
+ this.memory = opts.memory;
54
+ this.syncIntervalMs = opts.syncIntervalMs ?? DEFAULT_SYNC_INTERVAL_MS;
55
+ // Register handler for incoming Global context pushes from Primary
56
+ opts.server.onSyncPush((req) => this.handlePush(req));
57
+ }
58
+ /** Start periodic sync (Worker -> Primary). */
59
+ start(contextNames) {
60
+ this.stop();
61
+ this.syncTimer = setInterval(() => {
62
+ this.pullTowardsPrimary(contextNames()).catch((err) => {
63
+ console.warn("[sync] Pull cycle failed:", err.message);
64
+ });
65
+ }, this.syncIntervalMs);
66
+ }
67
+ /** Stop periodic sync. */
68
+ stop() {
69
+ if (this.syncTimer) {
70
+ clearInterval(this.syncTimer);
71
+ this.syncTimer = null;
72
+ }
73
+ }
74
+ /**
75
+ * Pull L3 knowledge from all assigned contexts and send to Primary.
76
+ * Called periodically by the sync timer.
77
+ */
78
+ async pullTowardsPrimary(contextNames) {
79
+ for (const contextName of contextNames) {
80
+ try {
81
+ const entries = await this.memory.getL3Knowledge(contextName);
82
+ if (entries.length === 0)
83
+ continue;
84
+ const syncEntries = entries.map(l3ToSync);
85
+ const req = {
86
+ worker_id: this.workerId,
87
+ context_name: contextName,
88
+ entries: syncEntries,
89
+ };
90
+ const controller = new AbortController();
91
+ const timeout = setTimeout(() => controller.abort(), HEALTH_TIMEOUT_MS);
92
+ const resp = await fetch(`${this.primaryUrl}${PRIMARY_ROUTES.syncPull}`, {
93
+ method: "POST",
94
+ headers: { "Content-Type": "application/json" },
95
+ body: JSON.stringify(req),
96
+ signal: controller.signal,
97
+ });
98
+ clearTimeout(timeout);
99
+ if (resp.ok) {
100
+ const result = (await resp.json());
101
+ if (result.accepted > 0) {
102
+ console.log(`[sync] Pushed ${result.accepted} L3 entries from "${contextName}" to Primary`);
103
+ }
104
+ }
105
+ }
106
+ catch {
107
+ // Primary unreachable — will retry next interval
108
+ }
109
+ }
110
+ }
111
+ /**
112
+ * Handle an incoming push of Global context updates from the Primary.
113
+ * L3: last-write-wins. L2: append-only.
114
+ */
115
+ async handlePush(req) {
116
+ let l3Accepted = 0;
117
+ let l2Appended = 0;
118
+ // Process L3 entries with last-write-wins
119
+ for (const entry of req.entries) {
120
+ const existing = this.knownL3Ids.get(entry.id);
121
+ if (existing && existing >= entry.updated_at) {
122
+ // Local version is same or newer — skip
123
+ continue;
124
+ }
125
+ // Store in local memory daemon (the memory daemon's L3 store handles upsert)
126
+ try {
127
+ // Store as an episode in the global context so the worker has access
128
+ await this.memory.storeEpisode({
129
+ context_name: entry.context_name,
130
+ role: "system",
131
+ content: entry.content,
132
+ });
133
+ this.knownL3Ids.set(entry.id, entry.updated_at);
134
+ l3Accepted++;
135
+ }
136
+ catch {
137
+ // Non-fatal — entry will be retried on next push
138
+ }
139
+ }
140
+ // Process L2 episodes as append-only
141
+ for (const episode of req.episodes) {
142
+ if (this.knownL2Ids.has(episode.id)) {
143
+ continue; // Already stored
144
+ }
145
+ try {
146
+ await this.memory.storeEpisode({
147
+ context_name: episode.context_name,
148
+ role: episode.role,
149
+ content: episode.content,
150
+ });
151
+ this.knownL2Ids.add(episode.id);
152
+ l2Appended++;
153
+ }
154
+ catch {
155
+ // Non-fatal
156
+ }
157
+ }
158
+ if (l3Accepted > 0 || l2Appended > 0) {
159
+ console.log(`[sync] Received push: ${l3Accepted} L3 accepted, ${l2Appended} L2 appended`);
160
+ }
161
+ return { l3_accepted: l3Accepted, l2_appended: l2Appended };
162
+ }
163
+ getSyncIntervalMs() {
164
+ return this.syncIntervalMs;
165
+ }
166
+ }
167
+ /**
168
+ * Primary-side memory sync. Handles incoming L3 pulls from workers and
169
+ * can push Global context updates out to all workers.
170
+ */
171
+ export class PrimaryMemorySync {
172
+ primary;
173
+ memory;
174
+ syncIntervalMs;
175
+ pushTimer = null;
176
+ l3Store = new Map(); // id -> latest entry
177
+ lastPushAt = new Date(0).toISOString();
178
+ constructor(opts) {
179
+ this.primary = opts.primary;
180
+ this.memory = opts.memory;
181
+ this.syncIntervalMs = opts.syncIntervalMs ?? DEFAULT_SYNC_INTERVAL_MS;
182
+ // Register handler for incoming L3 pulls from workers
183
+ this.primary.onSyncPull((req) => this.handlePull(req));
184
+ }
185
+ /**
186
+ * Handle an incoming pull — Worker sending L3 knowledge to Primary.
187
+ * Uses last-write-wins for conflict resolution.
188
+ */
189
+ async handlePull(req) {
190
+ let accepted = 0;
191
+ let rejected = 0;
192
+ for (const entry of req.entries) {
193
+ const existing = this.l3Store.get(entry.id);
194
+ if (existing && existing.updated_at >= entry.updated_at) {
195
+ // Primary has same or newer version — reject
196
+ rejected++;
197
+ continue;
198
+ }
199
+ // Accept the entry — store locally
200
+ this.l3Store.set(entry.id, entry);
201
+ // Persist to Primary's memory daemon
202
+ try {
203
+ await this.memory.storeEpisode({
204
+ context_name: entry.context_name,
205
+ role: "system",
206
+ content: entry.content,
207
+ });
208
+ }
209
+ catch {
210
+ // Non-fatal — the in-memory store is the source of truth for sync
211
+ }
212
+ accepted++;
213
+ }
214
+ if (accepted > 0) {
215
+ console.log(`[sync] Accepted ${accepted} L3 entries from worker "${req.worker_id}" context "${req.context_name}"`);
216
+ }
217
+ return { accepted, rejected };
218
+ }
219
+ /**
220
+ * Push Global context updates to all workers.
221
+ * Fetches current Global L3 knowledge and recent L2 episodes,
222
+ * then pushes to every registered worker.
223
+ */
224
+ async pushGlobalToAll() {
225
+ // Gather Global context L3 knowledge
226
+ let l3Entries = [];
227
+ try {
228
+ const knowledge = await this.memory.getL3Knowledge("global");
229
+ l3Entries = knowledge.map(l3ToSync);
230
+ }
231
+ catch {
232
+ // Memory daemon may not have global context yet
233
+ }
234
+ // Gather recent Global L2 episodes (append-only)
235
+ let l2Episodes = [];
236
+ try {
237
+ const episodes = await this.memory.getContext("global");
238
+ // Only send episodes newer than last push
239
+ l2Episodes = episodes
240
+ .filter((ep) => ep.timestamp > this.lastPushAt)
241
+ .map(episodeToSync);
242
+ }
243
+ catch {
244
+ // Memory daemon may not have global context yet
245
+ }
246
+ if (l3Entries.length === 0 && l2Episodes.length === 0) {
247
+ return new Map();
248
+ }
249
+ const payload = {
250
+ entries: l3Entries,
251
+ episodes: l2Episodes,
252
+ };
253
+ this.lastPushAt = new Date().toISOString();
254
+ const results = await this.primary.pushSyncToAll(payload);
255
+ let totalL3 = 0;
256
+ let totalL2 = 0;
257
+ for (const resp of results.values()) {
258
+ if (resp) {
259
+ totalL3 += resp.l3_accepted;
260
+ totalL2 += resp.l2_appended;
261
+ }
262
+ }
263
+ if (totalL3 > 0 || totalL2 > 0) {
264
+ console.log(`[sync] Pushed Global updates: ${totalL3} L3, ${totalL2} L2 across ${results.size} workers`);
265
+ }
266
+ return results;
267
+ }
268
+ /** Start periodic Global push to all workers. */
269
+ startPushLoop() {
270
+ this.stopPushLoop();
271
+ this.pushTimer = setInterval(() => {
272
+ this.pushGlobalToAll().catch((err) => {
273
+ console.warn("[sync] Push cycle failed:", err.message);
274
+ });
275
+ }, this.syncIntervalMs);
276
+ }
277
+ /** Stop periodic push. */
278
+ stopPushLoop() {
279
+ if (this.pushTimer) {
280
+ clearInterval(this.pushTimer);
281
+ this.pushTimer = null;
282
+ }
283
+ }
284
+ /** Get all synced L3 entries the Primary has received. */
285
+ getSyncedEntries() {
286
+ return Array.from(this.l3Store.values());
287
+ }
288
+ getSyncIntervalMs() {
289
+ return this.syncIntervalMs;
290
+ }
291
+ }
292
+ //# sourceMappingURL=memory-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-sync.js","sourceRoot":"","sources":["../../src/fleet/memory-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Primary-side client for managing Workers.
3
+ *
4
+ * The Primary uses this to:
5
+ * - Track registered workers
6
+ * - Poll worker health
7
+ * - Assign/unassign contexts to workers
8
+ * - Collect status reports
9
+ */
10
+ import type { WorkerInfo, WorkerRegistrationRequest, WorkerRegistrationResponse, WorkerHealthResponse, WorkerHealthStatus, WorkerStatus, WorkerStatusReport, ContextAssignResponse, SyncPushRequest, SyncPushResponse, SyncPullRequest, SyncPullResponse } from "./worker-protocol.js";
11
+ export declare class PrimaryClient {
12
+ private workers;
13
+ private healthTimer;
14
+ private nextId;
15
+ private onSyncPullCallback;
16
+ /** All registered workers. */
17
+ getWorkers(): WorkerInfo[];
18
+ /** Get a single worker by ID. */
19
+ getWorker(workerId: string): WorkerInfo | undefined;
20
+ /** Find which worker owns a context, if any. */
21
+ findWorkerForContext(contextName: string): WorkerInfo | undefined;
22
+ handleRegistration(req: WorkerRegistrationRequest): WorkerRegistrationResponse;
23
+ /** Remove a worker from the registry. */
24
+ deregister(workerId: string): boolean;
25
+ /** Poll a single worker's health endpoint. */
26
+ checkHealth(workerId: string): Promise<WorkerHealthResponse | null>;
27
+ /** Poll all workers and return their statuses. */
28
+ checkAllHealth(): Promise<Map<string, WorkerHealthStatus>>;
29
+ /** Start periodic health polling. */
30
+ startHealthPolling(intervalMs?: number): void;
31
+ /** Stop periodic health polling. */
32
+ stopHealthPolling(): void;
33
+ /** Assign a context to a worker. */
34
+ assignContext(workerId: string, contextName: string, contextDescription?: string): Promise<ContextAssignResponse>;
35
+ /** Unassign a context from a worker. */
36
+ unassignContext(workerId: string, contextName: string): Promise<boolean>;
37
+ /** Handle an incoming status report from a Worker. */
38
+ handleStatusReport(workerId: string, report: WorkerStatusReport): WorkerStatus | null;
39
+ /** Register a handler for incoming sync pull requests from Workers. */
40
+ onSyncPull(cb: (req: SyncPullRequest) => Promise<SyncPullResponse>): void;
41
+ /** Handle an incoming sync pull (Worker sends L3 knowledge to Primary). */
42
+ handleSyncPull(req: SyncPullRequest): Promise<SyncPullResponse>;
43
+ /** Push Global context updates to a specific worker. */
44
+ pushSyncToWorker(workerId: string, payload: SyncPushRequest): Promise<SyncPushResponse | null>;
45
+ /** Push Global context updates to all registered workers. */
46
+ pushSyncToAll(payload: SyncPushRequest): Promise<Map<string, SyncPushResponse | null>>;
47
+ private markUnreachable;
48
+ }
49
+ //# sourceMappingURL=primary-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primary-client.d.ts","sourceRoot":"","sources":["../../src/fleet/primary-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,yBAAyB,EACzB,0BAA0B,EAC1B,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAElB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAS9B,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,kBAAkB,CAAsE;IAEhG,8BAA8B;IAC9B,UAAU,IAAI,UAAU,EAAE;IAI1B,iCAAiC;IACjC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAInD,gDAAgD;IAChD,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IASjE,kBAAkB,CAAC,GAAG,EAAE,yBAAyB,GAAG,0BAA0B;IAiB9E,yCAAyC;IACzC,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAMrC,8CAA8C;IACxC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IA2BzE,kDAAkD;IAC5C,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAYhE,qCAAqC;IACrC,kBAAkB,CAAC,UAAU,SAA6B,GAAG,IAAI;IAOjE,oCAAoC;IACpC,iBAAiB,IAAI,IAAI;IASzB,oCAAoC;IAC9B,aAAa,CACjB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,kBAAkB,SAAK,GACtB,OAAO,CAAC,qBAAqB,CAAC;IAwCjC,wCAAwC;IAClC,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqB9E,sDAAsD;IACtD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,YAAY,GAAG,IAAI;IAkBrF,uEAAuE;IACvE,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAIzE,2EAA2E;IACrE,cAAc,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAOrE,wDAAwD;IAClD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAuBpG,6DAA6D;IACvD,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAc5F,OAAO,CAAC,eAAe;CAIxB"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Primary-side client for managing Workers.
3
+ *
4
+ * The Primary uses this to:
5
+ * - Track registered workers
6
+ * - Poll worker health
7
+ * - Assign/unassign contexts to workers
8
+ * - Collect status reports
9
+ */
10
+ import { WORKER_ROUTES, DEFAULT_HEALTH_INTERVAL_MS, HEALTH_TIMEOUT_MS, } from "./worker-protocol.js";
11
+ export class PrimaryClient {
12
+ workers = new Map();
13
+ healthTimer = null;
14
+ nextId = 1;
15
+ onSyncPullCallback = null;
16
+ /** All registered workers. */
17
+ getWorkers() {
18
+ return Array.from(this.workers.values());
19
+ }
20
+ /** Get a single worker by ID. */
21
+ getWorker(workerId) {
22
+ return this.workers.get(workerId);
23
+ }
24
+ /** Find which worker owns a context, if any. */
25
+ findWorkerForContext(contextName) {
26
+ for (const w of this.workers.values()) {
27
+ if (w.assigned_contexts.includes(contextName))
28
+ return w;
29
+ }
30
+ return undefined;
31
+ }
32
+ // --- Registration (called when Worker POSTs to Primary) ---
33
+ handleRegistration(req) {
34
+ const id = `worker-${this.nextId++}`;
35
+ const now = new Date().toISOString();
36
+ const info = {
37
+ id,
38
+ url: req.url,
39
+ capabilities: req.capabilities,
40
+ assigned_contexts: [],
41
+ registered_at: now,
42
+ last_heartbeat: now,
43
+ };
44
+ this.workers.set(id, info);
45
+ return { worker_id: id, registered_at: now };
46
+ }
47
+ /** Remove a worker from the registry. */
48
+ deregister(workerId) {
49
+ return this.workers.delete(workerId);
50
+ }
51
+ // --- Health Checking ---
52
+ /** Poll a single worker's health endpoint. */
53
+ async checkHealth(workerId) {
54
+ const worker = this.workers.get(workerId);
55
+ if (!worker)
56
+ return null;
57
+ try {
58
+ const controller = new AbortController();
59
+ const timeout = setTimeout(() => controller.abort(), HEALTH_TIMEOUT_MS);
60
+ const resp = await fetch(`${worker.url}${WORKER_ROUTES.health}`, {
61
+ signal: controller.signal,
62
+ });
63
+ clearTimeout(timeout);
64
+ if (!resp.ok) {
65
+ this.markUnreachable(workerId);
66
+ return null;
67
+ }
68
+ const health = (await resp.json());
69
+ worker.last_heartbeat = new Date().toISOString();
70
+ return health;
71
+ }
72
+ catch {
73
+ this.markUnreachable(workerId);
74
+ return null;
75
+ }
76
+ }
77
+ /** Poll all workers and return their statuses. */
78
+ async checkAllHealth() {
79
+ const results = new Map();
80
+ const checks = Array.from(this.workers.keys()).map(async (id) => {
81
+ const health = await this.checkHealth(id);
82
+ results.set(id, health?.status ?? "unreachable");
83
+ });
84
+ await Promise.all(checks);
85
+ return results;
86
+ }
87
+ /** Start periodic health polling. */
88
+ startHealthPolling(intervalMs = DEFAULT_HEALTH_INTERVAL_MS) {
89
+ this.stopHealthPolling();
90
+ this.healthTimer = setInterval(() => {
91
+ this.checkAllHealth().catch(() => { });
92
+ }, intervalMs);
93
+ }
94
+ /** Stop periodic health polling. */
95
+ stopHealthPolling() {
96
+ if (this.healthTimer) {
97
+ clearInterval(this.healthTimer);
98
+ this.healthTimer = null;
99
+ }
100
+ }
101
+ // --- Context Assignment ---
102
+ /** Assign a context to a worker. */
103
+ async assignContext(workerId, contextName, contextDescription = "") {
104
+ const worker = this.workers.get(workerId);
105
+ if (!worker) {
106
+ return { context_name: contextName, accepted: false, reason: "Worker not found" };
107
+ }
108
+ if (worker.assigned_contexts.length >= worker.capabilities.max_contexts) {
109
+ return { context_name: contextName, accepted: false, reason: "Worker at capacity" };
110
+ }
111
+ const body = {
112
+ context_name: contextName,
113
+ context_description: contextDescription,
114
+ };
115
+ try {
116
+ const resp = await fetch(`${worker.url}${WORKER_ROUTES.assign}`, {
117
+ method: "POST",
118
+ headers: { "Content-Type": "application/json" },
119
+ body: JSON.stringify(body),
120
+ });
121
+ if (!resp.ok) {
122
+ const text = await resp.text();
123
+ return { context_name: contextName, accepted: false, reason: `Worker rejected: ${text}` };
124
+ }
125
+ const result = (await resp.json());
126
+ if (result.accepted) {
127
+ worker.assigned_contexts.push(contextName);
128
+ }
129
+ return result;
130
+ }
131
+ catch (err) {
132
+ const msg = err instanceof Error ? err.message : String(err);
133
+ return { context_name: contextName, accepted: false, reason: `Request failed: ${msg}` };
134
+ }
135
+ }
136
+ /** Unassign a context from a worker. */
137
+ async unassignContext(workerId, contextName) {
138
+ const worker = this.workers.get(workerId);
139
+ if (!worker)
140
+ return false;
141
+ try {
142
+ const resp = await fetch(`${worker.url}${WORKER_ROUTES.unassign(contextName)}`, {
143
+ method: "DELETE",
144
+ });
145
+ if (resp.ok) {
146
+ worker.assigned_contexts = worker.assigned_contexts.filter((c) => c !== contextName);
147
+ return true;
148
+ }
149
+ return false;
150
+ }
151
+ catch {
152
+ return false;
153
+ }
154
+ }
155
+ // --- Status Collection ---
156
+ /** Handle an incoming status report from a Worker. */
157
+ handleStatusReport(workerId, report) {
158
+ const worker = this.workers.get(workerId);
159
+ if (!worker)
160
+ return null;
161
+ worker.last_heartbeat = new Date().toISOString();
162
+ return {
163
+ worker_id: workerId,
164
+ activity: report.activity,
165
+ current_context: report.current_context,
166
+ current_task: report.current_task,
167
+ error: report.error,
168
+ reported_at: new Date().toISOString(),
169
+ };
170
+ }
171
+ // --- Memory Sync ---
172
+ /** Register a handler for incoming sync pull requests from Workers. */
173
+ onSyncPull(cb) {
174
+ this.onSyncPullCallback = cb;
175
+ }
176
+ /** Handle an incoming sync pull (Worker sends L3 knowledge to Primary). */
177
+ async handleSyncPull(req) {
178
+ if (!this.onSyncPullCallback) {
179
+ return { accepted: 0, rejected: req.entries.length };
180
+ }
181
+ return this.onSyncPullCallback(req);
182
+ }
183
+ /** Push Global context updates to a specific worker. */
184
+ async pushSyncToWorker(workerId, payload) {
185
+ const worker = this.workers.get(workerId);
186
+ if (!worker)
187
+ return null;
188
+ try {
189
+ const controller = new AbortController();
190
+ const timeout = setTimeout(() => controller.abort(), HEALTH_TIMEOUT_MS);
191
+ const resp = await fetch(`${worker.url}${WORKER_ROUTES.syncPush}`, {
192
+ method: "POST",
193
+ headers: { "Content-Type": "application/json" },
194
+ body: JSON.stringify(payload),
195
+ signal: controller.signal,
196
+ });
197
+ clearTimeout(timeout);
198
+ if (!resp.ok)
199
+ return null;
200
+ return (await resp.json());
201
+ }
202
+ catch {
203
+ return null;
204
+ }
205
+ }
206
+ /** Push Global context updates to all registered workers. */
207
+ async pushSyncToAll(payload) {
208
+ const results = new Map();
209
+ const pushes = Array.from(this.workers.keys()).map(async (id) => {
210
+ const result = await this.pushSyncToWorker(id, payload);
211
+ results.set(id, result);
212
+ });
213
+ await Promise.all(pushes);
214
+ return results;
215
+ }
216
+ // --- Internal ---
217
+ markUnreachable(workerId) {
218
+ // Worker stays registered but health is tracked via last_heartbeat staleness.
219
+ // Fleet manager (Phase 3.3) will decide when to evict.
220
+ }
221
+ }
222
+ //# sourceMappingURL=primary-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primary-client.js","sourceRoot":"","sources":["../../src/fleet/primary-client.ts"],"names":[],"mappings":"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"}