@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.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +21 -2
  3. package/dist/anchor.d.ts +114 -0
  4. package/dist/anchor.js +243 -0
  5. package/dist/anchor.js.map +1 -0
  6. package/dist/audit.d.ts +53 -0
  7. package/dist/audit.js +122 -0
  8. package/dist/audit.js.map +1 -0
  9. package/dist/consolidator.d.ts +62 -0
  10. package/dist/consolidator.js +141 -0
  11. package/dist/consolidator.js.map +1 -0
  12. package/dist/crypto.d.ts +26 -0
  13. package/dist/crypto.js +72 -0
  14. package/dist/crypto.js.map +1 -0
  15. package/dist/engram.d.ts +266 -0
  16. package/dist/engram.js +681 -0
  17. package/dist/engram.js.map +1 -0
  18. package/dist/env.d.ts +28 -0
  19. package/dist/env.js +81 -0
  20. package/dist/env.js.map +1 -0
  21. package/dist/index.d.ts +18 -0
  22. package/dist/index.js +19 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/inspect.d.ts +19 -0
  25. package/dist/inspect.js +61 -0
  26. package/dist/inspect.js.map +1 -0
  27. package/dist/link.d.ts +40 -0
  28. package/dist/link.js +57 -0
  29. package/dist/link.js.map +1 -0
  30. package/dist/llm.d.ts +60 -0
  31. package/dist/llm.js +188 -0
  32. package/dist/llm.js.map +1 -0
  33. package/dist/memwal-account.d.ts +39 -0
  34. package/dist/memwal-account.js +75 -0
  35. package/dist/memwal-account.js.map +1 -0
  36. package/dist/merkle.d.ts +14 -0
  37. package/dist/merkle.js +69 -0
  38. package/dist/merkle.js.map +1 -0
  39. package/dist/mind.d.ts +150 -0
  40. package/dist/mind.js +193 -0
  41. package/dist/mind.js.map +1 -0
  42. package/dist/proof.d.ts +21 -0
  43. package/dist/proof.js +46 -0
  44. package/dist/proof.js.map +1 -0
  45. package/dist/remote.d.ts +112 -0
  46. package/dist/remote.js +232 -0
  47. package/dist/remote.js.map +1 -0
  48. package/dist/store.d.ts +28 -0
  49. package/dist/store.js +72 -0
  50. package/dist/store.js.map +1 -0
  51. package/dist/tatum.d.ts +83 -0
  52. package/dist/tatum.js +148 -0
  53. package/dist/tatum.js.map +1 -0
  54. package/dist/types.d.ts +122 -0
  55. package/dist/types.js +2 -0
  56. package/dist/types.js.map +1 -0
  57. package/dist/vault.d.ts +31 -0
  58. package/dist/vault.js +45 -0
  59. package/dist/vault.js.map +1 -0
  60. package/package.json +53 -3
package/dist/llm.js ADDED
@@ -0,0 +1,188 @@
1
+ export const DEFAULT_GEMINI_FALLBACKS = ["gemini-3.8-flash", "gemini-flash-lite-latest", "gemini-2.5-flash", "gemma-4-26b-a4b-it", "gemma-4-31b-it"];
2
+ export class GeminiLLM {
3
+ name;
4
+ /** Model that answered the last request. */
5
+ lastModel;
6
+ keys;
7
+ current = 0;
8
+ /** "key|model" pairs that hit their daily quota. */
9
+ exhausted = new Set();
10
+ models;
11
+ temperature;
12
+ baseUrl;
13
+ fetchFn;
14
+ delay;
15
+ constructor(opts) {
16
+ this.keys = opts.apiKeys.map((k) => k.trim()).filter(Boolean);
17
+ if (this.keys.length === 0)
18
+ throw new Error("GeminiLLM needs at least one API key");
19
+ const main = opts.model ?? "gemini-flash-latest";
20
+ this.models = [main, ...(opts.fallbackModels ?? DEFAULT_GEMINI_FALLBACKS).filter((m) => m !== main)];
21
+ this.temperature = opts.temperature ?? 0.2;
22
+ this.baseUrl = opts.baseUrl ?? "https://generativelanguage.googleapis.com/v1beta";
23
+ this.fetchFn = opts.fetch ?? fetch;
24
+ this.delay = opts.retryDelayMs ?? 1000;
25
+ this.name = `gemini:${main}`;
26
+ }
27
+ async json(system, prompt, schema) {
28
+ const errors = [];
29
+ for (const model of this.models) {
30
+ const body = requestBody(model, system, prompt, schema, this.temperature);
31
+ // Each model gets two rounds over all keys before moving to the next model.
32
+ for (let attempt = 0; attempt < this.keys.length * 2; attempt++) {
33
+ const live = this.keys.filter((k) => !this.exhausted.has(`${k}|${model}`));
34
+ if (live.length === 0)
35
+ break;
36
+ if (this.exhausted.has(`${this.keys[this.current]}|${model}`))
37
+ this.current = this.keys.indexOf(live[0]);
38
+ const key = this.keys[this.current];
39
+ const r = await this.call(model, key, body);
40
+ if (r.ok) {
41
+ this.lastModel = model;
42
+ return r.value;
43
+ }
44
+ errors.push(`${model}: ${r.error}`);
45
+ if (r.fatal)
46
+ throw new Error(`Gemini ${model}: ${r.error}`);
47
+ if (r.skipModel)
48
+ break;
49
+ if (r.dailyLimit) {
50
+ this.exhausted.add(`${key}|${model}`);
51
+ continue;
52
+ }
53
+ if (r.rotate)
54
+ this.current = (this.current + 1) % this.keys.length;
55
+ await sleep(this.delay * (attempt + 1));
56
+ }
57
+ }
58
+ throw new Error(`Gemini failed on all models — last error ${errors[errors.length - 1] ?? "unknown"}`);
59
+ }
60
+ async call(model, key, body) {
61
+ let res;
62
+ try {
63
+ res = await this.fetchFn(`${this.baseUrl}/models/${model}:generateContent`, {
64
+ method: "POST",
65
+ headers: { "content-type": "application/json", "x-goog-api-key": key },
66
+ body,
67
+ signal: AbortSignal.timeout(120_000),
68
+ });
69
+ }
70
+ catch (err) {
71
+ return { ok: false, error: `network: ${err.message}` };
72
+ }
73
+ const raw = await res.text();
74
+ const msg = () => {
75
+ try {
76
+ return JSON.parse(raw).error?.message?.slice(0, 160) ?? raw.slice(0, 160);
77
+ }
78
+ catch {
79
+ return raw.slice(0, 160);
80
+ }
81
+ };
82
+ // "PerDay" quota: this key is done with this model until tomorrow.
83
+ if (res.status === 429 && raw.includes("PerDay"))
84
+ return { ok: false, error: `HTTP 429 daily quota used up`, dailyLimit: true };
85
+ if (res.status === 429 || res.status === 403)
86
+ return { ok: false, error: `HTTP ${res.status} ${msg()}`, rotate: true };
87
+ if (res.status === 503 || res.status === 500 || res.status === 502 || res.status === 504)
88
+ return { ok: false, error: `HTTP ${res.status} ${msg()}`, rotate: true };
89
+ if (res.status === 404)
90
+ return { ok: false, error: `HTTP 404 ${msg()}`, skipModel: true };
91
+ if (!res.ok)
92
+ return { ok: false, error: `HTTP ${res.status} ${msg()}`, fatal: true };
93
+ const data = JSON.parse(raw);
94
+ const text = data.candidates?.[0]?.content?.parts?.map((p) => p.text ?? "").join("") ?? "";
95
+ if (!text)
96
+ return { ok: false, error: `empty response (${data.candidates?.[0]?.finishReason ?? data.promptFeedback?.blockReason ?? "unknown"})` };
97
+ const value = parseJsonLoose(text);
98
+ return value === undefined ? { ok: false, error: `invalid JSON: ${text.slice(0, 120)}` } : { ok: true, value };
99
+ }
100
+ }
101
+ /**
102
+ * Gemini models get native JSON mode with a schema. Gemma models (open
103
+ * weights, separate free quota) support neither system instructions nor
104
+ * schemas, so they get everything in one prompt and we parse the JSON out.
105
+ */
106
+ function requestBody(model, system, prompt, schema, temperature) {
107
+ if (model.startsWith("gemma")) {
108
+ const text = `${system}\n\n${prompt}\n\nAnswer with ONLY a JSON object matching this JSON schema, no prose, no code fences:\n${JSON.stringify(schema)}`;
109
+ return JSON.stringify({ contents: [{ role: "user", parts: [{ text }] }], generationConfig: { temperature } });
110
+ }
111
+ return JSON.stringify({
112
+ systemInstruction: { parts: [{ text: system }] },
113
+ contents: [{ role: "user", parts: [{ text: prompt }] }],
114
+ generationConfig: { temperature, responseMimeType: "application/json", responseSchema: schema },
115
+ });
116
+ }
117
+ /** Parses JSON, also when wrapped in ```json fences or surrounded by text. */
118
+ export function parseJsonLoose(text) {
119
+ const tryParse = (s) => {
120
+ try {
121
+ return JSON.parse(s);
122
+ }
123
+ catch {
124
+ return undefined;
125
+ }
126
+ };
127
+ const direct = tryParse(text.trim());
128
+ if (direct !== undefined)
129
+ return direct;
130
+ const fenced = /```(?:json)?\s*([\s\S]*?)```/.exec(text);
131
+ if (fenced) {
132
+ const v = tryParse(fenced[1].trim());
133
+ if (v !== undefined)
134
+ return v;
135
+ }
136
+ const start = text.indexOf("{");
137
+ const end = text.lastIndexOf("}");
138
+ return start >= 0 && end > start ? tryParse(text.slice(start, end + 1)) : undefined;
139
+ }
140
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
141
+ /** Returns scripted answers in order. For tests and offline demos. */
142
+ export class ScriptedLLM {
143
+ answers;
144
+ name = "scripted";
145
+ calls = [];
146
+ constructor(answers) {
147
+ this.answers = answers;
148
+ }
149
+ async json(system, prompt) {
150
+ this.calls.push({ system, prompt });
151
+ if (this.answers.length === 0)
152
+ throw new Error("ScriptedLLM: no answers left");
153
+ return this.answers.shift();
154
+ }
155
+ }
156
+ /**
157
+ * Gemini embeddings (gemini-embedding-001) at 1536 dims, rotating keys on quota
158
+ * errors. Used for Walrus Memory manual mode.
159
+ */
160
+ export function geminiEmbedder(apiKeys, opts = {}) {
161
+ const model = opts.model ?? "gemini-embedding-001";
162
+ const f = opts.fetch ?? fetch;
163
+ let next = 0;
164
+ return async (text) => {
165
+ let last = "";
166
+ for (let attempt = 0; attempt < apiKeys.length * 2; attempt++) {
167
+ const key = apiKeys[next % apiKeys.length];
168
+ const res = await f(`https://generativelanguage.googleapis.com/v1beta/models/${model}:embedContent`, {
169
+ method: "POST",
170
+ headers: { "content-type": "application/json", "x-goog-api-key": key },
171
+ body: JSON.stringify({ content: { parts: [{ text }] }, outputDimensionality: opts.dims ?? 1536 }),
172
+ });
173
+ if (res.ok) {
174
+ const j = (await res.json());
175
+ if (!j.embedding?.values?.length)
176
+ throw new Error("Gemini embedding returned no values");
177
+ return j.embedding.values;
178
+ }
179
+ last = `HTTP ${res.status}`;
180
+ if (res.status !== 429 && res.status < 500)
181
+ throw new Error(`Gemini embedding failed: ${last} ${(await res.text()).slice(0, 200)}`);
182
+ next++;
183
+ await new Promise((r) => setTimeout(r, 500 * (attempt + 1)));
184
+ }
185
+ throw new Error(`Gemini embedding failed on every key: ${last}`);
186
+ };
187
+ }
188
+ //# sourceMappingURL=llm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm.js","sourceRoot":"","sources":["../src/llm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { SuiGrpcClient } from "@mysten/sui/grpc";
2
+ /**
3
+ * A user's own Walrus Memory account, set up from the browser: the user's
4
+ * wallet creates the account and authorizes a delegate key that the Engram
5
+ * server holds for their agent. These helpers read that state from chain and
6
+ * build the two transactions; the wallet only signs.
7
+ */
8
+ export interface MemwalIds {
9
+ packageId: string;
10
+ registryId: string;
11
+ }
12
+ export interface MemwalAccountInfo {
13
+ accountId: string;
14
+ owner: string;
15
+ delegates: {
16
+ publicKey: string;
17
+ suiAddress: string;
18
+ label: string;
19
+ }[];
20
+ }
21
+ /** A fresh Ed25519 delegate key; `secret` is the suiprivkey1… form. */
22
+ export declare function newDelegateKey(): {
23
+ secret: string;
24
+ publicKey: string;
25
+ suiAddress: string;
26
+ };
27
+ export declare function delegateFromSecret(secret: string): {
28
+ publicKey: string;
29
+ suiAddress: string;
30
+ };
31
+ /** Finds the Walrus Memory account an address owns (each address can own one). */
32
+ export declare function findMemwalAccount(client: SuiGrpcClient, owner: string, ids?: MemwalIds): Promise<string | null>;
33
+ export declare function readMemwalAccount(client: SuiGrpcClient, accountId: string): Promise<MemwalAccountInfo>;
34
+ /** Unsigned `create_account` transaction for `sender`, as base64 bytes ready for a wallet. */
35
+ export declare function buildCreateAccountTx(client: SuiGrpcClient, sender: string, ids?: MemwalIds): Promise<string>;
36
+ /** Unsigned `add_delegate_key` transaction (owner adds the server's key). */
37
+ export declare function buildAddDelegateTx(client: SuiGrpcClient, sender: string, accountId: string, publicKeyHex: string, label: string, ids?: MemwalIds): Promise<string>;
38
+ /** Submits wallet-signed bytes and waits for them to land. Returns the digest. */
39
+ export declare function executeSigned(client: SuiGrpcClient, bytesBase64: string, signature: string): Promise<string>;
@@ -0,0 +1,75 @@
1
+ import { bcs } from "@mysten/sui/bcs";
2
+ import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
3
+ import { Transaction } from "@mysten/sui/transactions";
4
+ import { normalizeSuiAddress } from "@mysten/sui/utils";
5
+ import { MEMWAL_MAINNET } from "./remote.js";
6
+ /** A fresh Ed25519 delegate key; `secret` is the suiprivkey1… form. */
7
+ export function newDelegateKey() {
8
+ const kp = new Ed25519Keypair();
9
+ return { secret: kp.getSecretKey(), publicKey: Buffer.from(kp.getPublicKey().toRawBytes()).toString("hex"), suiAddress: kp.toSuiAddress() };
10
+ }
11
+ export function delegateFromSecret(secret) {
12
+ const kp = Ed25519Keypair.fromSecretKey(secret);
13
+ return { publicKey: Buffer.from(kp.getPublicKey().toRawBytes()).toString("hex"), suiAddress: kp.toSuiAddress() };
14
+ }
15
+ /** Finds the Walrus Memory account an address owns (each address can own one). */
16
+ export async function findMemwalAccount(client, owner, ids = MEMWAL_MAINNET) {
17
+ const { object } = await client.getObject({ objectId: ids.registryId, include: { json: true } });
18
+ const tableId = object.json?.accounts?.id;
19
+ if (!tableId)
20
+ throw new Error("Walrus Memory registry has no accounts table");
21
+ try {
22
+ const f = await client.getDynamicField({ parentId: tableId, name: { type: "address", bcs: bcs.Address.serialize(normalizeSuiAddress(owner)).toBytes() } });
23
+ const value = f.dynamicField?.value;
24
+ if (!value)
25
+ return null;
26
+ // Table<address, ID>: the value is the 32-byte account ID.
27
+ return normalizeSuiAddress(Buffer.from(value.bcs).toString("hex"));
28
+ }
29
+ catch (err) {
30
+ if (/not ?found|does not exist/i.test(String(err.message)))
31
+ return null;
32
+ throw err;
33
+ }
34
+ }
35
+ export async function readMemwalAccount(client, accountId) {
36
+ const { object } = await client.getObject({ objectId: accountId, include: { json: true } });
37
+ const j = object.json;
38
+ if (!j?.owner)
39
+ throw new Error(`${accountId} is not a Walrus Memory account`);
40
+ return {
41
+ accountId,
42
+ owner: normalizeSuiAddress(j.owner),
43
+ delegates: (j.delegate_keys ?? []).map((d) => ({
44
+ publicKey: /^[0-9a-f]+$/i.test(d.public_key) ? d.public_key.toLowerCase() : Buffer.from(d.public_key, "base64").toString("hex"),
45
+ suiAddress: normalizeSuiAddress(d.sui_address),
46
+ label: d.label ?? "",
47
+ })),
48
+ };
49
+ }
50
+ /** Unsigned `create_account` transaction for `sender`, as base64 bytes ready for a wallet. */
51
+ export async function buildCreateAccountTx(client, sender, ids = MEMWAL_MAINNET) {
52
+ const tx = new Transaction();
53
+ tx.setSender(sender);
54
+ tx.moveCall({ target: `${ids.packageId}::account::create_account`, arguments: [tx.object(ids.registryId), tx.object.clock()] });
55
+ return Buffer.from(await tx.build({ client })).toString("base64");
56
+ }
57
+ /** Unsigned `add_delegate_key` transaction (owner adds the server's key). */
58
+ export async function buildAddDelegateTx(client, sender, accountId, publicKeyHex, label, ids = MEMWAL_MAINNET) {
59
+ const tx = new Transaction();
60
+ tx.setSender(sender);
61
+ tx.moveCall({
62
+ target: `${ids.packageId}::account::add_delegate_key`,
63
+ arguments: [tx.object(accountId), tx.object(ids.registryId), tx.pure.vector("u8", Buffer.from(publicKeyHex, "hex")), tx.pure.string(label), tx.object.clock()],
64
+ });
65
+ return Buffer.from(await tx.build({ client })).toString("base64");
66
+ }
67
+ /** Submits wallet-signed bytes and waits for them to land. Returns the digest. */
68
+ export async function executeSigned(client, bytesBase64, signature) {
69
+ const res = await client.executeTransaction({ transaction: Buffer.from(bytesBase64, "base64"), signatures: [signature] });
70
+ if (res.$kind !== "Transaction")
71
+ throw new Error(`transaction failed: ${JSON.stringify(res.FailedTransaction?.status)}`);
72
+ await client.waitForTransaction({ digest: res.Transaction.digest });
73
+ return res.Transaction.digest;
74
+ }
75
+ //# sourceMappingURL=memwal-account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memwal-account.js","sourceRoot":"","sources":["../src/memwal-account.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { MerkleProofStep } from "./types.js";
2
+ /** Root of an empty tree. */
3
+ export declare const EMPTY_ROOT: string;
4
+ /**
5
+ * Binary Merkle tree over hex leaf values, in the given order.
6
+ * An odd node at the end of a level is carried up unchanged.
7
+ */
8
+ export declare class MerkleTree {
9
+ private levels;
10
+ constructor(leaves: string[]);
11
+ get root(): string;
12
+ proof(index: number): MerkleProofStep[];
13
+ }
14
+ export declare function verifyProof(leafHex: string, proof: MerkleProofStep[], rootHex: string): boolean;
package/dist/merkle.js ADDED
@@ -0,0 +1,69 @@
1
+ import { bytesToHex, hexToBytes, sha256Bytes } from "./crypto.js";
2
+ // Domain separation so a leaf can never be passed off as an inner node.
3
+ const LEAF = 0x00;
4
+ const NODE = 0x01;
5
+ function hashLeaf(leafHex) {
6
+ return bytesToHex(sha256Bytes(concat([LEAF], hexToBytes(leafHex))));
7
+ }
8
+ function hashNode(leftHex, rightHex) {
9
+ return bytesToHex(sha256Bytes(concat([NODE], hexToBytes(leftHex), hexToBytes(rightHex))));
10
+ }
11
+ function concat(prefix, ...parts) {
12
+ const out = new Uint8Array(prefix.length + parts.reduce((n, p) => n + p.length, 0));
13
+ out.set(prefix, 0);
14
+ let o = prefix.length;
15
+ for (const p of parts) {
16
+ out.set(p, o);
17
+ o += p.length;
18
+ }
19
+ return out;
20
+ }
21
+ /** Root of an empty tree. */
22
+ export const EMPTY_ROOT = bytesToHex(sha256Bytes(new Uint8Array([NODE])));
23
+ /**
24
+ * Binary Merkle tree over hex leaf values, in the given order.
25
+ * An odd node at the end of a level is carried up unchanged.
26
+ */
27
+ export class MerkleTree {
28
+ levels;
29
+ constructor(leaves) {
30
+ let level = leaves.map(hashLeaf);
31
+ this.levels = [level];
32
+ while (level.length > 1) {
33
+ const next = [];
34
+ for (let i = 0; i < level.length; i += 2) {
35
+ const l = level[i];
36
+ const r = level[i + 1];
37
+ next.push(r === undefined ? l : hashNode(l, r));
38
+ }
39
+ this.levels.push(next);
40
+ level = next;
41
+ }
42
+ }
43
+ get root() {
44
+ const top = this.levels[this.levels.length - 1];
45
+ return top[0] ?? EMPTY_ROOT;
46
+ }
47
+ proof(index) {
48
+ if (index < 0 || index >= this.levels[0].length)
49
+ throw new Error(`leaf ${index} out of range`);
50
+ const steps = [];
51
+ let i = index;
52
+ for (let d = 0; d < this.levels.length - 1; d++) {
53
+ const level = this.levels[d];
54
+ const isRight = i % 2 === 1;
55
+ const sib = isRight ? level[i - 1] : level[i + 1];
56
+ if (sib !== undefined)
57
+ steps.push({ hash: sib, left: isRight });
58
+ i = Math.floor(i / 2);
59
+ }
60
+ return steps;
61
+ }
62
+ }
63
+ export function verifyProof(leafHex, proof, rootHex) {
64
+ let h = hashLeaf(leafHex);
65
+ for (const s of proof)
66
+ h = s.left ? hashNode(s.hash, h) : hashNode(h, s.hash);
67
+ return h === rootHex;
68
+ }
69
+ //# sourceMappingURL=merkle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merkle.js","sourceRoot":"","sources":["../src/merkle.ts"],"names":[],"mappings":"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"}
package/dist/mind.d.ts ADDED
@@ -0,0 +1,150 @@
1
+ import { type Anchorer, type SuiNetwork } from "./anchor.js";
2
+ import { Engram, type ForgetResult, type ObserveInput, type SleepReport, type VerifyReport } from "./engram.js";
3
+ import { type LLM } from "./llm.js";
4
+ import { type RemoteMemory } from "./remote.js";
5
+ import { type LinkInfo, type LinkStart, type SyncResult } from "./link.js";
6
+ import type { Belief, Commit, Episode, Receipt } from "./types.js";
7
+ /**
8
+ * Settings for `engram()`. Anything left out is read from the environment
9
+ * (`.env`: MEMWAL_KEY, MEMWAL_ACCOUNT_ID, TATUM_API_KEY, GEMINI_API_KEYS, …).
10
+ */
11
+ export interface EngramConfig {
12
+ /** Agent name — lowercase letters, digits and dashes. Used for a new repo. */
13
+ agent: string;
14
+ /** Folder for `.engram/` (default: the current directory). */
15
+ dir?: string;
16
+ /** Walrus Memory account, a ready remote, or "memory" for an in-process store (tests). */
17
+ walrus?: {
18
+ accountId: string;
19
+ key: string;
20
+ serverUrl?: string;
21
+ } | RemoteMemory | "memory";
22
+ /** Tatum Sui gateway (mainnet) — wallet reads and anchor checks. */
23
+ tatum?: {
24
+ apiKey: string;
25
+ };
26
+ /** LLM for `sleep()`: Gemini keys, or any `LLM`. */
27
+ llm?: {
28
+ gemini: string[];
29
+ model?: string;
30
+ } | LLM;
31
+ /** Anchor commits with the engram_anchor Move module. */
32
+ anchor?: {
33
+ packageId: string;
34
+ mnemonic: string;
35
+ network?: SuiNetwork;
36
+ } | Anchorer | false;
37
+ /** Domain hint for consolidation, e.g. "a wallet-watching agent". */
38
+ context?: string;
39
+ /** Where unspecified settings come from (default: process.env). */
40
+ env?: Record<string, string | undefined>;
41
+ }
42
+ export interface WrapOptions<In, Out> {
43
+ /** What to look up beliefs about (default: the input as JSON). */
44
+ query?: (input: In) => string;
45
+ /** One-line description of the decision for the receipt (default: the output as JSON). */
46
+ action?: (output: Out, input: In) => string;
47
+ /** Beliefs the decision used: ids like "b_rent" (default: every belief the agent was given). */
48
+ used?: (output: Out, beliefs: Belief[]) => string[];
49
+ /** Also record the input as an episode (default true). */
50
+ observe?: boolean | ((input: In) => ObserveInput);
51
+ /** Max beliefs handed to the agent (default 6). */
52
+ limit?: number;
53
+ }
54
+ /** A wrapped agent: same call, plus the last receipt. */
55
+ export interface WrappedAgent<In, Out> {
56
+ (input: In): Promise<Out>;
57
+ /** Receipt of the most recent call (null before the first commit). */
58
+ lastReceipt: Receipt | null;
59
+ }
60
+ /**
61
+ * The high-level API: one object for an agent's memory.
62
+ *
63
+ * ```ts
64
+ * const mind = engram({ agent: "money-ops" });
65
+ * const agent = mind.wrap(myAgent); // beliefs in, signed receipts out
66
+ * mind.observe({ source: "tatum", data: tx });
67
+ * await mind.sleep(); // episodes → beliefs
68
+ * await mind.commit("weekly"); // Merkle root → Walrus → Sui
69
+ * await mind.beliefs({ about: "rent" });
70
+ * mind.at("2026-10-25"); // time travel
71
+ * mind.forget("ep_…"); // provable forgetting
72
+ * await mind.verify("r_…"); // proof check
73
+ * ```
74
+ */
75
+ export declare class Mind {
76
+ private llmFactory;
77
+ private context?;
78
+ readonly core: Engram;
79
+ private llmInstance?;
80
+ constructor(core: Engram, llmFactory: () => LLM, context?: string | undefined);
81
+ get agent(): string;
82
+ /** Records an episode (encrypted with its own key). */
83
+ observe(input: ObserveInput): Episode;
84
+ /** Consolidates new episodes into beliefs with the configured LLM. */
85
+ sleep(opts?: {
86
+ context?: string;
87
+ batchSize?: number;
88
+ }): Promise<SleepReport>;
89
+ /**
90
+ * Signs and stores a snapshot of the current beliefs, anchored on Sui. If the
91
+ * agent is linked to a dashboard, the new history is synced too (a failed
92
+ * sync never fails the commit; see `lastSyncError`).
93
+ */
94
+ commit(message: string): Promise<Commit>;
95
+ /** Why the last automatic sync after commit failed, if it did. */
96
+ lastSyncError: string | null;
97
+ /**
98
+ * Links this agent to an Engram web app account (a Sui wallet). `onCode`
99
+ * gets the code and URL to show the owner; resolves once they approve.
100
+ */
101
+ link(opts: {
102
+ server?: string;
103
+ label?: string;
104
+ onCode: (start: LinkStart) => void;
105
+ }): Promise<LinkInfo>;
106
+ /** Uploads the audit bundle to the linked dashboard (verified there before it's shown). */
107
+ sync(): Promise<SyncResult>;
108
+ get linked(): LinkInfo | null;
109
+ unlink(): boolean;
110
+ /**
111
+ * Current beliefs. With `about`, the most relevant ones (Walrus Memory
112
+ * semantic recall, keyword fallback offline).
113
+ */
114
+ beliefs(opts?: {
115
+ about?: string;
116
+ limit?: number;
117
+ }): Promise<Belief[]>;
118
+ /** Beliefs as they were at a commit, `HEAD~n`, or a date ("2026-10-25"). */
119
+ at(ref: string): Belief[];
120
+ /** Destroys an episode's key; dependent beliefs are retracted or revised. */
121
+ forget(episodeId: string, reason?: string): ForgetResult;
122
+ /** Verifies a receipt (`r_…`) or a commit (id, `HEAD`, date) end to end. */
123
+ verify(ref: string, opts?: {
124
+ offline?: boolean;
125
+ }): Promise<VerifyReport>;
126
+ log(): Commit[];
127
+ diff(from: string, to?: string): import("./engram.js").BeliefDiff;
128
+ blame(belief: string): {
129
+ belief: Belief;
130
+ history: Belief[];
131
+ evidence: import("./engram.js").BlameEntry[];
132
+ };
133
+ receipts(): Receipt[];
134
+ /**
135
+ * Wraps an existing agent function. Each call: the relevant committed
136
+ * beliefs are passed in, the agent runs, and a signed receipt records what it
137
+ * decided and which beliefs it relied on.
138
+ *
139
+ * ```ts
140
+ * const agent = mind.wrap(async (tx, beliefs) => decide(tx, beliefs), {
141
+ * used: (out) => out.beliefIds,
142
+ * });
143
+ * const decision = await agent(tx);
144
+ * agent.lastReceipt; // r_…
145
+ * ```
146
+ */
147
+ wrap<In, Out>(fn: (input: In, beliefs: Belief[]) => Promise<Out> | Out, opts?: WrapOptions<In, Out>): WrappedAgent<In, Out>;
148
+ }
149
+ /** Opens (or creates) an agent's memory. See {@link EngramConfig}. */
150
+ export declare function engram(cfg: EngramConfig): Mind;