You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Developers go from "I have a Python ML model" to a discoverable BYOC
capability on Livepeer in under 5 minutes — surfaced in the developer dashboard
ready for any caller to invoke.
The Pipeline SDK is the authoring surface that makes that possible:
write a Python class, get a containerised, BYOC-compatible,
schema-described capability.
A FastAPI + Pydantic-native authoring SDK delivered as a staircase
of small, shippable commits. Each step yields a working SDK that's
strictly more capable than the previous one. Status updated as work
lands.
Roadmap
C1 — Pipeline base + serve() + hello-world BYOC E2E
C2 — setup() lifecycle + HuggingFace sentiment example
C4 — Pydantic BaseModel for inputs/outputs via signature introspection (/docs shows real fields instead of additionalProp1)
C5 — Image upscale example (binary I/O via Pydantic Base64Bytes)
C6 — /health state machine (LOADING / OK / ERROR / IDLE) matching go-livepeer's HealthCheck wire format
C7 — SSE auto-detection from generator predict() + LLM chat example
C8 — LivePipeline for trickle transport (real-time video)
C9 — livepeer push CLI + livepeer.yaml manifest
C10 — Schema as Docker image label (org.livepeer.pipeline.schema)
C11 — Agent-friendly docs (AGENTS.md, expanded Pipeline docstring, examples/runner/_template/) so AI tooling and new contributors can scaffold pipelines without parsing the whole codebase
C12 — Migrate to monorepo with PEP 420 namespace packages: split into livepeer-runner (authoring SDK), livepeer-client (caller-side BYOC), livepeer-trickle (shared transport). User-facing imports become livepeer.runner.*, livepeer.client.*, livepeer.trickle.*. See Architecture: monorepo + namespace packages below for rationale and layout.
C13: Container self-registration to orch /capability/register — env-gated (ORCH_URL + ORCH_TOKEN), wired into serve() lifespan, lenient on failure (degrade /health, keep FastAPI serving so manual registration remains a fallback). Deregister on shutdown. Retry on conn-refused/timeout/5xx; fail fast on 400/404/405.
Architecture: monorepo + namespace packages
The repo will be reorganized into a uv workspace publishing three
distributions under a shared livepeer.* namespace.
Why monorepo (vs separate repos)
One team owns all packages — no cross-team coordination overhead
Atomic refactors across packages (BYOC contract changes touch both runner and client)
Shared transport code (livepeer.trickle) becomes a workspace dep, not a publish-and-depend dance
Future users of the client will also deploy pipelines — single resolution surface for pip install livepeer-runner livepeer-client
Single repo for issues, PRs, CI
Why namespace packages (vs flat package or extras)
No __init__.py at src/livepeer/ — that empty directory IS the
namespace marker (PEP 420 implicit namespace package). Each livepeer/X/__init__.py is a regular package. Adding an __init__.py
at the namespace level breaks cross-distribution discovery and has
historically bitten Airflow contributors. Add a CI check.
Tooling
uv workspaces — one lockfile, workspace-aware deps, per-package builds via uv build --package <name>
PyPI — three independent packages, can version sync or independent
CI — single GitHub Actions workflow with path filtering for per-package test/build/publish
Migration cost — ~1-2 days mechanical work (file moves, import updates, pyproject splits, CI adjustments)
Migration strategy
Clean break, no compatibility shim — the SDK is pre-1.0 and not yet
widely consumed externally. Coordinate with the in-flight fork to
contribute back upstream rather than maintain divergence.
Framework adapters (deferred — build on demand)
Migration paths for users from existing ML frameworks. Each ships as
its own pip package with its own foreign dep, isolated from core SDK.
Build only when a real migration ask shows up.
Future protocol work (cross-team, gated on C9 + upstream go-livepeer)
Cross-cutting changes to BYOC capability identity that span the SDK,
go-livepeer, and the spec. Tracked here so the SDK side is captured;
implementation lands once C9 (livepeer push) provides the publish
hook and upstream protocol changes are agreed.
Capability identity via OCI digest — replace free-form
capability names with content-hashed references like byoc/<repo>@sha256:<digest>. Aligns BYOC with Replicate's
reproducibility model: orchestrators advertise the digest, gateway
pins it, callers always invoke against an exact build. SDK side: livepeer push captures the digest at publish time and bakes it
into the manifest. Upstream side: orchestrator registration +
gateway routing + OrchestratorInfo carry the digest.
Cosign / Sigstore signing of capability digests — optional
layer on top of digest pinning. Publisher signs the digest, gateway
verifies signature against publisher's key. Same security property
as a Livepeer-specific PKI but identity lives in standard registry
/ Sigstore tooling.
Name:version aliases over digest-pinned wire — Replicate-
style mutable names (byoc/text-reverser:v2) that resolve to a
digest at lookup time. Wire protocol always pins the digest;
aliases are a UX layer for humans and dashboards.
Outcome
Developers go from "I have a Python ML model" to a discoverable BYOC
capability on Livepeer in under 5 minutes — surfaced in the
developer dashboard
ready for any caller to invoke.
The Pipeline SDK is the authoring surface that makes that possible:
write a Python class, get a containerised, BYOC-compatible,
schema-described capability.
Spec: pipeline-sdk.md
What we're building
A FastAPI + Pydantic-native authoring SDK delivered as a staircase
of small, shippable commits. Each step yields a working SDK that's
strictly more capable than the previous one. Status updated as work
lands.
Roadmap
Pipelinebase +serve()+ hello-world BYOC E2Esetup()lifecycle + HuggingFace sentiment example/health,/predict,/docs,/openapi.json)BaseModelfor inputs/outputs via signature introspection (/docsshows real fields instead ofadditionalProp1)Base64Bytes)/healthstate machine (LOADING / OK / ERROR / IDLE) matching go-livepeer'sHealthCheckwire formatpredict()+ LLM chat exampleLivePipelinefor trickle transport (real-time video)livepeer pushCLI +livepeer.yamlmanifestorg.livepeer.pipeline.schema)AGENTS.md, expandedPipelinedocstring,examples/runner/_template/) so AI tooling and new contributors can scaffold pipelines without parsing the whole codebaselivepeer-runner(authoring SDK),livepeer-client(caller-side BYOC),livepeer-trickle(shared transport). User-facing imports becomelivepeer.runner.*,livepeer.client.*,livepeer.trickle.*. See Architecture: monorepo + namespace packages below for rationale and layout.Architecture: monorepo + namespace packages
The repo will be reorganized into a
uvworkspace publishing threedistributions under a shared
livepeer.*namespace.Why monorepo (vs separate repos)
livepeer.trickle) becomes a workspace dep, not a publish-and-depend dancepip install livepeer-runner livepeer-clientWhy namespace packages (vs flat package or extras)
livepeer.runner,livepeer.client,livepeer.tricklelivepeer-runner, callers onlylivepeer-clientairflow.providers.*, Google Cloud SDKgoogle.cloud.*, Azure SDKazure.*)livepeer.cli,livepeer.adapters.cog, etc.)Layout
Critical convention
No
__init__.pyatsrc/livepeer/— that empty directory IS thenamespace marker (PEP 420 implicit namespace package). Each
livepeer/X/__init__.pyis a regular package. Adding an__init__.pyat the namespace level breaks cross-distribution discovery and has
historically bitten Airflow contributors. Add a CI check.
Tooling
uvworkspaces — one lockfile, workspace-aware deps, per-package builds viauv build --package <name>Migration strategy
Clean break, no compatibility shim — the SDK is pre-1.0 and not yet
widely consumed externally. Coordinate with the in-flight fork to
contribute back upstream rather than maintain divergence.
Framework adapters (deferred — build on demand)
Migration paths for users from existing ML frameworks. Each ships as
its own pip package with its own foreign dep, isolated from core SDK.
Build only when a real migration ask shows up.
livepeer-gateway-cog— wrapscog.BasePredictorlivepeer-gateway-fal— wrapsfal.Applivepeer-gateway-modal— wraps Modal@app.functionlivepeer-gateway-bentoml— wraps@bentoml.serviceFuture protocol work (cross-team, gated on C9 + upstream go-livepeer)
Cross-cutting changes to BYOC capability identity that span the SDK,
go-livepeer, and the spec. Tracked here so the SDK side is captured;
implementation lands once C9 (
livepeer push) provides the publishhook and upstream protocol changes are agreed.
capability names with content-hashed references like
byoc/<repo>@sha256:<digest>. Aligns BYOC with Replicate'sreproducibility model: orchestrators advertise the digest, gateway
pins it, callers always invoke against an exact build. SDK side:
livepeer pushcaptures the digest at publish time and bakes itinto the manifest. Upstream side: orchestrator registration +
gateway routing +
OrchestratorInfocarry the digest.layer on top of digest pinning. Publisher signs the digest, gateway
verifies signature against publisher's key. Same security property
as a Livepeer-specific PKI but identity lives in standard registry
/ Sigstore tooling.
style mutable names (
byoc/text-reverser:v2) that resolve to adigest at lookup time. Wire protocol always pins the digest;
aliases are a UX layer for humans and dashboards.
Related
livepeer-specs/docs/developer-journey/_followups.mdTODO.mduvworkspace docs: https://docs.astral.sh/uv/concepts/projects/workspaces/