### [aider](https://github.com/paul-gauthier/aider)

> Handle: `aider`
> URL: [http://localhost:34011/](http://localhost:34011/)

Aider lets you pair program with LLMs,
to edit code in your local git repository.
Start a new project or work with an existing git repo.
Aider works best with GPT-4o & Claude 3.5 Sonnet and can
[connect to almost any LLM](https://aider.chat/docs/llms.html).

<p align="center">
  <img
    src="https://aider.chat/assets/screencast.svg"
    alt="aider screencast"
  >
</p>

#### Starting

Harbor runs `aider` in a CLI mode.

```bash
# [Optional] pre-pull if needed
harbor pull aider

# See available options
harbor aider --help
```

When running `aider`, Harbor will mount current working directory as a container workspace. This means that running `aider` from a subfolder in a git repo will mask away the fact it's a git repo within the container.

```bash
# Run aider in the current directory
harbor aider

# Aider supports browser/GUI mode
# "Network URL" will be open-able in your browser
harbor aider --gui
```

#### Integrations

`aider` (the pair-programming CLI that edits code in your local git repo, with optional GUI on port 8501) is automatically wired to many Harbor LLM backends via cross-compose files (`services/compose.x.aider.*.yml`). When you `harbor up <backend> aider` (or invoke `harbor aider` while a backend is active), the matching overlay mounts a backend-specific snippet from `services/aider/configs/aider.<backend>.yml` into `/home/appuser/.aider/`. The container entrypoint (`start_aider.sh`, always mounted) runs `yaml_config_merger.py --pattern ".yml"` over the directory; it renders `${VAR}` references from the current environment, recursively merges the YAML dicts (base first, then snippets in lexical order), and writes the result to `.aider.conf.yml` (also mirrored to `$HOME` for auto-discovery). Aider then reads the produced `openai-api-base`, `openai-api-key`, and `model` settings.

**LLM backends that auto-configure for aider**

- `ollama` — mounts `aider.ollama.yml` using the dynamic `${HARBOR_OLLAMA_INTERNAL_URL}/v1` + `sk-ollama`
- `llamacpp` — `aider.llamacpp.yml` → `http://llamacpp:8080/v1` with `sk-llamacpp`
- `vllm`, `litellm`, `tabbyapi`, `sglang`, `aphrodite`, `mistralrs`, `ktransformers`, `airllm` — each contributes its own `aider.<name>.yml` with the service's internal OpenAI-compatible URL and the corresponding Harbor key
- `dify` — targets the `dify-openai:3000/v1` workflow proxy using `${HARBOR_DIFY_OPENAI_WORKFLOW}`
- `unsloth-studio` — `aider.unsloth-studio.yml` + a bootstrap sidecar (`unsloth-studio-bootstrap`). The sidecar's freshly minted key is read at runtime by `start_aider.sh` from the read-only mount of `./services/unsloth-studio/.studio-auth` (into `/run/unsloth-studio-auth`) *before* the merger executes, and an explicit `depends_on: service_completed_successfully` ensures the first `harbor up unsloth-studio aider` succeeds cleanly. Uses `${HARBOR_UNSLOTH_STUDIO_API_KEY}`.

Every snippet sets `model: openai/${HARBOR_AIDER_MODEL}` (and `verify-ssl: false`). Control the model via `harbor aider model <spec>` (updates `HARBOR_AIDER_MODEL` in `.env`); the next launch re-runs the merger with the fresh value. The Configuration section examples (`harbor aider model $(harbor vllm model)`) keep the two sides in sync.

**Direct cloud / third-party provider keys**

The base `compose.aider.yml` always populates a wide set of provider API keys in the container environment from the corresponding Harbor variables:

- `ANTHROPIC_API_KEY=${HARBOR_ANTHROPIC_KEY}`
- `GROQ_API_KEY=${HARBOR_GROQ_KEY}`
- `OPENROUTER_API_KEY=${HARBOR_OPENROUTER_KEY}`
- `TOGETHERAI_API_KEY=${HARBOR_TOGETHERAI_KEY}`
- `PERPLEXITY_API_KEY=${HARBOR_PERPLEXITY_KEY}`
- `FIREWORKS_API_KEY=${HARBOR_FIREWORKS_KEY}`
- `MISTRAL_API_KEY=${HARBOR_MISTRAL_KEY}`
- `COHERE_API_KEY=${HARBOR_COHERE_KEY}`
- `GOOGLE_API_KEY=${HARBOR_GOOGLE_KEY}`
- plus `ANYSCALE`, `APIPIE`, `SHUTTLEAI`, `ASSISTANTS`, `BINGAI`, etc.

You can therefore invoke `harbor aider --model claude-3-5-sonnet-20241022` (or any supported provider model) directly against those services as soon as the key exists in Harbor — no local backend required.

**Reverse proxy / external access**

- With `traefik` present: `compose.x.traefik.aider.yml` (generated) adds labels so the GUI mode (`harbor aider --gui`) is reachable at `https://aider.${HARBOR_TRAEFIK_DOMAIN}` on the websecure entrypoint.

**Host / volume interactions**

- **Workspace / git repo mount (core host integration)**: `run_aider_command` in the Harbor CLI performs
  ```
  docker compose run -it --rm -v "$original_dir:/home/appuser/workspace" --workdir /home/appuser/workspace ... aider "$@"
  ```
  (plus TERM and PYTHONIOENCODING). The directory you are in on the host becomes the container workspace; aider can therefore read, edit, and `git` your local repository. The entrypoint also executes `git config --global --add safe.directory ...` to permit operations across the bind mount.
- **Important documented behavior**: invoking from a subdirectory of a git repo mounts only that subdirectory; the parent `.git` is invisible inside the container, so aider's git features will not see the outer repository root.
- **Config & runtime volumes** (always active): `services/aider/configs/aider.config.yml` (empty base) mounted at `config.yaml`, plus `start_aider.sh` and `yaml_config_merger.py` (from `shared/`). Any active backend also mounts its `aider.<backend>.yml` into the scanned directory. `services/aider/override.env` supplies extra `AIDER_*` settings visible only to the container.
- All `.aider.*` state files (history, etc.) written by aider land back on the host inside the workspace mount because the container is ephemeral (`--rm` for normal `harbor aider` use).

**GPU / accelerator support**

- `compose.x.aider.nvidia.yml` and the generated `compose.x.aider.cdi.yml` (chosen by Harbor's capability detection) add GPU device reservations (`capabilities: [gpu]`, count all) to the aider container via the nvidia driver or CDI. This keeps the container consistent with GPU-backed backends and enables any local acceleration paths inside the `paulgauthier/aider-full` image.

All of the above is supplied by the cross-compose layer; you do not edit the `compose.x.*.aider.yml` or per-backend snippets directly. After changing `HARBOR_AIDER_MODEL`, any `HARBOR_*_KEY`, or `HARBOR_TRAEFIK_DOMAIN`, run `harbor config update` (if applicable) and simply re-execute `harbor aider` — the entrypoint will re-merge with the current environment and the currently-mounted backend snippets.

#### Configuration

`aider` is pre-configured to automatically work with the LLM backends supported by Harbor. You only need to point it to the correct model.

```bash
# Lists active services
harbor ls -a # nothing

# Will try using OpenAI API
harbor aider

# Run one of supported backends
harbor up vllm webui
harbor ls -a # webui vllm

# Set a new model for aider as the model that
# vllm is currently using
harbor aider model $(harbor vllm model)
# Or set a specific model
harbor aider model "microsoft/Phi-3.5-mini-instruct"

# Will use vLLM model
harbor aider

# Let's run with Ollama
harbor down
# "ollama" specifier is not needed if ollama
# is one of the default services
harbor up ollama
# Will use Ollama config now, ensure to point
# it to the correct model!
harbor aider
```

You can configure aider in Harbor via:
- specifying [supported CLI args](https://aider.chat/docs/config/options.html)
- `services/aider/override.env` file, [official .env reference](https://aider.chat/docs/config/dotenv.html)
- `services/aider/configs/aider.config.yml` file, [official config reference](https://aider.chat/docs/config/aider_conf.html)
  - Note, that Harbor will override certain portions of this config to connect Aider to the LLM backends
