agent-comms 2.21.8 → 2.21.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/dist/test/mesh-store-shared.test.d.ts +2 -0
- package/dist/test/mesh-store-shared.test.d.ts.map +1 -0
- package/dist/test/mesh-store-shared.test.js +89 -0
- package/dist/test/mesh-store-shared.test.js.map +1 -0
- package/dist/test/wire-mesh-transport-shutdown-unref.test.d.ts +5 -0
- package/dist/test/wire-mesh-transport-shutdown-unref.test.d.ts.map +1 -0
- package/dist/test/wire-mesh-transport-shutdown-unref.test.js +194 -0
- package/dist/test/wire-mesh-transport-shutdown-unref.test.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/ExaDev/agent-comms)
|
|
4
4
|
[](https://www.npmjs.com/package/agent-comms)
|
|
5
|
-
[](https://github.com/ExaDev/agent-comms/releases/tag/v2.21.10)
|
|
6
6
|
[](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 @@
|
|
|
1
|
+
{"version":3,"file":"mesh-store-shared.test.d.ts","sourceRoot":"","sources":["../../src/test/mesh-store-shared.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { mergeMessageHistories, ROOM_TOKEN_LIFETIME_MS, } from "../core/mesh-store-shared.js";
|
|
3
|
+
const DAYS = 30;
|
|
4
|
+
const HOURS_PER_DAY = 24;
|
|
5
|
+
const MINUTES_PER_HOUR = 60;
|
|
6
|
+
const SECONDS_PER_MINUTE = 60;
|
|
7
|
+
const MS_PER_SECOND = 1000;
|
|
8
|
+
describe("ROOM_TOKEN_LIFETIME_MS", () => {
|
|
9
|
+
it("is exactly 30 days, in milliseconds", () => {
|
|
10
|
+
expect(ROOM_TOKEN_LIFETIME_MS).toBe(DAYS *
|
|
11
|
+
HOURS_PER_DAY *
|
|
12
|
+
MINUTES_PER_HOUR *
|
|
13
|
+
SECONDS_PER_MINUTE *
|
|
14
|
+
MS_PER_SECOND);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
function msg(id, readBy = []) {
|
|
18
|
+
return { id, readBy: [...readBy] };
|
|
19
|
+
}
|
|
20
|
+
describe("mergeMessageHistories", () => {
|
|
21
|
+
it("appends an incoming entry the local list does not have", () => {
|
|
22
|
+
const merged = mergeMessageHistories([msg("a")], [msg("b")]);
|
|
23
|
+
expect(merged.map((m) => m.id)).toEqual(["a", "b"]);
|
|
24
|
+
});
|
|
25
|
+
it("appends multiple new entries in incoming order", () => {
|
|
26
|
+
const merged = mergeMessageHistories([msg("a")], [msg("b"), msg("c")]);
|
|
27
|
+
expect(merged.map((m) => m.id)).toEqual(["a", "b", "c"]);
|
|
28
|
+
});
|
|
29
|
+
it("preserves local ordering -- new entries are appended, not inserted", () => {
|
|
30
|
+
const merged = mergeMessageHistories([msg("a"), msg("z")], [msg("m")]);
|
|
31
|
+
expect(merged.map((m) => m.id)).toEqual(["a", "z", "m"]);
|
|
32
|
+
});
|
|
33
|
+
it("unions a new reader onto an existing entry's readBy", () => {
|
|
34
|
+
const merged = mergeMessageHistories([msg("a", ["u1"])], [msg("a", ["u2"])]);
|
|
35
|
+
expect(merged[0]?.readBy.sort()).toEqual(["u1", "u2"]);
|
|
36
|
+
});
|
|
37
|
+
it("does not duplicate a reader already present locally", () => {
|
|
38
|
+
const merged = mergeMessageHistories([msg("a", ["u1"])], [msg("a", ["u1"])]);
|
|
39
|
+
expect(merged[0]?.readBy).toEqual(["u1"]);
|
|
40
|
+
});
|
|
41
|
+
it("unions several readers from one incoming entry", () => {
|
|
42
|
+
const merged = mergeMessageHistories([msg("a", ["u1"])], [msg("a", ["u1", "u2", "u3"])]);
|
|
43
|
+
expect(merged[0]?.readBy.sort()).toEqual(["u1", "u2", "u3"]);
|
|
44
|
+
});
|
|
45
|
+
it("leaves an existing entry's readBy untouched when incoming has none", () => {
|
|
46
|
+
const merged = mergeMessageHistories([msg("a", ["u1"])], [msg("a", [])]);
|
|
47
|
+
expect(merged[0]?.readBy).toEqual(["u1"]);
|
|
48
|
+
});
|
|
49
|
+
it("does not grow the merged length for an already-known entry", () => {
|
|
50
|
+
const merged = mergeMessageHistories([msg("a")], [msg("a")]);
|
|
51
|
+
expect(merged).toHaveLength(1);
|
|
52
|
+
});
|
|
53
|
+
it("handles an empty incoming list as a no-op, returning an equivalent copy", () => {
|
|
54
|
+
const merged = mergeMessageHistories([msg("a", ["u1"])], []);
|
|
55
|
+
expect(merged).toEqual([msg("a", ["u1"])]);
|
|
56
|
+
});
|
|
57
|
+
it("handles an empty local list, returning everything incoming", () => {
|
|
58
|
+
const merged = mergeMessageHistories([], [msg("a"), msg("b")]);
|
|
59
|
+
expect(merged.map((m) => m.id)).toEqual(["a", "b"]);
|
|
60
|
+
});
|
|
61
|
+
it("merges a mix of new and existing entries in one call", () => {
|
|
62
|
+
const merged = mergeMessageHistories([msg("a", ["u1"]), msg("b", [])], [msg("a", ["u2"]), msg("c", ["u3"])]);
|
|
63
|
+
expect(merged.map((m) => m.id)).toEqual(["a", "b", "c"]);
|
|
64
|
+
expect(merged[0]?.readBy.sort()).toEqual(["u1", "u2"]);
|
|
65
|
+
expect(merged[1]?.readBy).toEqual([]);
|
|
66
|
+
expect(merged[2]?.readBy).toEqual(["u3"]);
|
|
67
|
+
});
|
|
68
|
+
it("does not mutate either input array", () => {
|
|
69
|
+
const local = [msg("a", ["u1"])];
|
|
70
|
+
const incoming = [msg("a", ["u2"]), msg("b")];
|
|
71
|
+
mergeMessageHistories(local, incoming);
|
|
72
|
+
expect(local).toEqual([msg("a", ["u1"])]);
|
|
73
|
+
expect(incoming).toEqual([msg("a", ["u2"]), msg("b")]);
|
|
74
|
+
});
|
|
75
|
+
it("does not mutate an existing local entry's own readBy array in place", () => {
|
|
76
|
+
const originalEntry = msg("a", ["u1"]);
|
|
77
|
+
const local = [originalEntry];
|
|
78
|
+
mergeMessageHistories(local, [msg("a", ["u2"])]);
|
|
79
|
+
// The merged result's entry for "a" must be a distinct object/array from the one still referenced by the caller's own original local list -- otherwise a caller holding onto its own pre-merge array would see readers silently appear in it too.
|
|
80
|
+
expect(originalEntry.readBy).toEqual(["u1"]);
|
|
81
|
+
});
|
|
82
|
+
it("unions two same-id entries within one incoming batch into a single merged entry, not a duplicate", () => {
|
|
83
|
+
// A brand-new id appearing twice in the same incoming batch is the one case where the freshly-added entry must be looked up again within the same call, not just against local's own pre-existing entries -- proves the id-to-entry index is kept in sync as new entries are added mid-merge, not only seeded from local up front.
|
|
84
|
+
const merged = mergeMessageHistories([], [msg("a", ["u1"]), msg("a", ["u2"])]);
|
|
85
|
+
expect(merged.map((m) => m.id)).toEqual(["a"]);
|
|
86
|
+
expect(merged[0]?.readBy.sort()).toEqual(["u1", "u2"]);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
//# sourceMappingURL=mesh-store-shared.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mesh-store-shared.test.js","sourceRoot":"","sources":["../../src/test/mesh-store-shared.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WireMeshTransport shutdown()/unref() -- direct mechanism assertions, split out of wire-mesh-transport.test.ts to stay under this repo's max-lines cap. Existing shutdown coverage in the sibling file proves observable, cross-peer behaviour (B sees A's session close, a second decision finds nothing pending). These tests instead assert directly on the specific cleanup mechanisms shutdown() itself performs -- the underlying Map/Set.clear() calls, timer cancellations, and listener unref() calls -- so a mutation removing one of those calls fails here even when nothing was ever added to the collection it clears, which no behavioural assertion downstream of an empty collection could otherwise observe.
|
|
3
|
+
*/
|
|
4
|
+
export {};
|
|
5
|
+
//# sourceMappingURL=wire-mesh-transport-shutdown-unref.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wire-mesh-transport-shutdown-unref.test.d.ts","sourceRoot":"","sources":["../../src/test/wire-mesh-transport-shutdown-unref.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WireMeshTransport shutdown()/unref() -- direct mechanism assertions, split out of wire-mesh-transport.test.ts to stay under this repo's max-lines cap. Existing shutdown coverage in the sibling file proves observable, cross-peer behaviour (B sees A's session close, a second decision finds nothing pending). These tests instead assert directly on the specific cleanup mechanisms shutdown() itself performs -- the underlying Map/Set.clear() calls, timer cancellations, and listener unref() calls -- so a mutation removing one of those calls fails here even when nothing was ever added to the collection it clears, which no behavioural assertion downstream of an empty collection could otherwise observe.
|
|
3
|
+
*/
|
|
4
|
+
import * as net from "node:net";
|
|
5
|
+
import { test, describe, expect, vi } from "vitest";
|
|
6
|
+
import { createTlsTransport } from "wire-mesh-core/adapters/tls-transport";
|
|
7
|
+
import { acceptMeshSession } from "wire-mesh-core/domain/mesh-session";
|
|
8
|
+
import { generateIdentity } from "../core/identity.js";
|
|
9
|
+
import { toIdentityPort } from "../core/wire-mesh-identity.js";
|
|
10
|
+
import { WireMeshTransport, DOMAIN, FRAME_SCOPE, buildCommand, } from "../core/wire-mesh-transport.js";
|
|
11
|
+
import { deviceIdToHex } from "wire-mesh-core/domain/device-id";
|
|
12
|
+
import { waitFor } from "./test-transport.js";
|
|
13
|
+
function noopEvents(overrides = {}) {
|
|
14
|
+
return {
|
|
15
|
+
onMessage: () => undefined,
|
|
16
|
+
onPeerConnected: () => undefined,
|
|
17
|
+
onPeerDisconnected: () => undefined,
|
|
18
|
+
onIntroduction: () => undefined,
|
|
19
|
+
onConnectionRequest: () => undefined,
|
|
20
|
+
onPeerList: () => undefined,
|
|
21
|
+
onPeerJoined: () => undefined,
|
|
22
|
+
onBecomeCoordinator: () => undefined,
|
|
23
|
+
onRevocationAnnounce: () => undefined,
|
|
24
|
+
onPresenceAdvert: () => undefined,
|
|
25
|
+
...overrides,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
async function findFreePort() {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const server = net.createServer();
|
|
31
|
+
server.listen(0, "127.0.0.1", () => {
|
|
32
|
+
const addr = server.address();
|
|
33
|
+
const port = typeof addr === "object" && addr !== null ? addr.port : 0;
|
|
34
|
+
server.close(() => resolve(port));
|
|
35
|
+
});
|
|
36
|
+
server.on("error", reject);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async function peerId(identity) {
|
|
40
|
+
return deviceIdToHex(Uint8Array.from(identity.deviceId));
|
|
41
|
+
}
|
|
42
|
+
// pendingConnections, peerSessions, coordinatorListeners -- the three Maps shutdown() clears.
|
|
43
|
+
const SHUTDOWN_MAP_CLEAR_COUNT = 3;
|
|
44
|
+
describe("WireMeshTransport shutdown -- direct mechanism assertions", () => {
|
|
45
|
+
test("shutdown clears every internal bookkeeping collection, even when all of them are already empty", async () => {
|
|
46
|
+
const identity = generateIdentity();
|
|
47
|
+
const transport = new WireMeshTransport(noopEvents(), identity);
|
|
48
|
+
const mapClearSpy = vi.spyOn(Map.prototype, "clear");
|
|
49
|
+
const setClearSpy = vi.spyOn(Set.prototype, "clear");
|
|
50
|
+
try {
|
|
51
|
+
await transport.shutdown();
|
|
52
|
+
// dataDials, allSessions (Sets) + pendingConnections, peerSessions, coordinatorListeners (Maps) -- five distinct collections shutdown() is documented to clear, regardless of whether any of them held anything.
|
|
53
|
+
expect(setClearSpy.mock.calls.length).toBeGreaterThanOrEqual(2);
|
|
54
|
+
expect(mapClearSpy.mock.calls.length).toBeGreaterThanOrEqual(SHUTDOWN_MAP_CLEAR_COUNT);
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
mapClearSpy.mockRestore();
|
|
58
|
+
setClearSpy.mockRestore();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
test("shutdown cancels the pending-connection timeout for every still-pending connect_request, not just its own reject response", async () => {
|
|
62
|
+
const identityA = generateIdentity();
|
|
63
|
+
const identityB = generateIdentity();
|
|
64
|
+
const idB = await peerId(await toIdentityPort(identityB));
|
|
65
|
+
const requestsSeenByA = [];
|
|
66
|
+
const transportA = new WireMeshTransport(noopEvents({
|
|
67
|
+
onConnectionRequest: (h) => void requestsSeenByA.push(h),
|
|
68
|
+
}), identityA);
|
|
69
|
+
const clearTimeoutSpy = vi.spyOn(global, "clearTimeout");
|
|
70
|
+
try {
|
|
71
|
+
await transportA.becomeCoordinator("127.0.0.1", 0);
|
|
72
|
+
const [listener] = transportA.listListeners();
|
|
73
|
+
if (listener === undefined)
|
|
74
|
+
throw new Error("expected a bound listener");
|
|
75
|
+
const clientTransport = createTlsTransport({
|
|
76
|
+
certificatePem: identityB.certificate,
|
|
77
|
+
privateKeyPem: identityB.privateKey,
|
|
78
|
+
});
|
|
79
|
+
const connection = await clientTransport.connect(`127.0.0.1:${String(listener.port)}`);
|
|
80
|
+
const clientIdentityPort = await toIdentityPort(identityB);
|
|
81
|
+
const session = await acceptMeshSession(connection, clientIdentityPort, [
|
|
82
|
+
DOMAIN,
|
|
83
|
+
]);
|
|
84
|
+
void session
|
|
85
|
+
.sendManageRequest(buildCommand({
|
|
86
|
+
method: "connect_request",
|
|
87
|
+
peerId: idB,
|
|
88
|
+
dataPort: 0,
|
|
89
|
+
name: "connector",
|
|
90
|
+
fingerprint: "",
|
|
91
|
+
}), FRAME_SCOPE)
|
|
92
|
+
.catch(() => undefined);
|
|
93
|
+
await waitFor(() => requestsSeenByA.some((h) => h.id === idB), "A observes the pending connect_request");
|
|
94
|
+
clearTimeoutSpy.mockClear();
|
|
95
|
+
await transportA.shutdown();
|
|
96
|
+
expect(clearTimeoutSpy).toHaveBeenCalled();
|
|
97
|
+
await session.close();
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
clearTimeoutSpy.mockRestore();
|
|
101
|
+
await transportA.shutdown();
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
test("shutdown clears the presence-readvertise interval when one was started", async () => {
|
|
105
|
+
const identity = generateIdentity();
|
|
106
|
+
const clearIntervalSpy = vi.spyOn(global, "clearInterval");
|
|
107
|
+
try {
|
|
108
|
+
const transport = new WireMeshTransport(noopEvents(), identity, undefined, undefined, () => "active");
|
|
109
|
+
clearIntervalSpy.mockClear();
|
|
110
|
+
await transport.shutdown();
|
|
111
|
+
expect(clearIntervalSpy).toHaveBeenCalledTimes(1);
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
clearIntervalSpy.mockRestore();
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
test("shutdown does not call clearInterval at all when no presence source was ever configured", async () => {
|
|
118
|
+
const identity = generateIdentity();
|
|
119
|
+
const clearIntervalSpy = vi.spyOn(global, "clearInterval");
|
|
120
|
+
try {
|
|
121
|
+
const transport = new WireMeshTransport(noopEvents(), identity);
|
|
122
|
+
clearIntervalSpy.mockClear();
|
|
123
|
+
await transport.shutdown();
|
|
124
|
+
expect(clearIntervalSpy).not.toHaveBeenCalled();
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
clearIntervalSpy.mockRestore();
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
test("a connect_request left unanswered past the configured timeout is auto-rejected with the documented error code", async () => {
|
|
131
|
+
const identityA = generateIdentity();
|
|
132
|
+
const identityB = generateIdentity();
|
|
133
|
+
const idB = await peerId(await toIdentityPort(identityB));
|
|
134
|
+
const SHORT_TIMEOUT_MS = 150;
|
|
135
|
+
const transportA = new WireMeshTransport(noopEvents(), identityA, undefined, SHORT_TIMEOUT_MS);
|
|
136
|
+
const transportB = new WireMeshTransport(noopEvents(), identityB);
|
|
137
|
+
try {
|
|
138
|
+
await transportA.becomeCoordinator("127.0.0.1", 0);
|
|
139
|
+
const [listener] = transportA.listListeners();
|
|
140
|
+
if (listener === undefined)
|
|
141
|
+
throw new Error("expected a bound listener");
|
|
142
|
+
const clientTransport = createTlsTransport({
|
|
143
|
+
certificatePem: identityB.certificate,
|
|
144
|
+
privateKeyPem: identityB.privateKey,
|
|
145
|
+
});
|
|
146
|
+
const connection = await clientTransport.connect(`127.0.0.1:${String(listener.port)}`);
|
|
147
|
+
const clientIdentityPort = await toIdentityPort(identityB);
|
|
148
|
+
const session = await acceptMeshSession(connection, clientIdentityPort, [
|
|
149
|
+
DOMAIN,
|
|
150
|
+
]);
|
|
151
|
+
const outcome = await session.sendManageRequest(buildCommand({
|
|
152
|
+
method: "connect_request",
|
|
153
|
+
peerId: idB,
|
|
154
|
+
dataPort: 0,
|
|
155
|
+
name: "connector",
|
|
156
|
+
fingerprint: "",
|
|
157
|
+
}), FRAME_SCOPE);
|
|
158
|
+
expect(outcome).toMatchObject({ result: "error", code: "timeout" });
|
|
159
|
+
await session.close();
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
await transportB.shutdown();
|
|
163
|
+
await transportA.shutdown();
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
describe("WireMeshTransport unref", () => {
|
|
168
|
+
test("unrefs the data listener and every coordinator listener, not just one of them", async () => {
|
|
169
|
+
const identity = generateIdentity();
|
|
170
|
+
const transport = new WireMeshTransport(noopEvents(), identity);
|
|
171
|
+
const unrefSpy = vi.spyOn(net.Server.prototype, "unref");
|
|
172
|
+
try {
|
|
173
|
+
await transport.startDataServer();
|
|
174
|
+
const port = await findFreePort();
|
|
175
|
+
await transport.addListener("127.0.0.1", port, "full");
|
|
176
|
+
unrefSpy.mockClear();
|
|
177
|
+
transport.unref();
|
|
178
|
+
// The data listener plus exactly one added coordinator listener -- two distinct real net.Server instances, each individually unref'd.
|
|
179
|
+
expect(unrefSpy).toHaveBeenCalledTimes(2);
|
|
180
|
+
}
|
|
181
|
+
finally {
|
|
182
|
+
unrefSpy.mockRestore();
|
|
183
|
+
await transport.shutdown();
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
test("unref with no listeners started at all is a safe no-op, not a throw", async () => {
|
|
187
|
+
const identity = generateIdentity();
|
|
188
|
+
const transport = new WireMeshTransport(noopEvents(), identity);
|
|
189
|
+
expect(() => {
|
|
190
|
+
transport.unref();
|
|
191
|
+
}).not.toThrow();
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
//# sourceMappingURL=wire-mesh-transport-shutdown-unref.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wire-mesh-transport-shutdown-unref.test.js","sourceRoot":"","sources":["../../src/test/wire-mesh-transport-shutdown-unref.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.
|
|
3
|
+
"version": "2.21.10",
|
|
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",
|