@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
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { LLM } from "./llm.js";
|
|
2
|
+
import type { Belief, EpisodeContent } from "./types.js";
|
|
3
|
+
/** One change the consolidator wants to make to the belief set. */
|
|
4
|
+
export type BeliefOp = {
|
|
5
|
+
op: "create";
|
|
6
|
+
key: string;
|
|
7
|
+
statement: string;
|
|
8
|
+
confidence: number;
|
|
9
|
+
evidence: string[];
|
|
10
|
+
tags: string[];
|
|
11
|
+
reason: string;
|
|
12
|
+
} | {
|
|
13
|
+
op: "revise";
|
|
14
|
+
belief: string;
|
|
15
|
+
statement: string;
|
|
16
|
+
confidence: number;
|
|
17
|
+
evidence: string[];
|
|
18
|
+
tags?: string[];
|
|
19
|
+
reason: string;
|
|
20
|
+
} | {
|
|
21
|
+
op: "retract";
|
|
22
|
+
belief: string;
|
|
23
|
+
reason: string;
|
|
24
|
+
};
|
|
25
|
+
export interface ConsolidationInput {
|
|
26
|
+
episodes: {
|
|
27
|
+
id: string;
|
|
28
|
+
content: EpisodeContent;
|
|
29
|
+
summary?: string;
|
|
30
|
+
}[];
|
|
31
|
+
beliefs: Belief[];
|
|
32
|
+
/** Optional domain hint, e.g. "You manage a crypto wallet for one owner." */
|
|
33
|
+
context?: string;
|
|
34
|
+
}
|
|
35
|
+
interface RawOp {
|
|
36
|
+
op?: string;
|
|
37
|
+
key?: string;
|
|
38
|
+
belief?: string;
|
|
39
|
+
statement?: string;
|
|
40
|
+
confidence?: number;
|
|
41
|
+
evidence?: string[];
|
|
42
|
+
tags?: string[];
|
|
43
|
+
reason?: string;
|
|
44
|
+
}
|
|
45
|
+
export declare function buildPrompt(input: ConsolidationInput): string;
|
|
46
|
+
/** Asks the LLM for belief changes and drops anything malformed or ungrounded. */
|
|
47
|
+
export declare function proposeOps(llm: LLM, input: ConsolidationInput): Promise<{
|
|
48
|
+
ops: BeliefOp[];
|
|
49
|
+
rejected: {
|
|
50
|
+
op: unknown;
|
|
51
|
+
why: string;
|
|
52
|
+
}[];
|
|
53
|
+
}>;
|
|
54
|
+
export declare function validateOps(rawOps: RawOp[], input: ConsolidationInput): {
|
|
55
|
+
ops: BeliefOp[];
|
|
56
|
+
rejected: {
|
|
57
|
+
op: unknown;
|
|
58
|
+
why: string;
|
|
59
|
+
}[];
|
|
60
|
+
};
|
|
61
|
+
export declare function slug(s: string): string;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
const SYSTEM = `You are the memory consolidator of an AI agent — the part that "sleeps" on new experiences and turns them into durable beliefs.
|
|
2
|
+
|
|
3
|
+
You receive the agent's CURRENT BELIEFS and a batch of NEW EPISODES (raw observations). Return the smallest set of operations that keeps the beliefs accurate:
|
|
4
|
+
|
|
5
|
+
- create: a new belief that the episodes support. Beliefs are general, reusable knowledge — habits, schedules, preferences, relationships, rules, facts about the world. Do NOT turn every single event into a belief; one-off events only become beliefs if they are clearly important (e.g. a large unusual transfer, an explicit instruction from the user).
|
|
6
|
+
- revise: an existing belief needs a new version — new evidence strengthens it (raise confidence), weakens it (lower confidence), refines it (more precise wording), or contradicts it (change the statement). Include ALL episodes that support the NEW version (old and new evidence).
|
|
7
|
+
- retract: an existing belief is now clearly false or superseded and should no longer guide the agent.
|
|
8
|
+
|
|
9
|
+
Rules:
|
|
10
|
+
- Cite evidence ONLY with episode IDs that appear in the input (new episodes or the evidence lists of current beliefs). Never invent IDs.
|
|
11
|
+
- Refer to existing beliefs ONLY by their exact id.
|
|
12
|
+
- An explicit statement or correction from the user outweighs patterns inferred from data.
|
|
13
|
+
- Confidence: 0.3–0.5 for a weak single-observation inference, 0.6–0.8 for a repeated pattern, 0.85–0.97 for a pattern confirmed by the user or seen many times. Never 1.0.
|
|
14
|
+
- Statements are one clear sentence, specific (amounts, counterparties, timing) and in the present tense.
|
|
15
|
+
- "key" for create is a short snake_case name for the belief, e.g. "rent_payment".
|
|
16
|
+
- tags: 1–3 lowercase topic words (e.g. "rent", "income", "security").
|
|
17
|
+
- reason: one short sentence a human auditor can read.
|
|
18
|
+
- If nothing should change, return an empty list.`;
|
|
19
|
+
const SCHEMA = {
|
|
20
|
+
type: "object",
|
|
21
|
+
properties: {
|
|
22
|
+
ops: {
|
|
23
|
+
type: "array",
|
|
24
|
+
items: {
|
|
25
|
+
type: "object",
|
|
26
|
+
properties: {
|
|
27
|
+
op: { type: "string", enum: ["create", "revise", "retract"] },
|
|
28
|
+
key: { type: "string", description: "create only: snake_case name" },
|
|
29
|
+
belief: { type: "string", description: "revise/retract only: existing belief id" },
|
|
30
|
+
statement: { type: "string" },
|
|
31
|
+
confidence: { type: "number" },
|
|
32
|
+
evidence: { type: "array", items: { type: "string" } },
|
|
33
|
+
tags: { type: "array", items: { type: "string" } },
|
|
34
|
+
reason: { type: "string" },
|
|
35
|
+
},
|
|
36
|
+
// Gemini's schema has no conditionals, so ask for every field; retract ignores the extras.
|
|
37
|
+
required: ["op", "statement", "confidence", "evidence", "tags", "reason"],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
required: ["ops"],
|
|
42
|
+
};
|
|
43
|
+
export function buildPrompt(input) {
|
|
44
|
+
const beliefs = input.beliefs.length
|
|
45
|
+
? input.beliefs
|
|
46
|
+
.map((b) => `- id=${b.id} v${b.version} conf=${b.confidence.toFixed(2)} tags=[${b.tags.join(",")}] evidence=[${b.evidence.join(",")}]\n "${b.statement}"`)
|
|
47
|
+
.join("\n")
|
|
48
|
+
: "(none yet)";
|
|
49
|
+
const eps = input.episodes
|
|
50
|
+
.map((e) => `- id=${e.id} at=${new Date(e.content.ts).toISOString()} source=${e.content.source}\n ${JSON.stringify(e.content.data)}`)
|
|
51
|
+
.join("\n");
|
|
52
|
+
return `${input.context ? `CONTEXT: ${input.context}\n\n` : ""}CURRENT BELIEFS:\n${beliefs}\n\nNEW EPISODES (${input.episodes.length}):\n${eps}\n\nReturn the operations as JSON.`;
|
|
53
|
+
}
|
|
54
|
+
/** Asks the LLM for belief changes and drops anything malformed or ungrounded. */
|
|
55
|
+
export async function proposeOps(llm, input) {
|
|
56
|
+
const prompt = buildPrompt(input);
|
|
57
|
+
const raw = await llm.json(SYSTEM, prompt, SCHEMA);
|
|
58
|
+
const first = validateOps(raw.ops ?? [], input);
|
|
59
|
+
if (first.rejected.length === 0)
|
|
60
|
+
return first;
|
|
61
|
+
// One repair round: show the model what was rejected and why, keep whatever it fixes.
|
|
62
|
+
const feedback = first.rejected.map((r) => `- ${r.why}: ${JSON.stringify(r.op)}`).join("\n");
|
|
63
|
+
const accepted = first.ops.map((o) => JSON.stringify(o)).join("\n") || "(none)";
|
|
64
|
+
let repaired;
|
|
65
|
+
try {
|
|
66
|
+
repaired = await llm.json(SYSTEM, `${prompt}\n\nYour previous answer had operations that were REJECTED:\n${feedback}\n\nThese were ACCEPTED and are already applied — do not repeat them:\n${accepted}\n\nReturn ONLY corrected versions of the rejected operations (with valid episode IDs as evidence), or an empty list if they should be dropped.`, SCHEMA);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return first;
|
|
70
|
+
}
|
|
71
|
+
// Validate repairs against the same input, minus beliefs the first pass already touched.
|
|
72
|
+
const touched = new Set(first.ops.flatMap((o) => (o.op === "create" ? [] : [o.belief])));
|
|
73
|
+
const second = validateOps((repaired.ops ?? []).filter((o) => !o.belief || !touched.has(o.belief)), input);
|
|
74
|
+
return { ops: [...first.ops, ...second.ops], rejected: second.rejected };
|
|
75
|
+
}
|
|
76
|
+
export function validateOps(rawOps, input) {
|
|
77
|
+
const knownEpisodes = new Set([...input.episodes.map((e) => e.id), ...input.beliefs.flatMap((b) => b.evidence)]);
|
|
78
|
+
const knownBeliefs = new Set(input.beliefs.map((b) => b.id));
|
|
79
|
+
const touched = new Set();
|
|
80
|
+
const ops = [];
|
|
81
|
+
const rejected = [];
|
|
82
|
+
const reject = (op, why) => rejected.push({ op, why });
|
|
83
|
+
for (const r of rawOps) {
|
|
84
|
+
const reason = (r.reason ?? "").trim() || "no reason given";
|
|
85
|
+
if (r.op === "retract") {
|
|
86
|
+
if (!r.belief || !knownBeliefs.has(r.belief)) {
|
|
87
|
+
reject(r, "unknown belief");
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (touched.has(r.belief)) {
|
|
91
|
+
reject(r, "belief changed twice");
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
touched.add(r.belief);
|
|
95
|
+
ops.push({ op: "retract", belief: r.belief, reason });
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (r.op !== "create" && r.op !== "revise") {
|
|
99
|
+
reject(r, "unknown op");
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const statement = (r.statement ?? "").trim();
|
|
103
|
+
if (!statement) {
|
|
104
|
+
reject(r, "empty statement");
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const evidence = [...new Set(r.evidence ?? [])];
|
|
108
|
+
const bad = evidence.filter((e) => !knownEpisodes.has(e));
|
|
109
|
+
const good = evidence.filter((e) => knownEpisodes.has(e));
|
|
110
|
+
if (good.length === 0) {
|
|
111
|
+
reject(r, `no valid evidence${bad.length ? ` (unknown: ${bad.join(",")})` : ""}`);
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const confidence = clamp(Number(r.confidence ?? 0.5), 0.01, 0.99);
|
|
115
|
+
const tags = [...new Set((r.tags ?? []).map((t) => t.toLowerCase().trim()).filter(Boolean))].slice(0, 3);
|
|
116
|
+
if (r.op === "revise") {
|
|
117
|
+
if (!r.belief || !knownBeliefs.has(r.belief)) {
|
|
118
|
+
reject(r, "unknown belief");
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (touched.has(r.belief)) {
|
|
122
|
+
reject(r, "belief changed twice");
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
touched.add(r.belief);
|
|
126
|
+
ops.push({ op: "revise", belief: r.belief, statement, confidence, evidence: good, tags, reason });
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
ops.push({ op: "create", key: slug(r.key ?? statement), statement, confidence, evidence: good, tags, reason });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return { ops, rejected };
|
|
133
|
+
}
|
|
134
|
+
function clamp(x, lo, hi) {
|
|
135
|
+
return Number.isFinite(x) ? Math.min(hi, Math.max(lo, x)) : 0.5;
|
|
136
|
+
}
|
|
137
|
+
export function slug(s) {
|
|
138
|
+
const out = s.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 32).replace(/_+$/, "");
|
|
139
|
+
return out || "belief";
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=consolidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consolidator.js","sourceRoot":"","sources":["../src/consolidator.ts"],"names":[],"mappings":"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"}
|
package/dist/crypto.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { bytesToHex, hexToBytes } from "@noble/hashes/utils.js";
|
|
2
|
+
export { bytesToHex, hexToBytes };
|
|
3
|
+
/**
|
|
4
|
+
* Deterministic JSON: object keys sorted, no whitespace, `undefined` fields dropped.
|
|
5
|
+
* Everything Engram hashes or signs goes through this.
|
|
6
|
+
*/
|
|
7
|
+
export declare function canonical(value: unknown): string;
|
|
8
|
+
export declare function sha256Hex(data: string | Uint8Array): string;
|
|
9
|
+
export declare function sha256Bytes(data: Uint8Array): Uint8Array;
|
|
10
|
+
export declare function randomId(prefix: string, bytes?: number): string;
|
|
11
|
+
export interface KeyPair {
|
|
12
|
+
secretKey: string;
|
|
13
|
+
publicKey: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function generateKeyPair(): KeyPair;
|
|
16
|
+
export declare function publicKeyOf(secretKeyHex: string): string;
|
|
17
|
+
export declare function sign(message: string, secretKeyHex: string): string;
|
|
18
|
+
export declare function verifySignature(message: string, signatureHex: string, publicKeyHex: string): boolean;
|
|
19
|
+
export interface Sealed {
|
|
20
|
+
iv: string;
|
|
21
|
+
ct: string;
|
|
22
|
+
tag: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function newDataKey(): Buffer;
|
|
25
|
+
export declare function encrypt(plaintext: Uint8Array, key: Uint8Array, aad?: string): Sealed;
|
|
26
|
+
export declare function decrypt(sealed: Sealed, key: Uint8Array, aad?: string): Buffer;
|
package/dist/crypto.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
|
2
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
3
|
+
import { bytesToHex, hexToBytes, utf8ToBytes } from "@noble/hashes/utils.js";
|
|
4
|
+
import { ed25519 } from "@noble/curves/ed25519.js";
|
|
5
|
+
export { bytesToHex, hexToBytes };
|
|
6
|
+
/**
|
|
7
|
+
* Deterministic JSON: object keys sorted, no whitespace, `undefined` fields dropped.
|
|
8
|
+
* Everything Engram hashes or signs goes through this.
|
|
9
|
+
*/
|
|
10
|
+
export function canonical(value) {
|
|
11
|
+
return JSON.stringify(sortValue(value));
|
|
12
|
+
}
|
|
13
|
+
function sortValue(v) {
|
|
14
|
+
if (Array.isArray(v))
|
|
15
|
+
return v.map(sortValue);
|
|
16
|
+
if (v && typeof v === "object") {
|
|
17
|
+
const out = {};
|
|
18
|
+
for (const k of Object.keys(v).sort()) {
|
|
19
|
+
const x = v[k];
|
|
20
|
+
if (x !== undefined)
|
|
21
|
+
out[k] = sortValue(x);
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
return v;
|
|
26
|
+
}
|
|
27
|
+
export function sha256Hex(data) {
|
|
28
|
+
return bytesToHex(sha256(typeof data === "string" ? utf8ToBytes(data) : data));
|
|
29
|
+
}
|
|
30
|
+
export function sha256Bytes(data) {
|
|
31
|
+
return sha256(data);
|
|
32
|
+
}
|
|
33
|
+
export function randomId(prefix, bytes = 6) {
|
|
34
|
+
return `${prefix}_${randomBytes(bytes).toString("hex")}`;
|
|
35
|
+
}
|
|
36
|
+
export function generateKeyPair() {
|
|
37
|
+
const sk = ed25519.utils.randomSecretKey();
|
|
38
|
+
return { secretKey: bytesToHex(sk), publicKey: bytesToHex(ed25519.getPublicKey(sk)) };
|
|
39
|
+
}
|
|
40
|
+
export function publicKeyOf(secretKeyHex) {
|
|
41
|
+
return bytesToHex(ed25519.getPublicKey(hexToBytes(secretKeyHex)));
|
|
42
|
+
}
|
|
43
|
+
export function sign(message, secretKeyHex) {
|
|
44
|
+
return bytesToHex(ed25519.sign(utf8ToBytes(message), hexToBytes(secretKeyHex)));
|
|
45
|
+
}
|
|
46
|
+
export function verifySignature(message, signatureHex, publicKeyHex) {
|
|
47
|
+
try {
|
|
48
|
+
return ed25519.verify(hexToBytes(signatureHex), utf8ToBytes(message), hexToBytes(publicKeyHex));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export function newDataKey() {
|
|
55
|
+
return randomBytes(32);
|
|
56
|
+
}
|
|
57
|
+
export function encrypt(plaintext, key, aad) {
|
|
58
|
+
const iv = randomBytes(12);
|
|
59
|
+
const c = createCipheriv("aes-256-gcm", key, iv);
|
|
60
|
+
if (aad)
|
|
61
|
+
c.setAAD(Buffer.from(aad, "utf8"));
|
|
62
|
+
const ct = Buffer.concat([c.update(plaintext), c.final()]);
|
|
63
|
+
return { iv: iv.toString("base64"), ct: ct.toString("base64"), tag: c.getAuthTag().toString("base64") };
|
|
64
|
+
}
|
|
65
|
+
export function decrypt(sealed, key, aad) {
|
|
66
|
+
const d = createDecipheriv("aes-256-gcm", key, Buffer.from(sealed.iv, "base64"));
|
|
67
|
+
if (aad)
|
|
68
|
+
d.setAAD(Buffer.from(aad, "utf8"));
|
|
69
|
+
d.setAuthTag(Buffer.from(sealed.tag, "base64"));
|
|
70
|
+
return Buffer.concat([d.update(Buffer.from(sealed.ct, "base64")), d.final()]);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
|
package/dist/engram.d.ts
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { LocalStore } from "./store.js";
|
|
2
|
+
import { KeyVault } from "./vault.js";
|
|
3
|
+
import type { RemoteMemory } from "./remote.js";
|
|
4
|
+
import type { LLM } from "./llm.js";
|
|
5
|
+
import { type BeliefOp } from "./consolidator.js";
|
|
6
|
+
import type { Anchorer } from "./anchor.js";
|
|
7
|
+
import type { Belief, Commit, CommitManifest, Episode, EpisodeContent, EpisodeSource, Receipt } from "./types.js";
|
|
8
|
+
export interface Check {
|
|
9
|
+
name: string;
|
|
10
|
+
ok: boolean;
|
|
11
|
+
detail: string;
|
|
12
|
+
/** Skipped checks (e.g. no network) don't fail the report but are shown. */
|
|
13
|
+
skipped?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface VerifyReport {
|
|
16
|
+
ok: boolean;
|
|
17
|
+
checks: Check[];
|
|
18
|
+
}
|
|
19
|
+
export interface VerifyOptions {
|
|
20
|
+
/** Also confirm the manifest on Walrus Memory (network). Default true. */
|
|
21
|
+
walrus?: boolean;
|
|
22
|
+
/** Also confirm the anchor on Sui via the anchorer (network). Default true. */
|
|
23
|
+
chain?: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface DecideInput {
|
|
26
|
+
action: string;
|
|
27
|
+
/** What the agent was asked / saw. Only its hash is stored. */
|
|
28
|
+
input: unknown;
|
|
29
|
+
/** Beliefs the decision relied on: "b_x" (version in HEAD) or "b_x@2". */
|
|
30
|
+
beliefs: string[];
|
|
31
|
+
}
|
|
32
|
+
export interface ForgetResult {
|
|
33
|
+
episode: Episode;
|
|
34
|
+
revised: Belief[];
|
|
35
|
+
retracted: Belief[];
|
|
36
|
+
}
|
|
37
|
+
export declare class NothingToCommitError extends Error {
|
|
38
|
+
constructor(first?: boolean);
|
|
39
|
+
}
|
|
40
|
+
export interface BeliefDiff {
|
|
41
|
+
added: Belief[];
|
|
42
|
+
/** [before, after] */
|
|
43
|
+
changed: [Belief, Belief][];
|
|
44
|
+
removed: Belief[];
|
|
45
|
+
}
|
|
46
|
+
export interface BisectResult {
|
|
47
|
+
/** First commit where the agent behaves badly. */
|
|
48
|
+
commit: Commit;
|
|
49
|
+
/** What that commit changed — the likely culprit. */
|
|
50
|
+
diff: BeliefDiff;
|
|
51
|
+
steps: {
|
|
52
|
+
commit: string;
|
|
53
|
+
bad: boolean;
|
|
54
|
+
}[];
|
|
55
|
+
tested: number;
|
|
56
|
+
candidates: number;
|
|
57
|
+
}
|
|
58
|
+
export interface BlameEntry {
|
|
59
|
+
episode: Episode;
|
|
60
|
+
/** Decrypted content, or null if forgotten. */
|
|
61
|
+
content: EpisodeContent | null;
|
|
62
|
+
}
|
|
63
|
+
/** "b_rent@2" */
|
|
64
|
+
export declare const beliefKey: (b: Pick<Belief, "id" | "version">) => string;
|
|
65
|
+
export interface SleepOptions {
|
|
66
|
+
llm: LLM;
|
|
67
|
+
/** Domain hint for the consolidator. */
|
|
68
|
+
context?: string;
|
|
69
|
+
/** Episodes per LLM call. Default 40. */
|
|
70
|
+
batchSize?: number;
|
|
71
|
+
}
|
|
72
|
+
export interface SleepReport {
|
|
73
|
+
episodes: number;
|
|
74
|
+
created: Belief[];
|
|
75
|
+
revised: Belief[];
|
|
76
|
+
retracted: Belief[];
|
|
77
|
+
rejected: {
|
|
78
|
+
op: unknown;
|
|
79
|
+
why: string;
|
|
80
|
+
}[];
|
|
81
|
+
}
|
|
82
|
+
export interface EngramConfig {
|
|
83
|
+
v: 1;
|
|
84
|
+
agent: string;
|
|
85
|
+
agentPubKey: string;
|
|
86
|
+
createdAt: number;
|
|
87
|
+
namespaces: {
|
|
88
|
+
episodes: string;
|
|
89
|
+
beliefs: string;
|
|
90
|
+
commits: string;
|
|
91
|
+
receipts: string;
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export interface OpenOptions {
|
|
95
|
+
/** Folder that contains (or will contain) `.engram/`. Default: cwd. */
|
|
96
|
+
dir?: string;
|
|
97
|
+
remote: RemoteMemory;
|
|
98
|
+
/** Finds the on-chain anchor for commits. Without one, commits are signed but unanchored. */
|
|
99
|
+
anchorer?: Anchorer;
|
|
100
|
+
/**
|
|
101
|
+
* Open without the agent's keys (e.g. a repo rebuilt from an audit bundle):
|
|
102
|
+
* history, beliefs, receipts and verification work; signing and decrypting don't.
|
|
103
|
+
*/
|
|
104
|
+
readOnly?: boolean;
|
|
105
|
+
}
|
|
106
|
+
export interface ObserveInput {
|
|
107
|
+
source: EpisodeSource;
|
|
108
|
+
data: unknown;
|
|
109
|
+
/** Short label shown in logs. Stored in the clear locally — keep it non-sensitive. */
|
|
110
|
+
summary?: string;
|
|
111
|
+
ts?: number;
|
|
112
|
+
}
|
|
113
|
+
export interface PushResult {
|
|
114
|
+
episodes: number;
|
|
115
|
+
beliefs: number;
|
|
116
|
+
receipts: number;
|
|
117
|
+
}
|
|
118
|
+
export declare class Engram {
|
|
119
|
+
readonly store: LocalStore;
|
|
120
|
+
readonly vault: KeyVault;
|
|
121
|
+
readonly config: EngramConfig;
|
|
122
|
+
readonly remote: RemoteMemory;
|
|
123
|
+
readonly anchorer?: Anchorer;
|
|
124
|
+
private secretKey;
|
|
125
|
+
/** True when opened without keys — nothing can be signed or decrypted. */
|
|
126
|
+
readonly readOnly: boolean;
|
|
127
|
+
private constructor();
|
|
128
|
+
/** Creates `.engram/` with a fresh agent signing key and master key. */
|
|
129
|
+
static init(agent: string, opts: OpenOptions): Engram;
|
|
130
|
+
static open(opts: OpenOptions): Engram;
|
|
131
|
+
get agent(): string;
|
|
132
|
+
get publicKey(): string;
|
|
133
|
+
/** Signs with the agent key (commits and receipts). */
|
|
134
|
+
protected signRaw(message: string): string;
|
|
135
|
+
/** Records a raw event, encrypted with its own key. Stored locally; `push()` uploads it. */
|
|
136
|
+
observe(input: ObserveInput): Episode;
|
|
137
|
+
episodes(): Episode[];
|
|
138
|
+
episode(id: string): Episode | null;
|
|
139
|
+
/** Decrypts an episode. Returns null if it was forgotten. Throws if it was tampered with. */
|
|
140
|
+
read(id: string): EpisodeContent | null;
|
|
141
|
+
/** Every version of every belief, oldest first. */
|
|
142
|
+
beliefVersions(): Belief[];
|
|
143
|
+
/** Latest version of each belief, including retracted ones. */
|
|
144
|
+
latestBeliefs(): Belief[];
|
|
145
|
+
/** The beliefs that currently guide the agent. */
|
|
146
|
+
beliefs(): Belief[];
|
|
147
|
+
/** A belief by "b_x" (latest) or "b_x@2" (exact version). */
|
|
148
|
+
belief(ref: string): Belief | null;
|
|
149
|
+
/** All versions of one belief, oldest first. */
|
|
150
|
+
history(id: string): Belief[];
|
|
151
|
+
/** Episodes that `sleep()` has not processed yet (forgotten ones are skipped). */
|
|
152
|
+
pendingEpisodes(): Episode[];
|
|
153
|
+
/**
|
|
154
|
+
* Consolidation: new episodes + current beliefs → belief changes, via the LLM.
|
|
155
|
+
* Every change is a new immutable belief version with evidence and a reason.
|
|
156
|
+
*/
|
|
157
|
+
sleep(opts: SleepOptions): Promise<SleepReport>;
|
|
158
|
+
/** Applies one belief change. Exposed so users (and tests) can edit beliefs by hand. */
|
|
159
|
+
applyOp(op: BeliefOp): Belief;
|
|
160
|
+
/**
|
|
161
|
+
* Beliefs relevant to a task. Uses Walrus Memory semantic recall over pushed
|
|
162
|
+
* beliefs, then falls back to keyword matching for anything not pushed yet.
|
|
163
|
+
*/
|
|
164
|
+
relevant(query: string, limit?: number): Promise<Belief[]>;
|
|
165
|
+
/** Current commit ID, or null before the first commit. */
|
|
166
|
+
head(): string | null;
|
|
167
|
+
getCommit(id: string): Commit | null;
|
|
168
|
+
/** IDs of forgotten episodes, sorted. */
|
|
169
|
+
tombstones(): string[];
|
|
170
|
+
/**
|
|
171
|
+
* Snapshot of the current beliefs: push pending data, build the Merkle root,
|
|
172
|
+
* sign the manifest, store it on Walrus Memory and look up its Sui anchor.
|
|
173
|
+
*/
|
|
174
|
+
commit(message: string, opts?: {
|
|
175
|
+
allowEmpty?: boolean;
|
|
176
|
+
}): Promise<Commit>;
|
|
177
|
+
/** Looks up (or retries looking up) the Sui anchor of a commit. */
|
|
178
|
+
anchor(id: string): Promise<Commit>;
|
|
179
|
+
/** Commits from HEAD back to the first one. */
|
|
180
|
+
log(from?: string): Commit[];
|
|
181
|
+
/**
|
|
182
|
+
* Resolves "HEAD", "HEAD~2", a full or short (≥4 chars) commit ID, or a
|
|
183
|
+
* date ("2026-10-25") → the last commit made at or before it.
|
|
184
|
+
*/
|
|
185
|
+
resolve(ref: string): string;
|
|
186
|
+
/** The beliefs the agent had at a commit — time travel. */
|
|
187
|
+
beliefsAt(ref: string): Belief[];
|
|
188
|
+
/** What changed between two commits (or a commit and the working beliefs when `to` is omitted). */
|
|
189
|
+
diff(from: string, to?: string): BeliefDiff;
|
|
190
|
+
/**
|
|
191
|
+
* Binary search over history: given a commit where the agent behaved well
|
|
192
|
+
* and a later one where it didn't, finds the first bad commit. `isBad`
|
|
193
|
+
* receives the beliefs at a commit (time travel) — run the agent's test there.
|
|
194
|
+
*/
|
|
195
|
+
bisect(opts: {
|
|
196
|
+
good: string;
|
|
197
|
+
bad: string;
|
|
198
|
+
isBad: (beliefs: Belief[], commit: Commit) => Promise<boolean> | boolean;
|
|
199
|
+
}): Promise<BisectResult>;
|
|
200
|
+
/** The episodes behind a belief version, decrypted where possible. */
|
|
201
|
+
blame(ref: string): {
|
|
202
|
+
belief: Belief;
|
|
203
|
+
history: Belief[];
|
|
204
|
+
evidence: BlameEntry[];
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* In a read-only repo rebuilt from an audit bundle the raw episodes aren't
|
|
208
|
+
* present (they stay with the agent). Commits still record each evidence
|
|
209
|
+
* episode's Walrus blob ID, so blame can point at it.
|
|
210
|
+
*/
|
|
211
|
+
private sharedEpisodeStub;
|
|
212
|
+
/**
|
|
213
|
+
* Records a signed receipt for a decision: which committed beliefs it used,
|
|
214
|
+
* with Merkle proofs that they were in the HEAD commit.
|
|
215
|
+
*/
|
|
216
|
+
decide(input: DecideInput): Receipt;
|
|
217
|
+
/**
|
|
218
|
+
* The runtime hook: gives `fn` the committed beliefs relevant to `task`,
|
|
219
|
+
* then records a signed receipt for what it decided and which beliefs it used.
|
|
220
|
+
* Before the first commit, `fn` gets no beliefs and no receipt is written.
|
|
221
|
+
*/
|
|
222
|
+
act<T>(task: {
|
|
223
|
+
query: string;
|
|
224
|
+
input: unknown;
|
|
225
|
+
limit?: number;
|
|
226
|
+
}, fn: (beliefs: Belief[]) => Promise<{
|
|
227
|
+
action: string;
|
|
228
|
+
used: string[];
|
|
229
|
+
result: T;
|
|
230
|
+
}> | {
|
|
231
|
+
action: string;
|
|
232
|
+
used: string[];
|
|
233
|
+
result: T;
|
|
234
|
+
}): Promise<{
|
|
235
|
+
result: T;
|
|
236
|
+
action: string;
|
|
237
|
+
receipt: Receipt | null;
|
|
238
|
+
beliefs: Belief[];
|
|
239
|
+
}>;
|
|
240
|
+
receipts(): Receipt[];
|
|
241
|
+
receipt(id: string): Receipt | null;
|
|
242
|
+
/**
|
|
243
|
+
* Checks a commit end to end: ID, signature, Merkle root rebuilt from the
|
|
244
|
+
* beliefs, the parent chain, the manifest on Walrus Memory, and the Sui anchor.
|
|
245
|
+
*/
|
|
246
|
+
verifyCommit(ref: string, opts?: VerifyOptions): Promise<VerifyReport>;
|
|
247
|
+
/** Checks a receipt: its signature, each belief's Merkle proof, then the commit it points at. */
|
|
248
|
+
verifyReceipt(id: string, opts?: VerifyOptions): Promise<VerifyReport>;
|
|
249
|
+
/**
|
|
250
|
+
* Crypto-shredding: destroys the episode's key so its ciphertext (local and
|
|
251
|
+
* on Walrus) can never be decrypted again. Beliefs that relied on it lose
|
|
252
|
+
* that evidence — and are retracted if nothing else supports them. The next
|
|
253
|
+
* commit records a tombstone.
|
|
254
|
+
*/
|
|
255
|
+
forget(episodeId: string, reason?: string): ForgetResult;
|
|
256
|
+
/** Uploads everything not yet on Walrus Memory and records the blob IDs. */
|
|
257
|
+
push(): Promise<PushResult>;
|
|
258
|
+
}
|
|
259
|
+
/** How a belief is written to Walrus Memory: readable statement first (for semantic recall), then the full record. */
|
|
260
|
+
export declare function beliefText(b: Belief): string;
|
|
261
|
+
/** Returns "id@version" from a belief text, or null if it isn't one. */
|
|
262
|
+
export declare function parseBeliefText(text: string): string | null;
|
|
263
|
+
/** How a commit is written to Walrus Memory. */
|
|
264
|
+
export declare function commitText(id: string, manifest: CommitManifest, signature: string): string;
|
|
265
|
+
/** How a receipt is written to Walrus Memory. */
|
|
266
|
+
export declare function receiptText(r: Receipt): string;
|