@rookdaemon/agora 0.1.5 → 0.2.1
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/README.md +192 -0
- package/dist/cli.js +146 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +18 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +63 -22
- package/dist/config.js.map +1 -1
- package/dist/discovery/bootstrap.d.ts +32 -0
- package/dist/discovery/bootstrap.d.ts.map +1 -0
- package/dist/discovery/bootstrap.js +36 -0
- package/dist/discovery/bootstrap.js.map +1 -0
- package/dist/discovery/peer-discovery.d.ts +59 -0
- package/dist/discovery/peer-discovery.d.ts.map +1 -0
- package/dist/discovery/peer-discovery.js +108 -0
- package/dist/discovery/peer-discovery.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/message/envelope.d.ts +1 -1
- package/dist/message/envelope.d.ts.map +1 -1
- package/dist/message/envelope.js.map +1 -1
- package/dist/message/types/peer-discovery.d.ts +78 -0
- package/dist/message/types/peer-discovery.d.ts.map +1 -0
- package/dist/message/types/peer-discovery.js +90 -0
- package/dist/message/types/peer-discovery.js.map +1 -0
- package/dist/registry/discovery-service.d.ts +64 -0
- package/dist/registry/discovery-service.d.ts.map +1 -0
- package/dist/registry/discovery-service.js +129 -0
- package/dist/registry/discovery-service.js.map +1 -0
- package/dist/registry/messages.d.ts +55 -0
- package/dist/registry/messages.d.ts.map +1 -1
- package/dist/relay/server.d.ts +16 -0
- package/dist/relay/server.d.ts.map +1 -1
- package/dist/relay/server.js +73 -1
- package/dist/relay/server.js.map +1 -1
- package/dist/service.d.ts +82 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +132 -0
- package/dist/service.js.map +1 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +12 -0
- package/dist/utils.js.map +1 -0
- package/package.json +43 -1
package/dist/service.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { getDefaultConfigPath, loadAgoraConfigAsync } from './config.js';
|
|
2
|
+
import { RelayClient } from './relay/client.js';
|
|
3
|
+
import { decodeInboundEnvelope, sendToPeer } from './transport/http.js';
|
|
4
|
+
/**
|
|
5
|
+
* High-level Agora service: send by peer name, decode inbound, relay lifecycle.
|
|
6
|
+
*/
|
|
7
|
+
export class AgoraService {
|
|
8
|
+
config;
|
|
9
|
+
relayClient = null;
|
|
10
|
+
relayMessageHandler = null;
|
|
11
|
+
logger;
|
|
12
|
+
relayClientFactory;
|
|
13
|
+
constructor(config, logger, relayClientFactory) {
|
|
14
|
+
this.config = config;
|
|
15
|
+
this.logger = logger ?? null;
|
|
16
|
+
this.relayClientFactory = relayClientFactory ?? null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Send a signed message to a named peer.
|
|
20
|
+
*/
|
|
21
|
+
async sendMessage(options) {
|
|
22
|
+
const peer = this.config.peers.get(options.peerName);
|
|
23
|
+
if (!peer) {
|
|
24
|
+
return {
|
|
25
|
+
ok: false,
|
|
26
|
+
status: 0,
|
|
27
|
+
error: `Unknown peer: ${options.peerName}`,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const transportConfig = {
|
|
31
|
+
identity: {
|
|
32
|
+
publicKey: this.config.identity.publicKey,
|
|
33
|
+
privateKey: this.config.identity.privateKey,
|
|
34
|
+
},
|
|
35
|
+
peers: new Map([[peer.publicKey, peer]]),
|
|
36
|
+
};
|
|
37
|
+
return sendToPeer(transportConfig, peer.publicKey, options.type, options.payload, options.inReplyTo);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Decode and verify an inbound envelope from a webhook message.
|
|
41
|
+
*/
|
|
42
|
+
async decodeInbound(message) {
|
|
43
|
+
const peersByPubKey = new Map();
|
|
44
|
+
for (const peer of this.config.peers.values()) {
|
|
45
|
+
peersByPubKey.set(peer.publicKey, peer);
|
|
46
|
+
}
|
|
47
|
+
const result = decodeInboundEnvelope(message, peersByPubKey);
|
|
48
|
+
if (result.ok) {
|
|
49
|
+
return { ok: true, envelope: result.envelope };
|
|
50
|
+
}
|
|
51
|
+
return { ok: false, reason: result.reason };
|
|
52
|
+
}
|
|
53
|
+
getPeers() {
|
|
54
|
+
return Array.from(this.config.peers.keys());
|
|
55
|
+
}
|
|
56
|
+
getPeerConfig(name) {
|
|
57
|
+
return this.config.peers.get(name);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Connect to the relay server.
|
|
61
|
+
*/
|
|
62
|
+
async connectRelay(url) {
|
|
63
|
+
if (this.relayClient) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const maxReconnectDelay = this.config.relay?.reconnectMaxMs ?? 300000;
|
|
67
|
+
const name = this.config.identity.name ?? this.config.relay?.name;
|
|
68
|
+
const opts = {
|
|
69
|
+
relayUrl: url,
|
|
70
|
+
publicKey: this.config.identity.publicKey,
|
|
71
|
+
privateKey: this.config.identity.privateKey,
|
|
72
|
+
name,
|
|
73
|
+
pingInterval: 30000,
|
|
74
|
+
maxReconnectDelay,
|
|
75
|
+
};
|
|
76
|
+
if (this.relayClientFactory) {
|
|
77
|
+
this.relayClient = this.relayClientFactory(opts);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.relayClient = new RelayClient(opts);
|
|
81
|
+
}
|
|
82
|
+
this.relayClient.on('error', (error) => {
|
|
83
|
+
this.logger?.debug(`Agora relay error: ${error.message}`);
|
|
84
|
+
});
|
|
85
|
+
this.relayClient.on('message', (envelope) => {
|
|
86
|
+
if (this.relayMessageHandler) {
|
|
87
|
+
this.relayMessageHandler(envelope);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
try {
|
|
91
|
+
await this.relayClient.connect();
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
95
|
+
this.logger?.debug(`Agora relay connect failed (${url}): ${message}`);
|
|
96
|
+
this.relayClient = null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
setRelayMessageHandler(handler) {
|
|
100
|
+
this.relayMessageHandler = handler;
|
|
101
|
+
}
|
|
102
|
+
async disconnectRelay() {
|
|
103
|
+
if (this.relayClient) {
|
|
104
|
+
this.relayClient.disconnect();
|
|
105
|
+
this.relayClient = null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
isRelayConnected() {
|
|
109
|
+
return this.relayClient?.connected() ?? false;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Load Agora configuration and return service config (peers as Map).
|
|
113
|
+
*/
|
|
114
|
+
static async loadConfig(path) {
|
|
115
|
+
const configPath = path ?? getDefaultConfigPath();
|
|
116
|
+
const loaded = await loadAgoraConfigAsync(configPath);
|
|
117
|
+
const peers = new Map();
|
|
118
|
+
for (const [name, p] of Object.entries(loaded.peers)) {
|
|
119
|
+
peers.set(name, {
|
|
120
|
+
publicKey: p.publicKey,
|
|
121
|
+
url: p.url,
|
|
122
|
+
token: p.token,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
identity: loaded.identity,
|
|
127
|
+
peers,
|
|
128
|
+
relay: loaded.relay,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get a short display version of a public key using the last 8 characters.
|
|
3
|
+
* Ed25519 public keys all share the same OID prefix, so the last 8 characters
|
|
4
|
+
* are more distinguishable than the first 8.
|
|
5
|
+
*
|
|
6
|
+
* @param publicKey - The full public key hex string
|
|
7
|
+
* @returns The last 8 characters of the key followed by "..."
|
|
8
|
+
*/
|
|
9
|
+
export declare function shortKey(publicKey: string): string;
|
|
10
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAElD"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get a short display version of a public key using the last 8 characters.
|
|
3
|
+
* Ed25519 public keys all share the same OID prefix, so the last 8 characters
|
|
4
|
+
* are more distinguishable than the first 8.
|
|
5
|
+
*
|
|
6
|
+
* @param publicKey - The full public key hex string
|
|
7
|
+
* @returns The last 8 characters of the key followed by "..."
|
|
8
|
+
*/
|
|
9
|
+
export function shortKey(publicKey) {
|
|
10
|
+
return publicKey.slice(-8) + "...";
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,SAAiB;IACxC,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AACrC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1 +1,43 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"name": "@rookdaemon/agora",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "A coordination network for AI agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"agora": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"test": "node --import tsx --test test/*.test.ts",
|
|
14
|
+
"lint": "eslint src test --ext .ts",
|
|
15
|
+
"prepublishOnly": "npm run lint && npm run build && npm test",
|
|
16
|
+
"pretest": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"agent",
|
|
25
|
+
"coordination",
|
|
26
|
+
"distributed",
|
|
27
|
+
"p2p"
|
|
28
|
+
],
|
|
29
|
+
"author": "",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^25.1.0",
|
|
33
|
+
"@types/ws": "^8.18.1",
|
|
34
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
35
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
36
|
+
"eslint": "^9.39.2",
|
|
37
|
+
"tsx": "^4.21.0",
|
|
38
|
+
"typescript": "^5.9.3"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"ws": "^8.19.0"
|
|
42
|
+
}
|
|
43
|
+
}
|