@octocodeai/freellama-mcp-server 0.9.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CONFIGURATION.md +82 -3
  2. package/DEVELOPING.md +40 -9
  3. package/README.md +317 -172
  4. package/dist/agent-cli.js +16963 -0
  5. package/dist/index.js +5424 -4320
  6. package/dist/research/bash-agent.js +308 -120
  7. package/dist/research/coder-agent.js +476 -139
  8. package/dist/research/github-agent.js +298 -107
  9. package/dist/research/octocode-agent.js +297 -106
  10. package/docs/AGENT_CLI.md +234 -0
  11. package/docs/API.md +160 -0
  12. package/docs/ARCHITECTURE.md +158 -50
  13. package/docs/ASSESSMENT.md +131 -0
  14. package/docs/BENCHMARK.md +381 -0
  15. package/docs/BUILD_AND_NOTES.md +12 -3
  16. package/docs/CLI.md +62 -17
  17. package/docs/CPU_GPU_ROUTING.md +22 -9
  18. package/docs/DEFERRED_JOBS.md +17 -4
  19. package/docs/FEATURES.md +97 -43
  20. package/docs/LLAMACPP.md +133 -0
  21. package/docs/LOCAL_MODELS.md +26 -20
  22. package/docs/MODEL_FORMS_AND_RESULTS.md +14 -6
  23. package/docs/MODEL_INTROSPECTION.md +9 -2
  24. package/docs/MODEL_SELECTION.md +39 -10
  25. package/docs/MONITORING.md +110 -12
  26. package/docs/OLLAMA_REVIEW.md +226 -0
  27. package/docs/PRODUCTION.md +68 -25
  28. package/docs/PROMPTS.md +119 -0
  29. package/docs/README.md +22 -6
  30. package/docs/RELIABILITY.md +207 -0
  31. package/docs/RUST_RESOURCE_AUDIT.md +65 -0
  32. package/docs/SCOPES_AND_WARMING.md +12 -5
  33. package/docs/TESTING.md +112 -6
  34. package/docs/TUNING.md +12 -8
  35. package/docs/assets/benchmark-results-2026-11-14.html +4 -0
  36. package/docs/assets/tool-calling-2026-11-14-bonsai-9b/TABLE.md +14 -0
  37. package/docs/assets/tool-calling-2026-11-14-lfm3-vl/TABLE.md +14 -0
  38. package/docs/assets/tool-calling-table.md +14 -0
  39. package/docs/cookbooks/README.md +9 -2
  40. package/docs/cookbooks/batch-text.md +4 -2
  41. package/docs/cookbooks/classify.md +19 -3
  42. package/docs/cookbooks/coding.md +13 -4
  43. package/docs/cookbooks/find-code.md +8 -3
  44. package/docs/cookbooks/jobs.md +8 -8
  45. package/docs/cookbooks/memory-and-caching.md +2 -2
  46. package/docs/cookbooks/ocr.md +3 -3
  47. package/docs/cookbooks/research-agent.md +32 -2
  48. package/docs/cookbooks/speech-to-text.md +1 -1
  49. package/docs/cookbooks/sweep.md +4 -1
  50. package/docs/octocode/GITHUB.md +4 -4
  51. package/docs/octocode/LOCAL.md +5 -4
  52. package/native/index.d.ts +1 -1
  53. package/package.json +6 -6
  54. package/docs/COMPARISON.md +0 -40
@@ -1,9 +1,10 @@
1
1
  # Local model catalog
2
2
 
3
- Which local model to use for each job on one machine, what was measured, and what is only
4
- published. The method for choosing a model on other hardware is in
5
- [Choose local models](MODEL_SELECTION.md). For live answers about your machine, use `models {view:"catalog"}`
6
- or `freellama catalog`; for the exact calls, see the [cookbooks](cookbooks/README.md).
3
+ A dated comparison of local models for each job on one machine, separating measured results
4
+ from published claims. The method for choosing a model on other hardware is in
5
+ [Choose local models](MODEL_SELECTION.md). For current installed candidates, use `models {view:"catalog"}`
6
+ or `freellama catalog`; job execution first consults [machine-local calibration](MODEL_SELECTION.md#turn-measurements-into-routing-evidence),
7
+ then catalog fallback. The tables below do not pin that live choice. For exact calls, see the [cookbooks](cookbooks/README.md).
7
8
 
8
9
  **Snapshot:** 2026-11-01. Apple M2 Pro, 32 GB unified memory, Ollama 0.40.13, FreeLlama 0.8.0. Other
9
10
  work was running throughout, leaving about 4–14 GB available. Each model answered the same questions
@@ -30,11 +31,11 @@ Group a model by the job it does, using the capability Ollama reports. FreeLlama
30
31
  | Speech | `speech` | `speech` | Text to speech | `audio {action:"speak", text}` |
31
32
  | Embedding | `embedding` | `embedding_only` | Code search, duplicates, image search | `run_task {task:"embedding", files, nearest}` |
32
33
  | Decision | `decision` | `decision` | Classify, triage, route, yes/no | `run_task {task:"decision", state, questions}` |
33
- | Not runnable in Ollama | none | none | Rerankers, tiny classifiers, most dedicated speech models | Needs another runtime; FreeLlama cannot serve them |
34
+ | Not runnable in Ollama | none | none | Rerankers, tiny classifiers, most dedicated speech models | Ollama cannot run these; the [managed llama.cpp adapter](LLAMACPP.md) supports only its documented text-task subset |
34
35
 
35
- ## Tested picks for each job
36
+ ## Historical tested picks for each job
36
37
 
37
- ### Use now: installed, and fit alongside normal work
38
+ ### Installed at the snapshot: fit alongside normal work
38
39
 
39
40
  | Job | Model | File | Memory needed | Evidence |
40
41
  |---|---|---:|---:|---|
@@ -42,13 +43,13 @@ Group a model by the job it does, using the capability Ollama reports. FreeLlama
42
43
  | Find code for an issue | `embeddinggemma-2:740m-q8_0` | 1.3 GB | 1.4 GB | Measured: right file first 9/10, top 3 9/10; `nomic-embed-text` 6/10 and 8/10, but indexes in 42 s against 67 s |
43
44
  | Find duplicates | `nomic-embed-text:v1.5` | 0.3 GB | 1.4 GB | Measured: 8/12 real issue pairs |
44
45
  | Find an image by describing it | `embeddinggemma-2:740m-q8_0` | 1.3 GB | 1.4 GB | Measured: 5/5 screenshots, about 1 s per query |
45
- | OCR, reading text in images | `hf.co/openbmb/MiniCPM-OCR-1.0-gguf:Q4_K_M` | 1.4 GB | 3.8 GB | Measured: 30/30 in all 3 rounds, 257 ms median; `glm-ocr` also 30/30 at 1,885 ms |
46
+ | OCR, reading text in images | `hf.co/openbmb/MiniCPM-OCR-1.0-gguf:Q4_K_M` | 1.4 GB | 3.8 GB | Measured: 30/30 in all 3 rounds, 257 ms median. Its tables come back as OTSL; `read-table` turns them into Markdown |
46
47
  | Image understanding | `lfm3-vl:2b-q4_K_M` | 1.5 GB | 4.1 GB | Measured: 20/20 drawn images in all 3 rounds, 299 ms; `lfm3-omni` 18/20, `bonsai-2:9b` 17/20 |
47
48
  | Speech to text | `lfm3-audio:2b-q4_K_M` | 1.7 GB | 5.5 GB | Measured: 1.7% word error on 12 generated sentences, 276 ms median, French and Spanish translation worked; `lfm3-omni` the same |
48
49
  | Text to speech | `phonon:en` | 0.1 GB | not previewed | Measured: 0.8–1.7% word error when transcribed back, 102 ms median; both LFM3 models 0% at 950 ms, but the judge is an LFM3 model |
49
- | Small coding tasks | `lfm3:1.7b-q4_K_M` | 1.1 GB | 3.3 GB | Measured: 21, 20, 20 of 25, 579 ms median; `bonsai-2:9b` 19, 19, 17 |
50
+ | Small coding tasks | `bonsai-2:9b` | 3.2 GB | 10.3 GB | Measured: 19, 19, 17 of 25, 475 ms median, and every workflow case right in the 2026-11-12 field test. `lfm3:1.7b` scored 21, 20, 20 on the questions but answered workflows with tool calls nobody asked for, so it is no longer a pick |
50
51
 
51
- ### Use when memory is free: installed
52
+ ### Installed at the snapshot: need more free memory
52
53
 
53
54
  | Job | Model | File | Memory needed | Evidence |
54
55
  |---|---|---:|---:|---|
@@ -66,7 +67,7 @@ Group a model by the job it does, using the capability Ollama reports. FreeLlama
66
67
  | `bonsai-2:27b` | 8.3 GB | Installed. FreeLlama asks for 16.3 GB available; this machine never had more than 14.4 GB, so it is not measured here. Published: SWE-bench Verified 60.8%, LiveCodeBench 90.1% |
67
68
  | `qwen3.6:27b-q4_K_M` | 17.4 GB | Needs 28.7 GB available, so only on a nearly empty 32 GB machine. Removed from this machine untested |
68
69
 
69
- ### Worth adding: not installed, untested here
70
+ ### Candidates at the snapshot: not installed, untested here
70
71
 
71
72
  Pull a tag only with approval for that exact tag and size.
72
73
 
@@ -97,9 +98,11 @@ score) in one forward pass, with no generated text. Local decision models follow
97
98
  The original Nimble 9B (not v3) scored 75.7% against Jev 1.13's 76.0% on the same 3,880 human-labeled
98
99
  decisions; its publisher ran that test.
99
100
 
100
- **Recommendation:** keep `strands-decider` for everyday decisions, and trial `nimble-v3:9b-q4_K_M`
101
- for harder ones. Compare them on your own labeled data before switching, since `strands-decider`
102
- already scores 35/36 on real issues here.
101
+ **Historical interpretation:** `strands-decider` was the smaller starting point and
102
+ `nimble-v3:9b-q4_K_M` a candidate for harder decisions in this sample. The 35/36 issue result
103
+ is one dataset, not a calibrated accuracy guarantee. Compare exact installed tags on your own
104
+ labeled data and use [machine-local evidence](MODEL_SELECTION.md#turn-measurements-into-routing-evidence)
105
+ before changing the live choice.
103
106
 
104
107
  **Limits of this comparison:**
105
108
 
@@ -111,9 +114,9 @@ Other families:
111
114
 
112
115
  - `d1`, `d1-omni` and `d3` publish other benchmarks, so they are not ranked here. `d1-omni` matters when decisions need images or audio.
113
116
  - `jevos-v4` claims 28–130 ms on a laptop CPU with its own binary and also ships GGUF files. No JevBench score was found, and loading in Ollama was not checked.
114
- - `openjev` is 27B and licensed CC-BY-NC, which bars commercial use.
117
+ - `openjev` was listed as 27B under CC-BY-NC in this snapshot; inspect the current repository license before use.
115
118
 
116
- ## New models on Hugging Face and Ollama
119
+ ## Candidates found on Hugging Face and Ollama, 2026-10-31
117
120
 
118
121
  Trending on 2026-10-31 and filtered to what could fit. Quality is the publishers' claim. **Path**:
119
122
  Ollama is an official tag, HF GGUF pulls as `hf.co/<repo>:<quant>`, and "not via Ollama" needs another
@@ -152,25 +155,28 @@ through the real CLI.
152
155
  | Model | Local questions | GitHub questions | Notes |
153
156
  |---|---:|---:|---|
154
157
  | `lfm3-audio:2b-q4_K_M` | 3, 3, 3 of 8 | 3, 3, 3 of 6 | Guessed names and repeated calls; 3.2 calls per question |
155
- | `lfm3:1.7b-q4_K_M` | 6, 5, 5 of 8 | 1, 1, 1 of 6 | Good on local lookups, weak on GitHub; 2 calls per question, 20 s median |
158
+ | `lfm3:1.7b-q4_K_M` | 6, 5, 5 of 8 | 1, 1, 1 of 6 | Good on local lookups, weak on GitHub; 2 calls per question, 20 s median. No longer a pick |
156
159
  | `bonsai-2:9b` | 4, 5, 5 of 8 | 3, 5, 5 of 6 | 2.2 calls per question; 82 s median per question |
157
160
  | Nemotron-3.5-Bolt-E4B | 6, 6, 6 of 8 | 5, 5, 5 of 6 | 2.2 calls per question; 96 s median per question; needs 13.5 GB |
158
161
 
159
162
  Three rounds each. An answer counts as right only if it contains every expected fact and rests on at
160
- least one tool call.
163
+ least one tool call. These historical research outcomes are separate from the newer
164
+ [tool-calling smoke suite](RELIABILITY.md#measured-on-2026-11-14), which has two exact models and
165
+ one trial per public case and does not establish general agent reliability.
161
166
 
162
167
  ## What runs in FreeLlama
163
168
 
164
169
  - **Managed, with routing, memory checks and receipts:** chat, coding, vision, embeddings, decisions.
165
170
  - **Through serve's passthrough, with memory checks:** speech and transcription (`audio`).
166
- - **Not supported:** a second, non-Ollama runtime; separate images per question in one decision, because Ollama shares images across all questions.
171
+ - **Managed llama.cpp text tasks:** one operator-run loopback `llama-server`, selected explicitly as `name/model`; see the [supported task subset and lifecycle limits](LLAMACPP.md).
172
+ - **Not supported:** separate images per question in one decision, because Ollama shares images across all questions.
167
173
  - **Hugging Face:** GGUF repositories work in discovery and pull through Ollama as `hf.co/<repo>:<quant>`. Multimodal GGUF needs an Ollama-supported architecture.
168
174
 
169
175
  ## Still open
170
176
 
171
177
  - Measure `bonsai-2:27b` when 16.3 GB is available.
172
178
  - Measure audio embeddings through `files`; image embeddings are measured, audio ones are not.
173
- - Run the candidates under "Worth adding".
179
+ - Evaluate the dated candidates above only after checking current availability and approving any exact-tag download.
174
180
  - Test `embeddinggemma-2` on duplicates; only `nomic-embed-text` is measured there.
175
181
 
176
182
  ## Detailed results
@@ -1,10 +1,14 @@
1
1
  # Model forms and measured results
2
2
 
3
- Moved from the root README. Dated measurements describe one machine and workload.
3
+ Dated measurements describe one machine and workload. Current job/workflow selection uses
4
+ [machine-local calibration](MODEL_SELECTION.md#turn-measurements-into-routing-evidence) before
5
+ catalog fallback; the historical ratings below do not determine that choice. Newer
6
+ [tool-calling evidence](RELIABILITY.md#measured-on-2026-11-14) covers two models with one trial on
7
+ each of seven public cases, separately from the older single-call examples below.
4
8
 
5
9
  ## Model forms
6
10
 
7
- Managed forms get routing, admission and a receipt; passthrough forms reach Ollama through `serve`
11
+ Ollama-managed forms get routing, admission and a receipt; passthrough forms reach Ollama through `serve`
8
12
  with the raw stream cap and memory checks but no routing or receipt.
9
13
 
10
14
  | Form | Ollama endpoint | Through FreeLlama | Measured here |
@@ -19,21 +23,25 @@ with the raw stream cap and memory checks but no routing or receipt.
19
23
  | Transcription and translation | `/v1/audio/transcriptions`, `/v1/audio/translations` | MCP `audio`, through the passthrough's memory checks; LFM3 audio needs Ollama 0.40.12+ | `lfm3-audio:2b-q4_K_M` transcription 7.5% word error over 5 sentences; translation not measured |
20
24
  | Image generation | removed from Ollama in 0.32.6 | not available | — |
21
25
 
22
- Find any of these with `models {view:"library", capabilities:["decision"]}` (or `audio`,
26
+ The [managed llama.cpp adapter](LLAMACPP.md) also supports explicit bounded text tasks; it does
27
+ not inherit Ollama's modalities, automatic catalog discovery or placement evidence.
28
+
29
+ Find Ollama forms with `models {view:"library", capabilities:["decision"]}` (or `audio`,
23
30
  `embedding`, `vision`...), or a Hugging Face GGUF build with a `query`.
24
31
 
25
32
  ### Local models, measured
26
33
 
27
34
  One Apple M2 Pro (32 GB), Ollama 0.40.8, FreeLlama 0.6.1, 2026-10-30, while other builds kept the
28
35
  one-minute load near 14 on 12 cores. Each check has a known answer; the batteries are small, so read
29
- the ratings as a first screen for these exact tags, not a benchmark.
36
+ the ratings as historical editorial judgments for these exact tags, not a benchmark score or
37
+ a measured probability of success. They predate the auditable [reliability corpus](RELIABILITY.md).
30
38
 
31
39
  | Model | Download | Forms | Result | Speed (warm) | Rating | Use it for |
32
40
  |---|---:|---|---|---|---:|---|
33
- | `gpt-oss:20b` | 13.8 GB | text, tools, thinking, JSON | 7/7: exact output, arithmetic, bat-and-ball, code reading, JSON extraction, tool call, 9/9 ticket routing | 1.4 s per routed ticket; 12 s first call with load | 9/10 | General agent work and tool calls when quality matters |
41
+ | `gpt-oss:20b` | 13.8 GB | text, tools, thinking, JSON | 7/7: exact output, arithmetic, bat-and-ball, code reading, JSON extraction, tool call, 9/9 ticket routing | 1.4 s per routed ticket; 12 s first call with load | 9/10 | Candidate for the measured text tasks; broader tool reliability unmeasured in that round |
34
42
  | `nomic-embed-text:v1.5` | 274 MB | embedding | Retrieval 4/4 top-1; ticket routing 9/9 from two examples per team | 51 ms per item, batched | 9/10 | Search, deduplication, cheap classification |
35
43
  | `strands-decider:2b-nvfp4` | 1.3 GB | decision | Ticket routing 9/9, return-policy yes/no 3/3, damage rubric 2/3 | 0.17 s per question | 8/10 | Fast routing and policy checks with probabilities; rubric scores run low at the top level |
36
- | `glm-ocr:latest` | 2.2 GB | vision (OCR) | 4/4 phrases read from a dense report strip; 0/7 on text tasks | 11 s per strip at a 400-token cap | 8/10 OCR, 1/10 text | Reading screenshots and scans only |
44
+ | `glm-ocr:latest` | 2.2 GB | vision (OCR) | 4/4 phrases read from a dense report strip; 0/7 on text tasks | 11 s per strip at a 400-token cap | 8/10 OCR, 1/10 text | OCR candidate for screenshots; scans were not measured |
37
45
 
38
46
  ### What they did for a coding agent
39
47
 
@@ -1,6 +1,9 @@
1
1
  # Inspecting model precision, placement and activations
2
2
 
3
- Reviewed 1 November 2026 against Ollama's current API documentation and source. The locally installed CLI reports 0.40.13; this session could not reach its server, so no live model or activation was inspected. The commands below are instructions, not recorded observations.
3
+ External API review: 1 November 2026. That session's locally installed Ollama CLI reported 0.40.13;
4
+ its server was unreachable, so no live model or activation was inspected. The commands below are
5
+ instructions, not recorded observations. The FreeLlama integration boundary was updated on
6
+ 14 November 2026; the historical API review is not a new verification of upstream versions.
4
7
 
5
8
  ## What “which bit/neuron was enabled” can mean
6
9
 
@@ -109,7 +112,11 @@ This example was not run. It assumes a compatible research model already loaded
109
112
 
110
113
  ## FreeLlama integration boundary
111
114
 
112
- Keep ordinary routing and resource control on stock Ollama. A future inspection tool can expose quantization, static tensor metadata and residency through existing endpoints. Label activation tracing unsupported unless a specific backend adapter actually provides it.
115
+ Ordinary discovery and observed placement use stock Ollama. The optional
116
+ [managed llama.cpp adapter](LLAMACPP.md) provides bounded text inference, not activation traces
117
+ or verified physical placement. Neither engine path exposes hidden activations through FreeLlama.
118
+ Static metadata and residency are separate from activation tracing; label traces unsupported
119
+ unless a specific backend adapter actually provides them.
113
120
 
114
121
  If deeper tracing is added, use a separate explicitly enabled debug runner or an instrumented Ollama backend, with bounded capture and paged artifacts. Rust should manage jobs, limits, cancellation and trace metadata. It should not infer neuron activity from GPU utilization, memory use, token probabilities or generated reasoning text.
115
122
 
@@ -4,13 +4,15 @@ To offload a task, select an installed model with the required capabilities and
4
4
  then check its memory fit under the intended concurrency. FreeLlama applies model eligibility
5
5
  and admission; the calling agent still verifies the output.
6
6
 
7
- The measurements in this guide come from single machines and are not compiled into routing:
7
+ The dated tables in this guide describe single machines; they do not qualify live routing on
8
+ another host. Current job selection uses [machine-local evidence](#turn-measurements-into-routing-evidence)
9
+ first, then the portable catalog fallback. The historical sources are:
8
10
  [Recommended starting points](#recommended-starting-points-by-form) from an Apple M2 Pro with 32 GB,
9
11
  the sections after it from an Apple M4 Pro with 48 GB unified memory. Re-run
10
12
  `npx @octocodeai/freellama doctor`, `models`, `bench-all`, and your quality suite on the target hardware.
11
13
  `doctor.machine.memory_bytes` is host RAM; a discrete GPU's usable VRAM must be observed separately.
12
14
 
13
- For the best model per job measured on one machine, with newer candidates, see the [local model catalog](LOCAL_MODELS.md).
15
+ For a dated per-job comparison and candidates from one machine, see the [local model catalog](LOCAL_MODELS.md).
14
16
 
15
17
  For supported features and sourced publisher use-case guidance, inspect
16
18
  `models {view:"installed", includeLibrary:true}` through MCP. [Model metadata](#model-metadata) explains digest matching, variant capabilities,
@@ -19,7 +21,7 @@ custom-model fallbacks, and how to read family claims without treating them as q
19
21
  ```mermaid
20
22
  flowchart TD
21
23
  T{"What must the task do?"}
22
- T -->|"Generate text, code, or inspect images"| L["Start with one qualified large multimodal model"]
24
+ T -->|"Generate text, code, or inspect images"| L["Inspect installed models with the required capabilities"]
23
25
  T -->|"Create retrieval vectors"| E["Use a small embedding model"]
24
26
  T -->|"Classify, route, or answer yes/no"| D["Use a small decision model"]
25
27
  T -->|"Transcribe or speak"| A["Use an audio or speech model"]
@@ -46,14 +48,14 @@ calls shown are the current ones. Later and larger measurements, audio and memor
46
48
  | Text, tools, JSON, reasoning | `gpt-oss:20b` (13.8 GB) | 7/7: exact output, arithmetic, bat-and-ball, code reading, JSON extraction, tool call, 9/9 ticket routing | 1.4 s per routed ticket | `run_task {model:"gpt-oss:20b", prompt, think:"low"}`; add `tools` or `format:"json"` |
47
49
  | Embeddings | `nomic-embed-text:v1.5` (274 MB) | Retrieval 4/4 top-1; ticket routing 9/9 from two examples per team | 51 ms per item, batched | `run_task {task:"embedding", files:["src/**/*.rs"] or input:[...], nearest:{query:"..."}}`: ranked labels, not vectors |
48
50
  | Decisions (classify, route, score) | `strands-decider:2b-nvfp4` (1.3 GB) | Ticket routing 9/9, return-policy yes/no 3/3, damage rubric 2/3 | 0.17 s per question | `run_task {task:"decision", model, state or files:[path], questions}`; one line per answer |
49
- | OCR | `glm-ocr:latest` (2.2 GB) | 4/4 phrases from a dense report strip; 0/7 on text tasks | 11 s per strip at a 400-token cap | `run_task {task:"vision", model:"glm-ocr", prompt:"Text Recognition:", files:[path]}` |
51
+ | OCR | `hf.co/openbmb/MiniCPM-OCR-1.0-gguf:Q4_K_M` (1.4 GB) | 30/30 rendered text images in all 3 rounds | 257 ms median | `run_task {workflow:"read-text", files:[path]}` (or `job:"ocr"`) |
50
52
 
51
53
  `gpt-oss:20b` reasons before answering, and its reasoning counts as output. FreeLlama sends no
52
54
  output cap of its own and sizes the context from what the model has needed before, so leave room
53
55
  for the reasoning if you set `num_predict` yourself. It needed about 17 GB available, so FreeLlama held
54
- it when other work left less. `glm-ocr` reads text from images only and keeps generating after the
55
- visible text ends. `stopOnRepetition` handles that and is on by default without `num_predict`; set it
56
- explicitly if you also cap the output. The `strands-decider` tags need Apple silicon, and decision
56
+ it when other work left less. OCR models read text from images only; asked a chat question, one keeps generating to its output
57
+ limit. Use them through the `ocr` job's trained prompts. `stopOnRepetition` stops one that loops and is
58
+ on by default without `num_predict`; set it explicitly if you also cap the output. The `strands-decider` tags need Apple silicon, and decision
57
59
  models answer only through Ollama's decision API, which `run_task {task:"decision"}` reaches with
58
60
  FreeLlama's routing and memory checks. A busy CPU does not refuse them; low memory does.
59
61
 
@@ -124,7 +126,7 @@ These examples do not establish that a tag is installed or suitable on your host
124
126
 
125
127
  Dedicated OCR models answer best to the prompts their model card documents; name the image in
126
128
  `run_task {files}` rather than pasting base64 `images`. A model that repeats its answer until its
127
- output limit stops early with `stopOnRepetition`, on by default without `num_predict`. See [Route images](https://github.com/bgauryy/FreeLlama/blob/main/packages/mcp/README.md#route-images)
129
+ output limit stops early with `stopOnRepetition`, on by default without `num_predict`. See [Loop control](FEATURES.md#loop-control)
128
130
  for the early stop and the `output_check` receipt.
129
131
 
130
132
  `muse-glimmer:30b-mlx` was a credible alternative and answered 29 of 30 questions correctly
@@ -166,6 +168,33 @@ this machine and workload, not a universal model-placement rule. Follow
166
168
 
167
169
  ## Turn measurements into routing evidence
168
170
 
171
+ Run `freellama bench-all --include EXACT_INSTALLED_TAG` on the serving machine, repeating
172
+ `--include` for other installed tags. The default output is `benchmark-report.json` in the
173
+ FreeLlama home (`FREELLAMA_HOME`, otherwise `~/.octocode/freellama`), which `serve` discovers on
174
+ its next start. `--output` chooses a different report path. No models are downloaded. Existing
175
+ resident models are left loaded; only models this run successfully warmed are eligible for cleanup.
176
+
177
+ Schema 2 reports record an observation timestamp, server version, artifact digests, OS, CPU,
178
+ RAM, available GPU identity and a domain-separated hash of the OS machine identifier. Raw machine
179
+ identifiers and hostnames are not included. Routing requires the same host/hardware signature,
180
+ exact endpoint (apart from a trailing slash), and current model digest. Remote endpoints, unknown
181
+ machine identity, reports from another host, and older reports remain readable but do not qualify
182
+ local throughput. Regenerate them on this machine. Primary-endpoint scores never qualify a separate
183
+ CPU-assigned runner. GPU details absent from the OS remain unknown; server settings and upgrades can
184
+ change performance without changing this signature, so rerun after those changes.
185
+
186
+ Job and workflow selection first asks the Rust router for a locally benchmarked model. Ordinary
187
+ jobs request the fastest route; capable workflows require a task quality policy as well. OCR also
188
+ requires quality evidence, and image search requires vision-capable embeddings. Without matching
189
+ evidence, selection falls back to installed catalog picks and their live memory preview. If no
190
+ tested catalog pick is installed, a capability-qualified installed model may run with an untested
191
+ warning. A conservative preview miss can still reach the authoritative runtime admission gate,
192
+ which admits, waits or refuses; selection never reserves memory. An explicit caller `model` wins.
193
+ The result states when local throughput guided the choice; a throughput screen alone does not
194
+ establish job accuracy. `models {view:"catalog"}` shows portable starting points, not the final
195
+ calibrated decision. This calibrated-first path applies to `run_task` jobs/workflows and virtual
196
+ gateway models; `delegate_research` has its own [catalog-and-routing sequence](cookbooks/research-agent.md).
197
+
169
198
  `bench-all` measures local performance. A quality benchmark measures correctness. FreeLlama needs
170
199
  both the generated task policy and local benchmark data before grading a route medium confidence.
171
200
  See the [CLI reference](CLI.md#earn-medium-routing-confidence) for the commands.
@@ -192,7 +221,7 @@ command reports the core catalog and does not expose these enrichment flags.
192
221
  |---|---|---|---|
193
222
  | `includeLibrary` | `installed`, `detail` | `false` | Requests public metadata; the default makes no website calls |
194
223
  | `includeReadme` | Library step 2, or `detail` with `includeLibrary:true` | `false` | Returns the README text with its format |
195
- | `includeVerbose` | `detail` | `false` | Returns Ollama's license and Modelfile fields independently of README enrichment |
224
+ | `includeVerbose` | `installed`, `resident`, `detail` | `false` | `installed`/`resident`: full per-model records (benchmark, policy rank, execution observation, thinking, context defaults) instead of the slim set; `detail`: Ollama's license and Modelfile fields, independently of README enrichment |
196
225
  | `limit`, `cursor` | `raw`, library tag listings; `limit` also applies to library search | Tag/raw page size 20; search limit 10; maximum 50 | Pages large lists; the tag cursor rejects a changed tag list |
197
226
  | `query`, `capabilities`, `order`, `source` | Library search | Popular order, both sources | Filter by capability word (such as `decision`), order by `popular` or `newest`, or limit to `ollama` or `huggingface` |
198
227
  | `ollamaEndpoint` | Direct Ollama views and library inventory reads | Configured Ollama endpoint | Chooses the Ollama instance; enriched managed inventory uses each model's assigned backend |
@@ -211,7 +240,7 @@ feature with `capability`, `use`, `reason`, and `basis:"supported_feature"`;
211
240
  | Feature | Supported workflow | What to evaluate separately |
212
241
  |---|---|---|
213
242
  | `completion` | Text generation | Coding, summarization, reasoning, and instruction-following accuracy |
214
- | `tools` | Tool calls | Argument correctness, tool selection, and agent-loop reliability |
243
+ | `tools` | Tool calls | Argument correctness, tool selection, and agent-loop reliability; see the [bounded public smoke evidence](RELIABILITY.md#public-tool-calling-smoke-suite) |
215
244
  | `vision` | Image input | OCR and visual understanding accuracy |
216
245
  | `audio` | Audio workflows advertised by the model | Supported audio task and accuracy |
217
246
  | `embedding` | Retrieval and similarity vectors | Retrieval quality on your documents |
@@ -16,13 +16,15 @@ token and keeps it only for the browser tab.
16
16
 
17
17
  | Endpoint | CLI | MCP | What it returns |
18
18
  |---|---|---|---|
19
+ | `GET /health` | | `doctor` (`platform_health`) | Liveness, admission capacity, and configured backends; answers as soon as serve listens |
20
+ | `GET /ready` | `freellama ready` | `doctor` (`readiness`) | 200 once the primary Ollama (and CPU backend, when configured) answers and its catalog reads; otherwise 503 with `waiting_for` |
19
21
  | `GET /status` | `freellama status` | `doctor {view:"status"}` | Live view of every backend, the raw proxy, loaded models, host, Ollama settings, and today's usage |
20
22
  | `GET /usage?days=N` | `freellama usage --days N` | `doctor {view:"usage", days:N}` | Totals per day and per model (default 7 days) |
21
23
  | `GET /metrics` | | | Prometheus text exposition |
22
24
  | `GET /config` | `freellama config` | | Effective runtime settings and the source of each |
23
25
  | `POST /config/reload` | `freellama config --reload` | | Re-read the runtime file now; `422` keeps the last good values |
24
26
  | `GET /jobs` | `freellama jobs` | `task_jobs {action:"list"}` | Deferred job metadata without prompts or retained results |
25
- | `GET /jobs/:id` | `freellama jobs --id <uuid>` | `task_jobs {action:"get", jobId}` | One job receipt and its retained result or error |
27
+ | `GET /jobs/:id` | `freellama jobs --id <uuid>` | `task_jobs {action:"get", jobId}` | One job receipt and its retained result or error. `?wait_ms=N` (at most 5000) holds the read until the job changes; the reply then carries `long_poll: true` |
26
28
  | `POST /jobs/:id/cancel` | `freellama jobs --id <uuid> --cancel` | `task_jobs {action:"cancel", jobId}` | Cancellation receipt after local permits are released |
27
29
  | `DELETE /jobs/:id` | `freellama jobs --id <uuid> --remove` | `task_jobs {action:"remove", jobId}` | Stops active work, releases local permits, and removes the retained record |
28
30
 
@@ -49,9 +51,20 @@ token and keeps it only for the browser tab.
49
51
  A remote endpoint is never probed and is reported as unknown.
50
52
  - **`usage_today`**: tasks, errors, tokens, and busy time since midnight UTC.
51
53
  - **`task_jobs`**: deferred task IDs, selected models, configured backends, priorities, total
52
- deadlines, states, and waiting reasons. States cover discovery, admission, resources, runner
54
+ deadlines, states, and waiting reasons. MCP `doctor {view:"status"}` keeps only the active jobs
55
+ plus counts by state; `task_jobs {action:"list"}` lists them all. States cover discovery, admission, resources, runner
53
56
  transitions, loading, execution, and completion. Metadata excludes the original payload.
54
57
 
58
+ On Windows, host memory comes from a bounded, unprivileged PowerShell CIM query. The
59
+ `windows_cim` observation converts `Win32_OperatingSystem.TotalVisibleMemorySize` and
60
+ `FreePhysicalMemory` from KiB to bytes; available memory is the latter, with kind
61
+ `windows_free_physical_memory`. Missing, malformed, overflowing, or inconsistent readings remain
62
+ unknown. See [Microsoft's field definitions](https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-operatingsystem).
63
+ The default `require-memory` policy holds admission when this observation fails, as on Linux and
64
+ macOS. CPU load, OS pressure, thermal, swap and GPU measurements remain unavailable on Windows;
65
+ `require-all` therefore holds admission. An operator can explicitly choose `best-effort` to admit
66
+ with unknown memory telemetry; observed low memory still follows the configured low-memory policy.
67
+
55
68
  A task receipt explains its own wait. `admission.mode` is `resident_shared` (the runner was
56
69
  reused without the backend load lock) or `nonresident_transition_exclusive` (this task loaded the
57
70
  runner under it). `admission.reason` says why a present runner could not be shared when its identity
@@ -66,7 +79,9 @@ Use `run_task {defer:true}` in MCP or `task --defer` in the CLI to get a job han
66
79
  status request omits results; fetching one ID returns its retained result or structured failure.
67
80
  Terminal states are `completed`, `failed`, `cancelled`, and `expired`. Cancellation is per task,
68
81
  waits for local permits to be released, and does not unload a shared runner. Process-local job
69
- retention limits are documented in [CLI controls](CLI.md#execute-tasks).
82
+ retention limits are documented in [CLI controls](CLI.md#execute-tasks). The optional durable-job
83
+ mode retains receipts/results in the file-backed store without replaying inference; its recovery
84
+ and idempotency rules are in [durable deferred jobs](DEFERRED_JOBS.md).
70
85
 
71
86
  Removal uses the same exact job ID. It cancels active work before discarding the record, returns
72
87
  `{id, removed:true, status, scope:"process_memory"}`, and omits the saved result. The ID then returns
@@ -87,6 +102,13 @@ including after an Ollama restart. Each config receipt includes `observed_at` an
87
102
  invalidates the use of measurements taken under different parallelism or KV cache settings.
88
103
  FreeLlama admission limits remain governed by its runtime configuration.
89
104
 
105
+ These Ollama residency and process-setting observations do not apply to the optional managed
106
+ llama.cpp adapter. Its receipt identifies `execution.engine:"llamacpp"`, an operator-configured
107
+ memory forecast and processor assignment, with physical placement unknown. Its bounded text
108
+ tasks share admission pools and the host-memory governor; their results do not train Ollama
109
+ placement, residency or preload facts. See the [engine contract](LLAMACPP.md) for supported tasks
110
+ and the single live protocol smoke's limits.
111
+
90
112
  `host.gpu_activity` is nullable. When available, it identifies its `source`,
91
113
  `scope: "observed_devices_all_processes"`, `window: "driver_defined"`, and individual `devices`.
92
114
  Each device has an identity, nullable `busy_percent`, and nullable `memory_busy_percent`. Apple
@@ -96,14 +118,17 @@ Use `host.sample_age_ms` to check freshness.
96
118
 
97
119
  NVIDIA activity comes from the same bounded `nvidia-smi` query as memory. Apple Silicon activity
98
120
  comes from the accelerator's `PerformanceStatistics` in a bounded IORegistry read. Those Apple
99
- properties are driver-specific and may disappear or change; the read can cover only the devices
100
- within its retained output. AMD, Windows, unsupported drivers, and unavailable reads report unknown activity. The counters include other processes, use a driver-defined observation
121
+ properties are driver-specific and may disappear or change. A sample that may have reached the
122
+ 64 KiB output cap or omits a recognized device's busy counter is discarded rather than treated as
123
+ complete. Malformed NVIDIA device rows likewise discard the activity sample. AMD, Windows, unsupported drivers, and unavailable reads report unknown activity. The counters include other processes, use a driver-defined observation
101
124
  window, and do not attribute activity to a FreeLlama task or establish bandwidth or energy
102
- efficiency. They are diagnostics and do not alter admission or pressure decisions.
125
+ efficiency. They are diagnostic by default. The opt-in GPU headroom guard below also uses valid
126
+ busy counters to hold new GPU work.
103
127
 
104
128
  Each backend's admission `queue_depth` includes both `slot_waiters` and `resource_waiters`.
105
- A resource waiter returns its execution slot after two seconds but remains in the bounded queue
106
- until capacity recovers, its deadline expires, or it is cancelled.
129
+ An Ollama resource waiter returns its execution slot after at most two seconds; llama.cpp yields
130
+ after its initial bounded probe. Both remain in the bounded queue until capacity recovers, their
131
+ deadline expires, or they are cancelled.
107
132
 
108
133
  Model affinity is bounded: `affinity_max_skips` (4) and `affinity_max_wait_ms` (2000) in the same
109
134
  receipt are how often, and how long, an older waiter can be passed over before its class is served
@@ -116,6 +141,20 @@ process-wide memory for request bodies being read or held by running requests,
116
141
  queue wait and is then refused with 503 `request_body_budget_exhausted`; raise it, or lower
117
142
  `FREELLAMA_MAX_REQUEST_BYTES`, when large uploads are normal.
118
143
 
144
+ Managed response buffering also uses `FREELLAMA_MAX_REQUEST_BYTES` (64 MiB by default) as a
145
+ per-response byte ceiling. Ollama JSON, embedding and decision responses, error bodies, and total
146
+ NDJSON stream bytes share this limit. Oversized Ollama output returns `502` with
147
+ `code:"upstream_response_too_large"`, `retry_safe:false` and `execution_outcome:"unknown"`;
148
+ do not replay it automatically. This ceiling is separate from the shared request-body budget
149
+ and does not represent total process heap usage. See [stream bounds](ARCHITECTURE.md#request-shapes)
150
+ for backpressure and cancellation behavior.
151
+
152
+ The management catalog and compatibility proxy share a separate 4 MiB cap for internal model lists,
153
+ `/api/show`, residency observations and server versions. Oversized or failed observations remain
154
+ unknown; they cannot establish a model's residency or allocation forecast. An oversized external
155
+ engine model list appears under `unreachable` in the merged list. Direct raw metadata requests
156
+ still stream their upstream responses unchanged.
157
+
119
158
  ## Record usage
120
159
 
121
160
  Every managed task, and every raw Ollama or OpenAI-compatible generation, updates in-memory usage
@@ -167,7 +206,7 @@ FreeLlama waits for safe capacity within a deadline and bounds the retained back
167
206
  | Managed queue full | `429` | `admission_queue_full` |
168
207
  | Raw proxy over its cap after `raw_queue_wait_seconds` | `429` | |
169
208
  | Managed wait exceeded `max_queue_wait_seconds` (or the task's `max_wait_seconds`) | `503` | `admission_timeout` |
170
- | OS pressure, swapping, CPU, thermal, or required telemetry still holds when the waiting budget expires (low available RAM alone only warns on macOS; low RAM and swapping never hold an already-resident runner, and CPU load and thermal never hold one on the GPU) | `503` | `resource_admission_unavailable` |
209
+ | A new load still does not fit available memory with its reserve, or OS pressure, swapping, CPU, thermal, or required telemetry still holds, when the waiting budget expires. Low available RAM refuses by default on every OS; `--low-memory advisory` (`FREELLAMA_LOW_MEMORY=advisory`) makes it a warning. Low RAM and swapping never hold an already-resident runner, and CPU load and thermal never hold one on the GPU | `503` | `resource_admission_unavailable` |
171
210
  | Backend circuit open | `503` | `upstream_circuit_open` |
172
211
 
173
212
  These capacity refusals carry a `Retry-After` header and `retry_after_seconds` in the body. For a queue it
@@ -176,6 +215,63 @@ task's cost), and the backend's recent average service time, which excludes queu
176
215
  seconds). A task can ask for a shorter wait with `max_wait_seconds` (`maxWaitSeconds`
177
216
  in MCP); the server caps it at the configured maximum.
178
217
 
218
+ ## Leave capacity for other applications
219
+
220
+ Resource thresholds belong to the operator, not to a model name or a fixed machine size. Start
221
+ `serve` with CPU and, optionally, GPU headroom targets:
222
+
223
+ ```bash
224
+ freellama serve \
225
+ --resource-hold-load-per-cpu 0.75 \
226
+ --resource-resume-load-per-cpu 0.5 \
227
+ --resource-hold-gpu-busy-percent 80 \
228
+ --resource-resume-gpu-busy-percent 60
229
+ ```
230
+
231
+ These are **admission targets, not utilization quotas**. They hold new work until observations
232
+ recover; they do not pause, kill, or throttle work already executing. One admitted inference can
233
+ still saturate a device. Use OS/container CPU quotas and upstream/device isolation when a hard
234
+ resource partition is required. Direct calls to Ollama bypass FreeLlama's guard.
235
+
236
+ | Setting | Default | Meaning |
237
+ |---|---|---|
238
+ | `--resource-hold-load-per-cpu` | `1.5` | Hold CPU-bound work when one-minute load / logical CPUs reaches this value |
239
+ | `--resource-resume-load-per-cpu` | `1.0` | Recover the CPU hold at or below this value |
240
+ | `--resource-hold-gpu-busy-percent` | Disabled | Hold GPU work when any observed device reaches this busy percentage |
241
+ | `--resource-resume-gpu-busy-percent` | Disabled | Recover only when all observed devices are at or below this percentage |
242
+
243
+ The four flags also accept environment variables named `FREELLAMA_RESOURCE_HOLD_LOAD_PER_CPU`,
244
+ `FREELLAMA_RESOURCE_RESUME_LOAD_PER_CPU`, `FREELLAMA_RESOURCE_HOLD_GPU_BUSY_PERCENT`, and
245
+ `FREELLAMA_RESOURCE_RESUME_GPU_BUSY_PERCENT`. They are startup settings, not runtime-TOML keys;
246
+ changing them requires restarting your own FreeLlama service. Inspect the effective policy under
247
+ `host.policy` in raw `status` (or the full saved `doctor` response).
248
+
249
+ CPU load is **not CPU utilization**: `0.75` does not guarantee 25% idle CPU. It scales with logical
250
+ CPU count and includes the OS's runnable/waiting load. Both CPU thresholds must be finite and
251
+ positive, with resume less than hold; no fixed upper ceiling is imposed. Missing CPU telemetry
252
+ follows `--resource-telemetry-policy`; use `require-all` if unavailable CPU-load observations must
253
+ block work. CPU load holds CPU-assigned work and work on hosts without an observed accelerator;
254
+ it does not hold an observed GPU runner merely because a compiler is busy. Raw Ollama requests
255
+ with explicit integer `options.num_gpu: 0` use CPU admission without rewriting the body; this is
256
+ request intent, not proof of physical placement. Unknown raw/OpenAI-compatible placement stays
257
+ conservatively GPU-gated when the optional GPU guard is enabled.
258
+
259
+ Both GPU settings must be supplied together and satisfy `0 <= resume < hold <= 100`. GPU activity
260
+ is optional by default so unsupported machines continue to work. When explicitly enabled, missing,
261
+ partial, or invalid GPU busy counters refuse GPU admission with `gpu_activity` in the assessment's
262
+ `missing_telemetry`, even with `best-effort`; CPU-assigned work remains eligible. Enable this guard
263
+ only on hosts exposing the counters described above. It conservatively considers the busiest of
264
+ all observed GPUs, not a per-model device assignment. CPU-only or remote Ollama deployments should
265
+ enforce resource controls on the machine actually executing work: remote upstreams bypass local
266
+ resource admission. Holds recover after two fresh healthy samples by default, avoiding rapid
267
+ stop/start at a single threshold.
268
+
269
+ For memory headroom, the existing `--resource-hold-available-percent` and
270
+ `--resource-resume-available-percent` settings default to 15 and 20. The per-load reserve is
271
+ size-aware rather than a promise to keep that entire share unused for every small model. Use
272
+ `model_memory_budget` in the runtime file to cap combined model residency on unified-memory/CPU
273
+ backends. GPU busy percentage is not a VRAM reserve.
274
+
179
275
  ## Circuit breaker
180
276
 
181
277
  After `breaker_failures` consecutive upstream failures on a backend (connection errors, `500`,
@@ -187,9 +283,9 @@ model do not count. Set `breaker_failures = 0` to disable it.
187
283
  ## Adaptive concurrency
188
284
 
189
285
  Managed task costs are configurable through the runtime file's `[task_costs]` table. Valid keys
190
- are `completion`, `coding`, `code_repair`, `tools`, `browser`, `vision`, `embedding`, and
286
+ are `completion`, `coding`, `code_repair`, `tools`, `browser`, `vision`, `embedding`, `decision`, and
191
287
  `long_context`. Each value is a positive integer through 4294967295. Omitted kinds retain their
192
- defaults: vision four, embeddings one, and other tasks two. Embeddings multiply their base by
288
+ defaults: vision four, embeddings and decisions one, and other tasks two. Embeddings multiply their base by
193
289
  `ceil(input_items/4)`; the acquired charge cannot exceed the pool's current limit.
194
290
 
195
291
  For a qualified light OCR workload, `[task_costs]` with `vision = 2` permits two vision requests
@@ -245,7 +341,9 @@ Omitted managed `keep_alive` values use finite retention informed by measured re
245
341
  starting from `base_seconds` (300, Ollama's own default) and shortened by `pressure_factor` under a
246
342
  host hold. Explicit values take precedence. The background pressure sweep releases, under
247
343
  FreeLlama's own low-memory estimate, only runners idle longer than `base_seconds ×
248
- pressure_factor` (75 s by default); swapping or OS memory pressure releases any idle runner. For governed prewarming, profile compatibility, and retention
344
+ pressure_factor` (75 s by default); swapping or OS memory pressure shortens that to `min_seconds`
345
+ (15 s). A runner counts as used when a task ran on it here or when another client moved its Ollama
346
+ `expires_at` since the sweep's last check; the audit then lists it as `used_elsewhere`. For governed prewarming, profile compatibility, and retention
249
347
  settings, see [Scope history and model warming](SCOPES_AND_WARMING.md).
250
348
 
251
349
  When a model about to load needs room, FreeLlama unloads idle runners itself (`keep_alive: 0`)