How Artifact Stores Work in aisuite for Persisting Generated Outputs

aisuite uses a lightweight artifact store abstraction to store large data payloads—such as command-line output, file contents, or model-generated text—outside of trace messages, preventing trace bloat while enabling efficient retrieval.

The aisuite framework implements a clean separation between trace metadata and bulky generated outputs. This article explains how artifact stores work, drawing directly from the source code in andrewyng/aisuite.

Core Concepts and Data Structures

Three foundational classes define the artifact system in aisuite/agents/artifact_store.py:

ArtifactRef: The Lightweight Pointer

An ArtifactRef is a JSON-serializable reference that gets embedded directly in trace messages. According to the source at lines 14-21, it stores:

  • artifact_id: Unique identifier for retrieval
  • uri: Location hint for the stored data
  • media_type: MIME type describing the content
  • size: Byte length of the payload
  • metadata: Optional dictionary for additional context

Artifact: The Payload Container

The Artifact class (lines 44-50) wraps the actual binary data with its reference and creation timestamp. It provides convenient access methods:

  • .data: Raw bytes payload
  • .text(): Decoded string representation

ArtifactStore Protocol

Any artifact store must implement three operations defined at lines 54-66:

  • put(data, media_type, metadata=None) → ArtifactRef: Store payload, return reference
  • get(ref: ArtifactRef) → Artifact: Retrieve payload by reference
  • delete(ref: ArtifactRef) → None: Remove stored artifact

Built-in Artifact Store Implementations

InMemoryArtifactStore: Ephemeral Storage

The InMemoryArtifactStore (put implementation at lines 72-93) keeps artifacts in a Python dictionary keyed by artifact_id. This store is ideal for:

  • Unit tests requiring fast cleanup
  • Short-lived runs where persistence isn't needed
  • CI/CD environments without filesystem access

Artifacts evaporate when the process terminates—no cleanup required.

FileArtifactStore: Durable Persistence

The FileArtifactStore (put implementation at lines 15-35) provides production-grade persistence:

  • Each artifact gets its own directory under a configurable root (default: .aisuite/artifacts/)
  • Raw payload written to a data file
  • Reference and timestamp saved to metadata.json

This structure enables external tools to inspect artifacts without loading the full aisuite runtime.

The Artifact Lifecycle: Creation and Retrieval

How Artifacts Are Created

The dehydration process in aisuite/agents/artifacts.py converts large values into artifact references:

  1. Threshold detection: During message dehydration, values exceeding a configurable size limit trigger artifact creation
  2. Store invocation: The Context-supplied artifact_store receives the payload via artifactize_value, which calls artifact_store.put(data, media_type=…, metadata=…)
  3. Reference insertion: The returned ArtifactRef replaces the original value in the trace JSON, appearing as {"type":"artifact_ref","artifact_ref":{…}}

How Artifacts Are Retrieved

Hydration reverses the process:

  1. hydrate_value detects dictionaries with type=="artifact_ref"
  2. It calls artifact_store.get(ref) to fetch the full Artifact
  3. The caller accesses .text() or .data to recover the original content

This design keeps traces compact while preserving access to complete outputs.

Integration with aisuite Components

Runner: Orchestration Layer

aisuite/agents/runner.py manages de-/hydration around every tool execution. It ensures the same artifact_store instance handles both sides of the transformation, maintaining consistency across the execution boundary.

CLI and Viewer: User-Facing Access

The CLI (aisuite/cli/py/aisuite-code-cli/aisuite_code_cli/app.py) instantiates a FileArtifactStore from the --artifact-root argument. The viewer (aisuite/tracing/viewer.py) serves stored artifacts via an HTTP endpoint at /api/artifacts/<id>, enabling browser-based inspection of generated outputs.

Key Files Reference

File Purpose
aisuite/agents/artifact_store.py Core abstractions: ArtifactRef, Artifact, ArtifactStore protocol, and concrete implementations
aisuite/agents/artifacts.py De-/hydration logic: artifactize_value, hydrate_value
aisuite/agents/runner.py Execution wrapper applying artifact transformations
aisuite/cli/py/aisuite-code-cli/aisuite_code_cli/app.py CLI wiring for FileArtifactStore instantiation
aisuite/tracing/viewer.py HTTP server exposing artifacts to the web viewer

Summary

  • ArtifactRef provides a JSON-serializable pointer that keeps traces small
  • ArtifactStore protocol defines three required operations: put(), get(), delete()
  • Two implementations ship with aisuite: InMemoryArtifactStore for ephemeral use, FileArtifactStore for durable persistence
  • Automatic threshold-based dehydration in aisuite/agents/artifacts.py converts large values to references without manual intervention
  • CLI and viewer integration enables seamless artifact inspection via filesystem or HTTP

Frequently Asked Questions

What triggers artifact creation in aisuite?

Values larger than a configurable threshold during message dehydration are automatically converted to artifacts. The artifactize_value function in aisuite/agents/artifacts.py performs this detection and delegates to the context's artifact_store.put() method.

Can I implement a custom artifact store for cloud storage?

Yes. The ArtifactStore protocol at lines 54-66 requires only three methods. Implement put(), get(), and delete() with your preferred backend—S3, GCS, Azure Blob, or any object storage—and inject your store into the Context.

How does FileArtifactStore organize files on disk?

Each artifact receives a dedicated directory under the configured root. The raw bytes go to a data file; the ArtifactRef plus timestamp serialize to metadata.json. This human-readable structure supports external tooling and manual inspection.

Are artifacts automatically cleaned up?

The InMemoryArtifactStore loses all data on process exit. For FileArtifactStore, persistence is intentional—artifacts remain until explicitly deleted via store.delete(ref) or manual filesystem removal. The viewer's HTTP endpoint allows on-demand retrieval without loading the full trace.

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 →