-
Notifications
You must be signed in to change notification settings - Fork 1
backend selection
- src/repodocs/backend.py
- README.md
RepoDocs delegates all page-planning and page-writing work to an external LLM CLI rather than calling a model API directly. Which CLI is invoked, and with what model, is controlled by two environment variables, REPODOCS_BACKEND and REPODOCS_MODEL, read by src/repodocs/backend.py. The module supports exactly three backends — claude, omp, and codex — each invoked as a read-only subprocess with no session persistence.
Sources: src/repodocs/backend.py:L14-L14, README.md:L130-L138
backend_name() reads REPODOCS_BACKEND from the environment, lowercases and strips it, and defaults to "claude" when unset. If the value is not one of BACKENDS = {"omp", "claude", "codex"}, it raises ValueError. require_backend() wraps this and calls die() with exit code 2 on an invalid value, so CLI entry points fail fast with a clear message instead of propagating a traceback.
Sources: src/repodocs/backend.py:L14-L39
The README documents the same three choices and the login step each requires: Claude Code needs claude installed and /login once; OMP needs repodocs setup plus omp --profile=repo-docs /login; Codex needs codex login.
Sources: README.md:L88-L93, README.md:L136-L138
effective_model(backend) implements the precedence: an explicit REPODOCS_MODEL environment value always wins regardless of backend. If it's unset, the claude backend falls back to DEFAULT_CLAUDE_MODEL = "claude-sonnet-5", while omp and codex fall back to None, letting those CLIs use their own built-in default model.
Sources: src/repodocs/backend.py:L17-L17, src/repodocs/backend.py:L42-L50
llm_label() composes a human-readable string for logging/UI, e.g. "claude/claude-sonnet-5" or "omp default model", by combining backend_name() and effective_model().
Sources: src/repodocs/backend.py:L78-L81
Before dispatch, backend_contract(prompt) selects a system-prompt contract based on the prompt's opening text: prompts starting with "Plan the wiki pages" load agents/wiki-planner.md, prompts starting with "Write the wiki page" load agents/wiki-writer.md, both prefixed with the vendored AGENTS.md; any other prompt gets a minimal deterministic-subprocess instruction. Loaded contracts are cached in _CONTRACT_CACHE per mode.
Sources: src/repodocs/backend.py:L20-L23, src/repodocs/backend.py:L53-L75
run_llm(repo, prompt) dispatches to one of three subprocess command builders based on backend_name(), using a timeout from REPODOCS_TIMEOUT (default 600 seconds).
Sources: src/repodocs/backend.py:L120-L127
claude -p --safe-mode --no-session-persistence --permission-mode dontAsk \
--tools Read,Grep,Glob --append-system-prompt <contract> [--model <model>]
The prompt is piped via input=prompt with cwd=repo, so Claude Code operates directly against the target repository's working directory, restricted to the Read,Grep,Glob tool set.
Sources: src/repodocs/backend.py:L140-L150
omp --profile=repo-docs -p --no-session --cwd <repo> \
--config <isolation.yml> --no-rules --no-skills --no-extensions \
--tools=read,grep,glob --approval-mode=write \
--append-system-prompt <contract> [--model=<model>] <prompt>
OMP is invoked with an explicit isolation config file (PROFILE_SOURCE / "isolation.yml"), rules/skills/extensions disabled, and the tool set constrained to read,grep,glob; the prompt is passed as a trailing positional argument rather than via stdin.
Sources: src/repodocs/backend.py:L128-L139
codex exec --ephemeral --sandbox read-only --skip-git-repo-check \
--cd <tempdir> --output-last-message <tempfile> [--model <model>] -
The Codex path first prints a one-time stderr warning via _warn_codex_read_boundary(), then creates a temporary directory, symlinks the target repo into it as repo_view, and runs codex exec from that temp directory with the prompt (contract + repo-root note + original prompt) piped over stdin (-). Codex writes its final answer to --output-last-message, which run_llm reads back into a CompletedProcess; if the file is missing, it synthesizes a failed result from stderr.
Sources: src/repodocs/backend.py:L100-L117, src/repodocs/backend.py:L151-L179
Security note: --sandbox read-only only blocks writes, not reads. The code's own comment states this restriction does not stop an adversarial repository (e.g. a hostile README or source comment) from causing the model to read and exfiltrate files outside the repo through generated docs, and that a real fix would need a container/VM-level read boundary, which is out of scope for this CLI. The README repeats this as "Ephemeral read-only sandbox" without further caveat, so the fuller warning lives only in code and in the runtime stderr message.
Sources: src/repodocs/backend.py:L100-L117, README.md:L138-L138
jobs_count() reads REPODOCS_JOBS (default 4), clamped to the range 1–16, falling back to 4 if the value isn't a valid integer. parallel_llm() uses this to size a ThreadPoolExecutor that submits run_llm for each (key, prompt) pair; with REPODOCS_JOBS=1 this becomes effectively serial. Each REPODOCS_TIMEOUT-bounded subprocess call is independent, so a hung backend call fails only that page rather than the whole run.
Sources: src/repodocs/backend.py:L182-L205, README.md:L152-L154
| Backend | Env value | Login step | Tool restriction | Model override | Prompt delivery |
|---|---|---|---|---|---|
| Claude Code (default) | claude |
claude then /login
|
--tools Read,Grep,Glob |
--model (default claude-sonnet-5) |
stdin |
| OMP | omp |
repodocs setup, omp --profile=repo-docs /login
|
--tools=read,grep,glob, --no-rules --no-skills --no-extensions, isolation config |
--model= |
trailing arg |
| Codex | codex |
codex login |
--sandbox read-only (write-only boundary, see security note) |
--model |
stdin, output via --output-last-message
|
Sources: src/repodocs/backend.py:L120-L179, README.md:L88-L93, README.md:L136-L138
- Home
- Installation & Setup
- Architecture
- CLI Reference
- LLM Backend Selection
- Repository Scanning
- Wiki Page Planning
- Page Generation
- Source Citations
- Translation
- HTML Rendering
- Diagram Rendering
- Diagram Poster Tool
- Git Remote Link Resolution
- Publishing
- GitHub Wiki Integration
- Shared Utilities
- Environment Configuration
- Security & Trust Boundaries
- Limitations & Non-goals
- Testing
- Development
- Contributing
- Upgrading
- Changelog