Bootstrap rein-openweights: minimal agentic loop over OpenRouter (REIN-OW-WP-0001)

Implements T01-T04:
- tools.py: green-commit-only-equivalent tool surface (read/write/edit/
  glob/grep + git status/diff/log/add+commit), path-traversal guarded.
- openrouter_client.py: own minimal chat-completions client — llm-connect's
  OpenRouterAdapter takes a single prompt string and never surfaces
  tool_calls, so it can't drive a multi-turn tool-calling loop without a
  breaking change to its frozen Core ABC. llm-connect stays an optional
  dependency (pyproject.toml), not load-bearing.
- loop.py: plan -> tool call -> observe -> repeat, budget- and
  turn-bounded, tool errors reported back to the model instead of
  crashing the loop.
- credentials.py: own OpenBao AppRole/ambient-token acquisition, per
  glas-harness ADR-002 (Option B) — glas-harness does not broker this.
- runner.py/hub.py: commit-verified success criterion + State Hub
  progress/token reporting, mirroring rein-aharness's model.

26 tests, all mocked at the httpx/subprocess boundary — no real
OpenRouter or OpenBao calls made. T05 (Forgejo repo creation) stays
open, deferred to the operator.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-07-26 13:37:09 +02:00
parent ac5407a83e
commit 4ee612140b
21 changed files with 1207 additions and 36 deletions

View file

@ -14,11 +14,11 @@ repeat, with a bounded tool policy) without building one from scratch per
occasion.
rein-openweights exists to be that harness: one agentic loop, model
supplied via OpenRouter (through `llm-connect`), usable anywhere a
rein-aharness-equivalent session is wanted but a frontier-vendor
dependency is not — cost-sensitive workloads, offline/degraded-network
tolerance, or simply comparing open-weight model capability against
frontier baselines on the same task.
supplied via OpenRouter, usable anywhere a rein-aharness-equivalent
session is wanted but a frontier-vendor dependency is not —
cost-sensitive workloads, offline/degraded-network tolerance, or simply
comparing open-weight model capability against frontier baselines on
the same task.
## Governing principle
@ -32,8 +32,11 @@ owns the open-weight-model-specific agentic loop and tool execution.
## What it must never become
- **Not a model router.** Choosing which OpenRouter model to use for a
given task, pricing, and fallback stays in `llm-connect`. This repo
consumes `llm-connect`, it does not reimplement provider routing.
given task, pricing, and fallback is a caller/config concern (`--model`),
not logic this repo owns. `llm-connect` remains available as an
optional dependency for future needs (structured-JSON side calls,
diagnostics/replay) but is not load-bearing for the base agentic loop
— see glas-harness ADR-002 and `src/rein_openweights/openrouter_client.py`.
- **Not a second harness framework.** Session semantics, tool policy
schema, sandbox consumption, and audit reporting are glas-harness's
contract (`GLAS-WP-0001-T01`) — this repo implements it, not forks it.
@ -44,7 +47,12 @@ owns the open-weight-model-specific agentic loop and tool execution.
## Status
Charter + local scaffold only. See `workplans/REIN-OW-WP-0001-bootstrap.md`
for the first concrete milestone (minimal tool-use loop against one
OpenRouter open-weight model, same starter tool surface as
rein-aharness's `green-commit-only` profile).
Minimal agentic loop implemented and unit-tested (26 tests, all mocked
at the network/subprocess boundary): tool surface, OpenRouter client,
credential acquisition, commit-verified success criterion, State Hub
reporting. See `workplans/REIN-OW-WP-0001-bootstrap.md`. Not yet
executed against a real OpenRouter model or a real OpenBao instance —
those are human-triggered follow-ups (real API cost, real credentials).
No glas-harness adapter (`reins/rein_openweights.py`, mirroring
`reins/rein_aharness.py`) yet — that's a `GLAS-WP-0001` follow-up once
this CLI is considered stable enough to shell out to.