OllamaDiscovery
Category: Providers
Source: ollama_discovery.dart
Read-only client for Ollama's metadata endpoints.
Today we only need /api/tags — the list of locally-pulled models — so the model picker can stop lying about which catalog entries are actually runnable. The client is fail-soft by construction: every network error, timeout, non-200, or malformed JSON collapses to an empty list. Callers never need to try/catch.
A tiny in-memory cache (30 s TTL keyed by base URL) absorbs the case where a user opens the picker repeatedly within a short window.
Classes
OllamaInstalledModel
One entry from GET /api/tags — the fields we actually use.
Constructor
const OllamaInstalledModel({
required this.tag,
required this.sizeBytes,
required this.modifiedAt,
})Properties
| Property | Type | Description |
|---|---|---|
tag | String | Fully-qualified tag as Ollama reports it, e.g. qwen3-coder:30b. |
sizeBytes | int | |
modifiedAt | DateTime? |
OllamaPullProgress
One NDJSON frame from POST /api/pull. Ollama emits a status string (pulling manifest, downloading, success, …) and, for download frames, total/completed byte counters.
Constructor
const OllamaPullProgress({
required this.status,
this.total,
this.completed,
this.digest,
this.error,
})Properties
| Property | Type | Description |
|---|---|---|
status | String | |
total | int? | |
completed | int? | |
digest | String? | |
error | String? | |
isSuccess | bool get | |
hasError | bool get | |
isSuccess | bool get | |
hasError | bool get | |
fraction | double? get | 0.0..1.0 when download byte counters are present, else null. |
OllamaDiscovery
Constructor
OllamaDiscovery({
required this.baseUrl,
http.Client Function()? clientFactory,
this.timeout = const Duration(seconds: 2),
this.cacheTtl = const Duration(seconds: 30),
DateTime Function()? now,
})Properties
| Property | Type | Description |
|---|---|---|
baseUrl | Uri | Ollama's HTTP root. Accepts the /v1 suffix (OpenAI-compat path) and the bare form — we normalise internally so callers don't have to. |
timeout | Duration | |
cacheTtl | Duration | |
models | List<OllamaInstalledModel> | |
expiresAt | DateTime |
Methods
Future<List<OllamaInstalledModel>> listInstalled()
GET /api/tags. Returns an empty list on any failure — never throws.
void invalidateCache()
Drop the cache entry for this base URL. Tests and /model refresh call this; normal picker open should rely on the TTL.
Stream<OllamaPullProgress> pullModel(String tag)
Stream NDJSON progress from POST /api/pull. The stream completes when Ollama finishes (a {"status":"success"} frame) or errors out. On error the final frame carries [OllamaPullProgress.error] so callers can surface it without try/catch boilerplate.
static void resetCacheForTesting()
For tests: wipe all cached entries regardless of base URL.