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
datastring is a base64 image ≥ 1024 bytes (BLOB_EXTERNALIZE_THRESHOLD) - The block contains a provider
image_urlusing adata: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
putorputSyncmultiple 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.getretrieves 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →