How the Blob Artifact System Handles Large Object Storage in Oh‑My‑Pi (OMP)

The blob artifact system externalizes large binary payloads into a content‑addressed SHA‑256 store, replacing base64 data with compact blob:sha256: references to keep session JSONL files small and enable automatic cross‑session deduplication.

The omp (Oh‑My‑Pi) coding agent manages conversation sessions as JSONL files that can grow unwieldy when image data is embedded as base64 strings. According to the source code in can1357/oh-my-pi, the blob artifact system solves this by moving payloads exceeding 1024 bytes into a global, immutable blob store while preserving lightweight references in the session log.

Content‑Addressed Storage Architecture

SHA‑256 Hashing and File Layout

At the core of the system is BlobStore, implemented in packages/coding-agent/src/session/blob-store.ts. When writing data, BlobStore.put (or its synchronous variant putSync) computes a SHA‑256 hash over the raw bytes and writes the content to <blobsDir>/<hash>. The method returns a structured reference string in the format blob:sha256:<hex‑hash>.

import { BlobStore } from "@oh-my-pi/pi-utils";

const store = new BlobStore("/home/user/.omp/agent/blobs");
const result = store.putSync(Buffer.from(bigBinary));

console.log(result.ref); // → "blob:sha256:9f2d..."

Because the filename is deterministically derived from content, identical binaries automatically map to the same filesystem location, guaranteeing deduplication without additional indexing.

Global Storage Directory

Blobs reside in a global directory (~/.omp/agent/blobs/ by default) that is shared among all sessions. As configured in SessionManager, the BlobStore instance uses getBlobsDir() to locate this path, meaning no per‑session copies are created when forking or resuming conversations.

Externalization Workflow During Persistence

Threshold Detection

When persisting a session entry, SessionManager.prepareEntryForPersistence scans the message’s content array for image blocks. The system triggers externalization when:

  • The block’s data string is a base64 image ≥ 1024 bytes (BLOB_EXTERNALIZE_THRESHOLD)
  • The block contains a provider image_url using a data:image/...;base64, data‑URL

These checks occur in packages/coding-agent/src/session/session-manager.ts around lines 77‑92.

Blob Storage and Reference Replacement

Once triggered, the payload is handed to BlobStore.put. The original base64 string or data‑URL is then rewritten to the blob:sha256:<hash> reference before the entry is appended to the JSONL file. This keeps each session line compact while maintaining a stable, content‑addressed identifier.

import { externalizeImageData } from "@oh-my-pi/pi-utils";

// Inside prepareEntryForPersistence
if (msg.content?.[i]?.type === "image") {
  const data = msg.content[i].data; // base64 string
  const ref = await externalizeImageData(blobStore, data);
  msg.content[i].data = ref;        // replace with blob:sha256:…
}

Rehydration on Session Load

Resolving Blob References

When loading a session, SessionManager.resolveBlobRefsInEntries scans entries for strings prefixed with blob:. For each match, it extracts the hash and calls BlobStore.get(hash) to retrieve the stored bytes from packages/coding-agent/src/session/blob-store.ts.

Data Reconstruction

The system handles two reconstruction paths:

  • Image blocks: Raw bytes are re‑encoded to base64 for the consumer
  • Data‑URLs: Bytes are returned as the original UTF‑8 string

If the blob file is missing, omp logs a warning and leaves the reference untouched, preventing a hard crash while preserving data integrity.

import { resolveImageData } from "@oh-my-pi/pi-utils";

const data = entry.content[i].data; // may be blob ref
const base64 = await resolveImageData(blobStore, data);

// base64 now contains the original image data (or original ref if missing)
entry.content[i].data = base64;

Deduplication and Immutability Guarantees

The use of content addressing provides several operational benefits:

  • Write idempotency: Calling put or putSync multiple times with identical data results in the same hash and filename, making the operation safe to repeat
  • Cross‑session sharing: Because blobs are stored globally, different sessions that process the same image (e.g., a common screenshot) reference the same physical file
  • Immutability: Once written to <blobsDir>/<hash>, blob files are never modified; new content receives a new hash, ensuring historical session files remain valid

Summary

  • Content addressing: SHA‑256 hashes identify blobs stored as flat files in ~/.omp/agent/blobs/
  • Externalization threshold: Base64 payloads ≥ 1024 bytes or data‑URLs are moved to the blob store
  • Reference format: Session files contain blob:sha256:<hash> instead of raw binary data
  • Rehydration: BlobStore.get retrieves bytes on load, converting back to base64 or UTF‑8 as needed
  • Global deduplication: Identical content across sessions maps to a single physical file

Frequently Asked Questions

What is the size threshold for blob externalization in Oh‑My‑Pi?

The BLOB_EXTERNALIZE_THRESHOLD constant is set to 1024 bytes according to docs/blob-artifact-architecture.md. Any base64 image data or data‑URL exceeding this length is automatically externalized to the blob store during the prepareEntryForPersistence phase.

How are blob references formatted inside session JSONL files?

Persisted references use the literal string format blob:sha256:<hex‑hash> (for example, blob:sha256:9f2d4c…). These references are resolved internally by SessionManager and are not treated as URLs by the application router.

Where does Oh‑My‑Pi physically store blob artifacts?

Blobs are stored in a global directory defaulting to ~/.omp/agent/blobs/. The path is determined by getBlobsDir() and shared across all sessions, enabling deduplication when the same binary content appears in different conversation histories.

What happens if a session references a blob that no longer exists on disk?

If BlobStore.get fails to locate the file for a referenced hash, the system logs a warning and returns the original blob:sha256: reference string unchanged. This graceful degradation prevents session loading from crashing while alerting the user to the missing artifact.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →