runpod-doc-worker
Guides

Declare output artifacts

Map engine-written files to validated text, JSON, and base64 response fields with an artifact manifest.

An artifact manifest describes which files an engine writes and how selected files become inline response values.

from pathlib import Path

from runpod_doc_worker.contract.artifacts import Artifact, resolve

MANIFEST = (
    Artifact("markdown", ("{basename}.md",), kind="text"),
    Artifact(
        "blocks",
        ("{basename}_blocks.json",),
        kind="json",
        default=[],
    ),
    Artifact("images", ("images/*",), kind="b64map"),
)

result = resolve(
    MANIFEST,
    Path("/tmp/job-output"),
    basename="document",
    keys=["markdown", "blocks"],
)

Artifact kinds

KindResultDerived default
textUTF-8 string from one file""
jsonParsed JSON from one file{}
b64mapFilename to base64 string mapping{}

Defaults are copied for each read. Mutating one response does not change the next response.

Pattern behavior

Patterns are evaluated in declaration order. For text and json, the first pattern with a match wins and must match only one file. b64map collects every match and uses each filename as its response key.

{basename} is substituted safely. A basename cannot be empty, equal . or .., contain a path separator, or use glob metacharacters to select another document's output.

The package rejects:

  • duplicate manifest keys;
  • unknown requested keys;
  • single-value patterns that match more than one file;
  • duplicate filenames collected into one b64map;
  • matches that resolve outside output_dir.

Missing and unreadable files

A missing artifact returns its declared or derived default. Unreadable text or JSON also returns the default, and an unreadable b64map member is skipped while readable members remain in the result.

A default returned because no file matched is the artifact's declared normal absence and does not add a degradation report. A substitution caused by an unreadable or invalid matched file, and every skipped b64map member, is recorded in a degradation report as well as logged. Mark the artifact required when a no-match result must fail instead of looking like an empty value.

Filtering with keys omits other keys completely. It does not emit them with empty values.

Require the artifact the response exists for

Substituting a default is the right trade for part of a response and the wrong one for the whole point of it. Mark that artifact required and an absent or unreadable file raises ArtifactError instead:

Artifact("markdown", ("{basename}.md",), kind="text", required=True)

ArtifactError is a RuntimeError, not a ValueError, so a worker can tell bad engine output apart from the manifest being declared wrong. Two declarations are refused: required on a b64map, which has no single file to require, and required alongside an explicit default, which could never be read.

Requiring one artifact does not change the others. A required artifact that a caller filtered out with keys is not read and cannot raise.

Archives use the output directory

Artifact patterns control inline extraction. Archive transports package the complete output directory instead of using the manifest as an archive allowlist. A required pattern still selects the file that must be present in the completed archive; an unsafe, unreadable, or invalid selected member makes packaging fail.

Continue with result packaging.

On this page