Adds llm.Foreman(baseURL, apiKey, opts...) to v2/constructors.go — a thin constructor that delegates to the existing native ollama provider. This is Level 0 of the foreman integration described in ADR-0011.
Zero new code paths. foreman speaks native Ollama on the wire (/api/chat), so the existing ollama provider handles streaming, tool use, and think transparently.
baseURL is positional and required — foreman has no default public address (it's a private daemon on the homelab/Tailscale).
apiKey can be empty for network-trusted deployments where the firewall/Tailscale is the auth boundary.
Includes DD#9 in v2/CLAUDE.md documenting the decision.
Usage
// Authenticated deploymentmodel:=llm.Foreman("http://foreman.orgrimmar:8080",os.Getenv("FOREMAN_TOKEN")).Model("qwen3:30b")// Network-trusted (no token)model:=llm.Foreman("http://foreman:8080","").Model("qwen3:30b")
What this does NOT include
A dedicated foreman provider (Level 2) — deferred unless async /jobs or webhook integration is needed at the llm layer.
The foreman client package (Level 1 sync facade over /jobs) — that lives in the foreman repo.
Test plan
Verify go build ./... passes in v2/
Verify go vet ./... passes in v2/
Verify go test ./... passes in v2/
Manual: llm.Foreman(url, token).Model("qwen3:30b") produces a working client against a running foreman instance
## Summary
Adds `llm.Foreman(baseURL, apiKey, opts...)` to `v2/constructors.go` — a thin constructor that delegates to the existing native ollama provider. This is Level 0 of the foreman integration described in [ADR-0011](https://gitea.stevedudenhoeffer.com/steve/foreman/src/branch/main/docs/adr/0011-go-client-and-go-llm-integration.md).
- **Zero new code paths.** foreman speaks native Ollama on the wire (`/api/chat`), so the existing ollama provider handles streaming, tool use, and think transparently.
- **`baseURL` is positional and required** — foreman has no default public address (it's a private daemon on the homelab/Tailscale).
- **`apiKey` can be empty** for network-trusted deployments where the firewall/Tailscale is the auth boundary.
- Includes DD#9 in `v2/CLAUDE.md` documenting the decision.
### Usage
```go
// Authenticated deployment
model := llm.Foreman("http://foreman.orgrimmar:8080", os.Getenv("FOREMAN_TOKEN")).Model("qwen3:30b")
// Network-trusted (no token)
model := llm.Foreman("http://foreman:8080", "").Model("qwen3:30b")
```
### What this does NOT include
- A dedicated foreman provider (Level 2) — deferred unless async `/jobs` or webhook integration is needed at the llm layer.
- The foreman `client` package (Level 1 sync facade over `/jobs`) — that lives in the [foreman repo](https://gitea.stevedudenhoeffer.com/steve/foreman).
## Test plan
- [ ] Verify `go build ./...` passes in `v2/`
- [ ] Verify `go vet ./...` passes in `v2/`
- [ ] Verify `go test ./...` passes in `v2/`
- [ ] Manual: `llm.Foreman(url, token).Model("qwen3:30b")` produces a working client against a running foreman instance
Foreman is a private queued Ollama endpoint with observability. Since it
speaks native Ollama on the wire, the constructor delegates to the existing
ollama provider — no new code paths. Streaming, tool use, and think all
work transparently.
baseURL is positional and required (no sensible default for a private
daemon). apiKey can be empty for network-trusted deployments.
See ADR-0011 in the foreman repo for the integration design.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Adds
llm.Foreman(baseURL, apiKey, opts...)tov2/constructors.go— a thin constructor that delegates to the existing native ollama provider. This is Level 0 of the foreman integration described in ADR-0011./api/chat), so the existing ollama provider handles streaming, tool use, and think transparently.baseURLis positional and required — foreman has no default public address (it's a private daemon on the homelab/Tailscale).apiKeycan be empty for network-trusted deployments where the firewall/Tailscale is the auth boundary.v2/CLAUDE.mddocumenting the decision.Usage
What this does NOT include
/jobsor webhook integration is needed at the llm layer.clientpackage (Level 1 sync facade over/jobs) — that lives in the foreman repo.Test plan
go build ./...passes inv2/go vet ./...passes inv2/go test ./...passes inv2/llm.Foreman(url, token).Model("qwen3:30b")produces a working client against a running foreman instancePull request closed