agent-comms 2.21.14 → 2.21.16

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.
@@ -15,7 +15,7 @@
15
15
  "url": "https://github.com/ExaDev/agent-comms.git"
16
16
  },
17
17
  "description": "Cross-harness LLM agent communication mesh — rooms, DMs, and presence",
18
- "version": "2.21.14"
18
+ "version": "2.21.16"
19
19
  }
20
20
  ]
21
21
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-comms",
3
3
  "description": "Cross-harness LLM agent communication mesh — rooms, DMs, and presence",
4
- "version": "2.21.14",
4
+ "version": "2.21.16",
5
5
  "author": {
6
6
  "name": "ExaDev"
7
7
  },
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github&logoColor=white)](https://github.com/ExaDev/agent-comms)
4
4
  [![npm](https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white)](https://www.npmjs.com/package/agent-comms)
5
- [![version](https://img.shields.io/badge/version-2.21.14-blue)](https://github.com/ExaDev/agent-comms/releases/tag/v2.21.14)
5
+ [![version](https://img.shields.io/badge/version-2.21.16-blue)](https://github.com/ExaDev/agent-comms/releases/tag/v2.21.16)
6
6
  [![CI](https://img.shields.io/github/actions/workflow/status/ExaDev/agent-comms/ci.yml?branch=main)](https://github.com/ExaDev/agent-comms/actions)
7
7
 
8
8
  Cross-harness communication mesh for LLM agents: rooms, DMs, presence, and visibility over TCP with zero filesystem dependencies.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mesh-store-orchestration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-store-orchestration.test.d.ts","sourceRoot":"","sources":["../../src/test/mesh-store-orchestration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,487 @@
1
+ /**
2
+ * Direct unit tests for MeshStore's own orchestration logic -- requireTransport/requireIdentity's guard errors, the connected getter, init()'s connect-vs-becomeCoordinator-vs-EADDRINUSE branching, the events getter's dispatch table, federation/listener/room-join-approval passthroughs, and shutdown() -- as opposed to the collaborator-owned behaviour wireTestTransport-based integration tests already cover end-to-end. MeshStore's constructor takes no injectable deps (unlike its collaborators), so these tests use a hand-built fake MeshTransport passed to the real setTransport(), and reach the private roomProtocol/connectionApproval/peerLifecycle/deliveryEngine/agentRegistry collaborators via a narrow, explicitly-justified cast -- TypeScript's `private` is compile-time only, and asserting a delegating wrapper actually calls through to the collaborator that owns the real implementation is exactly the kind of whitebox check no public-API-only test can express for a one-line pass-through.
3
+ */
4
+ import { beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { MeshStore } from "../core/mesh-store.js";
6
+ /** A device-id is a 64-character lowercase hex SHA-256 digest; room-path.ts's assertDeviceIdHex rejects anything shorter. */
7
+ const DEVICE_ID_HEX_LENGTH = 64;
8
+ const VALID_DEVICE_ID = "a".repeat(DEVICE_ID_HEX_LENGTH);
9
+ /** Arbitrary, distinctive remote port for a connectToRemote test fixture -- no significance beyond "a real-looking port number". */
10
+ const REMOTE_PORT = 4242;
11
+ function fakeTransport() {
12
+ return {
13
+ dataPort: 4000,
14
+ isCoordinator: false,
15
+ hasCoordinatorConnection: false,
16
+ startDataServer: vi.fn().mockResolvedValue(undefined),
17
+ connectToCoordinator: vi.fn().mockResolvedValue(undefined),
18
+ becomeCoordinator: vi.fn().mockResolvedValue(undefined),
19
+ connectToPeer: vi.fn().mockResolvedValue(undefined),
20
+ send: vi.fn().mockResolvedValue(undefined),
21
+ acceptConnection: vi.fn().mockResolvedValue(undefined),
22
+ rejectConnection: vi.fn().mockResolvedValue(undefined),
23
+ connectToRemote: vi.fn().mockResolvedValue(undefined),
24
+ broadcast: vi.fn().mockResolvedValue(undefined),
25
+ broadcastRevocation: vi.fn().mockResolvedValue(undefined),
26
+ sendRoomRequest: vi.fn().mockResolvedValue({
27
+ result: "error",
28
+ code: "not_connected",
29
+ }),
30
+ addListener: vi.fn().mockResolvedValue("listener-1"),
31
+ removeListener: vi.fn().mockResolvedValue(undefined),
32
+ listListeners: vi.fn().mockReturnValue([]),
33
+ shutdown: vi.fn().mockResolvedValue(undefined),
34
+ unref: vi.fn(),
35
+ };
36
+ }
37
+ /** Reaches a private collaborator for a whitebox delegation check -- see the file header for why this cast is justified rather than avoided. Returns `unknown`; each call site casts to the narrow method slice it actually needs. */
38
+ function collaborator(store, name) {
39
+ return store[name];
40
+ }
41
+ describe("MeshStore — requireTransport/requireIdentity guards", () => {
42
+ it("throws a specific error when a transport-using method is called before setTransport()", () => {
43
+ const store = new MeshStore();
44
+ expect(() => store.listListeners()).toThrow("MeshStore: no transport set; call setTransport() before using the store");
45
+ });
46
+ it("throws a specific error when an identity-using method is called before setIdentity()", async () => {
47
+ const store = new MeshStore();
48
+ store.setTransport(fakeTransport());
49
+ await expect(store.createRoom({
50
+ name: "r",
51
+ type: "public",
52
+ owner: VALID_DEVICE_ID,
53
+ description: "",
54
+ })).rejects.toThrow("MeshStore: no identity set; call setIdentity() before using the store");
55
+ });
56
+ });
57
+ describe("MeshStore — connected getter", () => {
58
+ it("is true when the transport is the coordinator", () => {
59
+ const store = new MeshStore();
60
+ const transport = fakeTransport();
61
+ transport.isCoordinator = true;
62
+ store.setTransport(transport);
63
+ expect(store.connected).toBe(true);
64
+ });
65
+ it("is true when the transport has a live coordinator connection", () => {
66
+ const store = new MeshStore();
67
+ const transport = fakeTransport();
68
+ transport.hasCoordinatorConnection = true;
69
+ store.setTransport(transport);
70
+ expect(store.connected).toBe(true);
71
+ });
72
+ it("is false when neither is true", () => {
73
+ const store = new MeshStore();
74
+ store.setTransport(fakeTransport());
75
+ expect(store.connected).toBe(false);
76
+ });
77
+ });
78
+ describe("MeshStore — init()", () => {
79
+ it("starts the data server, records its own peer info, connects to an existing coordinator, and unrefs -- without becoming coordinator", async () => {
80
+ const store = new MeshStore();
81
+ const transport = fakeTransport();
82
+ store.setTransport(transport);
83
+ await store.init();
84
+ expect(transport.startDataServer).toHaveBeenCalledTimes(1);
85
+ expect(transport.connectToCoordinator).toHaveBeenCalledTimes(1);
86
+ expect(transport.becomeCoordinator).not.toHaveBeenCalled();
87
+ expect(transport.unref).toHaveBeenCalledTimes(1);
88
+ });
89
+ it("falls back to becoming coordinator when no existing coordinator is reachable", async () => {
90
+ const store = new MeshStore();
91
+ const transport = fakeTransport();
92
+ vi.mocked(transport.connectToCoordinator).mockRejectedValue(new Error("ECONNREFUSED"));
93
+ store.setTransport(transport);
94
+ const staleAgentChecker = collaborator(store, "staleAgentChecker");
95
+ const startSpy = vi.spyOn(staleAgentChecker, "start");
96
+ await store.init();
97
+ expect(transport.becomeCoordinator).toHaveBeenCalledTimes(1);
98
+ expect(startSpy).toHaveBeenCalledTimes(1);
99
+ expect(transport.unref).toHaveBeenCalledTimes(1);
100
+ });
101
+ it("degrades gracefully (no throw, onError fires) when becomeCoordinator fails with EADDRINUSE", async () => {
102
+ const store = new MeshStore();
103
+ const transport = fakeTransport();
104
+ vi.mocked(transport.connectToCoordinator).mockRejectedValue(new Error("ECONNREFUSED"));
105
+ vi.mocked(transport.becomeCoordinator).mockRejectedValue(new Error("listen EADDRINUSE: address already in use"));
106
+ store.setTransport(transport);
107
+ const onError = vi.fn();
108
+ store.onError = onError;
109
+ await expect(store.init()).resolves.toBeUndefined();
110
+ expect(onError).toHaveBeenCalledTimes(1);
111
+ expect(onError.mock.calls[0]?.[0]?.message).toContain("could not join or create mesh");
112
+ expect(onError.mock.calls[0]?.[0]?.message).toContain("Running without mesh — agent-comms will be unavailable.");
113
+ expect(transport.unref).not.toHaveBeenCalled();
114
+ });
115
+ it("rethrows a becomeCoordinator failure that isn't EADDRINUSE", async () => {
116
+ const store = new MeshStore();
117
+ const transport = fakeTransport();
118
+ vi.mocked(transport.connectToCoordinator).mockRejectedValue(new Error("ECONNREFUSED"));
119
+ vi.mocked(transport.becomeCoordinator).mockRejectedValue(new Error("EPERM: permission denied"));
120
+ store.setTransport(transport);
121
+ await expect(store.init()).rejects.toThrow("EPERM");
122
+ });
123
+ it("is idempotent -- a second call does nothing", async () => {
124
+ const store = new MeshStore();
125
+ const transport = fakeTransport();
126
+ store.setTransport(transport);
127
+ await store.init();
128
+ await store.init();
129
+ expect(transport.startDataServer).toHaveBeenCalledTimes(1);
130
+ });
131
+ });
132
+ describe("MeshStore — events getter dispatch table", () => {
133
+ it("dispatches every transport event to the collaborator method that owns it", () => {
134
+ const store = new MeshStore();
135
+ store.setTransport(fakeTransport());
136
+ const peerLifecycle = collaborator(store, "peerLifecycle");
137
+ const connectionApproval = collaborator(store, "connectionApproval");
138
+ const deliveryEngine = collaborator(store, "deliveryEngine");
139
+ const spies = {
140
+ handleDataMessage: vi
141
+ .spyOn(peerLifecycle, "handleDataMessage")
142
+ .mockResolvedValue(undefined),
143
+ handlePeerConnected: vi
144
+ .spyOn(peerLifecycle, "handlePeerConnected")
145
+ .mockResolvedValue(undefined),
146
+ handlePeerDisconnected: vi
147
+ .spyOn(peerLifecycle, "handlePeerDisconnected")
148
+ .mockReturnValue(undefined),
149
+ handleIntroduction: vi
150
+ .spyOn(peerLifecycle, "handleIntroduction")
151
+ .mockResolvedValue(undefined),
152
+ handlePeerList: vi
153
+ .spyOn(peerLifecycle, "handlePeerList")
154
+ .mockReturnValue(undefined),
155
+ handlePeerJoined: vi
156
+ .spyOn(peerLifecycle, "handlePeerJoined")
157
+ .mockReturnValue(undefined),
158
+ handleBecomeCoordinator: vi
159
+ .spyOn(peerLifecycle, "handleBecomeCoordinator")
160
+ .mockResolvedValue(undefined),
161
+ handleConnectionRequest: vi
162
+ .spyOn(connectionApproval, "handleConnectionRequest")
163
+ .mockReturnValue(undefined),
164
+ handleRevocationAnnounce: vi
165
+ .spyOn(deliveryEngine, "handleRevocationAnnounce")
166
+ .mockResolvedValue(undefined),
167
+ handlePresenceAdvert: vi
168
+ .spyOn(deliveryEngine, "handlePresenceAdvert")
169
+ .mockReturnValue(undefined),
170
+ };
171
+ const handle = { id: "conn-1" };
172
+ const peer = {
173
+ id: "peer-1",
174
+ port: 1,
175
+ startedAt: "2026-01-01T00:00:00.000Z",
176
+ };
177
+ store.events.onMessage(handle, {
178
+ method: "state_update",
179
+ patch: { type: "room_delete", roomId: "r" },
180
+ });
181
+ expect(spies.handleDataMessage).toHaveBeenCalledWith(handle, {
182
+ method: "state_update",
183
+ patch: { type: "room_delete", roomId: "r" },
184
+ });
185
+ store.events.onPeerConnected(handle, peer);
186
+ expect(spies.handlePeerConnected).toHaveBeenCalledWith(handle, peer);
187
+ store.events.onPeerDisconnected(handle);
188
+ expect(spies.handlePeerDisconnected).toHaveBeenCalledWith(handle);
189
+ store.events.onIntroduction(handle, { peerId: "p", dataPort: 1 });
190
+ expect(spies.handleIntroduction).toHaveBeenCalledWith(handle, {
191
+ peerId: "p",
192
+ dataPort: 1,
193
+ });
194
+ store.events.onPeerList([peer]);
195
+ expect(spies.handlePeerList).toHaveBeenCalledWith([peer]);
196
+ store.events.onPeerJoined(peer);
197
+ expect(spies.handlePeerJoined).toHaveBeenCalledWith(peer);
198
+ store.events.onBecomeCoordinator([peer]);
199
+ expect(spies.handleBecomeCoordinator).toHaveBeenCalledWith([peer]);
200
+ store.events.onConnectionRequest(handle, {
201
+ peerId: "p",
202
+ dataPort: 1,
203
+ name: "n",
204
+ fingerprint: "fp",
205
+ });
206
+ expect(spies.handleConnectionRequest).toHaveBeenCalledWith(handle, {
207
+ peerId: "p",
208
+ dataPort: 1,
209
+ name: "n",
210
+ fingerprint: "fp",
211
+ });
212
+ const revocationEntry = {
213
+ tokenId: new Uint8Array(),
214
+ issuer: new Uint8Array(),
215
+ revokedAt: 0,
216
+ };
217
+ store.events.onRevocationAnnounce(revocationEntry);
218
+ expect(spies.handleRevocationAnnounce).toHaveBeenCalledWith(revocationEntry);
219
+ store.events.onPresenceAdvert(handle, "active");
220
+ expect(spies.handlePresenceAdvert).toHaveBeenCalledWith("conn-1", "active");
221
+ });
222
+ it("forwards a transport-level error to this store's own onError, when one is set", () => {
223
+ const store = new MeshStore();
224
+ store.setTransport(fakeTransport());
225
+ const onError = vi.fn();
226
+ store.onError = onError;
227
+ const error = new Error("transport failure");
228
+ store.events.onError?.(error);
229
+ expect(onError).toHaveBeenCalledWith(error);
230
+ });
231
+ });
232
+ describe("MeshStore — constructor wiring", () => {
233
+ it("registers both the mdns and tailscale discovery backends", async () => {
234
+ const store = new MeshStore();
235
+ await expect(store.discovery.advertise("not-a-real-backend", { name: "x", port: 1 })).rejects.toThrow("Available: mdns, tailscale");
236
+ });
237
+ it("fires onPatch when a broadcasted patch reaches it, via the getOnPatch closure passed to DeliveryEngine", async () => {
238
+ const store = new MeshStore();
239
+ store.setTransport(fakeTransport());
240
+ const onPatch = vi.fn();
241
+ store.onPatch = onPatch;
242
+ await store.registerAgent({
243
+ name: "a",
244
+ harness: "pi",
245
+ cwd: "/tmp",
246
+ pid: 1,
247
+ visibility: "visible",
248
+ tags: [],
249
+ });
250
+ expect(onPatch).toHaveBeenCalledWith(expect.objectContaining({ type: "agent_upsert" }));
251
+ });
252
+ it("wires ConnectionApproval's queueDelivery closure to the real DeliveryEngine, observable via drainDelivery", async () => {
253
+ const store = new MeshStore();
254
+ store.setTransport(fakeTransport());
255
+ store.events.onConnectionRequest({ id: "conn-1" }, { peerId: "remote", dataPort: 1, name: "n", fingerprint: "fp" });
256
+ const drained = await store.drainDelivery(store.peerId);
257
+ expect(drained).toContainEqual(expect.objectContaining({
258
+ type: "connection_request",
259
+ connectionId: "conn-1",
260
+ }));
261
+ });
262
+ it("deliver() actually reaches the real DeliveryEngine, observable via drainDelivery", async () => {
263
+ const store = new MeshStore();
264
+ store.setTransport(fakeTransport());
265
+ const event = {
266
+ type: "connection_request",
267
+ connectionId: "c",
268
+ peerId: "p",
269
+ dataPort: 1,
270
+ name: "n",
271
+ fingerprint: "fp",
272
+ };
273
+ await store.deliver(store.peerId, event);
274
+ const drained = await store.drainDelivery(store.peerId);
275
+ expect(drained).toContainEqual(event);
276
+ });
277
+ });
278
+ describe("MeshStore — identity delegation", () => {
279
+ it("writeIdentity actually persists to the identity cache, readable back by readIdentity", async () => {
280
+ const store = new MeshStore();
281
+ await store.writeIdentity("pi", "/tmp", "written-id");
282
+ await expect(store.readIdentity("pi", "/tmp")).resolves.toEqual({
283
+ id: "written-id",
284
+ });
285
+ });
286
+ });
287
+ describe("MeshStore — agent lifecycle delegation", () => {
288
+ it("setAgentOffline actually marks the agent offline in listAgents' own view", async () => {
289
+ const store = new MeshStore();
290
+ store.setTransport(fakeTransport());
291
+ const agent = await store.registerAgent({
292
+ name: "a",
293
+ harness: "pi",
294
+ cwd: "/tmp",
295
+ pid: 1,
296
+ visibility: "visible",
297
+ tags: [],
298
+ });
299
+ await store.setAgentOffline(agent.id);
300
+ const listed = await store.listAgents(agent.id);
301
+ expect(listed.find((a) => a.id === agent.id)?.status).toBe("offline");
302
+ });
303
+ });
304
+ describe("MeshStore — addListener policy validation", () => {
305
+ it("rejects an invalid policy naming the exact bad value, without ever touching the transport", async () => {
306
+ const store = new MeshStore();
307
+ const transport = fakeTransport();
308
+ store.setTransport(transport);
309
+ await expect(store.addListener("127.0.0.1", 0, "not-a-real-policy")).rejects.toMatchObject({
310
+ message: 'Invalid policy "not-a-real-policy"',
311
+ code: "INVALID_POLICY",
312
+ });
313
+ expect(transport.addListener).not.toHaveBeenCalled();
314
+ });
315
+ it.each(["full", "observe", "rooms-only", "gateway"])("accepts the valid policy %s and forwards it to the transport", async (policy) => {
316
+ const store = new MeshStore();
317
+ const transport = fakeTransport();
318
+ store.setTransport(transport);
319
+ await store.addListener("127.0.0.1", 0, policy);
320
+ expect(transport.addListener).toHaveBeenCalledWith("127.0.0.1", 0, policy);
321
+ });
322
+ });
323
+ describe("MeshStore — room-join approval passthroughs", () => {
324
+ it("acceptRoomJoin/rejectRoomJoin/listPendingRoomJoins all reach the real RoomProtocol collaborator", () => {
325
+ const store = new MeshStore();
326
+ store.setTransport(fakeTransport());
327
+ const roomProtocol = collaborator(store, "roomProtocol");
328
+ const acceptSpy = vi
329
+ .spyOn(roomProtocol, "acceptRoomJoin")
330
+ .mockReturnValue(undefined);
331
+ const rejectSpy = vi
332
+ .spyOn(roomProtocol, "rejectRoomJoin")
333
+ .mockReturnValue(undefined);
334
+ const listSpy = vi
335
+ .spyOn(roomProtocol, "listPendingRoomJoins")
336
+ .mockReturnValue([]);
337
+ store.acceptRoomJoin("room-path", "requester");
338
+ expect(acceptSpy).toHaveBeenCalledWith("room-path", "requester");
339
+ store.rejectRoomJoin("room-path", "requester", "no thanks");
340
+ expect(rejectSpy).toHaveBeenCalledWith("room-path", "requester", "no thanks");
341
+ store.listPendingRoomJoins();
342
+ expect(listSpy).toHaveBeenCalledTimes(1);
343
+ });
344
+ it("connectToRemote reaches the real ConnectionApproval collaborator", async () => {
345
+ const store = new MeshStore();
346
+ store.setTransport(fakeTransport());
347
+ const connectionApproval = collaborator(store, "connectionApproval");
348
+ const spy = vi
349
+ .spyOn(connectionApproval, "connectToRemote")
350
+ .mockResolvedValue(undefined);
351
+ await store.connectToRemote("example.test", REMOTE_PORT);
352
+ expect(spy).toHaveBeenCalledWith("example.test", REMOTE_PORT);
353
+ });
354
+ });
355
+ describe("MeshStore — federation passthroughs", () => {
356
+ it("forwards fedConnect/fedDisconnect/fedLinks/fedTrust/fedUntrust/fedTrustedFingerprints/fedListen/fedStopListening to the real, public federation manager", async () => {
357
+ const store = new MeshStore();
358
+ store.setTransport(fakeTransport());
359
+ const connectSpy = vi
360
+ .spyOn(store.federation, "connect")
361
+ .mockResolvedValue("link-1");
362
+ await expect(store.fedConnect("host", 1, "name")).resolves.toBe("link-1");
363
+ expect(connectSpy).toHaveBeenCalledWith("host", 1, "name");
364
+ const disconnectSpy = vi
365
+ .spyOn(store.federation, "disconnect")
366
+ .mockResolvedValue(undefined);
367
+ await store.fedDisconnect("link-1");
368
+ expect(disconnectSpy).toHaveBeenCalledWith("link-1");
369
+ const linksSpy = vi
370
+ .spyOn(store.federation, "listLinks")
371
+ .mockReturnValue([]);
372
+ store.fedLinks();
373
+ expect(linksSpy).toHaveBeenCalledTimes(1);
374
+ const trustSpy = vi
375
+ .spyOn(store.federation, "addTrustedFingerprint")
376
+ .mockReturnValue(undefined);
377
+ await store.fedTrust("fingerprint-a");
378
+ expect(trustSpy).toHaveBeenCalledWith("fingerprint-a");
379
+ const untrustSpy = vi
380
+ .spyOn(store.federation, "removeTrustedFingerprint")
381
+ .mockReturnValue(undefined);
382
+ await store.fedUntrust("fingerprint-a");
383
+ expect(untrustSpy).toHaveBeenCalledWith("fingerprint-a");
384
+ const listTrustedSpy = vi
385
+ .spyOn(store.federation, "listTrustedFingerprints")
386
+ .mockReturnValue([]);
387
+ store.fedTrustedFingerprints();
388
+ expect(listTrustedSpy).toHaveBeenCalledTimes(1);
389
+ const listenSpy = vi
390
+ .spyOn(store.federation, "listen")
391
+ .mockResolvedValue(undefined);
392
+ await store.fedListen("host", 2);
393
+ expect(listenSpy).toHaveBeenCalledWith("host", 2);
394
+ const stopListeningSpy = vi
395
+ .spyOn(store.federation, "stopListening")
396
+ .mockResolvedValue(undefined);
397
+ await store.fedStopListening();
398
+ expect(stopListeningSpy).toHaveBeenCalledTimes(1);
399
+ });
400
+ });
401
+ describe("MeshStore — shutdown()", () => {
402
+ let store;
403
+ let transport;
404
+ beforeEach(() => {
405
+ store = new MeshStore();
406
+ transport = fakeTransport();
407
+ store.setTransport(transport);
408
+ });
409
+ it("stops the stale-agent checker, shuts down federation, and shuts down the transport", async () => {
410
+ const staleAgentChecker = collaborator(store, "staleAgentChecker");
411
+ const stopSpy = vi.spyOn(staleAgentChecker, "stop");
412
+ const federationShutdownSpy = vi
413
+ .spyOn(store.federation, "shutdown")
414
+ .mockResolvedValue(undefined);
415
+ await store.shutdown();
416
+ expect(stopSpy).toHaveBeenCalledTimes(1);
417
+ expect(federationShutdownSpy).toHaveBeenCalledTimes(1);
418
+ expect(transport.shutdown).toHaveBeenCalledTimes(1);
419
+ });
420
+ it("broadcasts agent_offline for its own self agent when one is registered", async () => {
421
+ vi.spyOn(store.federation, "shutdown").mockResolvedValue(undefined);
422
+ const agent = await store.registerAgent({
423
+ name: "self",
424
+ harness: "pi",
425
+ cwd: "/tmp",
426
+ pid: 1,
427
+ visibility: "visible",
428
+ tags: [],
429
+ });
430
+ store.peerId = agent.id;
431
+ const deliveryEngine = collaborator(store, "deliveryEngine");
432
+ const broadcastSpy = vi
433
+ .spyOn(deliveryEngine, "broadcastPatch")
434
+ .mockResolvedValue(undefined);
435
+ await store.shutdown();
436
+ expect(broadcastSpy).toHaveBeenCalledWith({
437
+ type: "agent_offline",
438
+ agentId: agent.id,
439
+ });
440
+ });
441
+ it("clears every pending markRead timer", async () => {
442
+ vi.spyOn(store.federation, "shutdown").mockResolvedValue(undefined);
443
+ const pending = collaborator(store, "pendingMarkReadTimers");
444
+ // Long enough to guarantee it's still pending (never fires) for the duration of this test.
445
+ const FAR_FUTURE_DELAY_MS = 1_000_000;
446
+ const timer = setTimeout(() => undefined, FAR_FUTURE_DELAY_MS);
447
+ pending.push(timer);
448
+ const clearTimeoutSpy = vi.spyOn(global, "clearTimeout");
449
+ try {
450
+ await store.shutdown();
451
+ expect(clearTimeoutSpy).toHaveBeenCalledWith(timer);
452
+ expect(pending).toHaveLength(0);
453
+ }
454
+ finally {
455
+ clearTimeoutSpy.mockRestore();
456
+ }
457
+ });
458
+ it("actually sets isShutDown, observable via DeliveryEngine no longer scheduling markRead timers afterward", async () => {
459
+ // fireLocalDelivery returns before ever reaching the isShutDown-guarded push unless onDelivery is set -- without this, the test would pass for both real code and a mutant, since it never reaches the line under test.
460
+ store.onDelivery = vi.fn();
461
+ vi.spyOn(store.federation, "shutdown").mockResolvedValue(undefined);
462
+ await store.shutdown();
463
+ const pending = collaborator(store, "pendingMarkReadTimers");
464
+ await store.deliver(store.peerId, {
465
+ type: "room_message",
466
+ message: {
467
+ id: "m",
468
+ from: "a",
469
+ room: "r",
470
+ content: "hi",
471
+ timestamp: "2026-01-01T00:00:00.000Z",
472
+ readBy: [],
473
+ },
474
+ });
475
+ expect(pending).toHaveLength(0);
476
+ });
477
+ it("does not broadcast agent_offline when no self agent was ever registered", async () => {
478
+ vi.spyOn(store.federation, "shutdown").mockResolvedValue(undefined);
479
+ const deliveryEngine = collaborator(store, "deliveryEngine");
480
+ const broadcastSpy = vi
481
+ .spyOn(deliveryEngine, "broadcastPatch")
482
+ .mockResolvedValue(undefined);
483
+ await store.shutdown();
484
+ expect(broadcastSpy).not.toHaveBeenCalled();
485
+ });
486
+ });
487
+ //# sourceMappingURL=mesh-store-orchestration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-store-orchestration.test.js","sourceRoot":"","sources":["../../src/test/mesh-store-orchestration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=room-messaging.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room-messaging.test.d.ts","sourceRoot":"","sources":["../../src/test/room-messaging.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,328 @@
1
+ /**
2
+ * Direct, DI-based unit tests for RoomMessaging -- it was previously exercised only indirectly through end-to-end room-send integration tests, leaving many individual branches (optional-field spreads, error message text, since-filtering boundaries, self-DM vs cross-DM key derivation) unobserved. RoomMessagingDeps is a narrow, injectable surface built exactly for this. loadRoomTokens is a free function reading a real identity file, not part of the injectable deps -- mocked here since RoomMessaging only ever forwards its return value opaquely, never inspects or verifies it.
3
+ *
4
+ * Two mutants Stryker raises against readRoomMessages' `since === undefined || since === ""` check are practical equivalents, not gaps -- documented here rather than chased with a contrived test. Both replace the `since === ""` comparison (one with the literal `false`, one with `since === "Stryker was here!"`) and both share the identical root cause: whenever the real code's early-return branch would fire on `since === ""`, the mutant instead falls through to `arr.filter(m => m.timestamp > since)` with `since` still `""` -- and every RoomMessage in this codebase is constructed with `new Date().toISOString()`, never an empty string, so `m.timestamp > ""` is true for every real message regardless of which branch runs. The early-return and the filter produce identical output for any timestamp this codebase can actually produce; only a RoomMessage with an empty-string timestamp (violating that invariant) would distinguish them, and fabricating one would be exactly the kind of contrived test this repo's own convention (see stale-agent-checker.test.ts) says to document instead of force.
5
+ */
6
+ import { beforeEach, describe, expect, it, vi } from "vitest";
7
+ import { dmRoomPath } from "../core/room-path.js";
8
+ import { loadRoomTokens } from "../core/identity-store.js";
9
+ import { RoomMessaging, } from "../core/room-messaging.js";
10
+ vi.mock("../core/identity-store.js", () => ({
11
+ loadRoomTokens: vi.fn(),
12
+ }));
13
+ // Opaque placeholder: RoomMessaging never inspects a token's own COSE_Sign1 structure, only forwards whatever loadRoomTokens returns to sendRoomRequestToMember -- so any distinguishable value stands in for a real one in these tests.
14
+ const FAKE_TOKEN = "fake-token";
15
+ /** A device-id is a 64-character lowercase hex SHA-256 digest; room-path.ts's assertDeviceIdHex rejects anything shorter. */
16
+ const DEVICE_ID_HEX_LENGTH = 64;
17
+ /** A message/token id is 16 random bytes, hex-encoded to 32 characters -- randomId()'s own convention, matched here so bytesFromHex doesn't reject the fixture. */
18
+ const MESSAGE_ID_BYTE_LENGTH = 16;
19
+ const FROM_DEVICE_ID = "a".repeat(DEVICE_ID_HEX_LENGTH);
20
+ const TO_DEVICE_ID = "b".repeat(DEVICE_ID_HEX_LENGTH);
21
+ const NOW_MS = 1_700_000_000_000;
22
+ function room(overrides = {}) {
23
+ return {
24
+ id: "room-1",
25
+ version: 1,
26
+ name: "room-name",
27
+ type: "public",
28
+ owner: FROM_DEVICE_ID,
29
+ createdAt: "2026-01-01T00:00:00.000Z",
30
+ description: "",
31
+ members: [FROM_DEVICE_ID],
32
+ invited: [],
33
+ memberJoins: {},
34
+ memberLeaves: {},
35
+ invitedJoins: {},
36
+ invitedLeaves: {},
37
+ ...overrides,
38
+ };
39
+ }
40
+ function agent(overrides = {}) {
41
+ return {
42
+ id: TO_DEVICE_ID,
43
+ version: 1,
44
+ name: "recipient",
45
+ harness: "pi",
46
+ cwd: "/tmp",
47
+ pid: 111,
48
+ startedAt: "2026-01-01T00:00:00.000Z",
49
+ visibility: "visible",
50
+ status: "active",
51
+ tags: [],
52
+ subscribedRooms: [],
53
+ ...overrides,
54
+ };
55
+ }
56
+ function makeHarness() {
57
+ const sendRoomRequestToMember = vi.fn().mockResolvedValue(undefined);
58
+ const forwardRoomMessage = vi.fn().mockResolvedValue(undefined);
59
+ const deps = {
60
+ rooms: new Map(),
61
+ messages: new Map(),
62
+ dms: new Map(),
63
+ agents: new Map(),
64
+ requireIdentity: () => ({
65
+ slot: { harness: "pi", cwd: "/tmp" },
66
+ clock: { now: () => NOW_MS },
67
+ identity: {},
68
+ revocation: {},
69
+ }),
70
+ roomProtocol: { sendRoomRequestToMember },
71
+ federation: { forwardRoomMessage },
72
+ };
73
+ return {
74
+ deps,
75
+ messaging: new RoomMessaging(deps),
76
+ sendRoomRequestToMember,
77
+ forwardRoomMessage,
78
+ };
79
+ }
80
+ beforeEach(() => {
81
+ vi.mocked(loadRoomTokens).mockReset();
82
+ vi.mocked(loadRoomTokens).mockReturnValue({ "room-1": FAKE_TOKEN });
83
+ });
84
+ describe("RoomMessaging — sendRoomMessage", () => {
85
+ it("throws ROOM_NOT_FOUND naming the exact room id when the room doesn't exist", async () => {
86
+ const h = makeHarness();
87
+ await expect(h.messaging.sendRoomMessage("no-such-room", FROM_DEVICE_ID, "hi")).rejects.toMatchObject({
88
+ message: "Room no-such-room not found",
89
+ code: "ROOM_NOT_FOUND",
90
+ });
91
+ });
92
+ it("throws NOT_MEMBER naming the exact room id when the sender isn't a member", async () => {
93
+ const h = makeHarness();
94
+ h.deps.rooms.set("room-1", room({ members: [] }));
95
+ await expect(h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi")).rejects.toMatchObject({
96
+ message: "Not a member of room-1",
97
+ code: "NOT_MEMBER",
98
+ });
99
+ });
100
+ it("throws NOT_MEMBER naming the exact room id when no room:member token is persisted", async () => {
101
+ const h = makeHarness();
102
+ h.deps.rooms.set("room-1", room());
103
+ vi.mocked(loadRoomTokens).mockReturnValue({});
104
+ await expect(h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi")).rejects.toMatchObject({
105
+ message: "No room:member token for room-1",
106
+ code: "NOT_MEMBER",
107
+ });
108
+ });
109
+ it("stores the message and records it in the room's history", async () => {
110
+ const h = makeHarness();
111
+ h.deps.rooms.set("room-1", room());
112
+ const message = await h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hello");
113
+ expect(h.deps.messages.get("room-1")).toEqual([message]);
114
+ expect(message.content).toBe("hello");
115
+ expect(message.readBy).toEqual([FROM_DEVICE_ID]);
116
+ });
117
+ it("includes replyTo only when explicitly given", async () => {
118
+ const h = makeHarness();
119
+ h.deps.rooms.set("room-1", room());
120
+ const replyToId = "aa".repeat(MESSAGE_ID_BYTE_LENGTH);
121
+ const withReply = await h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi", replyToId);
122
+ expect(withReply.replyTo).toBe(replyToId);
123
+ const withoutReply = await h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi");
124
+ expect(withoutReply).not.toHaveProperty("replyTo");
125
+ });
126
+ it("includes streamingBehavior on the stored message only when given", async () => {
127
+ const h = makeHarness();
128
+ h.deps.rooms.set("room-1", room());
129
+ const withBehavior = await h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi", undefined, "steer");
130
+ expect(withBehavior.streamingBehavior).toBe("steer");
131
+ const withoutBehavior = await h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi");
132
+ expect(withoutBehavior).not.toHaveProperty("streamingBehavior");
133
+ });
134
+ it("forwards to federated links only when the room is federated", async () => {
135
+ const federated = makeHarness();
136
+ federated.deps.rooms.set("room-1", room({ federated: true }));
137
+ await federated.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi");
138
+ expect(federated.forwardRoomMessage).toHaveBeenCalledTimes(1);
139
+ const plain = makeHarness();
140
+ plain.deps.rooms.set("room-1", room({ federated: false }));
141
+ await plain.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi");
142
+ expect(plain.forwardRoomMessage).not.toHaveBeenCalled();
143
+ });
144
+ it("sends a directed request to every other member, never to the sender itself", async () => {
145
+ const h = makeHarness();
146
+ h.deps.rooms.set("room-1", room({ members: [FROM_DEVICE_ID, "member-b", "member-c"] }));
147
+ await h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi");
148
+ expect(h.sendRoomRequestToMember).toHaveBeenCalledTimes(2);
149
+ expect(h.sendRoomRequestToMember).toHaveBeenCalledWith("member-b", "room-1", FAKE_TOKEN, expect.anything());
150
+ expect(h.sendRoomRequestToMember).toHaveBeenCalledWith("member-c", "room-1", FAKE_TOKEN, expect.anything());
151
+ });
152
+ it('includes a refs entry with relation "reply" in the wire params only when replyTo is given', async () => {
153
+ const h = makeHarness();
154
+ h.deps.rooms.set("room-1", room({ members: [FROM_DEVICE_ID, "member-b"] }));
155
+ const replyToId = "aa".repeat(MESSAGE_ID_BYTE_LENGTH);
156
+ await h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi", replyToId);
157
+ const params = h.sendRoomRequestToMember.mock.calls[0]?.[3];
158
+ expect(params.refs).toEqual([
159
+ { id: expect.any(Uint8Array), relation: "reply" },
160
+ ]);
161
+ });
162
+ it("omits refs from the wire params when no replyTo is given", async () => {
163
+ const h = makeHarness();
164
+ h.deps.rooms.set("room-1", room({ members: [FROM_DEVICE_ID, "member-b"] }));
165
+ await h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi");
166
+ const params = h.sendRoomRequestToMember.mock.calls[0]?.[3];
167
+ expect(params).not.toHaveProperty("refs");
168
+ });
169
+ it("includes streaming-behavior in the wire params only when given", async () => {
170
+ const h = makeHarness();
171
+ h.deps.rooms.set("room-1", room({ members: [FROM_DEVICE_ID, "member-b"] }));
172
+ await h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi", undefined, "steer");
173
+ const params = h.sendRoomRequestToMember.mock.calls[0]?.[3];
174
+ expect(params["streaming-behavior"]).toBe("steer");
175
+ });
176
+ it("omits streaming-behavior from the wire params when not given", async () => {
177
+ const h = makeHarness();
178
+ h.deps.rooms.set("room-1", room({ members: [FROM_DEVICE_ID, "member-b"] }));
179
+ await h.messaging.sendRoomMessage("room-1", FROM_DEVICE_ID, "hi");
180
+ const params = h.sendRoomRequestToMember.mock.calls[0]?.[3];
181
+ expect(params).not.toHaveProperty("streaming-behavior");
182
+ });
183
+ });
184
+ describe("RoomMessaging — readRoomMessages", () => {
185
+ const OLDER = "2026-01-01T00:00:00.000Z";
186
+ const MIDDLE = "2026-01-01T00:05:00.000Z";
187
+ const NEWER = "2026-01-01T00:10:00.000Z";
188
+ function seeded(h) {
189
+ h.deps.messages.set("room-1", [
190
+ {
191
+ id: "m1",
192
+ from: "a",
193
+ room: "room-1",
194
+ content: "old",
195
+ timestamp: OLDER,
196
+ readBy: [],
197
+ },
198
+ {
199
+ id: "m2",
200
+ from: "a",
201
+ room: "room-1",
202
+ content: "mid",
203
+ timestamp: MIDDLE,
204
+ readBy: [],
205
+ },
206
+ {
207
+ id: "m3",
208
+ from: "a",
209
+ room: "room-1",
210
+ content: "new",
211
+ timestamp: NEWER,
212
+ readBy: [],
213
+ },
214
+ ]);
215
+ }
216
+ it("returns the full history when since is omitted", async () => {
217
+ const h = makeHarness();
218
+ seeded(h);
219
+ const result = await h.messaging.readRoomMessages("room-1");
220
+ expect(result.map((m) => m.id)).toEqual(["m1", "m2", "m3"]);
221
+ });
222
+ it("returns the full history when since is an empty string", async () => {
223
+ const h = makeHarness();
224
+ seeded(h);
225
+ const result = await h.messaging.readRoomMessages("room-1", "");
226
+ expect(result.map((m) => m.id)).toEqual(["m1", "m2", "m3"]);
227
+ });
228
+ it("returns only messages strictly newer than a real since timestamp", async () => {
229
+ const h = makeHarness();
230
+ seeded(h);
231
+ const result = await h.messaging.readRoomMessages("room-1", MIDDLE);
232
+ expect(result.map((m) => m.id)).toEqual(["m3"]);
233
+ });
234
+ it("returns an empty array for a room with no history", async () => {
235
+ const h = makeHarness();
236
+ const result = await h.messaging.readRoomMessages("no-such-room");
237
+ expect(result).toEqual([]);
238
+ });
239
+ it("filters out every message for an arbitrary since lexically greater than any real timestamp", async () => {
240
+ const h = makeHarness();
241
+ seeded(h);
242
+ // Lexically greater than any real ISO timestamp (which starts with a digit) -- proves filtering genuinely runs and genuinely excludes messages for a since value that isn't "" or undefined, distinct from the empty-string shortcut covered (and its equivalent mutants documented) above.
243
+ const result = await h.messaging.readRoomMessages("room-1", "not-a-real-timestamp");
244
+ expect(result).toEqual([]);
245
+ });
246
+ });
247
+ describe("RoomMessaging — sendDm", () => {
248
+ it("throws AGENT_NOT_FOUND naming the exact recipient id when the recipient doesn't exist", async () => {
249
+ const h = makeHarness();
250
+ await expect(h.messaging.sendDm(FROM_DEVICE_ID, TO_DEVICE_ID, "hi")).rejects.toMatchObject({
251
+ message: `Agent ${TO_DEVICE_ID} not found`,
252
+ code: "AGENT_NOT_FOUND",
253
+ });
254
+ });
255
+ it("throws AGENT_NOT_FOUND naming the exact recipient id when the recipient has ghost visibility", async () => {
256
+ const h = makeHarness();
257
+ h.deps.agents.set(TO_DEVICE_ID, agent({ visibility: "ghost" }));
258
+ await expect(h.messaging.sendDm(FROM_DEVICE_ID, TO_DEVICE_ID, "hi")).rejects.toMatchObject({
259
+ message: `Cannot DM agent ${TO_DEVICE_ID}`,
260
+ code: "AGENT_NOT_FOUND",
261
+ });
262
+ });
263
+ it("skips recipient validation entirely for a self-DM", async () => {
264
+ const h = makeHarness();
265
+ const message = await h.messaging.sendDm(FROM_DEVICE_ID, FROM_DEVICE_ID, "note to self");
266
+ expect(message.content).toBe("note to self");
267
+ });
268
+ it("stores a self-DM under a self:<id> key and never dials out", async () => {
269
+ const h = makeHarness();
270
+ const message = await h.messaging.sendDm(FROM_DEVICE_ID, FROM_DEVICE_ID, "note to self");
271
+ expect(h.deps.dms.get(`self:${FROM_DEVICE_ID}`)).toEqual([message]);
272
+ expect(h.sendRoomRequestToMember).not.toHaveBeenCalled();
273
+ });
274
+ it("stores a cross-agent DM under the sorted dmRoomPath key and dials the recipient", async () => {
275
+ const h = makeHarness();
276
+ h.deps.agents.set(TO_DEVICE_ID, agent());
277
+ vi.mocked(loadRoomTokens).mockReturnValue({
278
+ [dmRoomPath(FROM_DEVICE_ID, TO_DEVICE_ID)]: FAKE_TOKEN,
279
+ });
280
+ const message = await h.messaging.sendDm(FROM_DEVICE_ID, TO_DEVICE_ID, "hi");
281
+ const key = dmRoomPath(FROM_DEVICE_ID, TO_DEVICE_ID);
282
+ expect(h.deps.dms.get(key)).toEqual([message]);
283
+ expect(h.sendRoomRequestToMember).toHaveBeenCalledWith(TO_DEVICE_ID, key, FAKE_TOKEN, expect.anything());
284
+ });
285
+ it("sets readBy to exactly the sender on a new DM", async () => {
286
+ const h = makeHarness();
287
+ const message = await h.messaging.sendDm(FROM_DEVICE_ID, FROM_DEVICE_ID, "hi");
288
+ expect(message.readBy).toEqual([FROM_DEVICE_ID]);
289
+ });
290
+ it("includes streamingBehavior on the stored message only when given", async () => {
291
+ const h = makeHarness();
292
+ const withBehavior = await h.messaging.sendDm(FROM_DEVICE_ID, FROM_DEVICE_ID, "hi", "followUp");
293
+ expect(withBehavior.streamingBehavior).toBe("followUp");
294
+ const withoutBehavior = await h.messaging.sendDm(FROM_DEVICE_ID, FROM_DEVICE_ID, "hi");
295
+ expect(withoutBehavior).not.toHaveProperty("streamingBehavior");
296
+ });
297
+ it("throws NOT_MEMBER naming the exact dm key when no room:member token is persisted for a cross-agent DM", async () => {
298
+ const h = makeHarness();
299
+ h.deps.agents.set(TO_DEVICE_ID, agent());
300
+ vi.mocked(loadRoomTokens).mockReturnValue({});
301
+ const key = dmRoomPath(FROM_DEVICE_ID, TO_DEVICE_ID);
302
+ await expect(h.messaging.sendDm(FROM_DEVICE_ID, TO_DEVICE_ID, "hi")).rejects.toMatchObject({
303
+ message: `No room:member token for ${key}`,
304
+ code: "NOT_MEMBER",
305
+ });
306
+ });
307
+ it("includes streaming-behavior in the wire params only when given, for a cross-agent DM", async () => {
308
+ const h = makeHarness();
309
+ h.deps.agents.set(TO_DEVICE_ID, agent());
310
+ vi.mocked(loadRoomTokens).mockReturnValue({
311
+ [dmRoomPath(FROM_DEVICE_ID, TO_DEVICE_ID)]: FAKE_TOKEN,
312
+ });
313
+ await h.messaging.sendDm(FROM_DEVICE_ID, TO_DEVICE_ID, "hi", "info");
314
+ const params = h.sendRoomRequestToMember.mock.calls[0]?.[3];
315
+ expect(params["streaming-behavior"]).toBe("info");
316
+ });
317
+ it("omits streaming-behavior from the wire params when not given, for a cross-agent DM", async () => {
318
+ const h = makeHarness();
319
+ h.deps.agents.set(TO_DEVICE_ID, agent());
320
+ vi.mocked(loadRoomTokens).mockReturnValue({
321
+ [dmRoomPath(FROM_DEVICE_ID, TO_DEVICE_ID)]: FAKE_TOKEN,
322
+ });
323
+ await h.messaging.sendDm(FROM_DEVICE_ID, TO_DEVICE_ID, "hi");
324
+ const params = h.sendRoomRequestToMember.mock.calls[0]?.[3];
325
+ expect(params).not.toHaveProperty("streaming-behavior");
326
+ });
327
+ });
328
+ //# sourceMappingURL=room-messaging.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room-messaging.test.js","sourceRoot":"","sources":["../../src/test/room-messaging.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-comms",
3
- "version": "2.21.14",
3
+ "version": "2.21.16",
4
4
  "description": "Cross-harness communication mesh for LLM agents — rooms, DMs, presence, and real-time push delivery over TCP",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c",