feat(runner): serve routed inference against local Ollama (anvil#298) #25
merged
cole.christensen@gmail.com wants to merge
feat/inference-runner
into main
No CI
The runner side of the Anvil runner relay — fangorn/anvil#298 (epic fangorn/anvil#145).
What
When a runner carries the inference label, anvil runner start now also polls for inference requests and serves them from its own local model, exactly like the CI job loop runs over the runner’s outbound connection. The Anvil server never makes an outbound model call — the inference has the same trust boundary as a CI job.
src/runner/inference.rs— an inference poller (mirrorsloop_runner’s CI poller): claimsPOST /api/v1/runners/:id/inference/claim, does the Anvil↔Ollama wire translation, calls local Ollama/api/chat, and reports the result toPOST /api/v1/runners/:id/inference/:request_id/result.- Anvil internal → Ollama: messages (string and typed-block content, incl. tool_use / tool_result round-trips), tool defs → function tools,
system/temperature/max_tokensoptions. - Ollama → Anvil:
content/tool_uses/stop_reason/usage(mirrorsAnvil.Agents.Providers.Ollama).
- Anvil internal → Ollama: messages (string and typed-block content, incl. tool_use / tool_result round-trips), tool defs → function tools,
loop_runner— spawns the inference poller whenlabelsincludeinference(a runner can be CI-only, inference-only, or both).config—ollama_url(defaulthttp://localhost:11434).runner configure—--ollama-urlflag; args grouped intoConfigureOpts(clears clippytoo_many_arguments).
Verified end-to-end
Against a dockerized Anvil (this branch’s server code) + a local llama3.2:1b:
runner configure --labels self-hosted,inferenceregisters;runner startlogs[inference] polling ….- A routed agent run (
AgentProviderConfigtransport: routed→ resolver →Routedprovider) enqueues a request; the runner claims it, calls local Ollama, posts the result; the caller gets a real model response. DB shows the requestcompleted, claimed by this runner.
Notes
- Non-streaming v1 (the request runs to completion; token streaming from the runner is a later refinement).
cargo fmt/clippy -D warnings/cargo test(86) all clean.
Created May 30, 2026 at 08:34 UTC
| Merged May 30, 2026 at 23:54 UTC
by
cole.christensen@gmail.com