Doramagic Project Pack · Human Manual
model-compose
The runtime resolves a compose file by reading the declarative schema, instantiating the declared components and jobs, and wiring their inputs and outputs together. The high-level flow loo...
Introduction and Core Philosophy
Related topics: Component System and Architecture, Workflow Composition, Jobs and Streaming, Deployment, Runtimes, and Protocol Adapters
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Component System and Architecture, Workflow Composition, Jobs and Streaming, Deployment, Runtimes, and Protocol Adapters
Introduction and Core Philosophy
What is model-compose
model-compose is a Python-based framework for composing and orchestrating AI/ML workflows from small, reusable building blocks. Instead of writing monolithic pipelines, users declare a workflow as a *compose* description — a declarative schema that wires together components (units that perform an action, such as calling a model or running an HTTP request) and jobs (orchestration units that schedule or chain work). The framework then interprets that description, starts the required services, and exposes the assembled workflow as a runnable target such as an MCP server, a streaming endpoint, or a containerized controller.
The project lives under the Python package namespace mindor (see src/mindor/__init__.py), and the project metadata in pyproject.toml describes it as a toolkit for building modular, model-driven workflows. Source: pyproject.toml:1-40
At its heart, model-compose treats every interaction with a model, API, shell, or local script as a *component* that can be referenced by name and reused across multiple workflows. This composition-first mindset is what the rest of this wiki page unpacks.
Core Philosophy and Design Principles
The framework is built around a small set of recurring principles that recur across its release history and its schema definitions:
- Declarative composition over imperative glue code. A workflow is described as data, not as a sequence of function calls. The top-level schema in
src/mindor/dsl/schema/compose.pydefines theComposemodel that anchors the entire description, and every other schema (components, jobs, services) hangs off it. Source: src/mindor/dsl/schema/compose.py:1-80 - Components as first-class citizens. Each capability — calling an LLM, executing a shell command, exposing an HTTP server, running local inference — is encapsulated in its own component schema. The component type registry lives in
src/mindor/dsl/schema/component.py, where each component declares its own configuration, inputs, and outputs. Source: src/mindor/dsl/schema/component.py:1-60 - Jobs coordinate, components act. Jobs (
src/mindor/dsl/schema/job.py) describe *when* and *how* work runs — schedules, triggers, dependencies — without knowing the internal mechanics of any component. This separation lets users swap implementations without rewriting orchestration. Source: src/mindor/dsl/schema/job.py:1-60 - Multiple deployment targets from one description. The same compose file can be deployed as an MCP server, a streaming service, a Docker controller, or a local process. The README and the user guide position this flexibility as a core reason to use the project. Source: README.md:1-80
These principles are reflected concretely in the user documentation: docs/user-guide/02-core-concepts.md introduces the mental model of *compose → components → jobs* before any concrete syntax is shown. Source: docs/user-guide/02-core-concepts.md:1-60
Version Evolution and the Growing Component Ecosystem
The community release notes show a clear philosophical arc — each stable release expands the set of plug-in components while preserving the same declarative schema.
| Release | Theme | Key Additions |
|---|---|---|
| v0.1.0 | Initial stable release | Core schema, basic components, README |
| v0.2.0 | Production-oriented deployment | MCP server deployment, shell command components |
| v0.3.0 | Local model integration | Local model inference component, Docker-based controller |
| v0.4.0 | Real-time and HTTP workflows | Streaming/event-stream modes, HTTP server component |
This progression shows that the maintainers prioritize *backwards-compatible extensibility*: every release adds new component types without removing earlier ones. Source: README.md:1-120
Architectural Overview
The runtime resolves a compose file by reading the declarative schema, instantiating the declared components and jobs, and wiring their inputs and outputs together. The high-level flow looks like this:
flowchart LR
A[Compose YAML/Schema] --> B[Schema Parser]
B --> C[Component Registry]
B --> D[Job Registry]
C --> E[Runtime Instances]
D --> E
E --> F{Mode}
F --> G[MCP Server]
F --> H[Streaming Service]
F --> I[Docker Controller]
F --> J[Local Process]The schema parser, anchored by Compose in compose.py, normalizes the user input; the registries then look up each named component and job type and construct the appropriate runtime. Source: src/mindor/dsl/schema/compose.py:1-80, src/mindor/dsl/schema/component.py:1-60, src/mindor/dsl/schema/job.py:1-60
For newcomers, docs/user-guide/01-getting-started.md walks through the first end-to-end example — declaring a compose file, running it locally, and exposing it via the chosen deployment mode — which is the recommended entry point before diving into component-specific documentation. Source: docs/user-guide/01-getting-started.md:1-80
Summary
model-compose is best understood as a *declarative composition layer* on top of heterogeneous model and service runtimes. Its philosophy can be summarized in three sentences: describe workflows as data, treat every capability as a named component, and let the same description run anywhere the framework supports. The rest of the wiki — components, jobs, schema reference, deployment guides — elaborates on each of these themes in turn.
Source: https://github.com/hanyeol/model-compose / Human Manual
Component System and Architecture
Related topics: Introduction and Core Philosophy, Workflow Composition, Jobs and Streaming
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Introduction and Core Philosophy, Workflow Composition, Jobs and Streaming
Component System and Architecture
Overview
The Component System is the foundational abstraction of model-compose. It allows users to assemble workflows by composing modular building blocks — agents, models, HTTP servers, shell commands, and MCP servers — into a single, deployable pipeline. Each component encapsulates a self-contained unit of computation that can communicate with others through well-defined interfaces.
A component in model-compose is more than a simple function: it includes a runtime (such as Docker), a service implementation (such as an agent), and a configuration schema that is consumed at deployment time. This layered design enables the same logical component to be declared once in the DSL and executed in different environments without code changes. Source: src/mindor/core/component/component.py.
Across recent releases the component ecosystem has expanded significantly:
- v0.2.0 introduced shell commands and MCP server deployment as first-class components. Source: v0.2.0 release notes.
- v0.3.0 added a Local Model Inference Component and Docker-based Controller Deployment, enabling inference from models stored locally and containerized execution. Source: v0.3.0 release notes.
- v0.4.0 expanded the ecosystem further with an HTTP server component and introduced streaming and event-stream modes for real-time interactions. Source: v0.4.0 release notes.
Layered Architecture
The component system follows a clear three-layer separation of concerns:
| Layer | Responsibility | Example Source |
|---|---|---|
| DSL Schema | Declarative configuration and validation | src/mindor/dsl/schema/component/component.py |
| Core Component | Lifecycle, dispatch, and wiring between services and runtimes | src/mindor/core/component/component.py |
| Runtime / Service | Concrete execution: Docker containers, agent logic, model inference | src/mindor/core/component/runtime/docker.py, src/mindor/core/component/services/agent.py |
The DSL layer validates user-authored definitions; the core layer orchestrates the lifecycle of each declared component; the runtime and service layers provide the actual implementation. This separation means that swapping a Docker runtime for a different runtime — or replacing one service implementation with another — does not affect the configuration layer. Source: src/mindor/core/component/component.py, src/mindor/dsl/schema/component/component.py.
Component Lifecycle Flow
flowchart LR
A[DSL Definition] --> B[Schema Validation]
B --> C[Component Core]
C --> D[Service Layer<br/>agent | model | http | shell]
C --> E[Runtime Layer<br/>docker | local]
D --> F[Execution]
E --> FThe flow begins with a DSL definition that is validated against the schema, instantiated by the core, and then bound to a service and a runtime before execution. Source: src/mindor/core/component/component.py, src/mindor/core/component/runtime/docker.py.
Component Types and Built-Ins
Each documented component type has its own reference page describing configuration keys, inputs, and outputs:
- Model component — performs inference using a model backend. The reference page covers configuration of model identifiers, parameters, and input/output contracts. Source: docs/reference/compose/components/model.md.
- Agent component — implements reasoning behavior on top of a model. Its reference page describes how agents are wired to model components and how they expose structured outputs. Source: docs/reference/compose/components/agent.md, src/mindor/core/component/services/agent.py.
Beyond these, the release history shows the available built-in inventory:
| Component | First Stable Release | Reference |
|---|---|---|
| Agent | v0.1.0 | docs/reference/compose/components/agent.md |
| Model (local inference) | v0.3.0 | docs/reference/compose/components/model.md |
| MCP server deployment | v0.2.0 | release notes v0.2.0 |
| Shell command | v0.2.0 | release notes v0.2.0 |
| HTTP server | v0.4.0 | release notes v0.4.0 |
| Docker-based controller | v0.3.0 | release notes v0.3.0 |
The v0.4.0 release further extended the runtime contract with event-stream and streaming modes, which are expressed through the same component abstraction but alter how outputs flow back to the caller. Source: v0.4.0 release notes.
Configuration Through the DSL
Components are declared in the DSL and validated against the schema module. The schema module exposes the structure used to parse user-authored files and produce typed component instances, allowing the core to treat every component uniformly regardless of its concrete type. Source: src/mindor/dsl/schema/component/component.py.
In practice this means a typical user workflow:
- Author one or more components in a DSL file, selecting the type and supplying required configuration.
- The schema layer validates the file and produces typed objects.
- The core instantiates each component, attaches a service implementation (for example
agent), and binds a runtime (for exampledocker). - The workflow is executed; for MCP-style deployments the same component set can be exposed as an MCP server, a feature available since v0.2.0. Source: v0.2.0 release notes.
Streaming and Extensibility
The v0.4.0 release introduced event-stream and streaming modes directly into the component contract. Components that produce incremental output can now advertise this capability, and the runtime layer is responsible for delivering intermediate events rather than only a final result. This change is fully backward compatible — components that do not declare streaming behavior continue to return a single response. Source: v0.4.0 release notes.
New component types can be added without modifying the core by implementing the runtime and service contracts and registering a corresponding schema entry. The Docker runtime in particular serves as a reference implementation for any container-based component. Source: src/mindor/core/component/runtime/docker.py.
Summary
The Component System provides the modular backbone of model-compose. It cleanly separates declarative configuration (DSL/schema), lifecycle orchestration (core), and execution (service + runtime). Built-in components have grown steadily — from agents in v0.1.0, through MCP servers and shell components in v0.2.0, local model inference and Docker controller deployment in v0.3.0, to HTTP servers and streaming/event-stream modes in v0.4.0 — and the same architectural pattern accommodates each new addition without breaking existing workflows.
Source: https://github.com/hanyeol/model-compose / Human Manual
Workflow Composition, Jobs and Streaming
Related topics: Component System and Architecture, Deployment, Runtimes, and Protocol Adapters
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Component System and Architecture, Deployment, Runtimes, and Protocol Adapters
Workflow Composition, Jobs and Streaming
Overview
model-compose organizes AI/LLM pipelines as declarative workflows built from reusable components, with execution driven by a tree of jobs. A workflow describes the data flow between components, while jobs provide imperative control flow (branching, iteration, dispatch) that wires those components together. Starting with v0.4.0, workflows can also expose results through two streaming modes — event-stream and streaming — enabling real-time interaction with HTTP clients and the MCP server runtime.
The composition model lives under src/mindor/core/workflow/, with the orchestration primitives implemented as job types under src/mindor/core/workflow/job/ and the streaming layer under src/mindor/core/foundation/streaming/.
Source: src/mindor/core/workflow/workflow.py:1-58 Source: src/mindor/core/workflow/job/job.py:1-42
Workflow Composition
A workflow is the top-level artifact users define. It is parsed from configuration, validated against the component registry, and compiled into a directed graph whose nodes are component instances and whose edges carry typed payloads. The root Workflow object owns the lifecycle (start, run, stop) and delegates per-node execution to the job tree.
Key responsibilities of workflow.py:
- Loading and validating workflow YAML/JSON definitions
- Instantiating component instances by type identifier (HTTP server, shell, local model, MCP, etc.)
- Resolving input/output bindings between components
- Scheduling the initial job and propagating results downstream
Source: src/mindor/core/workflow/workflow.py:60-134
flowchart TD
W[Workflow Root] --> J0[Initial Job]
J0 --> C1[Component A]
J0 -->|if_ branch| J1[If-Job]
J0 -->|for_each iteration| J2[ForEach-Job]
J1 -->|switch case| J3[Switch-Job]
J2 --> C2[Component B]
J3 --> C3[Component C]
C1 --> S[(Streaming Sink)]
C2 --> S
C3 --> SJob System
Jobs are the imperative control layer that sits between declarative wiring and component execution. The abstract Job class defines setup(), run(), and teardown() hooks and tracks shared state such as inputs, outputs, and error context. Three control-flow implementations ship in v0.4.0:
`if_` Job
Evaluates a boolean expression against the workflow context and routes execution to one of two downstream branches. It supports nested expressions and short-circuit evaluation, making it suitable for guards and fallback paths.
Source: src/mindor/core/workflow/job/impl/if_.py:18-71
`for_each` Job
Iterates over a collection value in the context and spawns a sub-execution for each element. Each iteration runs in an isolated context but shares the parent workflow's component bindings, enabling map-style fan-out over arrays produced by upstream components.
Source: src/mindor/core/workflow/job/impl/for_each.py:22-88
`switch` Job
Dispatches to one of N branches based on a key or value match. Unlike if_, switch is designed for multi-way routing (e.g., routing model inference by provider or routing HTTP requests by path) and returns the resolved branch's output as its own.
Source: src/mindor/core/workflow/job/impl/switch.py:19-64
All three job types inherit the base Job lifecycle from job.py, which centralizes error propagation and ensures failed jobs surface as structured errors rather than silent drops.
Source: src/mindor/core/workflow/job/job.py:44-119
Streaming Support
v0.4.0 introduced first-class streaming so workflows can deliver incremental results instead of waiting for terminal completion. The streaming foundation is defined in src/mindor/core/foundation/streaming/base.py, which exposes a transport-agnostic StreamBase interface with emit(), close(), and async iteration support.
Two transport modes are exposed to clients:
| Mode | Transport | Use Case |
|---|---|---|
| event-stream | Server-Sent Events (SSE) | MCP server, web clients that consume SSE deltas |
| streaming | HTTP chunked transfer | Generic HTTP clients and the new HTTP server component |
Both modes are wired through the same StreamBase, meaning any component that yields incremental tokens — including the local model inference component introduced in v0.3.0 and the HTTP server component added in v0.4.0 — can be surfaced through either transport without component-side changes.
Source: src/mindor/core/foundation/streaming/base.py:1-96 Source: src/mindor/core/foundation/streaming/base.py:98-160
The MCP server deployment (introduced in v0.2.0) consumes the event-stream mode to push model tokens into MCP clients in real time, while the HTTP server component (v0.4.0) consumes the streaming mode for plain HTTP consumers.
Integration Patterns
Jobs and streaming compose naturally: a switch job can route a request to different model backends, each of which streams its response through the shared StreamBase. Similarly, for_each can fan out a prompt across multiple model components and merge their streams into a single SSE channel. Because the streaming interface is decoupled from component internals, future releases can add new transports (for example, WebSocket) by extending StreamBase alone, without touching the job layer.
Source: src/mindor/core/workflow/job/impl/switch.py:66-104 Source: src/mindor/core/foundation/streaming/base.py:162-205
Source: https://github.com/hanyeol/model-compose / Human Manual
Deployment, Runtimes, and Protocol Adapters
Related topics: Introduction and Core Philosophy, Workflow Composition, Jobs and Streaming
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Introduction and Core Philosophy, Workflow Composition, Jobs and Streaming
Deployment, Runtimes, and Protocol Adapters
The Deployment, Runtimes, and Protocol Adapters layer is the boundary in model-compose between a user-authored workflow and the outside world. Where the rest of the system describes *what* should run, this layer decides *where* it runs and *how* external systems talk to it. It is composed of three cooperating concerns: a Controller that owns lifecycle, two interchangeable Runtime backends (native process and Docker container), and a set of protocol adapters that expose the running workflow as MCP services, HTTP endpoints, or a Gradio web UI. Source: src/mindor/core/controller/controller.py:1-80.
Controller Lifecycle and Runtime Selection
The Controller is the orchestrator that loads a workflow definition, selects a runtime, and brings the workflow up or down. It is invoked once a deployment manifest is resolved and is responsible for translating runtime-agnostic intent (start, stop, stream, serve) into runtime-specific calls. Source: src/mindor/core/controller/controller.py:1-120.
Runtime selection is abstracted behind a common interface so that the same controller code can target either a local Python process or a containerized environment. Each runtime implementation owns the concerns specific to its environment: process supervision and module imports for native, image build, container creation, and port mapping for Docker. Source: src/mindor/core/runtime/native.py:1-90, Source: src/mindor/core/runtime/docker.py:1-120.
Native Runtime
The native runtime executes the workflow in the host Python interpreter. It is the lowest-friction target during development: no image to build, no container to start, and full access to local resources such as on-disk models. Source: src/mindor/core/runtime/native.py:40-140. The v0.3.0 release added a Local Model Inference component designed to run against this runtime, which is the canonical path for users who already have model weights on disk. Source: release notes v0.3.0.
Docker Runtime
The Docker runtime packages the workflow, its Python dependencies, and any required models into a container. It is the production target introduced in v0.3.0 and the recommended way to deploy the controller itself. It handles image construction, container lifecycle, log streaming, and cleanup of orphaned containers. Source: src/mindor/core/runtime/docker.py:60-200. Because each runtime exposes the same call surface, moving from native to Docker is a configuration change rather than a code change.
Protocol Service Adapters
Once a runtime is running a workflow, protocol adapters decide how clients reach it. Two service adapters ship in the core, and each presents the underlying workflow through an industry-standard wire format.
MCP Server Adapter
The MCP (Model Context Protocol) server adapter lets a workflow be consumed by MCP-compatible agents as if it were a native tool. This is the deployment mode advertised in the v0.2.0 release, where workflows can be served directly as MCP servers. Source: src/mindor/core/controller/adapters/services/mcp_server.py:1-160. The adapter is responsible for mapping the workflow's component graph onto MCP tool definitions, handling the request/response framing, and keeping tool schemas in sync with the live workflow definition.
HTTP Server Adapter
The HTTP server adapter exposes the same workflow surface over plain HTTP, making it reachable from curl, browsers, or any HTTP client. It was added alongside the v0.4.0 streaming support and is the path that enables event-stream and streaming modes for real-time interactions. Source: src/mindor/core/controller/adapters/services/http_server.py:1-180. Streaming semantics are expressed through the response framing rather than through a separate transport, which keeps the contract consistent with non-streaming calls.
Web UI Driver and End-to-End Deployment
Not every consumer of a workflow is an agent or a programmatic client. The Gradio web UI driver provides an interactive surface where developers and end users can drive a workflow through a browser. Source: src/mindor/core/controller/webui/gradio/driver.py:1-150. It reuses the same controller entry points as the protocol adapters but renders results through Gradio components instead of wire formats.
The end-to-end flow ties these pieces together as follows: a manifest is parsed, the Controller selects a runtime (native or Docker), the runtime brings the workflow online, and one or more adapters/UI drivers are attached to expose it. Multiple adapters can coexist against a single running workflow, so the same deployment can simultaneously serve MCP tools, HTTP clients, and a Gradio UI without redeploying.
| Layer | Component | Primary Source | Release |
|---|---|---|---|
| Orchestration | Controller | controller/controller.py | v0.2.0+ |
| Runtime (dev) | Native | runtime/native.py | v0.1.0+ |
| Runtime (prod) | Docker | runtime/docker.py | v0.3.0+ |
| Service Adapter | MCP Server | adapters/services/mcp_server.py | v0.2.0+ |
| Service Adapter | HTTP Server | adapters/services/http_server.py | v0.4.0+ |
| Web UI | Gradio Driver | webui/gradio/driver.py | v0.2.0+ |
This layering is the reason users can mix deployment surfaces freely: the runtime answers "what process is running," while adapters answer "how the world reaches it." Known limitations carried over from earlier releases, such as insufficient log messages, affect observability across all adapters and remain orthogonal to runtime choice. Source: release notes v0.1.0, v0.2.0, v0.3.0, v0.4.0.
Source: https://github.com/hanyeol/model-compose / Human Manual
Doramagic Pitfall Log
Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
Doramagic Pitfall Log
Found 6 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Capability evidence risk - Capability evidence risk requires verification.
1. Capability evidence risk: Capability evidence risk requires verification
- Severity: medium
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: capability.assumptions | https://github.com/hanyeol/model-compose
2. Maintenance risk: Maintenance risk requires verification
- Severity: medium
- 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.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: evidence.maintainer_signals | https://github.com/hanyeol/model-compose
3. Security or permission risk: Security or permission risk requires verification
- Severity: medium
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: downstream_validation.risk_items | https://github.com/hanyeol/model-compose
4. Security or permission risk: Security or permission risk requires verification
- Severity: medium
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: risks.scoring_risks | https://github.com/hanyeol/model-compose
5. Maintenance risk: Maintenance risk requires verification
- Severity: low
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: evidence.maintainer_signals | https://github.com/hanyeol/model-compose
6. Maintenance risk: Maintenance risk requires verification
- Severity: low
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: evidence.maintainer_signals | https://github.com/hanyeol/model-compose
Source: Doramagic discovery, validation, and Project Pack records
Community Discussion Evidence
These external discussion links are review inputs, not standalone proof that the project is production-ready.
Count of project-level external discussion links exposed on this manual page.
Open the linked issues or discussions before treating the pack as ready for your environment.
Community Discussion Evidence
Doramagic exposes project-level community discussion separately from official documentation. Review these links before using model-compose with real data or production workflows.
- v0.4.0 - github / github_release
- v0.3.0 - github / github_release
- v0.2.0 - github / github_release
- v0.1.0 - github / github_release
- Capability evidence risk requires verification - GitHub / issue
Source: Project Pack community evidence and pitfall evidence