Replace openrouter-rs with in-tree client and require sandbox

Remove the openrouter-rs dependency in favor of a minimal in-tree
OpenRouter chat-completions client, and drop the BOT_NAME and
SANDBOX_ENABLED config options. Reviews now always run inside the
sandbox, and the review prompt asks the model to read files with the
available tools instead of embedding the diff.
This commit is contained in:
2026-09-17 14:48:42 +00:00
parent ee221b0954
commit 04cc172848
15 changed files with 1301 additions and 740 deletions
+9 -6
View File
@@ -26,7 +26,6 @@ Herald reads its configuration from environment variables (a `.env` file is supp
| Variable | Description |
|---|---|
| `HTTP_PORT` | Port to listen on |
| `BOT_NAME` | The bot's Gitea username (used to detect mentions) |
| `WEBHOOK_SIG_HEADER_SECRET` | Gitea webhook secret for signature verification |
| `OPEN_ROUTER_API_KEY` | OpenRouter API key |
| `OPEN_ROUTER_MODEL` | Model to use (e.g. `deepseek/deepseek-v4-flash`) |
@@ -38,20 +37,24 @@ Herald reads its configuration from environment variables (a `.env` file is supp
| `METRICS_BIND_ADDR` | *(optional)* Bind address for the Prometheus metrics endpoint (e.g. `0.0.0.0:9100`). If unset, the metrics exporter is disabled. |
| `SENTRY_DSN` | *(optional)* Sentry DSN for error tracking |
| `RUST_LOG` | *(optional)* Log level, defaults to `info` |
| `SANDBOX_ENABLED` | *(optional)* Run reviews inside a devcontainer sandbox so the model can explore the repository with tools. Defaults to `false` |
| `CONTAINER_RUNTIME` | *(optional)* Container runtime binary used for the sandbox (`docker` or `podman`). Defaults to `docker` |
| `SANDBOX_MAX_ITERATIONS` | *(optional)* Maximum number of tool-calling iterations per sandboxed review. Defaults to `8` |
## Sandboxed reviews
When `SANDBOX_ENABLED=true`, Herald reviews pull requests inside an ephemeral
Herald reviews pull requests inside an ephemeral
[Dev Container](https://containers.dev/). For each review it:
1. clones the pull request head into a temporary directory,
2. builds and starts the repository's devcontainer (`devcontainer-rs`),
3. lets the model explore the repository with read-only tools (`ls`, `read_file`,
`grep`, `find`) executed inside the container,
4. posts the review and removes the container and the temporary clone.
3. reads the pull request diff and file list from the Gitea API with
`GITEA_TOKEN` (so private repositories work), tells the model which files and
lines changed — additions and deletions, with the line numbers of the new and
old versions of the file respectively — then lets it explore the repository
with read-only tools (`ls`, `read_file`, `grep`, `find`) run inside the
container: the code itself is not sent, so the model reads it at those lines,
4. posts the review, anchoring each comment on the added or removed line it
refers to, and removes the container and the temporary clone.
The container runtime is selected with `CONTAINER_RUNTIME` (`docker` or
`podman`). The repository must contain a `.devcontainer/devcontainer.json`.