Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Orchestrator (orch.py)

The orchestrator is a single CLI entry point, agents/orch.py (this repo's agents/ dir). Projects get a .agents symlink to this repo's agents/ dir, so the tool is invoked from inside a target project as:

./.agents/orch.py <action> <domain/Feature> [inline prompt] [options]

REPO_ROOT = Path.cwd() — the orchestrator operates on whatever directory you run it from (the target project), not on this repo. This repo is the tool. model_config.json, model_chain.json, personas/, and rules/ live in agents/ (i.e. .agents/... from a target project).

Every command routes through _orchestrator/commands.py::dispatch(). There are no other entry points — runner.py is an internal subprocess (never run by hand), and the old standalone scaffolder.py / scaffold_project.py scripts have been deleted.

Options

Flag Effect
--prompt / -p <path-or-text> Prompt file (.md read from disk) or inline string. Positional text after the target is also accepted.
--model / -m <id> Persist {"model": <id>} to model_config.json (this repo root), then continue the run with that model leading the chain.
--no-controller Skip Controller.py generation (background workers).
--app / -a <app> App context, e.g. -a private resolves against features/ instead of web/features/. Auto-selected from the domain when the project defines apps.

Target syntax

<domain/Feature> — split on the first /. Without a domain, it is inferred from .features.json known_features, else nodomain. Commands with no target (do, delete, merge, undo, qa) infer the feature from the current git branch name.

Commands

Command What it does Next
init <path>/<project-name> Create project folder + .agents symlink → agents/. Does not create .features.json. Prompt arg ignored. new
new <domain/Feature> "prompt" Create feature branch, write spec.md (LLM-generated + spec-QA'd, template fallback), scaffold 4 files (Schema.py, Handler.py, Controller.py, Tests.py) + __init__.py, register in .features.json. do
modify <domain/Feature> "prompt" Amend the feature's spec.md via LLM + append a CONTRACT AMENDMENT section; branch modify/<Feature>. Implicit mode (no target): uses the file currently open in nvim. Creates the feature dir if missing (no controller). do
do [Feature] Run the backend agent: LLM implements spec.md, QA gates validate, pytest must pass; then stage + commit (feat: <Name>) + push the branch (not merged). On main with clean slate, auto-creates the feature branch. merge
delete [Feature] rm -rf the feature dir, unregister from .features.json, delete local branch(es). Remote branch untouched. scan / new
merge On a feature branch: commit staged work, merge branch into main, delete local + remote branch. scan / new
undo On a feature branch: fetch + checkout main + reset --hard + clean -fd, delete local + remote branch. new / scan
move <OldDomain/OldFeature> <NewDomain/NewFeature> Rename dir, re-register in .features.json, run uv run pytest tests/, rename branch if checked out, commit move: ..., push (not merged). merge
scan Discover feature slices under features_dir by structure, list grouped by domain. new / modify
qa Run every feature's Tests.py via pytest + rules-based code standards audit. No LLM. scan / new

Flow per feature: newdomerge. modify slots in before do. delete / undo discard work. qa is a standalone audit — run anytime.

Feature model

  • .features.json (repo root, or discovered nested): features_dir (default features), known_features (name → domain), domain_keywords (keyword → [domain, action]), optional per-apps override configs.
  • Domains are subdirectories of features_dir; a feature is features/<domain>/<Feature>/.
  • Branches are named <domain>/<Feature> (or modify/<Feature>), mirroring the feature path. check_branch auto-creates them from main when the tree is clean; guard_open_branches refuses to start work while other open branches exist.
  • Owned by _orchestrator/feature.py (ProjectFeatures, register_target, unregister_feature, load_project). Single implementation — nothing else reads/writes .features.json.

Rules engine

rules/<lang>/core.json (this repo root, i.e. .agents/rules/... from a target project) holds declarative checks per language (currently python/). The engine in _orchestrator/rules.py classifies files by extension, loads the matching rule set, and executes checks (line, text-required, balanced, py-ast kinds). Both consumers use this single registry:

  • orch.py qa — audits every .py in the repo + feature slices.
  • runner.pyvalidate_code_standards (group standards) and validate_code_structure (group structure).

To add a check, edit rules/python/core.json (or create a new language dir). No code changes required.

Code-generation pipeline (do)

launcher.run_runner("backend", feature_dir, task) spawns runner.py as a subprocess with the backend_agent.md persona:

  1. Read spec.md + task; collect existing files in the feature dir.
  2. Few-shot prompt: built from working features in the same domain (FEW_SHOT_COUNT = 2).
  3. LLM (via _orchestrator/llm.py) returns code; extracted and written, protected files preserved.
  4. QA gates: code standards, unused imports, AGENTS.md constitution (11 rules), root-file checks, .features.json sync, PEP8, truncation, structure; then pytest on the feature's tests.
  5. On failure, loop re-runs with the error output (auto_backend), exhausting attempts before returning failure. do then reports and tells the user to paste the output back to the AI.

Only when all gates pass does do commit and push.

Model selection

_orchestrator/llm.py::llm_complete(prompt, system, model, timeout=300, max_attempts=6) shells out to the pi CLI (pi -p --mode json --model <m>) and extracts the final assistant text from the JSONL event stream. Attempt order = [requested model] (or default_model() from model_config.json) then the chain in model_chain.json, deduplicated, capped at max_attempts. Each model gets exactly one attempt — no repeats; on error / empty response / raw tool-call markers it falls through to the next model.

model_chain.json (this repo root) is the editable, most-capable-first tier-one chain — edit it to reorder without touching code. --model writes model_config.json so a paid model leads subsequent runs. Current chain:

[
  "openrouter/poolside/laguna-s-2.1:free",
  "openrouter/cohere/north-mini-code:free",
  "opencode/nemotron-3-ultra-free",
  "opencode/deepseek-v4-flash-free",
  "opencode/laguna-s-2.1-free",
  "llama-swap/qwen2.5-coder-7b-instruct"
]

Supporting files

File Role
orch.py CLI: arg parsing, --model persistence, dispatch.
_orchestrator/commands.py All command handlers + parsing (domain/Feature, known prefixes).
_orchestrator/feature.py Feature resolution: .features.json, domains, targets, branch-name inference.
_orchestrator/scaffold.py scaffold_new_feature (spec + 4 templates), init_new_project (folder + symlink).
_orchestrator/specs.py Spec generation/QA (rewrite_spec_with_ai, amend_spec, _qa_spec, _validate_spec).
_orchestrator/git_ops.py Every git operation — commands.py never shells out to git itself.
_orchestrator/launcher.py Spawns runner.py with a persona.
_orchestrator/llm.py pi-based completions with the model chain (sole owner of model selection).
_orchestrator/prompts.py Prompt resolution incl. current-file detection via nvim --headless.
_orchestrator/templates.py Code + spec templates, default overview.
_orchestrator/config.py Paths: REPO_ROOT, AGENTS_DIR, PERSONAS_DIR, MODEL_CONFIG; load_persona(name).
_orchestrator/rules.py Rules engine — executes rules/<lang>/core.json checks.
_orchestrator/runner.py Backend subprocess engine (never run by hand).
rules/python/core.json (via .agents/) Declarative Python checks (line/text/ast/balanced kinds).
personas/*.md backend_agent.md (used by do), spec_qa_agent.md (loaded via load_persona).

Tests

The orchestrator is managed with uv (no .venv, no pip). From this repo root:

uv run pytest _orchestrator/tests -q   # single suite: commands, feature, git, llm, templates, runner, rules

About

AI coding agent orchestrator: model chaining, feature scaffolding, and agentic execution

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages