TS · 09

Engram - shared memory

The full Engram subsystem is ported: the abstract Engram contract, the InMemoryEngram / SqliteEngram / PostgresEngram backends, EngramBinding, and EngramClient. The concepts (addressing, the five invariants, the RECALL / IMPRINT wire signals) are covered in the Engram reference - this section shows the TypeScript surface.

The Engram contract & backends

engram.ts
// One Engram wraps one backend and owns its own schema.
abstract class Engram {
  abstract engramId: string;
  abstract engramKind: string;
  abstract capabilities: string[];
  version: string | null;

  abstract connect(): Promise<void>;
  abstract close(): Promise<void>;

  // Return matching entries. Empty array on a miss; never throw on a miss.
  abstract recall(query: Json, opts?: RecallOptions): Promise<Hit[]>;
  // op: "add" | "append" | "merge" | "upsert" | "delete"
  abstract imprint(op: ImprintOp, entry: Json, opts?: ImprintOptions): Promise<ImprintReceipt>;
  // Return false to decline a query. Default: serve all.
  canServe(query: Json): Promise<boolean>;
}

// Bundled backends (constructor inits mirror Python):
new InMemoryEngram({ engramId: "engram-memory", engramKind: "keyvalue" });
new SqliteEngram({ path: "notes.db", engramId: "notes-default" });    // needs better-sqlite3
new PostgresEngram({ dsn: "postgresql://user:pw@host/db" });           // needs pg

Wiring memory into an Axon

An EngramBinding whitelists which Engrams a Neuron may address, by a stable local name. Unlike Python - where the SDK injects recall= / imprint= keyword arguments - the TS helpers arrive as the NeuronFn’s optional third argument.

binding.ts
import { Axon, EngramBinding } from "@cosmonapse/sdk";

// The helpers ride a context object as the NeuronFn's optional THIRD
// argument (JS cannot introspect parameter names like Python kwargs):
const summariser: NeuronFn = async (input, context, helpers) => {
  const prior = await helpers.recall("notes", {
    query: { text: input.topic },
    filters: { tags: ["kept"] },
    deadlineMs: 200,
    recallMode: "first",
    minConfidence: 0.5,
  });

  const note = "summary of " + input.topic;

  await helpers.imprint("notes", {
    op: "append",
    entry: { key: input.topic, value: note },
    awaitAck: false,                    // fire-and-forget by default
  });
  return { summary: note };
};

const axon = new Axon({
  neuronId: "summariser",
  neuronFn: summariser,
  engrams: [
    // Addressed routing  -  the Neuron says recall("notes", ...)
    new EngramBinding({ name: "notes", directedId: "notes-default" }),
    // Slot routing  -  deployment owns the concrete impl behind a kind
    new EngramBinding({
      name: "memory",
      directedType: "semantic",
      defaultDeadlineMs: 250,
      defaultRecallMode: "merge",      // "first" | "merge" | "all"
    }),
  ],
});

Hosting & Dendrite-side access

attachEngram() mounts a backend on a Dendrite; dendrite.recall() / dendrite.imprint() give any peer direct access over the same RECALL / IMPRINT signals. Failures throw EngramError subclasses ( EngramTimeout, EngramNotBound, EngramOverloaded, EngramCancelled).

host.ts
import { Dendrite, InMemoryEngram, connectSynapse } from "@cosmonapse/sdk";

const synapse = await connectSynapse("cosmo://127.0.0.1:7070");
const host = new Dendrite({ synapse, namespace: "prod" });

// Mount an Engram  -  it announces itself with REGISTER and serves
// RECALL / IMPRINT addressed to its engramId or engramKind.
await host.attachEngram(new InMemoryEngram({ engramId: "ctx" }));
await host.start();

// Any Dendrite can read / write directly (EngramClient under the hood):
const hits = await host.recall({
  engramId: "ctx",                     // OR engramKind  -  id wins
  query: { key: "user-42" },
});
await host.imprint({
  engramId: "ctx",
  op: "upsert",
  entry: { key: "user-42", value: { plan: "pro" } },
  awaitAck: true,                      // resolve with the ImprintReceipt
});

// Observability  -  watch Engram traffic on the bus:
host.onRecalled((sig) => console.log("hits:", sig.payload.hits));
host.onImprinted((sig) => console.log("receipt:", sig.payload.receipt));

Have a feature in mind?

The protocol, SDKs, and CLI are still pre-1.0. If something here is missing, ambiguous, or wrong - open an issue and propose a change. Every breaking change is debated in DECISIONS.md first.