Skip to content

About

Local-first stack for running coding agents against shared local or remote inference.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

20 Commits

Folders and files

Repository files navigation

local-agent-stack

A reproducible, local-first environment for running coding agents against a shared inference service.

The project separates two responsibilities:

  • inference host — runs the model runtime and model weights
  • agent client — runs coding-agent harnesses such as Codex, Pi, and Goose

A single machine may have both roles.

Goals

  • Reproducible setup on macOS and Linux.
  • One shared local inference endpoint for multiple machines.
  • Interchangeable coding-agent harnesses.
  • Declarative model configuration.
  • No secrets or personal infrastructure details in Git.
  • A single health-check command.
  • Reproducible evaluation of model/harness combinations.
  • Ability to replace the inference host without rebuilding the client environment.

Architecture

             ┌── Codex
             ├── Pi
Agent client ┼── Goose
             └── other harnesses
                  │
                  ▼
          inference endpoint
                  │
                  ▼
             model runtime
                  │
                  ▼
                model

The initial reference environment is:

Mac mini / Apple Silicon
        │
        └── Ollama
              │
              └── local coding model

MacBook / Linux laptop
        │
        └── coding-agent harness
              │
              └── remote inference endpoint

The architecture intentionally does not depend on the Mac mini.

A future backend may be:

Linux
  └── NVIDIA GPU
       └── Ollama / vLLM / another OpenAI-compatible runtime

without changing the agent-client workflow.

Roles

inference-host

Responsible for:

  • model downloads
  • model runtime
  • inference API
  • runtime health checks

agent-client

Responsible for:

  • Codex
  • Pi
  • Goose
  • agent configuration
  • connection to an inference endpoint

Quick start

Clone the repository:

git clone <https://github.com/akrisanov/local-agent-stack.git>
cd local-agent-stack

Configure a machine as an inference host:

make bootstrap ROLE=inference-host
make doctor

Configure a client:

make bootstrap ROLE=agent-client
make doctor

Local configuration

Public defaults live in .env.example.

Machine-specific configuration lives outside the repository in ~/.config/local-agent-stack/env.

The repository excludes secrets and personal infrastructure details, such as:

  • API keys
  • OAuth tokens
  • Tailscale auth keys
  • SSH credentials
  • machine-specific private addresses
  • work infrastructure endpoints

Models

Desired models are declared in models/models.yaml and managed through the repository tooling.

The current reference model is qwen3.6:35b-mlx, served by Ollama on the inference host.

Agent harnesses

The project currently supports:

  • Codex CLI
  • Pi
  • Goose

Each harness has repository-managed installation and local-inference launch scripts:

make codex-install
make codex-local

make pi-install
make pi-local

make goose-install
make goose-local

Qwen Code and OpenCode may be added later for comparison.

Running an implementation plan

scripts/run-plan starts Pi for a plan that is ready for implementation. It uses the public plan inspect --json contract and does not depend on a checkout of the plans source repository.

The runner is used directly from this checkout. Install its Python dependency, install Pi, and install the independent plan CLI using its distribution instructions:

uv sync
make pi-install

Prerequisites:

  • uv, plan, and pi are available through PATH;
  • PLANS_HOME points to the private plan data directory;
  • REPOS_HOME points to the directory under which repository checkouts are stored;
  • $PLANS_HOME/repos.yaml maps logical plan repository names to paths relative to REPOS_HOME.

For example, this private configuration:

# $PLANS_HOME/repos.yaml
repositories:
  local-agent-stack:
    path: local-agent-stack
  service-api:
    path: work/service-api

resolves local-agent-stack to $REPOS_HOME/local-agent-stack and service-api to $REPOS_HOME/work/service-api. Keep paths relative: machine-specific absolute paths must not be placed in plan files or repos.yaml.

Run a new plan in the next state with:

export PLANS_HOME="$HOME/path/to/plan-data"
export REPOS_HOME="$HOME/Projects"
uv run scripts/run-plan <plan-id> --harness pi

The same command retries a plan that is already in the open state. A retry starts a new Pi session from the current open plan; it does not resume the previous Pi session or perform another lifecycle transition.

To select an explicit provider and model (for example, via OpenRouter), including when retrying an open plan:

uv run scripts/run-plan <plan-id> --harness pi \
  --provider openrouter \
  --model openai/gpt-5.6-sol

For a next plan, the runner completes all preflight checks before transitioning it to open. The selected next plan must be tracked by the Git repository containing PLANS_HOME, and its contents must match the version in HEAD; commit the implementation-ready plan before running it. Unrelated uncommitted planning files do not block execution, and a local commit is sufficient—no push is required. The runner then re-inspects the plan and starts Pi in the resolved checkout with the open plan path and implementation instructions. For an open plan, it uses the existing open plan path and starts Pi without a transition. Plans in other states are rejected.

The runner never stages, commits, pushes, or marks a plan as done. If Pi fails, its nonzero status is returned and the plan remains open, so the command can be run again to retry it.

Run the deterministic runner tests (which use stub plan and pi executables) with:

make test

The Python toolchain uses Ruff for linting and formatting and ty for type checking:

make lint
make format-check
make typecheck

Evaluations

The repository includes a controlled evaluation suite for comparing model/harness combinations.

Run an evaluation with:

make eval HARNESS=pi TASK=bug-diagnosis

The current tasks are:

  • repo-inspection — inspect the repository, reconstruct its architecture and request paths, and propose concrete improvements without modifying files
  • bug-diagnosis — inspect a failing codebase, identify the root cause, and explain the minimal fix without modifying files
  • minimal-fix — diagnose the failure, implement the smallest correct change, and verify it with tests
  • multi-file-bug — trace a failure across multiple modules, identify the root cause, implement the smallest correct fix, and verify the full test suite
  • feature-implementation — implement a small cross-file feature, update the relevant tests, and verify the complete test suite

Evaluation fixtures live in evals/fixtures/, task definitions in evals/tasks/, generated runs in evals/runs/, manual reviews in evals/reviews/, and consolidated results in evals/results/.

Each evaluation produces objective run metadata locally, including wall time, test results, changed files, and diff size. A separate committed review records the subjective verdict, recovery behavior, requirement coverage, final-answer completion, and notes.

Create a review template after a run with:

make review HARNESS=goose TASK=minimal-fix

Preview the consolidated report for the current model with:

make report

The current baseline evaluates qwen3.6:35b-mlx with Codex, Pi, and Goose. Goose has a complete structured baseline across all five tasks; Pi and Codex are being migrated to the same evaluation pipeline so harness comparisons use identical run metadata and review criteria.


© 2026, Andrey Krisanov

About

Local-first stack for running coding agents against shared local or remote inference.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages