# OpenMAIC Storage Layer Primitives: The 7 Core Building Blocks Explained

> Discover the 7 core OpenMAIC storage layer primitives including KV store, asset store, and document store. Understand the persistence foundation for higher level APIs.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: deep-dive
- Published: 2026-09-06

---

**The OpenMAIC storage layer provides seven primitives—**KV store**, **asset store**, **KV persistence helper**, **asset ID utilities**, **asset collection**, **document store**, and **runtime store**—that form the persistence foundation for all higher‑level APIs including documents, runtimes, and agents.**

OpenMAIC, the open‑source multimodal AI computing framework from THU‑MAIC, exposes these primitives through a single package entry point at `@openmaic/storage`. Each primitive defines a minimal, storage‑agnostic contract with multiple concrete backends (browser IndexedDB, HTTP API, PostgreSQL), allowing the DSL layer to remain completely decoupled from persistence details.

## The Seven Storage Primitives in OpenMAIC

The OpenMAIC storage layer is intentionally minimal. Each primitive specifies only the operations absolutely required for its domain. According to the source code in `packages/@openmaic/storage/src/index.ts` (lines 24–166), the complete surface area breaks down as follows:

### Key‑Value (KV) Store Primitive

The **KV store** is the most fundamental primitive: a generic `{key → value}` persistence seam. It defines the abstract contract `KVStore`, `DeviceSafeKVStore`, and `LocalKVStore` (line 24) with three core operations: `get`, `set`, and `remove`.

**Concrete implementations:**

- **`BrowserKVStore`** – IndexedDB backend for browser environments (line 26, `type BrowserKVStoreOptions`)
- **`HttpKVStore`** / **`HttpAccountKV`** – HTTP‑based account store for server‑side persistence (lines 28–33)

The KV store can live in the browser, on a server, or in PostgreSQL without changing consumer code.

### KV Persistence Helper Primitive

The **KV persistence helper** is a thin wrapper that makes any value **persistable** through a Zustand‑style API. Exported as `kvPersistStorage`, `PersistedValue`, and `PersistStorageLike` (lines 77–80), this primitive bridges reactive UI state with durable storage.

### Asset Store Primitive

The **asset store** handles large binary blobs—images, audio, video—behind a stable **AssetRef**. The DSL layer never sees raw bytes; it only manipulates opaque references. The store resolves these to usable URLs.

**Concrete implementations:**

- **`BrowserAssetStore`** – IndexedDB plus CDN pool backend (line 37, `type BrowserAssetStoreOptions`)
- **`HttpAssetStore`** – server‑side HTTP backend (lines 39–44, `type HttpAssetStoreOptions`)

The abstract contract `AssetStore` is defined at line 57.

### Asset ID Utilities Primitive

The **asset ID utilities** provide functions for creating and parsing the opaque identifiers used by the asset store. Exports include `newAssetId`, `toAssetId`, and the `AssetId` type (line 45). These utilities ensure consistent, collision‑resistant identifier generation across backends.

### Asset Collection Primitive

The **asset collection** primitive handles bulk operations and lifecycle management for assets. Key exports include `AssetCollector` and `assertSignedUrlTtlWithinGrace` along with default batch and grace settings (lines 68–74). This enables quota enforcement and storage reclamation without blocking the main application flow.

### Document Store Primitive

The **document store** persists full MAIC documents—folders, scenes, and stages. Core exports span `DocumentStore`, `MaicDocument`, `DocumentFolder`, and related types (lines 82–92).

**Three implementations match different deployment contexts:**

1. **`BrowserDocumentStore`** – client‑side IndexedDB persistence (line 100)
2. **`HttpDocumentStore`** – HTTP API backend (lines 101–107)
3. **`PgDocumentStore`** – PostgreSQL backend for production deployments (lines 109–115)

### Runtime Store Primitive

The **runtime store** holds transient runtime state: chat streams, incremental stage data, and session‑scoped ephemeral information. Exports include `RuntimeStore`, `RuntimeSessionInit`, and `RuntimeAppendOptions` (lines 117–124).

The **`BrowserRuntimeStore`** (line 125) provides the in‑browser implementation. Unlike document storage, runtime state is typically not persisted across sessions unless explicitly captured.

### Agent‑Session Primitives (Built on Core Primitives)

Higher‑level **agent‑session primitives** are exported from `@openmaic/storage` but composed from the KV and asset primitives above. These include `AgentSessionStore`, `AgentSessionLifecycle`, and `AgentSessionMaterialStore` (lines 128–166). They demonstrate how the core primitives enable complex, domain‑specific APIs without expanding the storage surface area.

## Instantiating OpenMAIC Storage Primitives: Code Examples

All primitives import from a single entry point:

```ts
import {
  BrowserKVStore,
  HttpKVStore,
  BrowserAssetStore,
  HttpAssetStore,
  BrowserDocumentStore,
  BrowserRuntimeStore,
  kvPersistStorage,
} from '@openmaic/storage';

```

### Browser‑Backed KV Store

```ts
import { BrowserKVStore } from '@openmaic/storage';

const kv = new BrowserKVStore({
  namespace: 'my-app',
  dbName: 'openmaic-db',  // optional: custom IndexedDB name
});

await kv.set('theme', 'dark');
const theme = await kv.get('theme');  // → 'dark'
await kv.remove('theme');

```

### Storing an Image Asset

```ts
import { BrowserAssetStore, newAssetId } from '@openmaic/storage';

const assetStore = new BrowserAssetStore({ namespace: 'my-assets' });

const ref = await assetStore.put(blob, {
  contentType: blob.type,
  uploadedBy: 'user123',
});

const url = await assetStore.resolve(ref);  // → 'blob:https://…'

```

### Persisting a Document

```ts
import { BrowserDocumentStore } from '@openmaic/storage';

const docStore = new BrowserDocumentStore({
  namespace: 'workspace',
  maxVersions: 10,  // optional: document versioning policy
});

const docId = await docStore.create({
  title: 'My Presentation',
  scenes: [],
});

const doc = await docStore.load(docId);

```

### Using the KV Persistence Helper

```ts
import { kvPersistStorage } from '@openmaic/storage';

const persist = kvPersistStorage({
  storage: new BrowserKVStore({ namespace: 'settings' }),
  key: 'user-preferences',
});

const [state, setState] = persist.useStore((s) => s);
setState({ language: 'en', showTips: true });

```

## Key Source Files in the OpenMAIC Storage Layer

| File | Purpose |
|------|---------|
| `packages/@openmaic/storage/src/index.ts` | Central re‑export hub listing every primitive |
| `packages/@openmaic/storage/src/kv/types.ts` | Abstract `KVStore` contract definition |
| `packages/@openmaic/storage/src/kv/browser.js` | `BrowserKVStore` IndexedDB implementation |
| `packages/@openmaic/storage/src/kv/http.js` | `HttpKVStore` HTTP backend |
| `packages/@openmaic/storage/src/asset/browser-store.js` | `BrowserAssetStore` implementation |
| `packages/@openmaic/storage/src/asset/http.js` | `HttpAssetStore` server backend |
| `packages/@openmaic/storage/src/document/browser.js` | `BrowserDocumentStore` client persistence |
| `packages/@openmaic/storage/src/runtime/browser.js` | `BrowserRuntimeStore` transient state |
| `packages/@openmaic/storage/src/asset/id.ts` | `AssetId` generation and parsing utilities |

## Summary

- **Seven core primitives** form the complete OpenMAIC storage layer: KV store, KV persistence helper, asset store, asset ID utilities, asset collection, document store, and runtime store.
- **Storage‑agnostic contracts** allow identical DSL code to run against IndexedDB, HTTP APIs, or PostgreSQL without modification.
- **Single import entry point** at `@openmaic/storage` exposes all primitives and their implementations.
- **Minimal surface area** per primitive—e.g., `KVStore` only requires `get`, `set`, `remove`—with backends free to add richer capabilities like content‑addressable storage and quota enforcement.

## Frequently Asked Questions

### What is the difference between KVStore and AssetStore in OpenMAIC?

**`KVStore`** handles small, structured key‑value data with synchronous‑style async operations. **`AssetStore`** manages large binary blobs through opaque `AssetRef` handles; the DSL never manipulates raw bytes directly. The asset store adds content‑type tracking, CDN resolution, and bulk collection semantics that would be inefficient for KV data.

### Can I use PostgreSQL instead of IndexedDB with OpenMAIC storage?

**Yes.** The document store provides `PgDocumentStore` (lines 109–115 in [`index.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/index.ts)) as a first‑class PostgreSQL backend. The KV and asset primitives similarly support HTTP‑based backends that can proxy to any server‑side database. Switching backends requires only changing the constructor call, not consumer code.

### How does `kvPersistStorage` relate to Zustand?

**`kvPersistStorage`** implements the `PersistStorageLike` interface expected by Zustand's persistence middleware. It wraps any `KVStore` instance to provide the subscribe‑and‑persist pattern reactive UIs require. This lets OpenMAIC storage primitives drop into existing Zustand‑based state management without adapter code.

### Are agent sessions stored in the runtime store or document store?

**Neither directly.** `AgentSessionStore` and related primitives (lines 128–166) are built on top of KV and asset primitives. Session lifecycle state, material references, and event logs are decomposed into appropriate underlying stores—transient runtime data to `RuntimeStore`, durable materials to `AssetStore`, and configuration to `KVStore`—rather than stored monolithically.