Runtime artifacts¶
AbstractRuntime stores large payloads as artifacts so run state, ledger records, and workflow outputs remain JSON-safe. Artifacts are the durable record for files, generated media, tool evidence, exported history bundles, and other payloads that should be referenced by id rather than embedded inline.
The implementation lives in src/abstractruntime/storage/artifacts.py.
File-like vocabulary boundary¶
Runtime artifacts are not the same thing as live filesystem paths:
Artifact: a Runtime-owned durable payload safe to persist, search, reuse, and pass between runs by reference.Workspace File/Workspace Folder: a server-side path capability under Gateway/runtime workspace policy. These are path values, not durable payloads.Local File/Local Folder: a client-side intake source. In hosted/browser mode they should be uploaded and normalized into artifacts before durable execution.
Gateway/Flow product copy may say Server File / Server Folder when users
choose an origin, but Runtime stays anchored on artifact refs versus
workspace-scoped paths.
Artifact identity¶
An artifact has a stable artifact_id, a blob_id for content deduplication
when the backend supports it, and a run_id scope. JSON state and Gateway APIs
pass artifacts with refs such as:
{
"$artifact": "a7050ebc5c8330...",
"artifact_id": "a7050ebc5c8330...",
"run_id": "9e19bd6a-ba07-4c2e-86c6-94ec7ca0a373",
"content_type": "audio/wav",
"size_bytes": 5293012
}
The ref is a pointer, not authorization. Hosts such as AbstractGateway are responsible for deciding which principal may list or read an artifact.
Stored metadata¶
Runtime stores two metadata layers:
tags: string fields for compatibility and simple lookups.metadata: structured JSON for producer-specific details.descriptor: a Runtime-ownedArtifactDescriptorthat normalizes the fields Gateway and Observer should use.
The descriptor separates display format from semantic meaning:
render_kind: how the artifact should be rendered, such asimage,audio,video,markdown,html,json,text, ordocument.semantic_kind: what the artifact represents, such asvoice,music,sound,transcript,evidence,workflow_snapshot, orimage.classification_source: whether the classification came from the producer, runtime tags, MIME inference, or legacy fallback.
The descriptor can also carry session_id, workflow_id, node_id, turn_id,
ledger_cursor, producer, generation, media, source_refs, links,
security, and action metadata. Producer metadata may be sparse; consumers
should show missing fields as unavailable rather than guessing.
Generated media provenance¶
When generated media is produced through the Runtime AbstractCore integration with output selectors, Runtime stores descriptor and metadata alongside the bytes. Current generated outputs include image, video, voice/TTS, music, sound or audio outputs, and transcription-style text outputs where the host route stores a transcript artifact.
Generated-media descriptors record available producer facts:
- package/capability route, provider, model, backend, and runtime provider/model when they differ;
- prompt or TTS text, requested format, output index, negative prompt, and redacted generation parameters;
- source artifact refs for edit, image-to-video, cloned/reference voice, or other source-media flows when provided;
- measured media facts such as duration, sample rate, dimensions, channels, or frame counts when the store can inspect the bytes.
Runtime redacts obvious secret fields and bounds large metadata values. It does not store raw provider requests as indexed descriptor fields.
Gateway or package producers that store artifacts outside the main Runtime
generated-media path should use build_artifact_descriptor_payload(...) from
abstractruntime.storage.artifacts. That helper applies the Runtime descriptor
schema, bounded secret-key redaction, and prompt/text sensitivity labels without
making Gateway invent a parallel descriptor contract.
Tool-output offload¶
Large tool outputs are stored as session artifacts instead of being carried
inline in prompts and ledger records. The agent keeps a bounded preview plus an
open_attachment handle, so full content stays retrievable on demand while the
durable record stays lean.
Offload applies to:
read_filecontent above the inline threshold;execute_commandstdoutandstderr, regardless of exit code (verbose failures are offloaded like verbose successes);- any other host tool whose string output exceeds the inline threshold;
- any other host tool whose structured (dict) output exceeds the inline threshold as JSON: its largest string
values, at any depth, are stored one by one (largest first) until the output fits, each replaced by
{"$artifact": id, "offloaded": true, "bytes": n, "open": "open_attachment(...)"}; when many small values make it too large, the whole output is stored as one JSON attachment and replaced by its reference. The result lists the stored ids inoutput_offloaded_artifact_ids, and reading the run back resolves the references.
Thresholds (environment-configurable):
ABSTRACTRUNTIME_MAX_INLINE_BYTES(default 256 KiB): outputs at or below this size stay inline.ABSTRACTRUNTIME_MAX_ATTACHMENT_BYTES(default 50 MB): the retention cap for offloaded outputs.
Output above the retention cap is not stored and is never kept inline. The tool
result carries an explicit notice stating the size, the cap, and how to proceed
(narrow the command, for example with head or grep, or redirect to a file
and read a bounded range). The decision on how to proceed belongs to the agent
or user; the runtime never drops output silently.
Catalog and search¶
InMemoryArtifactStore and FileArtifactStore support:
store(...),load(...), andget_metadata(...);update_metadata(...)for descriptor or structured metadata enrichment;search(...)for bounded pages;count(...),facet_counts(...), andstats(...)for exact totals and filter chips;record_access(...)for explicit metadata/content/preview/download/export counters.
FileArtifactStore maintains a repairable SQLite catalog for descriptor fields,
time filters, exact counts, byte totals, and facets. The catalog is an index of
Runtime-owned artifact metadata; the payload bytes and metadata files remain the
source of truth.
Plain load(...) and get_metadata(...) are side-effect free. UI and HTTP
layers that want access statistics must call record_access(...) or use Gateway
content routes that label the action.
Gateway and Observer¶
AbstractGateway exposes Runtime artifacts through bounded HTTP APIs. Search
responses include artifact_envelope_v1, which projects Runtime descriptors,
media facts, access stats, and action links while preserving legacy row fields.
Gateway only forwards descriptor action links that are relative Gateway/UI
links; arbitrary external provider URLs should be represented as trace
availability or Gateway-owned trace records instead.
AbstractObserver renders Gateway envelopes. It should not infer canonical artifact meaning from filenames or raw content except as a visible legacy fallback. Use the Runtime tab for artifact inventory and the Observe tab for the workflow/ledger narrative.
Retrieval boundaries¶
Artifact search answers questions about stored files and media by metadata, scope, type, time, producer, and links back to runs. It is not a semantic memory search system.
- Use the ledger for "what happened in this workflow?"
- Use artifact search for "what files/media exist and how were they produced?"
- Use AbstractMemory/KG retrieval for "what knowledge or relationships were learned?"
- Use Gateway audit/provider links for system-level request traces when the envelope reports them.
Limits¶
Legacy artifacts may only have MIME type and tags. Runtime projects them with fallback descriptor fields so clients can still list and preview them, but producer-level prompt/model/source provenance is only available for artifacts created through descriptor-aware paths.