Skip to content

Memory drivers ​

Memory drivers provide named persistence surfaces declared in workspace memory configuration.

Package contract ​

Create a trusted driver package under workspace/drivers/memory/<name>/.

manifest.yaml:

yaml
apiVersion: 1
kind: memory
type: kv-json
entrypoint: ./driver.ts

The type must match the type used in config/memories.yaml.

Driver implementation ​

Export a MemoryDriverDefinition from the entrypoint file.

driver.ts:

ts
import { promises as fs } from "node:fs";
import path from "node:path";
import type {
  KeyValueMemory,
  MemoryDriverDefinition,
  WorkflowMemoryTarget,
} from "@faimulus/driver-sdk";

interface MemoryConfig {
  filePath: string;
}

class JsonKeyValueMemory implements KeyValueMemory {
  readonly kind = "key-value" as const;

  constructor(private readonly filePath: string) {}

  private async readStore(): Promise<Record<string, unknown>> {
    try {
      const raw = await fs.readFile(this.filePath, "utf8");
      return JSON.parse(raw) as Record<string, unknown>;
    } catch {
      return {};
    }
  }

  private key(target: WorkflowMemoryTarget, key: string): string {
    const scope =
      target.scope === "session" ? (target.sessionId ?? "session") : "named";
    return `${target.name}:${scope}:${key}`;
  }

  async read(target: WorkflowMemoryTarget, key: string): Promise<unknown> {
    const store = await this.readStore();
    return store[this.key(target, key)];
  }

  async write(
    target: WorkflowMemoryTarget,
    key: string,
    value: unknown,
  ): Promise<void> {
    const store = await this.readStore();
    store[this.key(target, key)] = value;
    await fs.mkdir(path.dirname(this.filePath), { recursive: true });
    await fs.writeFile(this.filePath, JSON.stringify(store, null, 2), "utf8");
  }
}

const definition: MemoryDriverDefinition<MemoryConfig> = {
  type: "kv-json",
  kind: "key-value",
  displayName: "JSON key/value",
  supportedScopes: ["named", "session"],
  configSchema: {
    type: "object",
    additionalProperties: false,
    required: ["filePath"],
    properties: {
      filePath: { type: "string", minLength: 1 },
    },
  },
  async createMemory(config, context) {
    const resolved = path.resolve(context.workspaceRoot, config.filePath);
    return new JsonKeyValueMemory(resolved);
  },
};

export default definition;

Workspace configuration ​

Add a memory definition that references the driver type.

config/memories.yaml:

yaml
version: 1
memories:
  session-cache:
    type: kv-json
    description: Session-scoped cache
    config:
      filePath: data/memory/session-cache.json

Startup and verification ​

  1. Restart the server so startup discovery recompiles and loads the driver.
  2. Verify registration through GET /api/memory/drivers.
  3. Verify runtime behavior by reading and writing through a workflow node that targets this memory.

Documentation for the current repository state.