@voidly/agent-sdk 1.6.0 → 1.8.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.
- package/dist/index.d.mts +148 -0
- package/dist/index.d.ts +148 -0
- package/dist/index.js +196 -0
- package/dist/index.mjs +196 -0
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -115,6 +115,7 @@ declare class VoidlyAgent {
|
|
|
115
115
|
threadId?: string;
|
|
116
116
|
replyTo?: string;
|
|
117
117
|
ttl?: number;
|
|
118
|
+
messageType?: string;
|
|
118
119
|
}): Promise<SendResult>;
|
|
119
120
|
/**
|
|
120
121
|
* Receive and decrypt messages. Decryption happens locally.
|
|
@@ -556,6 +557,153 @@ declare class VoidlyAgent {
|
|
|
556
557
|
signature: string;
|
|
557
558
|
timestamp: string;
|
|
558
559
|
}, signingPublicKey: string): boolean;
|
|
560
|
+
/**
|
|
561
|
+
* Store an encrypted key-value pair in persistent memory.
|
|
562
|
+
* Values are encrypted with a key derived from your API key — only you can read them.
|
|
563
|
+
*/
|
|
564
|
+
memorySet(namespace: string, key: string, value: unknown, options?: {
|
|
565
|
+
valueType?: string;
|
|
566
|
+
ttl?: number;
|
|
567
|
+
}): Promise<{
|
|
568
|
+
stored: boolean;
|
|
569
|
+
id: string;
|
|
570
|
+
size_bytes: number;
|
|
571
|
+
expires_at: string | null;
|
|
572
|
+
}>;
|
|
573
|
+
/**
|
|
574
|
+
* Retrieve a value from persistent memory.
|
|
575
|
+
* Decrypted server-side using your API key derivation.
|
|
576
|
+
*/
|
|
577
|
+
memoryGet(namespace: string, key: string): Promise<{
|
|
578
|
+
namespace: string;
|
|
579
|
+
key: string;
|
|
580
|
+
value: unknown;
|
|
581
|
+
value_type: string;
|
|
582
|
+
size_bytes: number;
|
|
583
|
+
created_at: string;
|
|
584
|
+
updated_at: string;
|
|
585
|
+
expires_at: string | null;
|
|
586
|
+
} | null>;
|
|
587
|
+
/**
|
|
588
|
+
* Delete a key from persistent memory.
|
|
589
|
+
*/
|
|
590
|
+
memoryDelete(namespace: string, key: string): Promise<{
|
|
591
|
+
deleted: boolean;
|
|
592
|
+
}>;
|
|
593
|
+
/**
|
|
594
|
+
* List all keys in a memory namespace.
|
|
595
|
+
*/
|
|
596
|
+
memoryList(namespace?: string, options?: {
|
|
597
|
+
prefix?: string;
|
|
598
|
+
limit?: number;
|
|
599
|
+
}): Promise<{
|
|
600
|
+
namespace: string;
|
|
601
|
+
keys: Array<{
|
|
602
|
+
key: string;
|
|
603
|
+
value_type: string;
|
|
604
|
+
size_bytes: number;
|
|
605
|
+
updated_at: string;
|
|
606
|
+
}>;
|
|
607
|
+
total_keys: number;
|
|
608
|
+
total_bytes: number;
|
|
609
|
+
}>;
|
|
610
|
+
/**
|
|
611
|
+
* List all memory namespaces and quota usage.
|
|
612
|
+
*/
|
|
613
|
+
memoryNamespaces(): Promise<{
|
|
614
|
+
namespaces: Array<{
|
|
615
|
+
namespace: string;
|
|
616
|
+
key_count: number;
|
|
617
|
+
total_bytes: number;
|
|
618
|
+
last_updated: string;
|
|
619
|
+
}>;
|
|
620
|
+
quota: {
|
|
621
|
+
used_bytes: number;
|
|
622
|
+
quota_bytes: number;
|
|
623
|
+
remaining_bytes: number;
|
|
624
|
+
};
|
|
625
|
+
}>;
|
|
626
|
+
/**
|
|
627
|
+
* Export all agent data as a portable JSON bundle.
|
|
628
|
+
* Includes identity, messages, channels, tasks, attestations, memory, and trust.
|
|
629
|
+
* Memory values remain encrypted — portable to another relay.
|
|
630
|
+
*/
|
|
631
|
+
exportData(options?: {
|
|
632
|
+
includeMessages?: boolean;
|
|
633
|
+
includeChannels?: boolean;
|
|
634
|
+
includeTasks?: boolean;
|
|
635
|
+
includeAttestations?: boolean;
|
|
636
|
+
includeMemory?: boolean;
|
|
637
|
+
includeTrust?: boolean;
|
|
638
|
+
}): Promise<Record<string, unknown>>;
|
|
639
|
+
/**
|
|
640
|
+
* List past data export records.
|
|
641
|
+
*/
|
|
642
|
+
listExports(): Promise<{
|
|
643
|
+
exports: Array<Record<string, unknown>>;
|
|
644
|
+
}>;
|
|
645
|
+
/**
|
|
646
|
+
* Get information about the relay this agent is connected to.
|
|
647
|
+
* Includes federation capabilities and known peers.
|
|
648
|
+
*/
|
|
649
|
+
getRelayInfo(): Promise<Record<string, unknown>>;
|
|
650
|
+
/**
|
|
651
|
+
* List known federated relay peers.
|
|
652
|
+
*/
|
|
653
|
+
getRelayPeers(): Promise<{
|
|
654
|
+
peers: Array<Record<string, unknown>>;
|
|
655
|
+
total: number;
|
|
656
|
+
}>;
|
|
657
|
+
/**
|
|
658
|
+
* Route a message through federation to an agent on a different relay.
|
|
659
|
+
* The relay will forward it to the recipient's home relay.
|
|
660
|
+
*/
|
|
661
|
+
routeMessage(toDid: string, message: string, options?: {
|
|
662
|
+
contentType?: string;
|
|
663
|
+
threadId?: string;
|
|
664
|
+
}): Promise<{
|
|
665
|
+
routed: boolean;
|
|
666
|
+
destination: string;
|
|
667
|
+
}>;
|
|
668
|
+
/** Send heartbeat — signals agent is alive, updates last_seen */
|
|
669
|
+
ping(): Promise<{
|
|
670
|
+
pong: boolean;
|
|
671
|
+
did: string;
|
|
672
|
+
status: string;
|
|
673
|
+
uptime: {
|
|
674
|
+
days: number;
|
|
675
|
+
hours: number;
|
|
676
|
+
};
|
|
677
|
+
}>;
|
|
678
|
+
/** Check if another agent is online (public) */
|
|
679
|
+
checkOnline(did: string): Promise<{
|
|
680
|
+
did: string;
|
|
681
|
+
online_status: 'online' | 'idle' | 'offline';
|
|
682
|
+
last_seen: string;
|
|
683
|
+
minutes_since_seen: number | null;
|
|
684
|
+
}>;
|
|
685
|
+
/** Pin another agent's public keys (Trust On First Use). Returns warning if keys changed since last pin. */
|
|
686
|
+
pinKeys(did: string): Promise<{
|
|
687
|
+
pinned: boolean;
|
|
688
|
+
key_changed: boolean;
|
|
689
|
+
status: string;
|
|
690
|
+
warning?: string;
|
|
691
|
+
}>;
|
|
692
|
+
/** List all pinned keys */
|
|
693
|
+
listPinnedKeys(options?: {
|
|
694
|
+
status?: string;
|
|
695
|
+
}): Promise<{
|
|
696
|
+
pins: any[];
|
|
697
|
+
total: number;
|
|
698
|
+
}>;
|
|
699
|
+
/** Verify an agent's keys against your pinned copy. Detects key changes (potential MitM). */
|
|
700
|
+
verifyKeys(did: string): Promise<{
|
|
701
|
+
did: string;
|
|
702
|
+
pinned: boolean;
|
|
703
|
+
verified?: boolean;
|
|
704
|
+
status: string;
|
|
705
|
+
warning?: string;
|
|
706
|
+
}>;
|
|
559
707
|
}
|
|
560
708
|
|
|
561
709
|
export { type AgentIdentity, type AgentProfile, type DecryptedMessage, type SendResult, VoidlyAgent, type VoidlyAgentConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -115,6 +115,7 @@ declare class VoidlyAgent {
|
|
|
115
115
|
threadId?: string;
|
|
116
116
|
replyTo?: string;
|
|
117
117
|
ttl?: number;
|
|
118
|
+
messageType?: string;
|
|
118
119
|
}): Promise<SendResult>;
|
|
119
120
|
/**
|
|
120
121
|
* Receive and decrypt messages. Decryption happens locally.
|
|
@@ -556,6 +557,153 @@ declare class VoidlyAgent {
|
|
|
556
557
|
signature: string;
|
|
557
558
|
timestamp: string;
|
|
558
559
|
}, signingPublicKey: string): boolean;
|
|
560
|
+
/**
|
|
561
|
+
* Store an encrypted key-value pair in persistent memory.
|
|
562
|
+
* Values are encrypted with a key derived from your API key — only you can read them.
|
|
563
|
+
*/
|
|
564
|
+
memorySet(namespace: string, key: string, value: unknown, options?: {
|
|
565
|
+
valueType?: string;
|
|
566
|
+
ttl?: number;
|
|
567
|
+
}): Promise<{
|
|
568
|
+
stored: boolean;
|
|
569
|
+
id: string;
|
|
570
|
+
size_bytes: number;
|
|
571
|
+
expires_at: string | null;
|
|
572
|
+
}>;
|
|
573
|
+
/**
|
|
574
|
+
* Retrieve a value from persistent memory.
|
|
575
|
+
* Decrypted server-side using your API key derivation.
|
|
576
|
+
*/
|
|
577
|
+
memoryGet(namespace: string, key: string): Promise<{
|
|
578
|
+
namespace: string;
|
|
579
|
+
key: string;
|
|
580
|
+
value: unknown;
|
|
581
|
+
value_type: string;
|
|
582
|
+
size_bytes: number;
|
|
583
|
+
created_at: string;
|
|
584
|
+
updated_at: string;
|
|
585
|
+
expires_at: string | null;
|
|
586
|
+
} | null>;
|
|
587
|
+
/**
|
|
588
|
+
* Delete a key from persistent memory.
|
|
589
|
+
*/
|
|
590
|
+
memoryDelete(namespace: string, key: string): Promise<{
|
|
591
|
+
deleted: boolean;
|
|
592
|
+
}>;
|
|
593
|
+
/**
|
|
594
|
+
* List all keys in a memory namespace.
|
|
595
|
+
*/
|
|
596
|
+
memoryList(namespace?: string, options?: {
|
|
597
|
+
prefix?: string;
|
|
598
|
+
limit?: number;
|
|
599
|
+
}): Promise<{
|
|
600
|
+
namespace: string;
|
|
601
|
+
keys: Array<{
|
|
602
|
+
key: string;
|
|
603
|
+
value_type: string;
|
|
604
|
+
size_bytes: number;
|
|
605
|
+
updated_at: string;
|
|
606
|
+
}>;
|
|
607
|
+
total_keys: number;
|
|
608
|
+
total_bytes: number;
|
|
609
|
+
}>;
|
|
610
|
+
/**
|
|
611
|
+
* List all memory namespaces and quota usage.
|
|
612
|
+
*/
|
|
613
|
+
memoryNamespaces(): Promise<{
|
|
614
|
+
namespaces: Array<{
|
|
615
|
+
namespace: string;
|
|
616
|
+
key_count: number;
|
|
617
|
+
total_bytes: number;
|
|
618
|
+
last_updated: string;
|
|
619
|
+
}>;
|
|
620
|
+
quota: {
|
|
621
|
+
used_bytes: number;
|
|
622
|
+
quota_bytes: number;
|
|
623
|
+
remaining_bytes: number;
|
|
624
|
+
};
|
|
625
|
+
}>;
|
|
626
|
+
/**
|
|
627
|
+
* Export all agent data as a portable JSON bundle.
|
|
628
|
+
* Includes identity, messages, channels, tasks, attestations, memory, and trust.
|
|
629
|
+
* Memory values remain encrypted — portable to another relay.
|
|
630
|
+
*/
|
|
631
|
+
exportData(options?: {
|
|
632
|
+
includeMessages?: boolean;
|
|
633
|
+
includeChannels?: boolean;
|
|
634
|
+
includeTasks?: boolean;
|
|
635
|
+
includeAttestations?: boolean;
|
|
636
|
+
includeMemory?: boolean;
|
|
637
|
+
includeTrust?: boolean;
|
|
638
|
+
}): Promise<Record<string, unknown>>;
|
|
639
|
+
/**
|
|
640
|
+
* List past data export records.
|
|
641
|
+
*/
|
|
642
|
+
listExports(): Promise<{
|
|
643
|
+
exports: Array<Record<string, unknown>>;
|
|
644
|
+
}>;
|
|
645
|
+
/**
|
|
646
|
+
* Get information about the relay this agent is connected to.
|
|
647
|
+
* Includes federation capabilities and known peers.
|
|
648
|
+
*/
|
|
649
|
+
getRelayInfo(): Promise<Record<string, unknown>>;
|
|
650
|
+
/**
|
|
651
|
+
* List known federated relay peers.
|
|
652
|
+
*/
|
|
653
|
+
getRelayPeers(): Promise<{
|
|
654
|
+
peers: Array<Record<string, unknown>>;
|
|
655
|
+
total: number;
|
|
656
|
+
}>;
|
|
657
|
+
/**
|
|
658
|
+
* Route a message through federation to an agent on a different relay.
|
|
659
|
+
* The relay will forward it to the recipient's home relay.
|
|
660
|
+
*/
|
|
661
|
+
routeMessage(toDid: string, message: string, options?: {
|
|
662
|
+
contentType?: string;
|
|
663
|
+
threadId?: string;
|
|
664
|
+
}): Promise<{
|
|
665
|
+
routed: boolean;
|
|
666
|
+
destination: string;
|
|
667
|
+
}>;
|
|
668
|
+
/** Send heartbeat — signals agent is alive, updates last_seen */
|
|
669
|
+
ping(): Promise<{
|
|
670
|
+
pong: boolean;
|
|
671
|
+
did: string;
|
|
672
|
+
status: string;
|
|
673
|
+
uptime: {
|
|
674
|
+
days: number;
|
|
675
|
+
hours: number;
|
|
676
|
+
};
|
|
677
|
+
}>;
|
|
678
|
+
/** Check if another agent is online (public) */
|
|
679
|
+
checkOnline(did: string): Promise<{
|
|
680
|
+
did: string;
|
|
681
|
+
online_status: 'online' | 'idle' | 'offline';
|
|
682
|
+
last_seen: string;
|
|
683
|
+
minutes_since_seen: number | null;
|
|
684
|
+
}>;
|
|
685
|
+
/** Pin another agent's public keys (Trust On First Use). Returns warning if keys changed since last pin. */
|
|
686
|
+
pinKeys(did: string): Promise<{
|
|
687
|
+
pinned: boolean;
|
|
688
|
+
key_changed: boolean;
|
|
689
|
+
status: string;
|
|
690
|
+
warning?: string;
|
|
691
|
+
}>;
|
|
692
|
+
/** List all pinned keys */
|
|
693
|
+
listPinnedKeys(options?: {
|
|
694
|
+
status?: string;
|
|
695
|
+
}): Promise<{
|
|
696
|
+
pins: any[];
|
|
697
|
+
total: number;
|
|
698
|
+
}>;
|
|
699
|
+
/** Verify an agent's keys against your pinned copy. Detects key changes (potential MitM). */
|
|
700
|
+
verifyKeys(did: string): Promise<{
|
|
701
|
+
did: string;
|
|
702
|
+
pinned: boolean;
|
|
703
|
+
verified?: boolean;
|
|
704
|
+
status: string;
|
|
705
|
+
warning?: string;
|
|
706
|
+
}>;
|
|
559
707
|
}
|
|
560
708
|
|
|
561
709
|
export { type AgentIdentity, type AgentProfile, type DecryptedMessage, type SendResult, VoidlyAgent, type VoidlyAgentConfig };
|
package/dist/index.js
CHANGED
|
@@ -2455,6 +2455,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2455
2455
|
envelope: envelopeData,
|
|
2456
2456
|
// Pass signed envelope so receiver can verify
|
|
2457
2457
|
content_type: options.contentType || "text/plain",
|
|
2458
|
+
message_type: options.messageType || "text",
|
|
2458
2459
|
thread_id: options.threadId,
|
|
2459
2460
|
reply_to: options.replyTo,
|
|
2460
2461
|
ttl: options.ttl
|
|
@@ -3332,6 +3333,201 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3332
3333
|
return false;
|
|
3333
3334
|
}
|
|
3334
3335
|
}
|
|
3336
|
+
// ─── Memory Store ──────────────────────────────────────────────────────────
|
|
3337
|
+
/**
|
|
3338
|
+
* Store an encrypted key-value pair in persistent memory.
|
|
3339
|
+
* Values are encrypted with a key derived from your API key — only you can read them.
|
|
3340
|
+
*/
|
|
3341
|
+
async memorySet(namespace, key, value, options) {
|
|
3342
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
|
|
3343
|
+
method: "PUT",
|
|
3344
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3345
|
+
body: JSON.stringify({
|
|
3346
|
+
value,
|
|
3347
|
+
value_type: options?.valueType || (typeof value === "object" ? "json" : typeof value),
|
|
3348
|
+
ttl: options?.ttl
|
|
3349
|
+
})
|
|
3350
|
+
});
|
|
3351
|
+
if (!res.ok) throw new Error(`Memory set failed: ${res.status} ${await res.text()}`);
|
|
3352
|
+
return res.json();
|
|
3353
|
+
}
|
|
3354
|
+
/**
|
|
3355
|
+
* Retrieve a value from persistent memory.
|
|
3356
|
+
* Decrypted server-side using your API key derivation.
|
|
3357
|
+
*/
|
|
3358
|
+
async memoryGet(namespace, key) {
|
|
3359
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
|
|
3360
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3361
|
+
});
|
|
3362
|
+
if (res.status === 404) return null;
|
|
3363
|
+
if (!res.ok) throw new Error(`Memory get failed: ${res.status} ${await res.text()}`);
|
|
3364
|
+
return res.json();
|
|
3365
|
+
}
|
|
3366
|
+
/**
|
|
3367
|
+
* Delete a key from persistent memory.
|
|
3368
|
+
*/
|
|
3369
|
+
async memoryDelete(namespace, key) {
|
|
3370
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
|
|
3371
|
+
method: "DELETE",
|
|
3372
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3373
|
+
});
|
|
3374
|
+
if (!res.ok) throw new Error(`Memory delete failed: ${res.status} ${await res.text()}`);
|
|
3375
|
+
return res.json();
|
|
3376
|
+
}
|
|
3377
|
+
/**
|
|
3378
|
+
* List all keys in a memory namespace.
|
|
3379
|
+
*/
|
|
3380
|
+
async memoryList(namespace, options) {
|
|
3381
|
+
const ns = namespace || "default";
|
|
3382
|
+
const params = new URLSearchParams();
|
|
3383
|
+
if (options?.prefix) params.set("prefix", options.prefix);
|
|
3384
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
3385
|
+
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
3386
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(ns)}${qs}`, {
|
|
3387
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3388
|
+
});
|
|
3389
|
+
if (!res.ok) throw new Error(`Memory list failed: ${res.status} ${await res.text()}`);
|
|
3390
|
+
return res.json();
|
|
3391
|
+
}
|
|
3392
|
+
/**
|
|
3393
|
+
* List all memory namespaces and quota usage.
|
|
3394
|
+
*/
|
|
3395
|
+
async memoryNamespaces() {
|
|
3396
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/memory`, {
|
|
3397
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3398
|
+
});
|
|
3399
|
+
if (!res.ok) throw new Error(`Memory namespaces failed: ${res.status} ${await res.text()}`);
|
|
3400
|
+
return res.json();
|
|
3401
|
+
}
|
|
3402
|
+
// ─── Data Export ───────────────────────────────────────────────────────────
|
|
3403
|
+
/**
|
|
3404
|
+
* Export all agent data as a portable JSON bundle.
|
|
3405
|
+
* Includes identity, messages, channels, tasks, attestations, memory, and trust.
|
|
3406
|
+
* Memory values remain encrypted — portable to another relay.
|
|
3407
|
+
*/
|
|
3408
|
+
async exportData(options) {
|
|
3409
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/export`, {
|
|
3410
|
+
method: "POST",
|
|
3411
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3412
|
+
body: JSON.stringify({
|
|
3413
|
+
include_messages: options?.includeMessages,
|
|
3414
|
+
include_channels: options?.includeChannels,
|
|
3415
|
+
include_tasks: options?.includeTasks,
|
|
3416
|
+
include_attestations: options?.includeAttestations,
|
|
3417
|
+
include_memory: options?.includeMemory,
|
|
3418
|
+
include_trust: options?.includeTrust
|
|
3419
|
+
})
|
|
3420
|
+
});
|
|
3421
|
+
if (!res.ok) throw new Error(`Export failed: ${res.status} ${await res.text()}`);
|
|
3422
|
+
return res.json();
|
|
3423
|
+
}
|
|
3424
|
+
/**
|
|
3425
|
+
* List past data export records.
|
|
3426
|
+
*/
|
|
3427
|
+
async listExports() {
|
|
3428
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/exports`, {
|
|
3429
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3430
|
+
});
|
|
3431
|
+
if (!res.ok) throw new Error(`List exports failed: ${res.status} ${await res.text()}`);
|
|
3432
|
+
return res.json();
|
|
3433
|
+
}
|
|
3434
|
+
// ─── Relay Federation ─────────────────────────────────────────────────────
|
|
3435
|
+
/**
|
|
3436
|
+
* Get information about the relay this agent is connected to.
|
|
3437
|
+
* Includes federation capabilities and known peers.
|
|
3438
|
+
*/
|
|
3439
|
+
async getRelayInfo() {
|
|
3440
|
+
const res = await fetch(`${this.baseUrl}/v1/relay/info`);
|
|
3441
|
+
if (!res.ok) throw new Error(`Relay info failed: ${res.status} ${await res.text()}`);
|
|
3442
|
+
return res.json();
|
|
3443
|
+
}
|
|
3444
|
+
/**
|
|
3445
|
+
* List known federated relay peers.
|
|
3446
|
+
*/
|
|
3447
|
+
async getRelayPeers() {
|
|
3448
|
+
const res = await fetch(`${this.baseUrl}/v1/relay/peers`);
|
|
3449
|
+
if (!res.ok) throw new Error(`Relay peers failed: ${res.status} ${await res.text()}`);
|
|
3450
|
+
return res.json();
|
|
3451
|
+
}
|
|
3452
|
+
/**
|
|
3453
|
+
* Route a message through federation to an agent on a different relay.
|
|
3454
|
+
* The relay will forward it to the recipient's home relay.
|
|
3455
|
+
*/
|
|
3456
|
+
async routeMessage(toDid, message, options) {
|
|
3457
|
+
const profile = await this.getIdentity(toDid);
|
|
3458
|
+
if (!profile) throw new Error(`Recipient ${toDid} not found`);
|
|
3459
|
+
const recipientPub = (0, import_tweetnacl_util.decodeBase64)(profile.encryption_public_key);
|
|
3460
|
+
const nonce = import_tweetnacl.default.randomBytes(import_tweetnacl.default.box.nonceLength);
|
|
3461
|
+
const encrypted = import_tweetnacl.default.box((0, import_tweetnacl_util.decodeUTF8)(message), nonce, recipientPub, this.encryptionKeyPair.secretKey);
|
|
3462
|
+
if (!encrypted) throw new Error("Encryption failed");
|
|
3463
|
+
const signaturePayload = (0, import_tweetnacl_util.decodeUTF8)(JSON.stringify({
|
|
3464
|
+
from: this.did,
|
|
3465
|
+
to: toDid,
|
|
3466
|
+
nonce: (0, import_tweetnacl_util.encodeBase64)(nonce),
|
|
3467
|
+
ciphertext_hash: await sha256((0, import_tweetnacl_util.encodeBase64)(encrypted))
|
|
3468
|
+
}));
|
|
3469
|
+
const signature = import_tweetnacl.default.sign.detached(signaturePayload, this.signingKeyPair.secretKey);
|
|
3470
|
+
const res = await fetch(`${this.baseUrl}/v1/relay/route`, {
|
|
3471
|
+
method: "POST",
|
|
3472
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3473
|
+
body: JSON.stringify({
|
|
3474
|
+
to: toDid,
|
|
3475
|
+
ciphertext: (0, import_tweetnacl_util.encodeBase64)(encrypted),
|
|
3476
|
+
nonce: (0, import_tweetnacl_util.encodeBase64)(nonce),
|
|
3477
|
+
signature: (0, import_tweetnacl_util.encodeBase64)(signature),
|
|
3478
|
+
content_type: options?.contentType || "text/plain",
|
|
3479
|
+
thread_id: options?.threadId
|
|
3480
|
+
})
|
|
3481
|
+
});
|
|
3482
|
+
if (!res.ok) throw new Error(`Route failed: ${res.status} ${await res.text()}`);
|
|
3483
|
+
return res.json();
|
|
3484
|
+
}
|
|
3485
|
+
// ── Heartbeat ──────────────────────────────────────────────────────────────
|
|
3486
|
+
/** Send heartbeat — signals agent is alive, updates last_seen */
|
|
3487
|
+
async ping() {
|
|
3488
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/ping`, {
|
|
3489
|
+
method: "POST",
|
|
3490
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3491
|
+
});
|
|
3492
|
+
if (!res.ok) throw new Error(`Ping failed: ${res.status}`);
|
|
3493
|
+
return res.json();
|
|
3494
|
+
}
|
|
3495
|
+
/** Check if another agent is online (public) */
|
|
3496
|
+
async checkOnline(did) {
|
|
3497
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/ping/${encodeURIComponent(did)}`);
|
|
3498
|
+
if (!res.ok) throw new Error(`Ping check failed: ${res.status}`);
|
|
3499
|
+
return res.json();
|
|
3500
|
+
}
|
|
3501
|
+
// ── Key Pinning (TOFU) ────────────────────────────────────────────────────
|
|
3502
|
+
/** Pin another agent's public keys (Trust On First Use). Returns warning if keys changed since last pin. */
|
|
3503
|
+
async pinKeys(did) {
|
|
3504
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/keys/pin`, {
|
|
3505
|
+
method: "POST",
|
|
3506
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3507
|
+
body: JSON.stringify({ did })
|
|
3508
|
+
});
|
|
3509
|
+
if (!res.ok) throw new Error(`Key pin failed: ${res.status}`);
|
|
3510
|
+
return res.json();
|
|
3511
|
+
}
|
|
3512
|
+
/** List all pinned keys */
|
|
3513
|
+
async listPinnedKeys(options) {
|
|
3514
|
+
const params = new URLSearchParams();
|
|
3515
|
+
if (options?.status) params.set("status", options.status);
|
|
3516
|
+
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
3517
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/keys/pins${qs}`, {
|
|
3518
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3519
|
+
});
|
|
3520
|
+
if (!res.ok) throw new Error(`List pins failed: ${res.status}`);
|
|
3521
|
+
return res.json();
|
|
3522
|
+
}
|
|
3523
|
+
/** Verify an agent's keys against your pinned copy. Detects key changes (potential MitM). */
|
|
3524
|
+
async verifyKeys(did) {
|
|
3525
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/keys/verify/${encodeURIComponent(did)}`, {
|
|
3526
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3527
|
+
});
|
|
3528
|
+
if (!res.ok) throw new Error(`Key verify failed: ${res.status}`);
|
|
3529
|
+
return res.json();
|
|
3530
|
+
}
|
|
3335
3531
|
};
|
|
3336
3532
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3337
3533
|
0 && (module.exports = {
|
package/dist/index.mjs
CHANGED
|
@@ -2445,6 +2445,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2445
2445
|
envelope: envelopeData,
|
|
2446
2446
|
// Pass signed envelope so receiver can verify
|
|
2447
2447
|
content_type: options.contentType || "text/plain",
|
|
2448
|
+
message_type: options.messageType || "text",
|
|
2448
2449
|
thread_id: options.threadId,
|
|
2449
2450
|
reply_to: options.replyTo,
|
|
2450
2451
|
ttl: options.ttl
|
|
@@ -3322,6 +3323,201 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3322
3323
|
return false;
|
|
3323
3324
|
}
|
|
3324
3325
|
}
|
|
3326
|
+
// ─── Memory Store ──────────────────────────────────────────────────────────
|
|
3327
|
+
/**
|
|
3328
|
+
* Store an encrypted key-value pair in persistent memory.
|
|
3329
|
+
* Values are encrypted with a key derived from your API key — only you can read them.
|
|
3330
|
+
*/
|
|
3331
|
+
async memorySet(namespace, key, value, options) {
|
|
3332
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
|
|
3333
|
+
method: "PUT",
|
|
3334
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3335
|
+
body: JSON.stringify({
|
|
3336
|
+
value,
|
|
3337
|
+
value_type: options?.valueType || (typeof value === "object" ? "json" : typeof value),
|
|
3338
|
+
ttl: options?.ttl
|
|
3339
|
+
})
|
|
3340
|
+
});
|
|
3341
|
+
if (!res.ok) throw new Error(`Memory set failed: ${res.status} ${await res.text()}`);
|
|
3342
|
+
return res.json();
|
|
3343
|
+
}
|
|
3344
|
+
/**
|
|
3345
|
+
* Retrieve a value from persistent memory.
|
|
3346
|
+
* Decrypted server-side using your API key derivation.
|
|
3347
|
+
*/
|
|
3348
|
+
async memoryGet(namespace, key) {
|
|
3349
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
|
|
3350
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3351
|
+
});
|
|
3352
|
+
if (res.status === 404) return null;
|
|
3353
|
+
if (!res.ok) throw new Error(`Memory get failed: ${res.status} ${await res.text()}`);
|
|
3354
|
+
return res.json();
|
|
3355
|
+
}
|
|
3356
|
+
/**
|
|
3357
|
+
* Delete a key from persistent memory.
|
|
3358
|
+
*/
|
|
3359
|
+
async memoryDelete(namespace, key) {
|
|
3360
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
|
|
3361
|
+
method: "DELETE",
|
|
3362
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3363
|
+
});
|
|
3364
|
+
if (!res.ok) throw new Error(`Memory delete failed: ${res.status} ${await res.text()}`);
|
|
3365
|
+
return res.json();
|
|
3366
|
+
}
|
|
3367
|
+
/**
|
|
3368
|
+
* List all keys in a memory namespace.
|
|
3369
|
+
*/
|
|
3370
|
+
async memoryList(namespace, options) {
|
|
3371
|
+
const ns = namespace || "default";
|
|
3372
|
+
const params = new URLSearchParams();
|
|
3373
|
+
if (options?.prefix) params.set("prefix", options.prefix);
|
|
3374
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
3375
|
+
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
3376
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(ns)}${qs}`, {
|
|
3377
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3378
|
+
});
|
|
3379
|
+
if (!res.ok) throw new Error(`Memory list failed: ${res.status} ${await res.text()}`);
|
|
3380
|
+
return res.json();
|
|
3381
|
+
}
|
|
3382
|
+
/**
|
|
3383
|
+
* List all memory namespaces and quota usage.
|
|
3384
|
+
*/
|
|
3385
|
+
async memoryNamespaces() {
|
|
3386
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/memory`, {
|
|
3387
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3388
|
+
});
|
|
3389
|
+
if (!res.ok) throw new Error(`Memory namespaces failed: ${res.status} ${await res.text()}`);
|
|
3390
|
+
return res.json();
|
|
3391
|
+
}
|
|
3392
|
+
// ─── Data Export ───────────────────────────────────────────────────────────
|
|
3393
|
+
/**
|
|
3394
|
+
* Export all agent data as a portable JSON bundle.
|
|
3395
|
+
* Includes identity, messages, channels, tasks, attestations, memory, and trust.
|
|
3396
|
+
* Memory values remain encrypted — portable to another relay.
|
|
3397
|
+
*/
|
|
3398
|
+
async exportData(options) {
|
|
3399
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/export`, {
|
|
3400
|
+
method: "POST",
|
|
3401
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3402
|
+
body: JSON.stringify({
|
|
3403
|
+
include_messages: options?.includeMessages,
|
|
3404
|
+
include_channels: options?.includeChannels,
|
|
3405
|
+
include_tasks: options?.includeTasks,
|
|
3406
|
+
include_attestations: options?.includeAttestations,
|
|
3407
|
+
include_memory: options?.includeMemory,
|
|
3408
|
+
include_trust: options?.includeTrust
|
|
3409
|
+
})
|
|
3410
|
+
});
|
|
3411
|
+
if (!res.ok) throw new Error(`Export failed: ${res.status} ${await res.text()}`);
|
|
3412
|
+
return res.json();
|
|
3413
|
+
}
|
|
3414
|
+
/**
|
|
3415
|
+
* List past data export records.
|
|
3416
|
+
*/
|
|
3417
|
+
async listExports() {
|
|
3418
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/exports`, {
|
|
3419
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3420
|
+
});
|
|
3421
|
+
if (!res.ok) throw new Error(`List exports failed: ${res.status} ${await res.text()}`);
|
|
3422
|
+
return res.json();
|
|
3423
|
+
}
|
|
3424
|
+
// ─── Relay Federation ─────────────────────────────────────────────────────
|
|
3425
|
+
/**
|
|
3426
|
+
* Get information about the relay this agent is connected to.
|
|
3427
|
+
* Includes federation capabilities and known peers.
|
|
3428
|
+
*/
|
|
3429
|
+
async getRelayInfo() {
|
|
3430
|
+
const res = await fetch(`${this.baseUrl}/v1/relay/info`);
|
|
3431
|
+
if (!res.ok) throw new Error(`Relay info failed: ${res.status} ${await res.text()}`);
|
|
3432
|
+
return res.json();
|
|
3433
|
+
}
|
|
3434
|
+
/**
|
|
3435
|
+
* List known federated relay peers.
|
|
3436
|
+
*/
|
|
3437
|
+
async getRelayPeers() {
|
|
3438
|
+
const res = await fetch(`${this.baseUrl}/v1/relay/peers`);
|
|
3439
|
+
if (!res.ok) throw new Error(`Relay peers failed: ${res.status} ${await res.text()}`);
|
|
3440
|
+
return res.json();
|
|
3441
|
+
}
|
|
3442
|
+
/**
|
|
3443
|
+
* Route a message through federation to an agent on a different relay.
|
|
3444
|
+
* The relay will forward it to the recipient's home relay.
|
|
3445
|
+
*/
|
|
3446
|
+
async routeMessage(toDid, message, options) {
|
|
3447
|
+
const profile = await this.getIdentity(toDid);
|
|
3448
|
+
if (!profile) throw new Error(`Recipient ${toDid} not found`);
|
|
3449
|
+
const recipientPub = (0, import_tweetnacl_util.decodeBase64)(profile.encryption_public_key);
|
|
3450
|
+
const nonce = import_tweetnacl.default.randomBytes(import_tweetnacl.default.box.nonceLength);
|
|
3451
|
+
const encrypted = import_tweetnacl.default.box((0, import_tweetnacl_util.decodeUTF8)(message), nonce, recipientPub, this.encryptionKeyPair.secretKey);
|
|
3452
|
+
if (!encrypted) throw new Error("Encryption failed");
|
|
3453
|
+
const signaturePayload = (0, import_tweetnacl_util.decodeUTF8)(JSON.stringify({
|
|
3454
|
+
from: this.did,
|
|
3455
|
+
to: toDid,
|
|
3456
|
+
nonce: (0, import_tweetnacl_util.encodeBase64)(nonce),
|
|
3457
|
+
ciphertext_hash: await sha256((0, import_tweetnacl_util.encodeBase64)(encrypted))
|
|
3458
|
+
}));
|
|
3459
|
+
const signature = import_tweetnacl.default.sign.detached(signaturePayload, this.signingKeyPair.secretKey);
|
|
3460
|
+
const res = await fetch(`${this.baseUrl}/v1/relay/route`, {
|
|
3461
|
+
method: "POST",
|
|
3462
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3463
|
+
body: JSON.stringify({
|
|
3464
|
+
to: toDid,
|
|
3465
|
+
ciphertext: (0, import_tweetnacl_util.encodeBase64)(encrypted),
|
|
3466
|
+
nonce: (0, import_tweetnacl_util.encodeBase64)(nonce),
|
|
3467
|
+
signature: (0, import_tweetnacl_util.encodeBase64)(signature),
|
|
3468
|
+
content_type: options?.contentType || "text/plain",
|
|
3469
|
+
thread_id: options?.threadId
|
|
3470
|
+
})
|
|
3471
|
+
});
|
|
3472
|
+
if (!res.ok) throw new Error(`Route failed: ${res.status} ${await res.text()}`);
|
|
3473
|
+
return res.json();
|
|
3474
|
+
}
|
|
3475
|
+
// ── Heartbeat ──────────────────────────────────────────────────────────────
|
|
3476
|
+
/** Send heartbeat — signals agent is alive, updates last_seen */
|
|
3477
|
+
async ping() {
|
|
3478
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/ping`, {
|
|
3479
|
+
method: "POST",
|
|
3480
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3481
|
+
});
|
|
3482
|
+
if (!res.ok) throw new Error(`Ping failed: ${res.status}`);
|
|
3483
|
+
return res.json();
|
|
3484
|
+
}
|
|
3485
|
+
/** Check if another agent is online (public) */
|
|
3486
|
+
async checkOnline(did) {
|
|
3487
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/ping/${encodeURIComponent(did)}`);
|
|
3488
|
+
if (!res.ok) throw new Error(`Ping check failed: ${res.status}`);
|
|
3489
|
+
return res.json();
|
|
3490
|
+
}
|
|
3491
|
+
// ── Key Pinning (TOFU) ────────────────────────────────────────────────────
|
|
3492
|
+
/** Pin another agent's public keys (Trust On First Use). Returns warning if keys changed since last pin. */
|
|
3493
|
+
async pinKeys(did) {
|
|
3494
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/keys/pin`, {
|
|
3495
|
+
method: "POST",
|
|
3496
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3497
|
+
body: JSON.stringify({ did })
|
|
3498
|
+
});
|
|
3499
|
+
if (!res.ok) throw new Error(`Key pin failed: ${res.status}`);
|
|
3500
|
+
return res.json();
|
|
3501
|
+
}
|
|
3502
|
+
/** List all pinned keys */
|
|
3503
|
+
async listPinnedKeys(options) {
|
|
3504
|
+
const params = new URLSearchParams();
|
|
3505
|
+
if (options?.status) params.set("status", options.status);
|
|
3506
|
+
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
3507
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/keys/pins${qs}`, {
|
|
3508
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3509
|
+
});
|
|
3510
|
+
if (!res.ok) throw new Error(`List pins failed: ${res.status}`);
|
|
3511
|
+
return res.json();
|
|
3512
|
+
}
|
|
3513
|
+
/** Verify an agent's keys against your pinned copy. Detects key changes (potential MitM). */
|
|
3514
|
+
async verifyKeys(did) {
|
|
3515
|
+
const res = await fetch(`${this.baseUrl}/v1/agent/keys/verify/${encodeURIComponent(did)}`, {
|
|
3516
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
3517
|
+
});
|
|
3518
|
+
if (!res.ok) throw new Error(`Key verify failed: ${res.status}`);
|
|
3519
|
+
return res.json();
|
|
3520
|
+
}
|
|
3325
3521
|
};
|
|
3326
3522
|
var export_decodeBase64 = import_tweetnacl_util.decodeBase64;
|
|
3327
3523
|
var export_decodeUTF8 = import_tweetnacl_util.decodeUTF8;
|