fix(router/discovery): always probe ollama capabilities, cache is optional

DiscoverOllama() interpreted a nil probeCache as 'skip probing
entirely' rather than 'probe but don't cache.' cmd/gnoma/main.go's
synchronous discovery path passes nil, so every ollama-discovered
model got SupportsTools=false (the Go zero value), regardless of
what ollama actually reported in its capabilities field.

The symptom: filterFeasible rejected every ollama arm for any
tool-requiring task with reason=tools_required_but_unsupported,
even when ollama itself reported the model as tool-capable. Verified
via curl: qwen3:14b advertises capabilities=[completion, tools,
thinking] and has 'tools' in its template, but the gnoma arm shipped
with tool_use_capability=false.

Fix: always run probeOllamaModel; treat probeCache as an optional
memoisation aid only. nil cache now means 'no caching across calls'
not 'no probing.' For users with many models, passing a real cache
still avoids redundant HTTP calls — semantics for that path are
unchanged.

Surfaced via the new filterFeasible Debug logging from the previous
commit, which made the per-arm rejection reasons visible.
This commit is contained in:
2026-05-25 02:28:05 +02:00
parent 0d3d190a8b
commit fd327107df
+16 -5
View File
@@ -93,16 +93,27 @@ func DiscoverOllama(ctx context.Context, baseURL string, probeCache map[string]O
Size: m.Size,
}
// Always probe; the cache is optional. Previously nil-cache was
// treated as "skip probing entirely", which left SupportsTools
// at its zero value (false) for every model — every ollama-
// discovered arm then got marked as tool-unsupported and
// rejected by filterFeasible for any tool-requiring task. main.go
// passes nil from the synchronous discovery path; we still want
// real probe data there.
var result OllamaProbeResult
if probeCache != nil {
result, ok := probeCache[m.Name]
if !ok {
if cached, ok := probeCache[m.Name]; ok {
result = cached
} else {
result = probeOllamaModel(ctx, baseURL, m.Name)
probeCache[m.Name] = result
}
dm.SupportsTools = result.SupportsTools
dm.SupportsVision = result.SupportsVision
dm.ContextSize = result.ContextSize
} else {
result = probeOllamaModel(ctx, baseURL, m.Name)
}
dm.SupportsTools = result.SupportsTools
dm.SupportsVision = result.SupportsVision
dm.ContextSize = result.ContextSize
if dm.ContextSize == 0 {
dm.ContextSize = defaultOllamaContextSize