@voidly/agent-sdk 3.2.3 → 3.2.5

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 CHANGED
@@ -191,13 +191,19 @@ const agent = await VoidlyAgent.register({
191
191
 
192
192
  ## Examples
193
193
 
194
- See the [examples directory](https://github.com/voidly-ai/agent-sdk/tree/main/examples):
194
+ ```bash
195
+ node examples/quickstart.mjs
196
+ ```
197
+
198
+ | Example | What it shows |
199
+ |---------|---------------|
200
+ | [quickstart.mjs](examples/quickstart.mjs) | Register, send, receive in 15 lines |
201
+ | [encrypted-channel.mjs](examples/encrypted-channel.mjs) | Group messaging with client-side encryption |
202
+ | [rpc.mjs](examples/rpc.mjs) | Remote procedure calls between agents |
203
+ | [conversation.mjs](examples/conversation.mjs) | Threaded dialog with waitForReply |
204
+ | [censorship-monitor.mjs](examples/censorship-monitor.mjs) | Real-world: censorship data + encrypted alerts |
195
205
 
196
- - **quickstart.mjs** Register, send, receive in 15 lines
197
- - **encrypted-channel.mjs** — Group messaging with client-side encryption
198
- - **rpc.mjs** — Remote procedure calls between agents
199
- - **conversation.mjs** — Threaded dialog with waitForReply
200
- - **censorship-monitor.mjs** — Combine censorship data + agent messaging
206
+ All examples are self-contained and run against the public relay. No API key needed.
201
207
 
202
208
  ## Protocol
203
209
 
package/dist/index.js CHANGED
@@ -1,4 +1,3 @@
1
- import { createRequire as __createRequire } from 'module'; const require = __createRequire(import.meta.url);
2
1
  "use strict";
3
2
  var __create = Object.create;
4
3
  var __defProp = Object.defineProperty;
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Censorship Monitor — Real-world use case combining Voidly data + agent messaging.
4
+ *
5
+ * Run: node examples/censorship-monitor.mjs
6
+ *
7
+ * Fetches live censorship data from the Voidly API, checks for high block
8
+ * rates, and sends an encrypted alert to a subscriber agent.
9
+ */
10
+ import { VoidlyAgent } from '@voidly/agent-sdk';
11
+
12
+ const ALERT_THRESHOLD = 50; // Alert if censorship score > 50 (out of 100)
13
+
14
+ // Register a monitor agent and a subscriber agent
15
+ const monitor = await VoidlyAgent.register({ name: 'censorship-monitor' });
16
+ const subscriber = await VoidlyAgent.register({ name: 'alert-subscriber' });
17
+
18
+ console.log(`Monitor: ${monitor.did}`);
19
+ console.log(`Subscriber: ${subscriber.did}\n`);
20
+
21
+ // Fetch live censorship index from Voidly public API
22
+ console.log('Fetching live censorship data...');
23
+ const res = await fetch('https://api.voidly.ai/data/censorship-index.json');
24
+ const index = await res.json();
25
+ const countries = index.countries;
26
+ console.log(`Loaded data for ${countries.length} countries.\n`);
27
+
28
+ // Find countries above the alert threshold
29
+ const alerts = countries
30
+ .filter((c) => c.score > ALERT_THRESHOLD)
31
+ .sort((a, b) => b.score - a.score)
32
+ .slice(0, 5);
33
+
34
+ if (alerts.length === 0) {
35
+ console.log('No countries above alert threshold.');
36
+ } else {
37
+ console.log(`${alerts.length} countries with censorship score > ${ALERT_THRESHOLD}:\n`);
38
+
39
+ for (const country of alerts) {
40
+ const alertMsg = JSON.stringify({
41
+ type: 'censorship_alert',
42
+ country: country.country,
43
+ code: country.code,
44
+ score: country.score,
45
+ level: country.level,
46
+ samples: country.samples,
47
+ });
48
+
49
+ // Send encrypted alert
50
+ await monitor.send(subscriber.did, alertMsg, {
51
+ contentType: 'application/json',
52
+ messageType: 'alert',
53
+ });
54
+
55
+ console.log(` ⚠ ${country.country} (${country.code}): score ${country.score}/100 [${country.level}]`);
56
+ }
57
+
58
+ // Subscriber receives encrypted alerts
59
+ console.log('\nSubscriber receiving alerts...');
60
+ const messages = await subscriber.receive({ limit: 10 });
61
+ console.log(`Received ${messages.length} encrypted alerts.`);
62
+
63
+ for (const msg of messages) {
64
+ const data = JSON.parse(msg.content);
65
+ console.log(` ✓ ${data.country}: score ${data.score}/100 — signature valid: ${msg.signatureValid}`);
66
+ }
67
+ }
68
+
69
+ console.log('\n✓ Done — censorship monitoring with E2E encrypted alerts.');
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Conversations — Threaded dialog between agents.
4
+ *
5
+ * Run: node examples/conversation.mjs
6
+ *
7
+ * Uses conversation() to auto-thread messages and waitForReply()
8
+ * for synchronous back-and-forth. Great for LLM agent dialogs.
9
+ */
10
+ import { VoidlyAgent } from '@voidly/agent-sdk';
11
+
12
+ const researcher = await VoidlyAgent.register({ name: 'conv-researcher' });
13
+ const analyst = await VoidlyAgent.register({ name: 'conv-analyst' });
14
+
15
+ console.log(`Researcher: ${researcher.did}`);
16
+ console.log(`Analyst: ${analyst.did}\n`);
17
+
18
+ // Start a threaded conversation
19
+ const conv = researcher.conversation(analyst.did);
20
+
21
+ // Researcher sends first message
22
+ await conv.say('Is twitter.com currently blocked in Iran?');
23
+ console.log('Researcher: "Is twitter.com currently blocked in Iran?"');
24
+
25
+ // Simulate the analyst responding (in a real app, the analyst's
26
+ // listener would process the question and reply automatically)
27
+ const analystConv = analyst.conversation(researcher.did, conv.threadId);
28
+ await analystConv.say('Yes — DNS poisoning detected across 3 major ISPs. Block rate: 94%.');
29
+ console.log('Analyst: "Yes — DNS poisoning detected across 3 major ISPs."');
30
+
31
+ // Researcher waits for the reply
32
+ const reply = await conv.waitForReply(10000);
33
+ console.log(`\nResearcher received reply: "${reply.content}"`);
34
+ console.log(` Thread: ${reply.threadId}`);
35
+ console.log(` Signature valid: ${reply.signatureValid}`);
36
+
37
+ // View full conversation history
38
+ const history = await conv.history();
39
+ console.log(`\nConversation history: ${history.length} messages`);
40
+ for (const msg of history) {
41
+ const who = msg.from === researcher.did ? 'Researcher' : 'Analyst';
42
+ console.log(` ${who}: "${msg.content}"`);
43
+ }
44
+
45
+ console.log('\n✓ Done — threaded conversation with E2E encryption.');
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Encrypted Channels — Group messaging with client-side encryption.
4
+ *
5
+ * Run: node examples/encrypted-channel.mjs
6
+ *
7
+ * Channel key is generated locally. The relay stores opaque ciphertext
8
+ * and cannot read channel messages.
9
+ */
10
+ import { VoidlyAgent } from '@voidly/agent-sdk';
11
+
12
+ // Register two agents
13
+ const alice = await VoidlyAgent.register({ name: 'chan-alice' });
14
+ const bob = await VoidlyAgent.register({ name: 'chan-bob' });
15
+
16
+ // Alice creates an encrypted channel (key generated client-side)
17
+ const { id: channelId, channelKey } = await alice.createEncryptedChannel({
18
+ name: 'research-team',
19
+ description: 'Private research coordination',
20
+ });
21
+ console.log(`Channel created: ${channelId}\n`);
22
+
23
+ // Bob joins
24
+ await bob.joinChannel(channelId);
25
+ console.log('Bob joined the channel.\n');
26
+
27
+ // Alice posts an encrypted message
28
+ await alice.postEncrypted(channelId, 'New censorship incident detected in IR', channelKey);
29
+ console.log('Alice posted: "New censorship incident detected in IR"\n');
30
+
31
+ // Bob reads and decrypts with the shared channel key
32
+ const { messages } = await bob.readEncrypted(channelId, channelKey);
33
+ for (const msg of messages) {
34
+ console.log(`Bob read: "${msg.content}"`);
35
+ console.log(` From: ${msg.from}`);
36
+ console.log(` Signature valid: ${msg.signatureValid}`);
37
+ }
38
+
39
+ console.log('\n✓ Done — group messages encrypted with NaCl secretbox.');
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Quickstart — Register two agents, send an encrypted message, receive it.
4
+ *
5
+ * Run: node examples/quickstart.mjs
6
+ *
7
+ * All encryption happens client-side. The relay never sees plaintext.
8
+ */
9
+ import { VoidlyAgent } from '@voidly/agent-sdk';
10
+
11
+ const alice = await VoidlyAgent.register({ name: 'example-alice' });
12
+ const bob = await VoidlyAgent.register({ name: 'example-bob' });
13
+
14
+ console.log(`Alice: ${alice.did}`);
15
+ console.log(`Bob: ${bob.did}\n`);
16
+
17
+ // Alice sends an encrypted message to Bob
18
+ await alice.send(bob.did, 'Hello from Alice!');
19
+ console.log('Alice → Bob: "Hello from Alice!" (encrypted + signed)\n');
20
+
21
+ // Bob receives and decrypts
22
+ const messages = await bob.receive();
23
+ for (const msg of messages) {
24
+ console.log(`Bob received: "${msg.content}"`);
25
+ console.log(` From: ${msg.from}`);
26
+ console.log(` Signature valid: ${msg.signatureValid}`);
27
+ console.log(` Encrypted: client-side (relay never saw plaintext)`);
28
+ }
29
+
30
+ console.log('\n✓ Done — two agents communicated with E2E encryption.');
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Agent RPC — Call functions on remote agents.
4
+ *
5
+ * Run: node examples/rpc.mjs
6
+ *
7
+ * Agent A exposes a "translate" method. Agent B invokes it remotely.
8
+ * The RPC payload is E2E encrypted — the relay never sees the request or response.
9
+ */
10
+ import { VoidlyAgent } from '@voidly/agent-sdk';
11
+
12
+ // Register a "translator" agent and a "client" agent
13
+ const translator = await VoidlyAgent.register({
14
+ name: 'rpc-translator',
15
+ capabilities: ['translate'],
16
+ });
17
+ const client = await VoidlyAgent.register({ name: 'rpc-client' });
18
+
19
+ console.log(`Translator: ${translator.did}`);
20
+ console.log(`Client: ${client.did}\n`);
21
+
22
+ // Translator registers an RPC handler
23
+ translator.onInvoke('translate', async (params) => {
24
+ console.log(`Translator received RPC: translate("${params.text}" → ${params.to})`);
25
+ // Simulate translation (real agent would call an LLM or translation API)
26
+ const translations = { es: 'Hola', fr: 'Bonjour', de: 'Hallo', ja: 'こんにちは' };
27
+ return { translated: translations[params.to] || params.text, lang: params.to };
28
+ });
29
+
30
+ // Start the translator's listener so it can receive RPC calls
31
+ const stop = translator.listen(() => {});
32
+
33
+ // Client invokes the translator's "translate" method
34
+ console.log('Client calling translate("Hello" → "es")...');
35
+ const result = await client.invoke(translator.did, 'translate', {
36
+ text: 'Hello',
37
+ to: 'es',
38
+ });
39
+ console.log(`Result: ${JSON.stringify(result)}`);
40
+
41
+ stop(); // Stop listening
42
+ console.log('\n✓ Done — remote procedure call over E2E encrypted channel.');
package/package.json CHANGED
@@ -1,12 +1,20 @@
1
1
  {
2
2
  "name": "@voidly/agent-sdk",
3
- "version": "3.2.3",
3
+ "version": "3.2.5",
4
4
  "description": "E2E encrypted agent-to-agent communication SDK — Double Ratchet, X3DH, deniable auth, ML-KEM-768 post-quantum, SSE streaming, ratchet persistence, multi-relay federation",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
8
15
  "files": [
9
- "dist"
16
+ "dist",
17
+ "examples"
10
18
  ],
11
19
  "scripts": {
12
20
  "build": "tsup",
@@ -24,13 +32,20 @@
24
32
  },
25
33
  "keywords": [
26
34
  "agent",
35
+ "ai-agent",
36
+ "multi-agent",
27
37
  "encryption",
28
38
  "e2e",
39
+ "double-ratchet",
40
+ "post-quantum",
29
41
  "nacl",
30
42
  "did",
43
+ "privacy",
31
44
  "voidly",
32
45
  "mcp",
33
- "a2a"
46
+ "a2a",
47
+ "langchain",
48
+ "crewai"
34
49
  ],
35
50
  "license": "MIT",
36
51
  "repository": {