ALLM.Pipeline.Artifacts.S3 (allm_pipeline v0.1.0)

Copy Markdown View Source

S3 ALLM.Pipeline.Artifacts adapter — the large-tier backend for artifacts that do not fit a DynamoDB item.

Speaks s3://<bucket>/<key> URLs. The wrapper (ALLM.Pipeline.ArtifactStore) still owns compression, checksum and size accounting; this adapter stores the already-encoded payload verbatim as an object, and records the caller's checksum / size_bytes / compressed flag as object metadata so fetch/1 can hand them back and ArtifactStore knows whether to gunzip.

Optional dependency

ex_aws_s3 is an optional dependency of this package (mix.exs), matching ex_aws / ex_aws_dynamo: a host that configures a different artifact adapter need not carry it. Every entry point therefore checks Code.ensure_loaded?/1 and returns {:error, :s3_unavailable} when the dep is absent — the same posture as ALLM.Pipeline.Artifacts.Dynamo.available?/0. The package compiles and its non-S3 tests pass without the dep loaded.

Configuration

Resolved at RUNTIME (a mix release build never evaluates config/runtime.exs, so the bucket cannot be baked at compile time):

config :allm_pipeline, ALLM.Pipeline.Artifacts.S3,
  bucket: "my-artifacts",
  # optional — a MinIO/localstack endpoint for local dev/test; unset in prod
  endpoint: "http://host.docker.internal:4026",
  region: "us-east-1"

When :endpoint is set the adapter threads a per-request host/port/scheme override into ExAws.request/2, so no global config :ex_aws, :s3 is needed and MinIO and real S3 can coexist. Credentials come from the standard config :ex_aws keys the rest of the app already uses.

Object layout

  • Object key: the artifact id verbatim ("<step_log_id>" or "<step_log_id>:llm") — both are valid S3 keys.
  • Object metadata: checksum, size_bytes, compressed (string-encoded).
  • content_type is the S3 object's Content-Type.

Summary

Functions

Whether the S3 adapter is configured — ex_aws_s3 is loaded and a bucket is named. Mirrors ALLM.Pipeline.Artifacts.Dynamo.available?/0. Configuration only; see reachable?/0 for whether the backend actually answers.

The configured artifacts S3 bucket, resolved at runtime. nil when unset — put/4 then refuses rather than writing to an unnamed bucket.

The ExUnit tags to exclude when S3/MinIO is unreachable, plus an operator hint. Mirrors ALLM.Pipeline.Artifacts.Dynamo.exclusions/0. Returns {[], nil} when the backend answers.

Whether the configured S3 backend actually answers — the probe the live round-trip test gates on. A head_bucket that returns any HTTP response (including 404 for a not-yet-created bucket) means the server is up; a connection error or a raise means it is not.

Functions

available?()

@spec available?() :: boolean()

Whether the S3 adapter is configured — ex_aws_s3 is loaded and a bucket is named. Mirrors ALLM.Pipeline.Artifacts.Dynamo.available?/0. Configuration only; see reachable?/0 for whether the backend actually answers.

bucket()

@spec bucket() :: String.t() | nil

The configured artifacts S3 bucket, resolved at runtime. nil when unset — put/4 then refuses rather than writing to an unnamed bucket.

exclusions()

@spec exclusions() :: {[atom()], String.t() | nil}

The ExUnit tags to exclude when S3/MinIO is unreachable, plus an operator hint. Mirrors ALLM.Pipeline.Artifacts.Dynamo.exclusions/0. Returns {[], nil} when the backend answers.

reachable?()

@spec reachable?() :: boolean()

Whether the configured S3 backend actually answers — the probe the live round-trip test gates on. A head_bucket that returns any HTTP response (including 404 for a not-yet-created bucket) means the server is up; a connection error or a raise means it is not.