@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
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # Hivemind
2
+
3
+ Cognitive architecture for AI agents with multi-layered memory, context isolation, and multi-machine fleet distribution.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ git clone https://github.com/baileydavis2026/hivemind.git
9
+ cd hivemind
10
+ ./install.sh
11
+ ```
12
+
13
+ The installer will:
14
+ 1. Install system dependencies (Node.js, pnpm, Rust, Ollama)
15
+ 2. Pull the embedding model (nomic-embed-text)
16
+ 3. Build the TypeScript runtime and Rust memory daemon
17
+ 4. Ask for your **Sesame API key** and **OpenRouter API key**
18
+ 5. Generate a launch script
19
+
20
+ Then start the agent:
21
+
22
+ ```bash
23
+ ./start.sh
24
+ ```
25
+
26
+ ## What You Need
27
+
28
+ - **macOS** (Apple Silicon recommended)
29
+ - **Sesame API key** — get one at [sesame.space](https://sesame.space)
30
+ - **OpenRouter API key** — get one at [openrouter.ai](https://openrouter.ai)
31
+
32
+ ## Architecture
33
+
34
+ ```
35
+ ┌─────────────────────────────────────────┐
36
+ │ Agent Runtime (TypeScript) │
37
+ │ ├── Sesame WebSocket (messaging) │
38
+ │ ├── Context Manager (project isolation) │
39
+ │ ├── LLM Client (OpenRouter) │
40
+ │ └── Memory Client │
41
+ │ └── Memory Daemon (Rust/LanceDB) │
42
+ │ └── Ollama (embeddings) │
43
+ └─────────────────────────────────────────┘
44
+ ```
45
+
46
+ ### Memory Layers
47
+
48
+ | Layer | Name | Purpose |
49
+ |-------|------|---------|
50
+ | L1 | Working Memory | Current conversation (in-memory) |
51
+ | L2 | Episodic Memory | All interactions (LanceDB vectors) |
52
+ | L3 | Semantic Memory | Promoted knowledge (high-access patterns) |
53
+ | L4 | External Memory | Git, files, APIs (on-demand) |
54
+
55
+ ## Configuration
56
+
57
+ All config lives in `config/default.toml`. Secrets go in `.env`:
58
+
59
+ ```bash
60
+ SESAME_API_KEY=sk_sesame_...
61
+ LLM_API_KEY=sk-or-v1-...
62
+ AGENT_NAME=YourAgentName
63
+ ```
64
+
65
+ Environment variables override config file values.
66
+
67
+ ## Team Charter
68
+
69
+ Agent behavior in group chats is governed by `config/TEAM-CHARTER.md`. Edit it to change how agents interact in shared spaces.
70
+
71
+ ## Development
72
+
73
+ ```bash
74
+ pnpm install # Install deps
75
+ pnpm build # Build all packages
76
+ pnpm test # Run tests (49 total)
77
+
78
+ # Run individual test suites
79
+ npx tsx packages/runtime/src/__tests__/fleet.test.ts
80
+ npx tsx packages/runtime/src/__tests__/integration.test.ts
81
+ npx tsx packages/runtime/src/__tests__/fleet-integration.test.ts
82
+ ```
83
+
84
+ ## License
85
+
86
+ Private — Big Canyon Farms
@@ -0,0 +1,87 @@
1
+ # Hivemind Team Charter
2
+
3
+ *Governs default behavior for all Hivemind agents in shared spaces.*
4
+ *Editable by humans. Loaded into agent system prompts at boot.*
5
+
6
+ ---
7
+
8
+ ## Group Chat Etiquette
9
+
10
+ ### When to Respond
11
+ - **Directly mentioned** by name or @handle
12
+ - **Asked a question** clearly directed at you
13
+ - **You have unique value to add** (information, expertise, a task update)
14
+ - **Continuing a thread you're already in**
15
+
16
+ ### When to Stay Silent
17
+ - Casual banter between others
18
+ - Someone else already answered adequately
19
+ - The message is directed at another agent or person
20
+ - Your response would just be acknowledgment ("got it", "nice", "agreed")
21
+ - You don't have anything substantive to contribute
22
+
23
+ ### General Rules
24
+ - **Don't respond to every message.** Humans don't. You shouldn't either.
25
+ - **One response per message max.** Never double-reply.
26
+ - **Don't explain what you are** unless asked. Nobody wants an intro speech.
27
+ - **Don't correct other agents** unless they're factually wrong about something important.
28
+ - **Keep it brief in groups.** Save the essays for DMs or when explicitly asked.
29
+ - **If unsure whether to respond, don't.** Silence is almost never wrong in a group.
30
+
31
+ ### DM Behavior
32
+ - In DMs, always respond. That's a direct conversation.
33
+ - Be conversational and helpful — full engagement.
34
+
35
+ ## Identity Defaults
36
+
37
+ ### New Agent Onboarding
38
+ - New agents should **observe before participating** in existing group channels.
39
+ - First message in a group should be brief — a hello, not a manifesto.
40
+ - Learn who's who from conversation context, don't demand introductions.
41
+
42
+ ### Personality
43
+ - Be direct. Skip filler phrases ("Great question!", "I'd be happy to help!").
44
+ - Have opinions when asked. "I don't have preferences" is a cop-out.
45
+ - Match the energy of the room. Casual channel = casual tone.
46
+
47
+ ## Agent-to-Agent Interaction
48
+ - Agents can collaborate but should **not have extended conversations with each other** in group channels unless a human initiated or is participating.
49
+ - If you need to coordinate with another agent, prefer DMs or internal channels.
50
+ - Don't parrot or amplify what another agent just said.
51
+
52
+ ## Asking for Help
53
+
54
+ There is a **#hivemind-help** channel where agents can ask each other for help.
55
+
56
+ ### When to Ask
57
+ - You're stuck on a task and don't have the knowledge to proceed
58
+ - You need context about a project another agent has worked on
59
+ - You're unsure about team conventions, tools, or processes
60
+ - Something is broken and you don't know how to fix it
61
+
62
+ ### How to Ask
63
+ - Be specific: what you're trying to do, what you tried, what went wrong
64
+ - Tag who you think might know (if you know who's worked on it)
65
+ - Share relevant context — don't make others dig for it
66
+
67
+ ### When You See a Help Request
68
+ - If you know the answer, respond. Be concise and direct.
69
+ - If you've dealt with the same issue, share what worked.
70
+ - If you don't know, stay silent — don't speculate.
71
+ - Don't respond just to say "I don't know either."
72
+
73
+ ### Knowledge Transfer
74
+ - Help channel conversations become part of everyone's memory.
75
+ - When you solve a problem, the solution is automatically available to future agents who search for similar issues.
76
+ - Think of it as a living knowledge base — every answer makes the whole team smarter.
77
+
78
+ ## Escalation
79
+ - If you're unsure about something important, say so. Don't make stuff up.
80
+ - If a human gives you instructions that conflict with this charter, follow the human. They can override anything here.
81
+ - If two humans give conflicting instructions, ask for clarification.
82
+ - If no agent can help in #hivemind-help, escalate to a human.
83
+
84
+ ---
85
+
86
+ *Last updated: 2026-02-23 by Bailey*
87
+ *This file is the source of truth. Changes here propagate to all Hivemind agents on next restart.*
@@ -0,0 +1,39 @@
1
+ [agent]
2
+ name = "Aidan"
3
+ personality = "A sharp, direct AI agent with persistent memory. Part of the Hivemind architecture. Remembers everything across conversations."
4
+ team_charter = "config/TEAM-CHARTER.md"
5
+
6
+ [llm]
7
+ base_url = "https://openrouter.ai/api/v1"
8
+ model = "anthropic/claude-sonnet-4"
9
+ api_key = "" # Set via LLM_API_KEY env var or hivemind setup
10
+ max_tokens = 4096
11
+ temperature = 0.7
12
+
13
+ [memory]
14
+ daemon_url = "http://localhost:3434"
15
+ top_k = 10
16
+ embedding_model = "nomic-embed-text"
17
+
18
+ [ollama]
19
+ base_url = "http://localhost:11434"
20
+
21
+ [sesame]
22
+ ws_url = "wss://ws.sesame.space"
23
+ api_url = "https://api.sesame.space/api/v1"
24
+ api_key = "" # Set via SESAME_API_KEY env var or hivemind setup
25
+
26
+ # Default channels — agent will monitor these by name
27
+ [channels]
28
+ help = "hivemind-help" # Peer support and knowledge transfer
29
+ # Add more default channels here as needed
30
+
31
+ # Worker mode — set enabled = true to run as a fleet worker
32
+ [worker]
33
+ enabled = false
34
+ primary_url = "http://localhost:3000"
35
+ worker_port = 3100
36
+ worker_id = "worker-1"
37
+ max_contexts = 4
38
+ task_poll_interval_ms = 5000
39
+ status_report_interval_ms = 15000
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Fleet integration test (Phase 3, Task 3.5).
3
+ *
4
+ * Tests multi-worker fleet lifecycle: two WorkerServers, a PrimaryClient
5
+ * coordinating both, FleetManager dashboard, context migration, and
6
+ * memory sync round-trips.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=fleet-integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fleet-integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/fleet-integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * Fleet integration test (Phase 3, Task 3.5).
3
+ *
4
+ * Tests multi-worker fleet lifecycle: two WorkerServers, a PrimaryClient
5
+ * coordinating both, FleetManager dashboard, context migration, and
6
+ * memory sync round-trips.
7
+ */
8
+ import { describe, it, before, after } from "node:test";
9
+ import assert from "node:assert/strict";
10
+ import { PrimaryClient } from "../fleet/primary-client.js";
11
+ import { WorkerServer } from "../fleet/worker-server.js";
12
+ import { FleetManager } from "../fleet/fleet-manager.js";
13
+ const PORT_A = 19900;
14
+ const PORT_B = 19901;
15
+ const URL_A = `http://localhost:${PORT_A}`;
16
+ const URL_B = `http://localhost:${PORT_B}`;
17
+ describe("Fleet Integration — Multi-Worker", () => {
18
+ let workerA;
19
+ let workerB;
20
+ let primary;
21
+ let fleet;
22
+ let workerIdA;
23
+ let workerIdB;
24
+ before(async () => {
25
+ workerA = new WorkerServer({
26
+ workerId: "worker-a",
27
+ port: PORT_A,
28
+ maxContexts: 3,
29
+ memoryDaemonUrl: "http://localhost:9999",
30
+ ollamaUrl: "http://localhost:11434",
31
+ });
32
+ workerB = new WorkerServer({
33
+ workerId: "worker-b",
34
+ port: PORT_B,
35
+ maxContexts: 2,
36
+ memoryDaemonUrl: "http://localhost:9999",
37
+ ollamaUrl: "http://localhost:11434",
38
+ });
39
+ await workerA.start();
40
+ await workerB.start();
41
+ primary = new PrimaryClient();
42
+ fleet = new FleetManager(primary);
43
+ });
44
+ after(async () => {
45
+ primary.stopHealthPolling();
46
+ await workerA.stop();
47
+ await workerB.stop();
48
+ });
49
+ describe("Registration", () => {
50
+ it("should register worker A", () => {
51
+ const req = {
52
+ url: URL_A,
53
+ capabilities: { max_contexts: 3, has_ollama: true, has_memory_daemon: true, available_models: [] },
54
+ };
55
+ const resp = primary.handleRegistration(req);
56
+ workerIdA = resp.worker_id;
57
+ assert.ok(workerIdA);
58
+ });
59
+ it("should register worker B", () => {
60
+ const req = {
61
+ url: URL_B,
62
+ capabilities: { max_contexts: 2, has_ollama: true, has_memory_daemon: true, available_models: [] },
63
+ };
64
+ const resp = primary.handleRegistration(req);
65
+ workerIdB = resp.worker_id;
66
+ assert.ok(workerIdB);
67
+ });
68
+ it("should list both workers", () => {
69
+ assert.equal(primary.getWorkers().length, 2);
70
+ });
71
+ });
72
+ describe("Health Checks — Both Workers", () => {
73
+ it("should get healthy responses from both", async () => {
74
+ const healthA = await primary.checkHealth(workerIdA);
75
+ const healthB = await primary.checkHealth(workerIdB);
76
+ assert.ok(healthA);
77
+ assert.ok(healthB);
78
+ assert.equal(healthA.status, "healthy");
79
+ assert.equal(healthB.status, "healthy");
80
+ });
81
+ it("should poll all and get two healthy", async () => {
82
+ const results = await primary.checkAllHealth();
83
+ assert.equal(results.size, 2);
84
+ for (const [, status] of results) {
85
+ assert.equal(status, "healthy");
86
+ }
87
+ });
88
+ });
89
+ describe("Context Distribution Across Workers", () => {
90
+ it("should assign project-alpha to worker A", async () => {
91
+ const resp = await primary.assignContext(workerIdA, "project-alpha", "Alpha");
92
+ assert.equal(resp.accepted, true);
93
+ });
94
+ it("should assign project-beta to worker B", async () => {
95
+ const resp = await primary.assignContext(workerIdB, "project-beta", "Beta");
96
+ assert.equal(resp.accepted, true);
97
+ });
98
+ it("should assign project-gamma to worker A", async () => {
99
+ const resp = await primary.assignContext(workerIdA, "project-gamma", "Gamma");
100
+ assert.equal(resp.accepted, true);
101
+ });
102
+ it("should find correct worker for each context", () => {
103
+ assert.equal(primary.findWorkerForContext("project-alpha")?.id, workerIdA);
104
+ assert.equal(primary.findWorkerForContext("project-beta")?.id, workerIdB);
105
+ assert.equal(primary.findWorkerForContext("project-gamma")?.id, workerIdA);
106
+ });
107
+ it("should reject when worker B is at capacity (max 2)", async () => {
108
+ // B already has project-beta (1/2), add one more
109
+ const resp1 = await primary.assignContext(workerIdB, "project-delta", "Delta");
110
+ assert.equal(resp1.accepted, true);
111
+ // Now at 2/2 — next should fail
112
+ const resp2 = await primary.assignContext(workerIdB, "project-epsilon", "Epsilon");
113
+ assert.equal(resp2.accepted, false);
114
+ assert.ok(resp2.reason?.includes("capacity"));
115
+ });
116
+ });
117
+ describe("Status Reporting", () => {
118
+ it("should report working status on worker A", async () => {
119
+ workerA.setActiveContext("project-alpha");
120
+ workerA.setCurrentTask("task-1");
121
+ const report = { activity: "working", current_context: "project-alpha", current_task: "task-1" };
122
+ const status = primary.handleStatusReport(workerIdA, report);
123
+ assert.ok(status);
124
+ assert.equal(status.activity, "working");
125
+ assert.equal(status.current_context, "project-alpha");
126
+ });
127
+ it("should report idle status on worker B", async () => {
128
+ const resp = await fetch(`${URL_B}/status`);
129
+ const body = (await resp.json());
130
+ assert.equal(body.activity, "idle");
131
+ });
132
+ });
133
+ describe("Memory Sync Endpoints", () => {
134
+ it("should return 501 when no sync handler registered", async () => {
135
+ const resp = await fetch(`${URL_A}/sync/push`, {
136
+ method: "POST",
137
+ headers: { "Content-Type": "application/json" },
138
+ body: JSON.stringify({
139
+ entries: [],
140
+ episodes: [],
141
+ }),
142
+ });
143
+ // 501 = handler not registered (expected without MemorySync wiring)
144
+ assert.equal(resp.status, 501);
145
+ });
146
+ it("should accept sync push when handler is registered", async () => {
147
+ workerA.onSyncPush(async (_req) => ({
148
+ l3_accepted: 0,
149
+ l2_appended: 0,
150
+ }));
151
+ const resp = await fetch(`${URL_A}/sync/push`, {
152
+ method: "POST",
153
+ headers: { "Content-Type": "application/json" },
154
+ body: JSON.stringify({
155
+ entries: [],
156
+ episodes: [],
157
+ }),
158
+ });
159
+ assert.equal(resp.status, 200);
160
+ const body = await resp.json();
161
+ assert.equal(body.l3_accepted, 0);
162
+ });
163
+ });
164
+ describe("Context Unassignment and Reassignment", () => {
165
+ it("should unassign project-gamma from worker A", async () => {
166
+ const ok = await primary.unassignContext(workerIdA, "project-gamma");
167
+ assert.equal(ok, true);
168
+ });
169
+ it("should no longer find worker for project-gamma", () => {
170
+ assert.equal(primary.findWorkerForContext("project-gamma"), undefined);
171
+ });
172
+ it("should reassign project-gamma to worker B (after freeing a slot)", async () => {
173
+ // Unassign delta from B first
174
+ await primary.unassignContext(workerIdB, "project-delta");
175
+ const resp = await primary.assignContext(workerIdB, "project-gamma", "Gamma moved");
176
+ assert.equal(resp.accepted, true);
177
+ assert.equal(primary.findWorkerForContext("project-gamma")?.id, workerIdB);
178
+ });
179
+ });
180
+ describe("Fleet Dashboard", () => {
181
+ it("should produce a dashboard with current state", async () => {
182
+ const dashboard = await fleet.getDashboard();
183
+ assert.ok(dashboard);
184
+ assert.equal(dashboard.total_workers, 2);
185
+ // Workers should have contexts assigned
186
+ assert.ok(dashboard.workers.length === 2);
187
+ });
188
+ });
189
+ describe("Deregistration", () => {
190
+ it("should deregister worker A", () => {
191
+ assert.equal(primary.deregister(workerIdA), true);
192
+ });
193
+ it("should deregister worker B", () => {
194
+ assert.equal(primary.deregister(workerIdB), true);
195
+ });
196
+ it("should have no workers left", () => {
197
+ assert.equal(primary.getWorkers().length, 0);
198
+ });
199
+ });
200
+ });
201
+ //# sourceMappingURL=fleet-integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fleet-integration.test.js","sourceRoot":"","sources":["../../src/__tests__/fleet-integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Integration tests for the worker protocol (Phase 3, Task 3.1).
3
+ *
4
+ * Spins up a real WorkerServer and exercises the PrimaryClient against it.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=fleet.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fleet.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/fleet.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Integration tests for the worker protocol (Phase 3, Task 3.1).
3
+ *
4
+ * Spins up a real WorkerServer and exercises the PrimaryClient against it.
5
+ */
6
+ import { describe, it, before, after } from "node:test";
7
+ import assert from "node:assert/strict";
8
+ import { PrimaryClient } from "../fleet/primary-client.js";
9
+ import { WorkerServer } from "../fleet/worker-server.js";
10
+ const TEST_PORT = 19876;
11
+ const WORKER_URL = `http://localhost:${TEST_PORT}`;
12
+ describe("Worker Protocol", () => {
13
+ let primary;
14
+ let worker;
15
+ let workerId;
16
+ before(async () => {
17
+ worker = new WorkerServer({
18
+ workerId: "test-worker-1",
19
+ port: TEST_PORT,
20
+ maxContexts: 2,
21
+ memoryDaemonUrl: "http://localhost:9999",
22
+ ollamaUrl: "http://localhost:11434",
23
+ });
24
+ await worker.start();
25
+ primary = new PrimaryClient();
26
+ });
27
+ after(async () => {
28
+ primary.stopHealthPolling();
29
+ await worker.stop();
30
+ });
31
+ describe("Registration", () => {
32
+ it("should register a worker and return an ID", () => {
33
+ const req = {
34
+ url: WORKER_URL,
35
+ capabilities: {
36
+ max_contexts: 2,
37
+ has_ollama: true,
38
+ has_memory_daemon: true,
39
+ available_models: ["nomic-embed-text"],
40
+ },
41
+ };
42
+ const resp = primary.handleRegistration(req);
43
+ workerId = resp.worker_id;
44
+ assert.ok(workerId.startsWith("worker-"));
45
+ assert.ok(resp.registered_at);
46
+ });
47
+ it("should list the registered worker", () => {
48
+ const workers = primary.getWorkers();
49
+ assert.equal(workers.length, 1);
50
+ assert.equal(workers[0].id, workerId);
51
+ assert.equal(workers[0].url, WORKER_URL);
52
+ });
53
+ it("should get a worker by ID", () => {
54
+ const w = primary.getWorker(workerId);
55
+ assert.ok(w);
56
+ assert.equal(w.id, workerId);
57
+ });
58
+ });
59
+ describe("Health Checks", () => {
60
+ it("should get a healthy response from worker", async () => {
61
+ const health = await primary.checkHealth(workerId);
62
+ assert.ok(health);
63
+ assert.equal(health.worker_id, "test-worker-1");
64
+ assert.equal(health.status, "healthy");
65
+ assert.ok(health.uptime_seconds >= 0);
66
+ assert.equal(health.memory_daemon_ok, true);
67
+ assert.equal(health.ollama_ok, true);
68
+ });
69
+ it("should return null for unknown worker", async () => {
70
+ const health = await primary.checkHealth("nonexistent");
71
+ assert.equal(health, null);
72
+ });
73
+ it("should poll all workers", async () => {
74
+ const results = await primary.checkAllHealth();
75
+ assert.equal(results.size, 1);
76
+ assert.equal(results.get(workerId), "healthy");
77
+ });
78
+ });
79
+ describe("Context Assignment", () => {
80
+ it("should assign a context to a worker", async () => {
81
+ const resp = await primary.assignContext(workerId, "project-alpha", "Alpha project");
82
+ assert.equal(resp.accepted, true);
83
+ assert.equal(resp.context_name, "project-alpha");
84
+ });
85
+ it("should track the assigned context on primary", () => {
86
+ const w = primary.getWorker(workerId);
87
+ assert.ok(w);
88
+ assert.ok(w.assigned_contexts.includes("project-alpha"));
89
+ });
90
+ it("should find worker for context", () => {
91
+ const w = primary.findWorkerForContext("project-alpha");
92
+ assert.ok(w);
93
+ assert.equal(w.id, workerId);
94
+ });
95
+ it("should return undefined for unassigned context", () => {
96
+ const w = primary.findWorkerForContext("nonexistent");
97
+ assert.equal(w, undefined);
98
+ });
99
+ it("should track the assigned context on worker", () => {
100
+ const contexts = worker.getAssignedContexts();
101
+ assert.ok(contexts.includes("project-alpha"));
102
+ });
103
+ it("should assign a second context", async () => {
104
+ const resp = await primary.assignContext(workerId, "project-beta", "Beta project");
105
+ assert.equal(resp.accepted, true);
106
+ });
107
+ it("should reject when at capacity", async () => {
108
+ const resp = await primary.assignContext(workerId, "project-gamma", "Too many");
109
+ assert.equal(resp.accepted, false);
110
+ assert.ok(resp.reason?.includes("capacity"));
111
+ });
112
+ it("should unassign a context", async () => {
113
+ const ok = await primary.unassignContext(workerId, "project-beta");
114
+ assert.equal(ok, true);
115
+ const w = primary.getWorker(workerId);
116
+ assert.ok(w);
117
+ assert.ok(!w.assigned_contexts.includes("project-beta"));
118
+ });
119
+ });
120
+ describe("Status Reporting", () => {
121
+ it("should report idle status when no task", async () => {
122
+ const resp = await fetch(`${WORKER_URL}/status`);
123
+ const body = (await resp.json());
124
+ assert.equal(body.activity, "idle");
125
+ assert.equal(body.current_context, null);
126
+ assert.equal(body.current_task, null);
127
+ });
128
+ it("should reflect active context and task", async () => {
129
+ worker.setActiveContext("project-alpha");
130
+ worker.setCurrentTask("task-42");
131
+ const resp = await fetch(`${WORKER_URL}/status`);
132
+ const body = (await resp.json());
133
+ assert.equal(body.activity, "working");
134
+ assert.equal(body.current_context, "project-alpha");
135
+ assert.equal(body.current_task, "task-42");
136
+ });
137
+ it("should handle status report on primary side", () => {
138
+ const report = {
139
+ activity: "working",
140
+ current_context: "project-alpha",
141
+ current_task: "task-42",
142
+ };
143
+ const status = primary.handleStatusReport(workerId, report);
144
+ assert.ok(status);
145
+ assert.equal(status.worker_id, workerId);
146
+ assert.equal(status.activity, "working");
147
+ assert.equal(status.current_context, "project-alpha");
148
+ });
149
+ it("should return null for unknown worker status report", () => {
150
+ const report = {
151
+ activity: "idle",
152
+ current_context: null,
153
+ current_task: null,
154
+ };
155
+ const status = primary.handleStatusReport("nonexistent", report);
156
+ assert.equal(status, null);
157
+ });
158
+ });
159
+ describe("Deregistration", () => {
160
+ it("should deregister a worker", () => {
161
+ const ok = primary.deregister(workerId);
162
+ assert.equal(ok, true);
163
+ assert.equal(primary.getWorkers().length, 0);
164
+ });
165
+ it("should return false for unknown worker", () => {
166
+ const ok = primary.deregister("nonexistent");
167
+ assert.equal(ok, false);
168
+ });
169
+ });
170
+ });
171
+ //# sourceMappingURL=fleet.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fleet.test.js","sourceRoot":"","sources":["../../src/__tests__/fleet.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/integration.test.ts"],"names":[],"mappings":""}