orchcore
orchcore is a typed, async-first Python 3.12+ library for running AI coding agent CLIs in phase-based pipelines. It launches agent CLIs as subprocesses, normalizes their JSONL output through one stream pipeline, runs phases in dependency order, and handles configuration, rate-limit recovery, and shutdown. Consuming projects supply the domain logic: phase definitions, prompt templates, agent configuration, and presentation.
The library was extracted from four production orchestration systems, where an estimated 60-70% of the orchestration code was the same infrastructure.
Features
- Launches agent CLIs as async subprocesses, captures their output streams, and limits how many run at once.
- Normalizes five JSONL output formats into one
StreamEvent model through a four-stage stream pipeline (filter, parse, monitor, stall detection).
- Runs phases in dependency order, with each phase's agents running sequentially or in parallel, and supports resume, skip, and single-phase options.
- Detects rate limits, parses reset times (including named time zones), and retries after a backoff wait.
- Layers settings from TOML files,
.env and environment variables, constructor arguments, and named profiles, built on pydantic-settings.
- Separates the engine from presentation through the
UICallback protocol, so the consuming project chooses Rich, Textual, or headless output.
- Defines agents as data: a new agent CLI that uses a supported stream format needs only a TOML entry.
- On SIGINT or SIGTERM, terminates agent process trees and force-kills them after a 30-second grace period. With a workspace attached, completed phases are saved for resume.
- Starts agent subprocesses with a filtered environment by default and in an explicit working directory when one is given (
cwd). Git recovery runs only when a phase opts in.
- Emits optional OpenTelemetry traces through
OrchcoreTelemetry.
Where to Start
- Installation: requirements, install options, and optional extras.
- Quick Start: define agents, build phases, and run a pipeline.
- Configuration Reference: settings fields, sources, profiles, and environment variables.
- Stream Events Reference:
StreamEvent fields, event types, and agent states.
- UICallback Reference: protocol methods and the built-in implementations.
- Architecture Overview: package layout, core abstractions, and design decisions.
- Stream Pipeline: how the four stream-processing stages work.
- Design Document: problem statement, requirements, and key interfaces.
Modules
| Module |
Purpose |
stream/ |
4-stage pipeline (Filter → Parse → Monitor → Stall Detect) for 5 agent formats |
pipeline/ |
Phase orchestration: sequential or parallel multi-agent execution in topological dependency order |
runner/ |
Async subprocess management with stdout/stderr streaming and optional stdin prompt transport (prompt_via = "stdin") |
registry/ |
Agent configurations as data (TOML/dict) with runtime lookup |
config/ |
Layered settings from TOML files, profiles, .env, environment variables, and constructor arguments |
recovery/ |
Rate-limit detection, exponential backoff, git dirty-tree recovery |
workspace/ |
Artifact lifecycle management |
prompt/ |
Jinja2 template rendering with frontmatter stripping |
ui/ |
UICallback protocol, implemented by each consuming project for its own display layer |
signals/ |
Graceful SIGINT/SIGTERM shutdown |
display/ |
Colored stderr logging (no Rich dependency in core) |
observability/ |
Optional OpenTelemetry integration |
Guides
Architecture Decision Records
| ADR |
Decision |
| 001 |
Extract reusable orchestration core from 4 production systems |
| 002 |
Async-first with stdlib asyncio |
| 003 |
Protocol-based UI decoupling |
| 004 |
Composable 4-stage stream processing pipeline |
| 005 |
Multi-source layered configuration |
| 006 |
Pydantic for all data models |
| 007 |
Registry pattern for agent management |
| 008 |
Partial failure semantics with retry |
| 009 |
Tool assignment as phase-level concern |
| 010 |
Topological phase ordering and explicit success semantics |
| 011 |
Consumer-defined flag profiles replace the AgentMode enum |