Skip to content

Asset Resolver

Resolve OpenAI asset pointers to actual files in export bundles.

Overview

OpenAI exports reference images and other assets via URI pointers (e.g., sediment://file_abc123). The asset resolver maps these pointers to actual files on disk using file ID matching and magic-byte MIME type detection.

ResolvedAsset

ResolvedAsset

Bases: BaseModel

resolve_asset

resolve_asset

resolve_asset(export_dir: Path, asset_pointer: str) -> ResolvedAsset | None

Resolve an asset pointer to a file in the export directory.

Parameters:

Name Type Description Default
export_dir Path

Directory containing export files

required
asset_pointer str

Asset URI (e.g., "sediment://file_abc123")

required

Returns:

Type Description
ResolvedAsset | None

ResolvedAsset with path and detected type, or None if not found

Source code in src/echomine/utils/asset_resolver.py
def resolve_asset(export_dir: Path, asset_pointer: str) -> ResolvedAsset | None:
    """Resolve an asset pointer to a file in the export directory.

    Args:
        export_dir: Directory containing export files
        asset_pointer: Asset URI (e.g., "sediment://file_abc123")

    Returns:
        ResolvedAsset with path and detected type, or None if not found
    """
    file_id = _extract_file_id(asset_pointer)
    if not file_id:
        return None

    for candidate in export_dir.iterdir():
        if candidate.is_file() and candidate.name.startswith(file_id):
            detected_type = _detect_mime_type(candidate)
            return ResolvedAsset(
                path=candidate.resolve(),
                detected_type=detected_type,
                original_extension=candidate.suffix,
                file_id=file_id,
            )

    return None

Supported Formats

Magic-byte detection supports the following formats:

Format MIME Type Signature
PNG image/png \x89PNG\r\n\x1a\n
JPEG image/jpeg \xff\xd8\xff
WebP image/webp RIFF....WEBP
GIF image/gif GIF87a or GIF89a
WAV audio/wav RIFF....WAVE

Unrecognized formats return application/octet-stream.

Usage Examples

Resolve Image Assets

from echomine.utils.asset_resolver import resolve_asset
from pathlib import Path

export_dir = Path("chatgpt_export/")

# Resolve a single asset pointer
asset = resolve_asset(export_dir, "sediment://file-abc123")
if asset:
    print(f"Path: {asset.path}")
    print(f"Type: {asset.detected_type}")       # e.g., "image/png"
    print(f"Extension: {asset.original_extension}")  # e.g., ".png"
    print(f"File ID: {asset.file_id}")           # e.g., "file-abc123"

Resolve All Images in a Conversation

from echomine import OpenAIAdapter
from echomine.utils.asset_resolver import resolve_asset
from pathlib import Path

adapter = OpenAIAdapter()
export_file = Path("chatgpt_export/conversations.json")
export_dir = export_file.parent

for conv in adapter.stream_conversations(export_file):
    for msg in conv.messages:
        for img in msg.images:
            asset = resolve_asset(export_dir, img.asset_pointer)
            if asset:
                print(f"[{conv.title}] {asset.detected_type}: {asset.path.name}")