Metadata-Version: 2.4
Name: orchcore
Version: 1.0.0
Summary: Reusable orchestration core for AI coding agent CLI pipelines
Project-URL: Homepage, https://github.com/AbdelazizMoustafa10m/orchcore
Project-URL: Repository, https://github.com/AbdelazizMoustafa10m/orchcore
Project-URL: Documentation, https://abdelazizmoustafa10m.github.io/orchcore
Project-URL: Issues, https://github.com/AbdelazizMoustafa10m/orchcore/issues
Project-URL: Changelog, https://github.com/AbdelazizMoustafa10m/orchcore/blob/main/CHANGELOG.md
Author: Abdelaziz Abdelrasol
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 5 - Production/Stable
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.12
Requires-Dist: jinja2>=3.1
Requires-Dist: pydantic-settings>=2.7
Requires-Dist: pydantic>=2.10
Requires-Dist: tzdata>=2024.1
Provides-Extra: dev
Requires-Dist: commitizen>=3.29; extra == 'dev'
Requires-Dist: coverage>=7.0; extra == 'dev'
Requires-Dist: hypothesis>=6.100; extra == 'dev'
Requires-Dist: mypy>=1.13; extra == 'dev'
Requires-Dist: pre-commit>=4.0; extra == 'dev'
Requires-Dist: pyright>=1.1; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest-cov>=6.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.8; extra == 'dev'
Provides-Extra: rich
Requires-Dist: rich>=13.0; extra == 'rich'
Provides-Extra: telemetry
Requires-Dist: opentelemetry-api>=1.29; extra == 'telemetry'
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.29; extra == 'telemetry'
Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.29; extra == 'telemetry'
Requires-Dist: opentelemetry-sdk>=1.29; extra == 'telemetry'
Provides-Extra: tui
Requires-Dist: textual>=0.40; extra == 'tui'
Description-Content-Type: text/markdown

# orchcore

> Reusable orchestration core for AI coding agent CLI pipelines.

[![CI](https://github.com/AbdelazizMoustafa10m/orchcore/actions/workflows/ci.yml/badge.svg)](https://github.com/AbdelazizMoustafa10m/orchcore/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/AbdelazizMoustafa10m/orchcore)](https://github.com/AbdelazizMoustafa10m/orchcore/releases)
[![PyPI](https://img.shields.io/pypi/v/orchcore)](https://pypi.org/project/orchcore/)
[![Python 3.12+](https://img.shields.io/badge/python-3.12%2B-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/AbdelazizMoustafa10m/orchcore/badge)](https://scorecard.dev/viewer/?uri=github.com/AbdelazizMoustafa10m/orchcore)
[![mypy: strict](https://img.shields.io/badge/mypy-strict-blue.svg)](https://mypy-lang.org/)
[![Ruff](https://img.shields.io/badge/linter-ruff-orange.svg)](https://docs.astral.sh/ruff/)
[![Coverage](https://codecov.io/gh/AbdelazizMoustafa10m/orchcore/graph/badge.svg)](https://codecov.io/gh/AbdelazizMoustafa10m/orchcore)

## What is orchcore?

orchcore is an async-first Python 3.12+ library that provides unified infrastructure for launching, monitoring, and managing multiple AI coding agent CLIs (Claude, Codex, Gemini, Copilot, OpenCode) as subprocesses through phase-based pipelines. It was extracted from four production orchestration systems — Planora, Articles, Finvault, and Raven — eliminating 60-70% of duplicated infrastructure so consuming projects only implement domain-specific logic.

<p align="center">
  <img src="assets/orchcore-architecture.png" alt="orchcore Architecture" width="700">
</p>

## Features

- **Multi-agent subprocess orchestration** — async launch, stream capture, concurrency control
- **Unified stream processing** — 4-stage pipeline normalizes 5 JSONL formats into a single `StreamEvent` model
- **Phase pipelines** — sequential/parallel execution with dependency checks and resume
- **Rate-limit recovery** — automatic detection, timezone-aware reset parsing, exponential backoff
- **Layered configuration** — TOML files, env vars, CLI overrides, named profiles
- **Protocol-based UI** — `UICallback` decouples engine from display (Rich, Textual, headless)
- **Registry-as-data** — new agent support via TOML config alone, zero code changes
- **Graceful shutdown** — SIGINT/SIGTERM with subprocess cleanup and state preservation
- **Safe subprocess boundaries** — filtered agent environments by default, explicit cwd support, and opt-in git recovery

## Installation

```bash
uv pip install orchcore
```

From source:

```bash
git clone https://github.com/AbdelazizMoustafa10m/orchcore.git
cd orchcore
uv pip install -e ".[dev]"
```

**Requirements:** Python 3.12+

## Quick Start

### 1. Define Agents

```toml
# agents.toml
[agents.claude]
binary = "claude"
model = "claude-sonnet-4-20250514"
subcommand = "-p"
stream_format = "claude"

[agents.claude.flags]
plan = ["--think", "--verbose"]

[agents.claude.output_extraction]
strategy = "jq_filter"
jq_expression = ".content[0].text"
```

### 2. Run a Pipeline

<!-- example:quickstart.py:begin -->
```python
"""Minimal orchcore pipeline setup.

Requires a matching ``agents.toml`` file and the configured agent CLI on
``PATH``. Use ``dry_run=True`` at the AgentRunner layer for artifact-level
smoke tests; a real pipeline run launches the configured CLI.
"""

from __future__ import annotations

import asyncio
from pathlib import Path

from orchcore.pipeline import Phase, PhaseRunner, PipelineRunner
from orchcore.registry import AgentMode, AgentRegistry, ToolSet
from orchcore.runner import AgentRunner
from orchcore.ui import NullCallback


async def main() -> None:
    registry = AgentRegistry()
    registry.load_from_toml(Path("agents.toml"))

    phase = Phase(
        name="planning",
        agents=("claude",),
        tools=ToolSet(internal=("Read", "Glob", "Grep"), permission="read-only"),
    )

    runner = AgentRunner()
    phase_runner = PhaseRunner(runner, registry, max_concurrency=4)
    pipeline = PipelineRunner(phase_runner)

    result = await pipeline.run_pipeline(
        phases=[phase],
        prompts={"planning": "Analyze the codebase and create a plan."},
        ui_callback=NullCallback(),
        mode=AgentMode.PLAN,
    )

    print(f"Success: {result.success} | Cost: ${result.total_cost_usd}")


if __name__ == "__main__":
    asyncio.run(main())
```
<!-- example:quickstart.py:end -->

By default, agent subprocesses receive a filtered environment: common API keys and provider-specific variables are not inherited unless you set `env_policy = "inherit"`, pass `env_passlist`, or provide explicit `env_vars` in your agent config.

## Modules

| Module | Purpose |
|--------|---------|
| `stream/` | 4-stage pipeline (Filter → Parse → Monitor → Stall Detect) for 5 agent formats |
| `pipeline/` | Phase orchestration — sequential/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 configuration: TOML → env vars → CLI overrides → profiles |
| `recovery/` | Rate-limit detection, exponential backoff, git dirty-tree recovery |
| `workspace/` | Artifact lifecycle management |
| `prompt/` | Jinja2 template rendering with frontmatter stripping |
| `ui/` | `UICallback` protocol for pluggable display layers |
| `signals/` | Graceful SIGINT/SIGTERM shutdown |
| `display/` | Colored stderr logging (no Rich dependency in core) |
| `observability/` | Optional OpenTelemetry integration |

## Documentation

Full documentation is available at **[abdelazizmoustafa10m.github.io/orchcore](https://abdelazizmoustafa10m.github.io/orchcore/)**.

| Document | Description |
|----------|-------------|
| [Installation](doc/getting-started/installation.md) | Prerequisites, install options, extras |
| [Quick Start](doc/getting-started/quickstart.md) | Define agents, build phases, run pipelines |
| [Configuration Reference](doc/reference/configuration.md) | Full settings table, profiles, env vars |
| [Stream Events Reference](doc/reference/stream-events.md) | StreamEvent fields, types, agent states |
| [UICallback Reference](doc/reference/ui-callback.md) | Protocol methods and built-in implementations |
| [Architecture](doc/architecture/overview.md) | Package layout, core abstractions, design decisions |
| [Stream Pipeline](doc/architecture/stream-pipeline.md) | 4-stage composable pipeline deep-dive |
| [Design Document](doc/architecture/design.md) | Problem statement, requirements, proposed design |
| [Writing a UICallback](doc/guides/writing-a-uicallback.md) | Build custom display layers |
| [Agent Registry](doc/guides/agent-registry.md) | TOML config, adding new agents, ToolSets |
| [Recovery & Retry](doc/guides/recovery-and-retry.md) | Rate limits, backoff, failure modes |
| [Contributing](doc/development/contributing.md) | Dev setup, code standards, testing |

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, testing instructions, and code standards.

Please also review [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) and [SECURITY.md](SECURITY.md).

## License

orchcore is released under the [MIT License](LICENSE).
