ref:main

feat(runner): advertise local models and their capabilities on heartbeat #57

merged colechristensen cole.christensen@gmail.com wants to merge feat/advertise-inference-models into main

Why

The routed model picker in Anvil is populated by the runner, not the server: Anvil.Agents.Inference.list_inference_models/1 unions metadata["inference_models"] across the online inference runners in scope.

The heartbeat only ever sent parallel and slots_busy. That union was therefore always empty, and the picker rendered the configured model as unchangeable text — indistinguishable from a provider that cannot enumerate. This is the missing runner-side half, documented on the server since the feature landed (docs/agents.md, “Routed discovery has a runner-side half”).

What it sends

{"name": "llama3.2:latest", "capabilities": ["completion", "tools"]}

Anvil filters on these. An agent chat always sends a tool set, so a model without tools fails on its first call — offering it is offering a guaranteed error.

Compatibility and failure behaviour

  • A model whose capabilities Ollama does not report is sent with the key omitted, not as an empty list. The server treats that as unknown and keeps the model — the right behaviour when nothing is known.
  • A bare string is still a valid entry server-side, so a fleet on an older runner keeps working.
  • Best-effort by design. Ollama being down or slow must never cost a heartbeat: a failed lookup omits the key and the heartbeat goes out regardless. The previously reported list then stays in place server-side, where sending an empty list would retract it. The lookup has its own 3s timeout, well inside the heartbeat interval.

Verification

End to end against a local Anvil dev instance with this runner and a local Ollama:

  • the picker lists the local models, grouped by provider, each tagged with the runner serving it
  • selecting one routes the run through this runner and the reply comes back credited to it
  • gemma3:1b reports ["completion"] and is correctly hidden when the chat requires tools (menu 23 → 19)

Pairs with fangorn/anvil#246, which adds the capability filtering on the server.

🤖 Generated with Claude Code

Created Aug 05, 2026 at 03:58 UTC | Merged Aug 05, 2026 at 04:41 UTC by colechristensen cole.christensen@gmail.com