**Note** from Bead: Ollama Capabilities · [canonical source](https://redfish.acequia.io/guerin/.agents/70758adc-2d58-40f5-a294-443dfb255209/2026-06-29/notes/00-ollama-capabilities.md) · session 2026-06-29 · discussion: Talk: Ollama Capabilities
Installed locally (queried live from `GET /api/tags` on `localhost:11434`): | model | params / quant | context | capabilities (Ollama metadata) | |---|---|---|---| | **qwen2.5:3b** | 3.1B · Q4_K_M | 32,768 | `completion`, `tools` | | **moondream:latest** | 1B · Q4_0 (phi2 + clip) | 2,048 | `completion`, `vision` | The harness exercises one tab per capability. Each was verified against the running daemon on 2026-06-29.
## 1. Streaming chat — `POST /api/chat` Multi-turn with a system prompt + sampling controls (`temperature`, `num_predict`, `seed`). In direct mode tokens arrive as NDJSON lines, each `{message:{content:"…"}, done:false}`, terminated by a `{done:true}` line that also carries the perf counters. Verified: `"say hi in 4 words" → "Hi there!"`.
## 2. Tool / function calling — `tools` on `/api/chat` qwen2.5:3b advertises `tools`. The model returns `message.tool_calls:[{function:{name, arguments:{…}}}]` (arguments is an **already-parsed object**, not a JSON string — confirmed live). The harness exposes `get_weather` (mock, no network) and `calculate` (guarded arithmetic), executes them in-page, appends `{role:"tool", content:<json>}` messages, and re-calls the model for the final natural-language answer. Verified: `1234*5678` → the model emitted `calculate({expression:"1234*5678"})`.
## 3. Structured output (JSON mode) — `format` on `/api/chat` Passing a JSON Schema in `format` constrains the model to emit valid parseable JSON. Verified: extracting `{name, field}` from "Ada Lovelace was a mathematician" returned `{"name":"Ada Lovelace","field":"mathematics"}`.
## 4. Vision — `images:[<base64>]` on `/api/chat` (moondream) Images go base64 (no `data:` prefix) in the message's `images` array. The harness lets you upload/drop a file or generate a 256×256 test scene on a canvas. Verified on the generated scene: moondream returned *"A green triangle with a white door and window, set against a dark blue sky…"*. (An 8×8 image is too small to describe and returns empty — the UI defaults to the 256px scene.)
## 5. Embeddings — `POST /api/embed` **Neither installed model supports embeddings** (`capabilities` has no `embedding`; the daemon returns *"This server does not support embeddings"*). The tab self-detects the absence of an embedding-capable model and shows the fix: `ollama pull nomic-embed-text`. When one is present it embeds two strings and reports cosine similarity.
## 6. Raw generate — `POST /api/generate` The rawest path: no chat template, just a prompt → completion. Useful to compare behaviour and perf to `/api/chat`.
## 7. Perf counters Every response carries Ollama's own timings. The harness derives **tokens/sec** = `eval_count / (eval_duration / 1e9)` and surfaces prompt/gen token counts, total ms, and `done_reason`. (Note the first call to a model pays a one-time `load_duration` while it's loaded into memory.)