# https://github.com/Pipelex/pipelex Project Manual

Generated at: 2026-07-30 18:14:36 UTC

## Table of Contents

- [Overview & MTHDS Language](#page-1)
- [System Architecture & Runtime](#page-2)
- [Pipes, Concepts & Orchestration](#page-3)
- [Inference, Providers & Extensibility](#page-4)

<a id='page-1'></a>

## Overview & MTHDS Language

### Related Pages

Related topics: [System Architecture & Runtime](#page-2), [Pipes, Concepts & Orchestration](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [README.md](https://github.com/Pipelex/pipelex/blob/main/README.md)
- [pipelex/__init__.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/__init__.py)
- [pipelex/pipelex.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/pipelex.py)
- [pipelex/cli/_cli.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/cli/_cli.py)
- [pipelex/language/mthds_config.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/language/mthds_config.py)
- [pipelex/mthds_parsing/pipelex_bundle_blueprint.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/mthds_parsing/pipelex_bundle_blueprint.py)
</details>

# Overview & MTHDS Language

Pipelex is an open-source inference engine and a DSL (domain-specific language) called **MTHDS** for declaratively composing LLM-driven workflows. A project on disk is a *bundle* of `.mthds` source files, parsed into a *library crate* and executed by a runtime that can be embedded without pulling in any interpreter modules.

## Project Mission and Repository Layout

The README frames Pipelex as a way to turn repeatable LLM tasks into typed, composable, testable building blocks. The package's public surface is re-exported from the top-level package init, so `import pipelex` is the entry point for embedding callers and CLI tools alike.

- The library entry is `pipelex/__init__.py`, which re-exports the runtime types, helper functions, and the `Pipelex` facade used to bootstrap pipelines. `Source: [pipelex/__init__.py:1-40]()`
- `pipelex/pipelex.py` defines the high-level facade that initializes the runtime, exposes configuration, and orchestrates pipeline execution. `Source: [pipelex/pipelex.py:1-120]()`
- The CLI is rooted at `pipelex/cli/_cli.py`, which registers subcommands such as `pipelex resolve`, `pipelex codegen`, and the run/debug commands. `Source: [pipelex/cli/_cli.py:1-80]()`
- `pipelex/language/mthds_config.py` holds the language-level configuration (parser options, native concept catalogue, validation toggles). `Source: [pipelex/language/mthds_config.py:1-60]()`
- `pipelex/mthds_parsing/pipelex_bundle_blueprint.py` defines the Pydantic blueprint for parsed bundles — the contract that every `.mthds` file is validated against. `Source: [pipelex/mthds_parsing/pipelex_bundle_blueprint.py:1-120]()`

## Runtime vs. Interpreter Hubs

The most consequential architectural change in v0.41.0 (2026-07-30) is the split of `pipelex.hub` into two layer-seamed subsystems:

- **`pipelex.runtime_hub`** — vendor adapters, inference clients, working-memory stores, the delivery executor, and the orchestration plugin SPI. Importing this hub loads **zero** interpreter modules (down from ~50), so applications that only need the engine can embed Pipelex without dragging in the MTHDS parser.
- **`pipelex.interpreter_hub`** — the MTHDS parser, the `Pipe*` classes, the bundle validator, and the `plxt` formatter.

The boot sequence gained a `RuntimeBoot` layer seam that decides which hub(s) to initialize for a given command. The CLI command `pipelex run` boots both; an embedder calling `Pipelex.make()` only for inference boots just the runtime hub. The community discussion in the v0.41.0 release notes highlights this as the headline change, because it makes the inference engine usable as a thin dependency for downstream products.

```mermaid
flowchart LR
    A["import pipelex"] --> B{pipelex.hub}
    B --> C["pipelex.runtime_hub<br/>(vendors, inference, executor)"]
    B --> D["pipelex.interpreter_hub<br/>(parser, pipes, validator)"]
    C --> E["Embedded inference"]
    D --> F["CLI: run / resolve / codegen"]
    D --> G["Library crate + ClassRegistry"]
```

## MTHDS — The Language

MTHDS is the DSL used to describe *Concepts* (typed data), *Pipes* (operations that consume and produce concepts), and the wiring between them. Source files use the `.mthds` extension and are validated against `PipelexBundleBlueprint` after parsing.

A bundle is the smallest unit the interpreter loads. It is parsed into a *bundle blueprint*, then resolved into a fully-qualified, fingerprinted *library crate* via `pipelex resolve`. The crate is the canonical, dependency-free artifact used by the runtime and by codegen. `Source: [pipelex/mthds_parsing/pipelex_bundle_blueprint.py:1-120]()`

### Concepts

Concepts are first-class typed declarations. v0.38.0 introduced **optionality** as a language feature: a concept reference on a pipe's `inputs` or `outputs` may carry `?` (optional) or `!` (force) markers. Optionality is tracked at runtime through a trichotomy: a plain input skips, an absent `?`-marked input is recorded as structured absence, and a `!`-marked input must be present or the run fails fast. `Source: [pipelex/language/mthds_config.py:1-60]()`

Several concepts ship in the `native` namespace — e.g. `native.Text`, `native.Image`, `native.Composite`. The `native.Composite` concept, added in v0.37.0, is the ready-made combination vehicle used by parallel pipes to merge branch outputs.

### Pipes

Pipes are the executable nodes of the graph. Major pipe kinds:

- **`PipeFunction`** — calls a Python handler.
- **`PipeImgGen`** — generates an image from a prompt template. v0.35.1 clarified that `PipeImgGen` has no dedicated "prompt concept"; instead, declared `inputs` are injected into a `prompt` template — `Text` is interpolated directly, while `Image` inputs (single or list) are referenced by placeholder. `Source: [pipelex/language/mthds_config.py:1-60]()`
- **`PipeParallel`** — runs branches concurrently. Since v0.37.0 it **always** combines branch outputs into its declared `output` concept; the legacy `combined_output` field was removed from the language. Every run also has a *main output* produced by the top-level pipe.

### Validation and Errors

v0.35.0 added **structured validation errors**. Bundle validation failures emit a `validation_errors[]` list whose items carry an `error_type` discriminator and locators (e.g. `pipe_validation` / `unresolved_concept` with the offending `pipe_code`). This lets CI tooling and IDE integrations consume errors as data instead of parsing free-form text. `Source: [pipelex/mthds_parsing/pipelex_bundle_blueprint.py:1-120]()`

## End-to-End Workflow

1. **Author** one or more `.mthds` files declaring concepts and pipes.
2. **Resolve** the bundle into a normalized crate via `pipelex resolve` (see v0.39.0 release notes for the crate-fingerprinting semantics and idempotent loading via `LibraryManagerAbstract.is_crate_loaded(*, library_id, fingerprint)` added in v0.39.2).
3. **Run** the pipeline with `pipelex run`, which boots both hubs and dispatches each pipe through the configured orchestrator. Since v0.36.0, orchestrators are pluggable via an SPI token (`orchestration_mode`), with a built-in `direct` orchestrator and room for distributed backends.
4. **Codegen** typed clients with `pipelex codegen types` (TypeScript `ts-zod` or Python dataclasses), introduced in v0.39.0.

The decoupling between the MTHDS interpreter and the runtime means authors, embedders, and tooling consumers each load only what they need — the central invariant the v0.41.0 release was designed to enforce.

---

<a id='page-2'></a>

## System Architecture & Runtime

### Related Pages

Related topics: [Overview & MTHDS Language](#page-1), [Pipes, Concepts & Orchestration](#page-3), [Inference, Providers & Extensibility](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [pipelex/runtime_boot.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/runtime_boot.py)
- [pipelex/runtime_hub.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/runtime_hub.py)
- [pipelex/interpreter_hub.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/interpreter_hub.py)
- [pipelex/runtime_bridge/bootstrap.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/runtime_bridge/bootstrap.py)
- [pipelex/runtime_bridge/direct_orchestrator.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/runtime_bridge/direct_orchestrator.py)
- [pipelex/pipeline/pipeline.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/pipeline/pipeline.py)
- [pipelex/libraries/library_manager_abstract.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/libraries/library_manager_abstract.py)
- [pipelex/pipe_operators/parallel/parallel_pipeline.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/pipe_operators/parallel/parallel_pipeline.py)
</details>

# System Architecture & Runtime

Pipelex is structured as a runtime kernel that executes inference flows defined in the MTHDS language. Starting in v0.41.0, the runtime is explicitly decoupled from the interpreter so that embedding the inference engine never pulls in MTHDS parser or pipe-operator code at import time. The architecture follows a layered boot sequence, a hub pattern for cross-component service location, and a pluggable orchestration SPI.

## Hub Layer: runtime_hub vs. interpreter_hub

Before v0.41.0, a single `pipelex.hub` mixed runtime services and interpreter services together, so any import pulled roughly 50 interpreter modules into memory. The release split that surface into two siblings:

- `pipelex.runtime_hub` exposes services that exist purely to execute a flow (inference backends, working memory, pipeline runner, delivery executor, orchestrator registry).
- `pipelex.interpreter_hub` exposes services that exist to compile MTHDS bundles into a library (bundle loader, MTHDS parser, library manager, pipe constructors).

`Source: [pipelex/runtime_hub.py:1-120]()` defines the runtime-side singleton and re-exports the inference-related interfaces. `Source: [pipelex/interpreter_hub.py:1-120]()` defines the interpreter-side singleton and owns the MTHDS parsing and library registration surface. Because the two modules no longer share an import graph, downstream code can `import pipelex.runtime_hub` without triggering the MTHDS parser, which the release notes confirm drops interpreter modules loaded at runtime import from 50 to 0.

## Bootstrap Sequence and the RuntimeBoot Seam

The boot sequence is layered so each tier can be entered or skipped independently:

1. **Core boot** — base configuration, logging, telemetry, class registries.
2. **RuntimeBoot seam** — the new layer introduced in v0.41.0 that initializes `runtime_hub` only (backends, pipeline runner, orchestrator registry, delivery executor).
3. **Interpreter boot** — opt-in step that loads `interpreter_hub` (MTHDS parser, bundle resolution, library manager, pipe constructors).

`Source: [pipelex/runtime_boot.py:1-200]()` orchestrates this sequence and exposes entry points such as `boot_for_runtime()` and `boot_for_interpreter()`. The seam itself is implemented in `Source: [pipelex/runtime_bridge/bootstrap.py:1-150]()`, which decides which subsystems to wire and which vendor adapters to register. This layering is what lets an embedder load the inference engine without ever touching the MTHDS surface.

## Orchestration SPI and the direct Orchestrator

Job execution is delegated to an orchestrator chosen per call by an `orchestration_mode` token. The core ships with an in-process orchestrator named `direct`, and the contract is open for plugins to plug in distributed backends. `Source: [pipelex/runtime_bridge/direct_orchestrator.py:1-200]()` implements that in-process orchestrator, which walks the pipeline graph inline on the caller's task: evaluate each pipe's inputs against working memory, dispatch to the pipe's operator, then write outputs back.

For `PipeParallel`, v0.37.0 made combining mandatory: every parallel branch's output is now always merged into the declared `output` concept (typically a `native.Composite`), and the legacy `combined_output` field was removed from the language. `Source: [pipelex/pipe_operators/parallel/parallel_pipeline.py:1-250]()` is where branch fan-out, dispatch, and the always-on combine happen. The orchestrator registry inside `runtime_hub` resolves a mode string to an implementation at call time, which is how v0.36.0 opened the execution path to third-party orchestrators without changing call sites.

## Library Management and Delivery Artifacts

Libraries are the resolved, fingerprinted snapshot of a bundle's closure. `Source: [pipelex/libraries/library_manager_abstract.py:1-200]()` is the public contract for loading them: `load_from_crate(library_id, fingerprint)` is idempotent and backed by per-library fingerprint bookkeeping, which v0.39.2 exposed through the new query method `is_crate_loaded(*, library_id, fingerprint)`. A `True` answer means the library's `ClassRegistry` already holds the crate's dynamic classes, so callers can rehydrate within an existing registry without re-parsing.

Durable runs write a directory of result artifacts after orchestration completes. Per v0.40.0, the delivery executor persists `tokens_usages.json` — a list of client-facing `TokensUsageRecord` wire shapes plus an optional `usage_assembly_error` — alongside `working_memory.json`, the `main_stuff.*` renders, and the graph outputs. `Source: [pipelex/pipeline/pipeline.py:1-300]()` is the entry point that drives the delivery executor for a successful run and finalizes that artifact directory.

The table below summarizes where each concern lives in the split topology:

| Concern | Runtime side | Interpreter side |
|---|---|---|
| Inference backends, working memory, pipeline runner | `runtime_hub` | — |
| MTHDS parser, bundle resolver, library manager | — | `interpreter_hub` |
| Orchestrator registry, `direct` orchestrator | `runtime_bridge` | — |
| Pipe constructors, `PipeParallel` operator | — | `pipe_operators` |
| Per-library fingerprint bookkeeping, `is_crate_loaded` | — | `libraries` |
| Result artifacts (`tokens_usages.json`, `working_memory.json`) | delivery executor | — |

Together, these layers give Pipelex a small embeddable runtime, a clear extension boundary for orchestration and tool integrations, and a stable library model that downstream code generation (`pipelex codegen`) can project into typed clients.

---

<a id='page-3'></a>

## Pipes, Concepts & Orchestration

### Related Pages

Related topics: [System Architecture & Runtime](#page-2), [Inference, Providers & Extensibility](#page-4)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [pipelex/pipe_machinery/pipe_abstract.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/pipe_machinery/pipe_abstract.py)
- [pipelex/pipe_controllers/sequence/pipe_sequence.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/pipe_controllers/sequence/pipe_sequence.py)
- [pipelex/pipe_controllers/parallel/pipe_parallel.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/pipe_controllers/parallel/pipe_parallel.py)
- [pipelex/pipe_controllers/batch/pipe_batch.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/pipe_controllers/batch/pipe_batch.py)
- [pipelex/pipe_controllers/condition/pipe_condition.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/pipe_controllers/condition/pipe_condition.py)
- [pipelex/pipe_operators/llm/pipe_llm.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/pipe_operators/llm/pipe_llm.py)
</details>

# Pipes, Concepts & Orchestration

## Purpose and Scope

Pipelex models AI work as a graph of **pipes** wired by **concepts**. A pipe is a typed, declarative unit that consumes concept-typed inputs and emits a concept-typed output; concepts are the schema vocabulary that flows on the edges. Orchestration is the layer that schedules, composes, and drives those pipes at run time, including the dispatching done by controller pipes and the per-call choice of an orchestrator backend.

This page covers three orthogonal axes:

1. The pipe hierarchy rooted at `PipeAbstract`, including controller pipes (sequence, parallel, batch, condition) and operator pipes (LLM, image generation).
2. The concept model, including the optionality markers that flow through pipes.
3. The orchestration plugin SPI that selects how a job is actually run (in-process `direct` or an external backend).

Source: [pipelex/pipe_machinery/pipe_abstract.py]()

## Pipe Hierarchy

`PipeAbstract` is the single base for every executable node in the graph. Subclasses fall into two families:

- **Controllers** under `pipelex/pipe_controllers/` — they orchestrate other pipes but do not invoke a model themselves.
- **Operators** under `pipelex/pipe_operators/` — they call a vendor/model adapter to transform data.

| Family | Pipe | Role |
|---|---|---|
| Controller | `PipeSequence` | Runs its `steps` in order, threading working memory from step to step. |
| Controller | `PipeParallel` | Fans out to `branches` concurrently and always combines into its declared `output` concept (often `native.Composite`). |
| Controller | `PipeBatch` | Iterates a pipe over a list-typed input and collects per-item outputs. |
| Controller | `PipeCondition` | Selects one of `outcomes` based on a condition expression evaluated over the working memory. |
| Operator | `PipeLLM` | Calls an LLM vendor adapter with a prompt template and structured output. |

`PipeAbstract` exposes the shared contract — `inputs`, `output`, optionality, and execution entry points — that all subclasses conform to. Source: [pipelex/pipe_machinery/pipe_abstract.py]()

### Controllers in Detail

`PipeSequence` is the workhorse of linear pipelines: each `step` is a `(pipe_code, result_id)` pair whose outputs feed the next. Source: [pipelex/pipe_controllers/sequence/pipe_sequence.py]()

`PipeParallel` no longer exposes a separate `combined_output` field; since v0.37.0 it always merges branch outputs into the pipe's declared `output` concept, and the `native.Composite` concept is the canonical combination shape. Source: [pipelex/pipe_controllers/parallel/pipe_parallel.py]()

`PipeBatch` handles list-shaped inputs by mapping the inner pipe across the collection, producing a list of outputs of the same concept. Source: [pipelex/pipe_controllers/batch/pipe_batch.py]()

`PipeCondition` evaluates an expression (typically against a `PipeCondition.Concept`) and routes to one `outcome`, letting the graph branch on runtime data. Source: [pipelex/pipe_controllers/condition/pipe_condition.py]()

### Operators in Detail

`PipeLLM` is the primary text/reasoning operator. It carries a prompt template, a structured output concept, and a vendor selection. Vendor adapters live behind a registry, so swapping providers does not change the pipe definition. Source: [pipelex/pipe_operators/llm/pipe_llm.py]()

## Concepts and Optionality

Concepts are the typed tokens that label every input and output. They are referenced by fully-qualified name in pipe signatures, and the language distinguishes three presence modes on each reference:

- **plain** — required, must be present in the working memory.
- **`?` optional** — may be absent; absence is a tracked, first-class value with provenance rather than an error.
- **`!` force** — must be present even if the producer would normally omit it.

Optionality propagates through the runtime as a trichotomy: a missing optional is skipped, a present optional is consumed, and a forced value is materialized before the dependent step runs. This makes absence routable (e.g., a `PipeCondition` can branch on whether an optional was supplied) instead of crashing. Source: [pipelex/pipe_machinery/pipe_abstract.py]()

## Orchestration Layer

Pipelex separates *what to run* (the pipe graph) from *how to run it* (the orchestrator). Since v0.36.0 the orchestrator is chosen per call by an `orchestration_mode` token; the core ships an in-process `direct` orchestrator and the SPI is open for plugins that supply distributed backends. Source: [pipelex/pipe_controllers/sequence/pipe_sequence.py]()

In v0.41.0 the runtime boot path was refactored: importing `pipelex.runtime_hub` no longer pulls in interpreter modules, and the boot sequence gained a `RuntimeBoot` layer seam. This means a host application that only needs inference can embed the engine without paying the cost of the MTHDS parser or pipe factory loading — the interpreter is loaded lazily on demand. Source: [pipelex/pipe_machinery/pipe_abstract.py]()

```mermaid
flowchart LR
    A[Bundle / MTHDS] --> B[PipeAbstract]
    B --> C[Controllers]
    B --> D[Operators]
    C --> C1[PipeSequence]
    C --> C2[PipeParallel]
    C --> C3[PipeBatch]
    C --> C4[PipeCondition]
    D --> D1[PipeLLM]
    D --> D2[PipeImgGen]
    E[orchestration_mode] --> F{Orchestrator}
    F -->|direct| G[In-process runner]
    F -->|plugin| H[External backend]
    I[Concepts + Optionality ? !] -.-> B
```

## Related Discussions

- v0.36.0 introduced the orchestration plugin SPI so that distributed backends can be plugged in without touching the pipe definitions. Source: [pipelex/pipe_machinery/pipe_abstract.py]()
- v0.37.0 made `PipeParallel` always combine, and `native.Composite` is the ready-made combination concept. Source: [pipelex/pipe_controllers/parallel/pipe_parallel.py]()
- v0.38.0 promoted optionality to a first-class language feature with `?` and `!` markers. Source: [pipelex/pipe_machinery/pipe_abstract.py]()
- v0.41.0 split `pipelex.hub` into `pipelex.runtime_hub` and `pipelex.interpreter_hub` and added the `RuntimeBoot` seam. Source: [pipelex/pipe_machinery/pipe_abstract.py]()

---

<a id='page-4'></a>

## Inference, Providers & Extensibility

### Related Pages

Related topics: [System Architecture & Runtime](#page-2), [Pipes, Concepts & Orchestration](#page-3)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this page:

- [pipelex/cogt/model_backends/backend.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/cogt/model_backends/backend.py)
- [pipelex/cogt/models/model_deck.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/cogt/models/model_deck.py)
- [pipelex/cogt/model_routing/routing_profile.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/cogt/model_routing/routing_profile.py)
- [pipelex/providers/openai/openai_plugin.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/providers/openai/openai_plugin.py)
- [pipelex/providers/anthropic/anthropic_plugin.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/providers/anthropic/anthropic_plugin.py)
- [pipelex/providers/google/google_plugin.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/providers/google/google_plugin.py)
- [pipelex/runtime_hub.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/runtime_hub.py)
- [pipelex/cogt/model_backends/model_spec.py](https://github.com/Pipelex/pipelex/blob/main/pipelex/cogt/model_backends/model_spec.py)
</details>

# Inference, Providers & Extensibility

## Purpose and Scope

The **Inference, Providers & Extensibility** subsystem is the layer of Pipelex that turns declarative MTHDS pipe specifications into actual model calls. It owns three concerns: (1) defining a uniform `Backend` abstraction so any vendor can be plugged in, (2) maintaining a `ModelDeck` registry of available models and the `RoutingProfile` that selects among them, and (3) exposing first-party `Plugin` classes — one per vendor — that wire credentials, transport, and SDK defaults into the runtime.

Because the `pipelex.hub` package was split in v0.41.0 into `pipelex.runtime_hub` and `pipelex.interpreter_hub`, the inference subsystem now lives entirely under the **runtime half**: importing the runtime loads the model deck, the routing profiles, and the provider plugins, but zero interpreter modules. This makes it possible to embed the inference engine into another application without dragging in MTHDS parsing. Source: [pipelex/runtime_hub.py](pipelex/runtime_hub.py).

## Backend Abstraction and Model Deck

At the center of the inference layer is `Backend`, an abstract base class that hides vendor-specific SDKs behind a stable surface for text generation, image generation, and structured output. Every concrete backend (OpenAI, Anthropic, Google, etc.) implements the same async methods so that higher-level pipes can call any model through the same code path. Source: [pipelex/cogt/model_backends/backend.py](pipelex/cogt/model_backends/backend.py).

The collection of backends and the models they expose is described by a `ModelDeck`, which is loaded at boot from configuration. A deck entry typically names a vendor, a model identifier, a `ModelSpec` (token limits, modality support, cost tier), and the `RoutingProfile` it should use. The deck is the single source of truth that pipes consult when they need to resolve `model = "best-claude"` or `model = "gpt-4o-mini"` into a concrete backend call. Source: [pipelex/cogt/models/model_deck.py](pipelex/cogt/models/model_deck.py).

Each model in the deck is also annotated with a `ModelSpec` capturing its capabilities (text, image, structured output, function calling, context window). Pipes query the spec to decide whether a given model can satisfy a request before falling back or routing to another. Source: [pipelex/cogt/model_backends/model_spec.py](pipelex/cogt/model_backends/model_spec.py).

## Routing Profiles

`RoutingProfile` is the policy object that turns "I need a model to do X" into "call backend Y's model Z". A profile combines selection rules (cheapest, fastest, highest quality, fallback chain), retry semantics, and the list of models eligible for each capability. When a pipe asks for inference, the runtime looks up the active profile, lets it pick the model, and dispatches the call through the matching `Backend`. Source: [pipelex/cogt/model_routing/routing_profile.py](pipelex/cogt/model_routing/routing_profile.py).

Routing profiles are typically grouped by environment (development, production) so that the same MTHDS bundle can target cheap local models locally and premium hosted models in CI without editing any pipe code.

## Provider Plugins

Vendor support is delivered through `Plugin` classes — small modules that register a backend with the runtime. Each plugin owns its SDK configuration, API key loading, and client lifecycle. Three first-party plugins ship with the core:

- **OpenAI plugin** — wires the OpenAI SDK, registers text, image, and structured-output backends, and handles organization-scoped API keys. Source: [pipelex/providers/openai/openai_plugin.py](pipelex/providers/openai/openai_plugin.py).
- **Anthropic plugin** — registers Claude-family backends with their own retry and streaming semantics. Source: [pipelex/providers/anthropic/anthropic_plugin.py](pipelex/providers/anthropic/anthropic_plugin.py).
- **Google plugin** — covers the Gemini family, including the multimodal endpoints. Source: [pipelex/providers/google/google_plugin.py](pipelex/providers/google/google_plugin.py).

Each plugin exposes a `register()` entry point that `runtime_hub` calls during boot. The plugin contributes one or more `Backend` subclasses, declares which model identifiers it serves, and supplies the model specs that will populate the `ModelDeck`.

## Extensibility Model

Adding a new vendor follows the same recipe used by the first-party plugins:

1. Subclass `Backend` in `pipelex/providers/<vendor>/`, implementing the async generation methods.
2. Write a `VendorPlugin` that builds the SDK client, reads API keys from environment or config, and registers the backend(s) with `runtime_hub`.
3. Append entries to the `ModelDeck` for every model the new backend exposes, each pointing at a `ModelSpec`.
4. Tag the models in one or more `RoutingProfile`s so pipes can reach them through the existing selector API.

Because the `Backend` contract is uniform, pipes and the interpreter layer never need to know which vendor is answering — the routing profile decides, and the backend hides the SDK details.

```mermaid
flowchart LR
    A[MTHDS Pipe] --> B[RoutingProfile]
    B --> C[ModelDeck lookup]
    C --> D[Backend subclass]
    D --> E[Vendor Plugin]
    E --> F[(Vendor SDK / API)]
```

This shape keeps inference orthogonal to the rest of the system: the runtime can be embedded (v0.41.0) without the interpreter, the deck can be swapped per environment, and any vendor that can speak HTTP or an SDK can be added by following the plugin contract. Source: [pipelex/runtime_hub.py](pipelex/runtime_hub.py), [pipelex/cogt/model_backends/backend.py](pipelex/cogt/model_backends/backend.py), [pipelex/cogt/models/model_deck.py](pipelex/cogt/models/model_deck.py).

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Pitfall Log

Project: Pipelex/pipelex

Summary: Found 17 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.

## 1. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this installation risk before relying on the project: v0.35.0
- User impact: Upgrade or migration may change expected behavior: v0.35.0
- Evidence: failure_mode_cluster:github_release | https://github.com/Pipelex/pipelex/releases/tag/v0.35.0

## 2. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this installation risk before relying on the project: v0.39.1
- User impact: Upgrade or migration may change expected behavior: v0.39.1
- Evidence: failure_mode_cluster:github_release | https://github.com/Pipelex/pipelex/releases/tag/v0.39.1

## 3. Installation risk - Installation risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this installation risk before relying on the project: v0.40.0
- User impact: Upgrade or migration may change expected behavior: v0.40.0
- Evidence: failure_mode_cluster:github_release | https://github.com/Pipelex/pipelex/releases/tag/v0.40.0

## 4. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.host_targets | https://github.com/Pipelex/pipelex

## 5. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: v0.37.0
- User impact: Upgrade or migration may change expected behavior: v0.37.0
- Evidence: failure_mode_cluster:github_release | https://github.com/Pipelex/pipelex/releases/tag/v0.37.0

## 6. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: v0.38.0
- User impact: Upgrade or migration may change expected behavior: v0.38.0
- Evidence: failure_mode_cluster:github_release | https://github.com/Pipelex/pipelex/releases/tag/v0.38.0

## 7. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: v0.39.0
- User impact: Upgrade or migration may change expected behavior: v0.39.0
- Evidence: failure_mode_cluster:github_release | https://github.com/Pipelex/pipelex/releases/tag/v0.39.0

## 8. Configuration risk - Configuration risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: v0.41.0
- User impact: Upgrade or migration may change expected behavior: v0.41.0
- Evidence: failure_mode_cluster:github_release | https://github.com/Pipelex/pipelex/releases/tag/v0.41.0

## 9. Capability evidence risk - Capability evidence risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: capability.assumptions | https://github.com/Pipelex/pipelex

## 10. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this migration risk before relying on the project: v0.35.1
- User impact: Upgrade or migration may change expected behavior: v0.35.1
- Evidence: failure_mode_cluster:github_release | https://github.com/Pipelex/pipelex/releases/tag/v0.35.1

## 11. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this migration risk before relying on the project: v0.36.0
- User impact: Upgrade or migration may change expected behavior: v0.36.0
- Evidence: failure_mode_cluster:github_release | https://github.com/Pipelex/pipelex/releases/tag/v0.36.0

## 12. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this migration risk before relying on the project: v0.39.2
- User impact: Upgrade or migration may change expected behavior: v0.39.2
- Evidence: failure_mode_cluster:github_release | https://github.com/Pipelex/pipelex/releases/tag/v0.39.2

## 13. Maintenance risk - Maintenance risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/Pipelex/pipelex

## 14. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: downstream_validation.risk_items | https://github.com/Pipelex/pipelex

## 15. Security or permission risk - Security or permission risk requires verification

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: risks.scoring_risks | https://github.com/Pipelex/pipelex

## 16. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/Pipelex/pipelex

## 17. Maintenance risk - Maintenance risk requires verification

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Evidence: evidence.maintainer_signals | https://github.com/Pipelex/pipelex

<!-- canonical_name: Pipelex/pipelex; human_manual_source: deepwiki_human_wiki -->
