@rohankumar4179/engram-sdk 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +21 -2
- package/dist/anchor.d.ts +114 -0
- package/dist/anchor.js +243 -0
- package/dist/anchor.js.map +1 -0
- package/dist/audit.d.ts +53 -0
- package/dist/audit.js +122 -0
- package/dist/audit.js.map +1 -0
- package/dist/consolidator.d.ts +62 -0
- package/dist/consolidator.js +141 -0
- package/dist/consolidator.js.map +1 -0
- package/dist/crypto.d.ts +26 -0
- package/dist/crypto.js +72 -0
- package/dist/crypto.js.map +1 -0
- package/dist/engram.d.ts +266 -0
- package/dist/engram.js +681 -0
- package/dist/engram.js.map +1 -0
- package/dist/env.d.ts +28 -0
- package/dist/env.js +81 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect.d.ts +19 -0
- package/dist/inspect.js +61 -0
- package/dist/inspect.js.map +1 -0
- package/dist/link.d.ts +40 -0
- package/dist/link.js +57 -0
- package/dist/link.js.map +1 -0
- package/dist/llm.d.ts +60 -0
- package/dist/llm.js +188 -0
- package/dist/llm.js.map +1 -0
- package/dist/memwal-account.d.ts +39 -0
- package/dist/memwal-account.js +75 -0
- package/dist/memwal-account.js.map +1 -0
- package/dist/merkle.d.ts +14 -0
- package/dist/merkle.js +69 -0
- package/dist/merkle.js.map +1 -0
- package/dist/mind.d.ts +150 -0
- package/dist/mind.js +193 -0
- package/dist/mind.js.map +1 -0
- package/dist/proof.d.ts +21 -0
- package/dist/proof.js +46 -0
- package/dist/proof.js.map +1 -0
- package/dist/remote.d.ts +112 -0
- package/dist/remote.js +232 -0
- package/dist/remote.js.map +1 -0
- package/dist/store.d.ts +28 -0
- package/dist/store.js +72 -0
- package/dist/store.js.map +1 -0
- package/dist/tatum.d.ts +83 -0
- package/dist/tatum.js +148 -0
- package/dist/tatum.js.map +1 -0
- package/dist/types.d.ts +122 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vault.d.ts +31 -0
- package/dist/vault.js +45 -0
- package/dist/vault.js.map +1 -0
- package/package.json +53 -3
package/dist/mind.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { MoveAnchorer, WalrusBlobAnchorer } from "./anchor.js";
|
|
4
|
+
import { Engram } from "./engram.js";
|
|
5
|
+
import { servicesFromEnv } from "./env.js";
|
|
6
|
+
import { GeminiLLM } from "./llm.js";
|
|
7
|
+
import { InMemoryRemote, WalrusMemoryRemote } from "./remote.js";
|
|
8
|
+
import { TatumSui } from "./tatum.js";
|
|
9
|
+
import { DEFAULT_SERVER, readLink, removeLink, startLink, syncLink, waitForLink } from "./link.js";
|
|
10
|
+
/**
|
|
11
|
+
* The high-level API: one object for an agent's memory.
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* const mind = engram({ agent: "money-ops" });
|
|
15
|
+
* const agent = mind.wrap(myAgent); // beliefs in, signed receipts out
|
|
16
|
+
* mind.observe({ source: "tatum", data: tx });
|
|
17
|
+
* await mind.sleep(); // episodes → beliefs
|
|
18
|
+
* await mind.commit("weekly"); // Merkle root → Walrus → Sui
|
|
19
|
+
* await mind.beliefs({ about: "rent" });
|
|
20
|
+
* mind.at("2026-10-25"); // time travel
|
|
21
|
+
* mind.forget("ep_…"); // provable forgetting
|
|
22
|
+
* await mind.verify("r_…"); // proof check
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export class Mind {
|
|
26
|
+
llmFactory;
|
|
27
|
+
context;
|
|
28
|
+
core;
|
|
29
|
+
llmInstance;
|
|
30
|
+
constructor(core, llmFactory, context) {
|
|
31
|
+
this.llmFactory = llmFactory;
|
|
32
|
+
this.context = context;
|
|
33
|
+
this.core = core;
|
|
34
|
+
}
|
|
35
|
+
get agent() {
|
|
36
|
+
return this.core.agent;
|
|
37
|
+
}
|
|
38
|
+
/** Records an episode (encrypted with its own key). */
|
|
39
|
+
observe(input) {
|
|
40
|
+
return this.core.observe(input);
|
|
41
|
+
}
|
|
42
|
+
/** Consolidates new episodes into beliefs with the configured LLM. */
|
|
43
|
+
sleep(opts = {}) {
|
|
44
|
+
this.llmInstance ??= this.llmFactory();
|
|
45
|
+
return this.core.sleep({ llm: this.llmInstance, context: opts.context ?? this.context, batchSize: opts.batchSize });
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Signs and stores a snapshot of the current beliefs, anchored on Sui. If the
|
|
49
|
+
* agent is linked to a dashboard, the new history is synced too (a failed
|
|
50
|
+
* sync never fails the commit; see `lastSyncError`).
|
|
51
|
+
*/
|
|
52
|
+
async commit(message) {
|
|
53
|
+
const c = await this.core.commit(message);
|
|
54
|
+
if (readLink(this.core)) {
|
|
55
|
+
try {
|
|
56
|
+
await this.sync();
|
|
57
|
+
this.lastSyncError = null;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
this.lastSyncError = err.message;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return c;
|
|
64
|
+
}
|
|
65
|
+
/** Why the last automatic sync after commit failed, if it did. */
|
|
66
|
+
lastSyncError = null;
|
|
67
|
+
/**
|
|
68
|
+
* Links this agent to an Engram web app account (a Sui wallet). `onCode`
|
|
69
|
+
* gets the code and URL to show the owner; resolves once they approve.
|
|
70
|
+
*/
|
|
71
|
+
async link(opts) {
|
|
72
|
+
const server = opts.server ?? DEFAULT_SERVER;
|
|
73
|
+
const start = await startLink(this.core, server, opts.label);
|
|
74
|
+
opts.onCode(start);
|
|
75
|
+
return waitForLink(this.core, start, server);
|
|
76
|
+
}
|
|
77
|
+
/** Uploads the audit bundle to the linked dashboard (verified there before it's shown). */
|
|
78
|
+
sync() {
|
|
79
|
+
return syncLink(this.core);
|
|
80
|
+
}
|
|
81
|
+
get linked() {
|
|
82
|
+
return readLink(this.core);
|
|
83
|
+
}
|
|
84
|
+
unlink() {
|
|
85
|
+
return removeLink(this.core);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Current beliefs. With `about`, the most relevant ones (Walrus Memory
|
|
89
|
+
* semantic recall, keyword fallback offline).
|
|
90
|
+
*/
|
|
91
|
+
async beliefs(opts = {}) {
|
|
92
|
+
if (!opts.about)
|
|
93
|
+
return this.core.beliefs().slice(0, opts.limit ?? Infinity);
|
|
94
|
+
return this.core.relevant(opts.about, opts.limit ?? 5);
|
|
95
|
+
}
|
|
96
|
+
/** Beliefs as they were at a commit, `HEAD~n`, or a date ("2026-10-25"). */
|
|
97
|
+
at(ref) {
|
|
98
|
+
return this.core.beliefsAt(ref);
|
|
99
|
+
}
|
|
100
|
+
/** Destroys an episode's key; dependent beliefs are retracted or revised. */
|
|
101
|
+
forget(episodeId, reason) {
|
|
102
|
+
return this.core.forget(episodeId, reason);
|
|
103
|
+
}
|
|
104
|
+
/** Verifies a receipt (`r_…`) or a commit (id, `HEAD`, date) end to end. */
|
|
105
|
+
verify(ref, opts = {}) {
|
|
106
|
+
const o = opts.offline ? { walrus: false, chain: false } : {};
|
|
107
|
+
return ref.startsWith("r_") ? this.core.verifyReceipt(ref, o) : this.core.verifyCommit(ref, o);
|
|
108
|
+
}
|
|
109
|
+
log() {
|
|
110
|
+
return this.core.head() ? this.core.log() : [];
|
|
111
|
+
}
|
|
112
|
+
diff(from, to) {
|
|
113
|
+
return this.core.diff(from, to);
|
|
114
|
+
}
|
|
115
|
+
blame(belief) {
|
|
116
|
+
return this.core.blame(belief);
|
|
117
|
+
}
|
|
118
|
+
receipts() {
|
|
119
|
+
return this.core.receipts();
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Wraps an existing agent function. Each call: the relevant committed
|
|
123
|
+
* beliefs are passed in, the agent runs, and a signed receipt records what it
|
|
124
|
+
* decided and which beliefs it relied on.
|
|
125
|
+
*
|
|
126
|
+
* ```ts
|
|
127
|
+
* const agent = mind.wrap(async (tx, beliefs) => decide(tx, beliefs), {
|
|
128
|
+
* used: (out) => out.beliefIds,
|
|
129
|
+
* });
|
|
130
|
+
* const decision = await agent(tx);
|
|
131
|
+
* agent.lastReceipt; // r_…
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
wrap(fn, opts = {}) {
|
|
135
|
+
const json = (v) => (typeof v === "string" ? v : JSON.stringify(v));
|
|
136
|
+
const wrapped = (async (input) => {
|
|
137
|
+
if (opts.observe !== false) {
|
|
138
|
+
this.core.observe(typeof opts.observe === "function" ? opts.observe(input) : { source: "agent", data: input });
|
|
139
|
+
}
|
|
140
|
+
const res = await this.core.act({ query: opts.query?.(input) ?? json(input).slice(0, 500), input, limit: opts.limit ?? 6 }, async (beliefs) => {
|
|
141
|
+
const out = await fn(input, beliefs);
|
|
142
|
+
return {
|
|
143
|
+
action: (opts.action?.(out, input) ?? json(out)).slice(0, 2000),
|
|
144
|
+
used: opts.used ? opts.used(out, beliefs) : beliefs.map((b) => b.id),
|
|
145
|
+
result: out,
|
|
146
|
+
};
|
|
147
|
+
});
|
|
148
|
+
wrapped.lastReceipt = res.receipt;
|
|
149
|
+
return res.result;
|
|
150
|
+
});
|
|
151
|
+
wrapped.lastReceipt = null;
|
|
152
|
+
return wrapped;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/** Opens (or creates) an agent's memory. See {@link EngramConfig}. */
|
|
156
|
+
export function engram(cfg) {
|
|
157
|
+
const env = cfg.env ?? process.env;
|
|
158
|
+
const fromEnv = servicesFromEnv(env);
|
|
159
|
+
const dir = resolve(cfg.dir ?? ".");
|
|
160
|
+
const remote = cfg.walrus === "memory"
|
|
161
|
+
? new InMemoryRemote()
|
|
162
|
+
: cfg.walrus && "putMany" in cfg.walrus
|
|
163
|
+
? cfg.walrus
|
|
164
|
+
: cfg.walrus
|
|
165
|
+
? new WalrusMemoryRemote({ key: cfg.walrus.key, accountId: cfg.walrus.accountId, serverUrl: cfg.walrus.serverUrl })
|
|
166
|
+
: fromEnv.remote;
|
|
167
|
+
const tatum = cfg.tatum ? new TatumSui({ apiKey: cfg.tatum.apiKey }) : fromEnv.tatum;
|
|
168
|
+
// A Walrus Memory account given in the config (not "memory", not a ready remote).
|
|
169
|
+
const account = typeof cfg.walrus === "object" && !("putMany" in cfg.walrus) ? cfg.walrus : undefined;
|
|
170
|
+
const blobAnchorer = account && tatum ? new WalrusBlobAnchorer(tatum, account.accountId) : undefined;
|
|
171
|
+
let anchorer;
|
|
172
|
+
if (cfg.anchor && "check" in cfg.anchor)
|
|
173
|
+
anchorer = cfg.anchor;
|
|
174
|
+
else if (cfg.anchor === false || cfg.walrus === "memory")
|
|
175
|
+
anchorer = undefined;
|
|
176
|
+
else if (cfg.anchor)
|
|
177
|
+
anchorer = new MoveAnchorer({ ...cfg.anchor, tatum, blobAnchorer: blobAnchorer ?? fromEnv.anchorer });
|
|
178
|
+
else
|
|
179
|
+
anchorer = blobAnchorer ?? fromEnv.anchorer;
|
|
180
|
+
const llmFactory = () => {
|
|
181
|
+
if (cfg.llm && "json" in cfg.llm)
|
|
182
|
+
return cfg.llm;
|
|
183
|
+
if (cfg.llm)
|
|
184
|
+
return new GeminiLLM({ apiKeys: cfg.llm.gemini, model: cfg.llm.model });
|
|
185
|
+
return fromEnv.llm();
|
|
186
|
+
};
|
|
187
|
+
const opts = { dir, remote, anchorer };
|
|
188
|
+
const core = existsSync(join(dir, ".engram", "config.json")) ? Engram.open(opts) : Engram.init(cfg.agent, opts);
|
|
189
|
+
if (core.agent !== cfg.agent)
|
|
190
|
+
throw new Error(`${dir} holds agent "${core.agent}", not "${cfg.agent}"`);
|
|
191
|
+
return new Mind(core, llmFactory, cfg.context);
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=mind.js.map
|
package/dist/mind.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mind.js","sourceRoot":"","sources":["../src/mind.ts"],"names":[],"mappings":"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"}
|
package/dist/proof.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { MerkleTree } from "./merkle.js";
|
|
2
|
+
import type { Belief, CommitManifest, MerkleProofStep } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Leaf for one belief version. Commits to everything that matters about it —
|
|
5
|
+
* change a word, the confidence or the evidence, and the root changes.
|
|
6
|
+
*/
|
|
7
|
+
export declare function beliefLeaf(b: Belief): string;
|
|
8
|
+
/** Leaf recording that an episode was forgotten, so forgetting is itself part of the proof. */
|
|
9
|
+
export declare function tombstoneLeaf(episodeId: string): string;
|
|
10
|
+
export interface CommitTree {
|
|
11
|
+
tree: MerkleTree;
|
|
12
|
+
/** "belief:b_x@2" / "tombstone:ep_1", in leaf order */
|
|
13
|
+
labels: string[];
|
|
14
|
+
}
|
|
15
|
+
/** Leaves sorted by label, so the same belief set always gives the same root. */
|
|
16
|
+
export declare function buildCommitTree(beliefs: Belief[], tombstones: string[]): CommitTree;
|
|
17
|
+
export declare function proofFor(ct: CommitTree, beliefKey: string): MerkleProofStep[];
|
|
18
|
+
export declare function verifyBeliefProof(b: Belief, proof: MerkleProofStep[], root: string): boolean;
|
|
19
|
+
/** Commit ID = sha256 of the canonical manifest. */
|
|
20
|
+
export declare function commitId(m: CommitManifest): string;
|
|
21
|
+
export declare function verifyManifestSignature(m: CommitManifest, signature: string): boolean;
|
package/dist/proof.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { canonical, sha256Hex, verifySignature } from "./crypto.js";
|
|
2
|
+
import { MerkleTree, verifyProof } from "./merkle.js";
|
|
3
|
+
/**
|
|
4
|
+
* Leaf for one belief version. Commits to everything that matters about it —
|
|
5
|
+
* change a word, the confidence or the evidence, and the root changes.
|
|
6
|
+
*/
|
|
7
|
+
export function beliefLeaf(b) {
|
|
8
|
+
return sha256Hex(canonical({
|
|
9
|
+
k: "belief",
|
|
10
|
+
id: b.id,
|
|
11
|
+
version: b.version,
|
|
12
|
+
statement: sha256Hex(b.statement),
|
|
13
|
+
confidence: b.confidence,
|
|
14
|
+
evidence: new MerkleTree([...b.evidence].sort().map((e) => sha256Hex(e))).root,
|
|
15
|
+
tags: [...b.tags].sort(),
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
/** Leaf recording that an episode was forgotten, so forgetting is itself part of the proof. */
|
|
19
|
+
export function tombstoneLeaf(episodeId) {
|
|
20
|
+
return sha256Hex(canonical({ k: "tombstone", episode: episodeId }));
|
|
21
|
+
}
|
|
22
|
+
/** Leaves sorted by label, so the same belief set always gives the same root. */
|
|
23
|
+
export function buildCommitTree(beliefs, tombstones) {
|
|
24
|
+
const entries = [
|
|
25
|
+
...beliefs.map((b) => ({ label: `belief:${b.id}@${b.version}`, leaf: beliefLeaf(b) })),
|
|
26
|
+
...tombstones.map((t) => ({ label: `tombstone:${t}`, leaf: tombstoneLeaf(t) })),
|
|
27
|
+
].sort((a, b) => (a.label < b.label ? -1 : a.label > b.label ? 1 : 0));
|
|
28
|
+
return { tree: new MerkleTree(entries.map((e) => e.leaf)), labels: entries.map((e) => e.label) };
|
|
29
|
+
}
|
|
30
|
+
export function proofFor(ct, beliefKey) {
|
|
31
|
+
const i = ct.labels.indexOf(`belief:${beliefKey}`);
|
|
32
|
+
if (i < 0)
|
|
33
|
+
throw new Error(`belief ${beliefKey} is not in this commit`);
|
|
34
|
+
return ct.tree.proof(i);
|
|
35
|
+
}
|
|
36
|
+
export function verifyBeliefProof(b, proof, root) {
|
|
37
|
+
return verifyProof(beliefLeaf(b), proof, root);
|
|
38
|
+
}
|
|
39
|
+
/** Commit ID = sha256 of the canonical manifest. */
|
|
40
|
+
export function commitId(m) {
|
|
41
|
+
return sha256Hex(canonical(m));
|
|
42
|
+
}
|
|
43
|
+
export function verifyManifestSignature(m, signature) {
|
|
44
|
+
return verifySignature(canonical(m), signature, m.agentPubKey);
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=proof.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proof.js","sourceRoot":"","sources":["../src/proof.ts"],"names":[],"mappings":"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"}
|
package/dist/remote.d.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
export interface RemoteHit {
|
|
2
|
+
blobId: string;
|
|
3
|
+
text: string;
|
|
4
|
+
distance: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Durable remote for Engram objects. The real one is Walrus Memory;
|
|
8
|
+
* tests use the in-memory one.
|
|
9
|
+
*/
|
|
10
|
+
export interface RemoteMemory {
|
|
11
|
+
/** Stores each text and returns its Walrus blob ID, in order. */
|
|
12
|
+
putMany(items: {
|
|
13
|
+
namespace: string;
|
|
14
|
+
text: string;
|
|
15
|
+
}[]): Promise<string[]>;
|
|
16
|
+
/**
|
|
17
|
+
* `deep`: also look where cheap search can't (e.g. Walrus Memory manual-mode
|
|
18
|
+
* records) — for verification, which needs one exact record.
|
|
19
|
+
*/
|
|
20
|
+
search(namespace: string, query: string, limit?: number, opts?: SearchOptions): Promise<RemoteHit[]>;
|
|
21
|
+
}
|
|
22
|
+
export interface SearchOptions {
|
|
23
|
+
deep?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface WalrusMemoryConfig {
|
|
26
|
+
key: string;
|
|
27
|
+
accountId: string;
|
|
28
|
+
serverUrl?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Manual-mode fallback: when the relayer's own embedding service fails, Engram
|
|
31
|
+
* embeds locally, Seal-encrypts with the account owner's key and has the relayer
|
|
32
|
+
* only store the ciphertext + vector. Reads use the same path.
|
|
33
|
+
*/
|
|
34
|
+
manual?: ManualModeConfig;
|
|
35
|
+
}
|
|
36
|
+
export interface ManualModeConfig {
|
|
37
|
+
/** Account owner's Sui private key (suiprivkey1…) — Seal encrypt/decrypt. */
|
|
38
|
+
suiPrivateKey: string;
|
|
39
|
+
/** Text → embedding vector (1536 dims, like the relayer's own). */
|
|
40
|
+
embed: (text: string) => Promise<number[]>;
|
|
41
|
+
/** Walrus Memory Move package and AccountRegistry (mainnet defaults). */
|
|
42
|
+
packageId?: string;
|
|
43
|
+
registryId?: string;
|
|
44
|
+
/** Sui client for Seal and Walrus reads (a gRPC client works). */
|
|
45
|
+
suiClient: unknown;
|
|
46
|
+
}
|
|
47
|
+
/** Walrus Memory on Sui Mainnet (read from the account object and its creating transaction). */
|
|
48
|
+
export declare const MEMWAL_MAINNET: {
|
|
49
|
+
packageId: string;
|
|
50
|
+
registryId: string;
|
|
51
|
+
};
|
|
52
|
+
export declare class WalrusMemoryRemote implements RemoteMemory {
|
|
53
|
+
private cfg;
|
|
54
|
+
private client;
|
|
55
|
+
private manualClient?;
|
|
56
|
+
/** Until when writes go straight to manual mode after a relayer failure. */
|
|
57
|
+
private manualUntil;
|
|
58
|
+
/** Set when the last write used the manual fallback (for logs and the UI). */
|
|
59
|
+
lastWriteMode: "relayer" | "manual";
|
|
60
|
+
constructor(cfg: WalrusMemoryConfig);
|
|
61
|
+
private manual;
|
|
62
|
+
putMany(items: {
|
|
63
|
+
namespace: string;
|
|
64
|
+
text: string;
|
|
65
|
+
}[]): Promise<string[]>;
|
|
66
|
+
private putManual;
|
|
67
|
+
private putRelayer;
|
|
68
|
+
/**
|
|
69
|
+
* Relayer recall first. Manual-mode recall (embed locally, decrypt here) runs
|
|
70
|
+
* when the relayer fails, or for a deep search — it is slower and only sees
|
|
71
|
+
* records written in manual mode. Results are merged by blob ID.
|
|
72
|
+
*/
|
|
73
|
+
search(namespace: string, query: string, limit?: number, opts?: SearchOptions): Promise<RemoteHit[]>;
|
|
74
|
+
health(): Promise<boolean>;
|
|
75
|
+
}
|
|
76
|
+
/** Offline stand-in. Blob IDs are sha256 of the text, base64url. */
|
|
77
|
+
export declare class InMemoryRemote implements RemoteMemory {
|
|
78
|
+
readonly items: {
|
|
79
|
+
namespace: string;
|
|
80
|
+
text: string;
|
|
81
|
+
blobId: string;
|
|
82
|
+
}[];
|
|
83
|
+
putMany(items: {
|
|
84
|
+
namespace: string;
|
|
85
|
+
text: string;
|
|
86
|
+
}[]): Promise<string[]>;
|
|
87
|
+
search(namespace: string, query: string, limit?: number): Promise<RemoteHit[]>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Writes go to `primary`; searches merge `primary` and `secondary`. Used when an
|
|
91
|
+
* agent moves to its owner's own Walrus Memory account: older memories stay
|
|
92
|
+
* readable (and verifiable) in the account they were written to.
|
|
93
|
+
*/
|
|
94
|
+
export declare class CombinedRemote implements RemoteMemory {
|
|
95
|
+
readonly primary: RemoteMemory;
|
|
96
|
+
readonly secondary: RemoteMemory;
|
|
97
|
+
constructor(primary: RemoteMemory, secondary: RemoteMemory);
|
|
98
|
+
putMany(items: {
|
|
99
|
+
namespace: string;
|
|
100
|
+
text: string;
|
|
101
|
+
}[]): Promise<string[]>;
|
|
102
|
+
search(namespace: string, query: string, limit?: number, opts?: SearchOptions): Promise<RemoteHit[]>;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* The relayer limits each key to 60 weighted requests a minute and answers 429
|
|
106
|
+
* with retry_after_seconds; it also has brief 5xx hiccups. Wait and retry
|
|
107
|
+
* instead of failing.
|
|
108
|
+
*/
|
|
109
|
+
export declare function relayerRetry<T>(fn: () => Promise<T>, opts?: {
|
|
110
|
+
attempts?: number;
|
|
111
|
+
sleep?: (ms: number) => Promise<void>;
|
|
112
|
+
}): Promise<T>;
|
package/dist/remote.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { MemWal } from "@mysten-incubation/memwal";
|
|
2
|
+
import { MemWalManual } from "@mysten-incubation/memwal/manual";
|
|
3
|
+
import { sha256Bytes } from "./crypto.js";
|
|
4
|
+
/** Walrus Memory on Sui Mainnet (read from the account object and its creating transaction). */
|
|
5
|
+
export const MEMWAL_MAINNET = {
|
|
6
|
+
packageId: "0xe7c16fbea0560e7057e2bf7422feaa4fb313749fc69c9e9092fac7a33b81d7f5",
|
|
7
|
+
registryId: "0x8bf82c9e09e36b8d1c38298f68b7cb68e7b8762887e7592add9986d5e9cf199f",
|
|
8
|
+
};
|
|
9
|
+
/** Errors that mean the relayer's server-side pipeline is down (not our request). */
|
|
10
|
+
const RELAYER_DOWN = /embedding|internal error|internal server error|\b5\d\d\b|unavailable|timed? ?out/i;
|
|
11
|
+
export class WalrusMemoryRemote {
|
|
12
|
+
cfg;
|
|
13
|
+
client;
|
|
14
|
+
manualClient;
|
|
15
|
+
/** Until when writes go straight to manual mode after a relayer failure. */
|
|
16
|
+
manualUntil = 0;
|
|
17
|
+
/** Set when the last write used the manual fallback (for logs and the UI). */
|
|
18
|
+
lastWriteMode = "relayer";
|
|
19
|
+
constructor(cfg) {
|
|
20
|
+
this.cfg = cfg;
|
|
21
|
+
this.client = MemWal.create({
|
|
22
|
+
key: cfg.key,
|
|
23
|
+
accountId: cfg.accountId,
|
|
24
|
+
serverUrl: cfg.serverUrl ?? "https://relayer.memory.walrus.xyz",
|
|
25
|
+
requestTimeoutMs: 60_000,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
manual() {
|
|
29
|
+
const m = this.cfg.manual;
|
|
30
|
+
if (!m)
|
|
31
|
+
return undefined;
|
|
32
|
+
if (!this.manualClient) {
|
|
33
|
+
this.manualClient = MemWalManual.create({
|
|
34
|
+
key: this.cfg.key,
|
|
35
|
+
accountId: this.cfg.accountId,
|
|
36
|
+
serverUrl: this.cfg.serverUrl ?? "https://relayer.memory.walrus.xyz",
|
|
37
|
+
suiPrivateKey: m.suiPrivateKey,
|
|
38
|
+
suiClient: m.suiClient,
|
|
39
|
+
embeddingApiKey: "local", // embedding is done by m.embed below
|
|
40
|
+
packageId: m.packageId ?? MEMWAL_MAINNET.packageId,
|
|
41
|
+
registryId: m.registryId ?? MEMWAL_MAINNET.registryId,
|
|
42
|
+
});
|
|
43
|
+
// The SDK only knows OpenAI-style embedding APIs; use ours instead.
|
|
44
|
+
this.manualClient.embed = m.embed;
|
|
45
|
+
}
|
|
46
|
+
return this.manualClient;
|
|
47
|
+
}
|
|
48
|
+
async putMany(items) {
|
|
49
|
+
if (items.length === 0)
|
|
50
|
+
return [];
|
|
51
|
+
const manual = this.manual();
|
|
52
|
+
if (manual && Date.now() < this.manualUntil)
|
|
53
|
+
return this.putManual(manual, items);
|
|
54
|
+
try {
|
|
55
|
+
const ids = await this.putRelayer(items);
|
|
56
|
+
this.lastWriteMode = "relayer";
|
|
57
|
+
return ids;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
if (!manual || !RELAYER_DOWN.test(err.message))
|
|
61
|
+
throw err;
|
|
62
|
+
this.manualUntil = Date.now() + 10 * 60_000;
|
|
63
|
+
return this.putManual(manual, items);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async putManual(manual, items) {
|
|
67
|
+
const out = [];
|
|
68
|
+
// Three at a time keeps Seal key servers and the embedder within rate limits.
|
|
69
|
+
for (let i = 0; i < items.length; i += 3) {
|
|
70
|
+
const batch = items.slice(i, i + 3);
|
|
71
|
+
const res = await Promise.all(batch.map((it) => relayerRetry(() => manual.rememberManual(it.text, it.namespace))));
|
|
72
|
+
for (const r of res) {
|
|
73
|
+
if (!r.blob_id)
|
|
74
|
+
throw new Error("Walrus Memory manual write returned no blob ID");
|
|
75
|
+
out.push(r.blob_id);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
this.lastWriteMode = "manual";
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
async putRelayer(items) {
|
|
82
|
+
const out = [];
|
|
83
|
+
// Keep batches small so one slow item doesn't hold up everything.
|
|
84
|
+
for (let i = 0; i < items.length; i += 20) {
|
|
85
|
+
const batch = items.slice(i, i + 20);
|
|
86
|
+
const res = await relayerRetry(() => this.client.rememberBulkAndWait(batch, { timeoutMs: 300_000 }));
|
|
87
|
+
batch.forEach((_, j) => {
|
|
88
|
+
const r = res.results[j];
|
|
89
|
+
if (!r || r.status !== "done" || !r.blob_id) {
|
|
90
|
+
throw new Error(`Walrus Memory write failed: ${r?.error ?? r?.status ?? "no result"}`);
|
|
91
|
+
}
|
|
92
|
+
out.push(r.blob_id);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Relayer recall first. Manual-mode recall (embed locally, decrypt here) runs
|
|
99
|
+
* when the relayer fails, or for a deep search — it is slower and only sees
|
|
100
|
+
* records written in manual mode. Results are merged by blob ID.
|
|
101
|
+
*/
|
|
102
|
+
async search(namespace, query, limit = 10, opts = {}) {
|
|
103
|
+
const manual = this.manual();
|
|
104
|
+
let auto = [];
|
|
105
|
+
let autoErr = null;
|
|
106
|
+
try {
|
|
107
|
+
const res = await relayerRetry(() => this.client.recall({ query, limit, namespace }));
|
|
108
|
+
auto = res.results.map((r) => ({ blobId: r.blob_id, text: r.text, distance: r.distance }));
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
autoErr = err;
|
|
112
|
+
}
|
|
113
|
+
if (!manual || (!autoErr && !opts.deep)) {
|
|
114
|
+
if (autoErr)
|
|
115
|
+
throw autoErr;
|
|
116
|
+
return auto;
|
|
117
|
+
}
|
|
118
|
+
let man = [];
|
|
119
|
+
try {
|
|
120
|
+
man = await quietSealLogs(() => manual.recallManual(query, { limit, namespace })).then((res) => res.results.flatMap((r) => ("text" in r ? [{ blobId: r.blob_id, text: r.text, distance: r.distance }] : [])));
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
if (autoErr)
|
|
124
|
+
throw autoErr;
|
|
125
|
+
}
|
|
126
|
+
const merged = new Map();
|
|
127
|
+
for (const r of [...auto, ...man]) {
|
|
128
|
+
const prev = merged.get(r.blobId);
|
|
129
|
+
if (!prev || r.distance < prev.distance)
|
|
130
|
+
merged.set(r.blobId, r);
|
|
131
|
+
}
|
|
132
|
+
return [...merged.values()].sort((x, y) => x.distance - y.distance).slice(0, limit);
|
|
133
|
+
}
|
|
134
|
+
async health() {
|
|
135
|
+
return (await this.client.health()).status === "ok";
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** Offline stand-in. Blob IDs are sha256 of the text, base64url. */
|
|
139
|
+
export class InMemoryRemote {
|
|
140
|
+
items = [];
|
|
141
|
+
async putMany(items) {
|
|
142
|
+
return items.map((it) => {
|
|
143
|
+
const blobId = Buffer.from(sha256Bytes(Buffer.from(it.namespace + "\n" + it.text))).toString("base64url");
|
|
144
|
+
this.items.push({ ...it, blobId });
|
|
145
|
+
return blobId;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
async search(namespace, query, limit = 10) {
|
|
149
|
+
const words = query.toLowerCase().split(/\W+/).filter(Boolean);
|
|
150
|
+
return this.items
|
|
151
|
+
.filter((i) => i.namespace === namespace)
|
|
152
|
+
.map((i) => {
|
|
153
|
+
const t = i.text.toLowerCase();
|
|
154
|
+
const hits = words.filter((w) => t.includes(w)).length;
|
|
155
|
+
return { blobId: i.blobId, text: i.text, distance: words.length ? 1 - hits / words.length : 1 };
|
|
156
|
+
})
|
|
157
|
+
.sort((a, b) => a.distance - b.distance)
|
|
158
|
+
.slice(0, limit);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Writes go to `primary`; searches merge `primary` and `secondary`. Used when an
|
|
163
|
+
* agent moves to its owner's own Walrus Memory account: older memories stay
|
|
164
|
+
* readable (and verifiable) in the account they were written to.
|
|
165
|
+
*/
|
|
166
|
+
export class CombinedRemote {
|
|
167
|
+
primary;
|
|
168
|
+
secondary;
|
|
169
|
+
constructor(primary, secondary) {
|
|
170
|
+
this.primary = primary;
|
|
171
|
+
this.secondary = secondary;
|
|
172
|
+
}
|
|
173
|
+
putMany(items) {
|
|
174
|
+
return this.primary.putMany(items);
|
|
175
|
+
}
|
|
176
|
+
async search(namespace, query, limit = 10, opts) {
|
|
177
|
+
const [a, b] = await Promise.allSettled([this.primary.search(namespace, query, limit, opts), this.secondary.search(namespace, query, limit, opts)]);
|
|
178
|
+
if (a.status === "rejected" && b.status === "rejected")
|
|
179
|
+
throw a.reason;
|
|
180
|
+
const merged = new Map();
|
|
181
|
+
for (const h of [...(a.status === "fulfilled" ? a.value : []), ...(b.status === "fulfilled" ? b.value : [])]) {
|
|
182
|
+
const prev = merged.get(h.blobId);
|
|
183
|
+
if (!prev || h.distance < prev.distance)
|
|
184
|
+
merged.set(h.blobId, h);
|
|
185
|
+
}
|
|
186
|
+
return [...merged.values()].sort((x, y) => x.distance - y.distance).slice(0, limit);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Manual recall tries to decrypt every hit in the namespace, including records
|
|
191
|
+
* written by the relayer under a different Seal identity; the SDK logs each of
|
|
192
|
+
* those expected failures. Keep them out of the agent's output.
|
|
193
|
+
*/
|
|
194
|
+
async function quietSealLogs(fn) {
|
|
195
|
+
const orig = console.error;
|
|
196
|
+
console.error = (...args) => {
|
|
197
|
+
if (typeof args[0] === "string" && args[0].startsWith("[MemWalManual]"))
|
|
198
|
+
return;
|
|
199
|
+
orig(...args);
|
|
200
|
+
};
|
|
201
|
+
try {
|
|
202
|
+
return await fn();
|
|
203
|
+
}
|
|
204
|
+
finally {
|
|
205
|
+
console.error = orig;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* The relayer limits each key to 60 weighted requests a minute and answers 429
|
|
210
|
+
* with retry_after_seconds; it also has brief 5xx hiccups. Wait and retry
|
|
211
|
+
* instead of failing.
|
|
212
|
+
*/
|
|
213
|
+
export async function relayerRetry(fn, opts = {}) {
|
|
214
|
+
const attempts = opts.attempts ?? 4;
|
|
215
|
+
const sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
216
|
+
for (let i = 0;; i++) {
|
|
217
|
+
try {
|
|
218
|
+
return await fn();
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
const msg = String(err.message ?? err);
|
|
222
|
+
const limited = /\b429\b|rate limit/i.test(msg);
|
|
223
|
+
// Transient server errors (the relayer has been flaky) get a short backoff too.
|
|
224
|
+
const transient = /\b50[0234]\b|internal server error|ECONNRESET|fetch failed/i.test(msg);
|
|
225
|
+
if (i + 1 >= attempts || (!limited && !transient))
|
|
226
|
+
throw err;
|
|
227
|
+
const after = limited ? Number(/retry_after_seconds"?\s*:\s*(\d+)/.exec(msg)?.[1] ?? 30) : 5 * (i + 1);
|
|
228
|
+
await sleep(Math.min(after, 90) * 1000 + 500);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=remote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
|