@octocodeai/freellama-mcp-server 0.10.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 +316 -213
  4. package/dist/agent-cli.js +16963 -0
  5. package/dist/index.js +4896 -4036
  6. package/dist/research/bash-agent.js +287 -108
  7. package/dist/research/coder-agent.js +455 -127
  8. package/dist/research/github-agent.js +276 -94
  9. package/dist/research/octocode-agent.js +276 -94
  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 +38 -9
  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
@@ -0,0 +1,14 @@
1
+ | Exact installed tag | Manifest digest | Complete cases | Tool choice | Arguments | Follow-up | Status |
2
+ |---|---|---:|---:|---:|---:|---|
3
+ | `bonsai-2:27b` | `f3c4f42086593225d8be9bb4270658d0e05f5232fb2b5e8faa49ef74d2cc843a` | — | — | — | — | unmeasured |
4
+ | `lfm3-vl:2b-q4_K_M` | `00ca45bf65a5c626104a906ec9b5f4cd2f576387dbcdefdb150e88d0b3bd7b2e` | — | — | — | — | unmeasured |
5
+ | `nimble-v3:9b-q4_K_M` | `88cbbd22b816429c7df38b2893acdda2492038dafb3d1c898b4328e31f757a5e` | — | — | — | — | unmeasured |
6
+ | `lfm3-omni:2b-q4_K_M` | `4c0ee9400634babb880868b873bcebf09fbbf1a5328e550bdbaff25888f1f7e2` | — | — | — | — | unmeasured |
7
+ | `hf.co/openbmb/MiniCPM-OCR-1.0-gguf:Q4_K_M` | `1e5957df106945b5aa2da5d5bb1effc45205b50f8878e22f1dfbf30445392adf` | — | — | — | — | unmeasured |
8
+ | `bonsai-2:9b` | `c8b5462f8688647fe0b53568e3c00181ada5f05300aa4bf00695f2902f4d388e` | 6/7 | 4/4 | 4/4 | 3/4 | measured-smoke |
9
+ | `hf.co/nvidia/NVIDIA-Nemotron-3.5-Bolt-E4B-4GB:Q4_K_M` | `139e7d57c1c319f8a244800512f359394c7a4dd6ae52c90bf4c2ae5a4d56cff1` | — | — | — | — | unmeasured |
10
+ | `embeddinggemma-2:740m-q8_0` | `f4981a15b99858ad1f2e0729416e526be7b4f428291b40082b9e4f7b27b5f62f` | — | — | — | — | unmeasured |
11
+ | `lfm3-audio:2b-q4_K_M` | `3327c1a067559929d03d9e6e811cc2bc50b292b295e896b10733990dc6187590` | — | — | — | — | unmeasured |
12
+ | `phonon:en` | `6667dd188d2e30e1448b0476ccbd36bdc8802225a848541d5049f450e2a983e0` | — | — | — | — | unmeasured |
13
+ | `strands-decider:2b-nvfp4` | `c92a6f466917893017ea7ca4d5e6b39d9950d51ec2b346b5e05855d79d87b5e4` | — | — | — | — | unmeasured |
14
+ | `nomic-embed-text:v1.5` | `0a109f422b47e3a30ba2b10eca18548e944e8a23073ee3f3e947efcf3c45e59f` | — | — | — | — | unmeasured |
@@ -0,0 +1,14 @@
1
+ | Exact installed tag | Manifest digest | Complete cases | Tool choice | Arguments | Follow-up | Status |
2
+ |---|---|---:|---:|---:|---:|---|
3
+ | `bonsai-2:27b` | `f3c4f42086593225d8be9bb4270658d0e05f5232fb2b5e8faa49ef74d2cc843a` | — | — | — | — | unmeasured |
4
+ | `lfm3-vl:2b-q4_K_M` | `00ca45bf65a5c626104a906ec9b5f4cd2f576387dbcdefdb150e88d0b3bd7b2e` | 5/7 | 4/4 | 4/4 | 3/4 | measured-smoke |
5
+ | `nimble-v3:9b-q4_K_M` | `88cbbd22b816429c7df38b2893acdda2492038dafb3d1c898b4328e31f757a5e` | — | — | — | — | unmeasured |
6
+ | `lfm3-omni:2b-q4_K_M` | `4c0ee9400634babb880868b873bcebf09fbbf1a5328e550bdbaff25888f1f7e2` | — | — | — | — | unmeasured |
7
+ | `hf.co/openbmb/MiniCPM-OCR-1.0-gguf:Q4_K_M` | `1e5957df106945b5aa2da5d5bb1effc45205b50f8878e22f1dfbf30445392adf` | — | — | — | — | unmeasured |
8
+ | `bonsai-2:9b` | `c8b5462f8688647fe0b53568e3c00181ada5f05300aa4bf00695f2902f4d388e` | — | — | — | — | unmeasured |
9
+ | `hf.co/nvidia/NVIDIA-Nemotron-3.5-Bolt-E4B-4GB:Q4_K_M` | `139e7d57c1c319f8a244800512f359394c7a4dd6ae52c90bf4c2ae5a4d56cff1` | — | — | — | — | unmeasured |
10
+ | `embeddinggemma-2:740m-q8_0` | `f4981a15b99858ad1f2e0729416e526be7b4f428291b40082b9e4f7b27b5f62f` | — | — | — | — | unmeasured |
11
+ | `lfm3-audio:2b-q4_K_M` | `3327c1a067559929d03d9e6e811cc2bc50b292b295e896b10733990dc6187590` | — | — | — | — | unmeasured |
12
+ | `phonon:en` | `6667dd188d2e30e1448b0476ccbd36bdc8802225a848541d5049f450e2a983e0` | — | — | — | — | unmeasured |
13
+ | `strands-decider:2b-nvfp4` | `c92a6f466917893017ea7ca4d5e6b39d9950d51ec2b346b5e05855d79d87b5e4` | — | — | — | — | unmeasured |
14
+ | `nomic-embed-text:v1.5` | `0a109f422b47e3a30ba2b10eca18548e944e8a23073ee3f3e947efcf3c45e59f` | — | — | — | — | unmeasured |
@@ -0,0 +1,14 @@
1
+ | Exact installed tag | Manifest digest | Complete cases | Tool choice | Arguments | Follow-up | Status |
2
+ |---|---|---:|---:|---:|---:|---|
3
+ | `bonsai-2:27b` | `f3c4f42086593225d8be9bb4270658d0e05f5232fb2b5e8faa49ef74d2cc843a` | — | — | — | — | unmeasured |
4
+ | `lfm3-vl:2b-q4_K_M` | `00ca45bf65a5c626104a906ec9b5f4cd2f576387dbcdefdb150e88d0b3bd7b2e` | 5/7 | 4/4 | 4/4 | 3/4 | measured-smoke |
5
+ | `nimble-v3:9b-q4_K_M` | `88cbbd22b816429c7df38b2893acdda2492038dafb3d1c898b4328e31f757a5e` | — | — | — | — | unmeasured |
6
+ | `lfm3-omni:2b-q4_K_M` | `4c0ee9400634babb880868b873bcebf09fbbf1a5328e550bdbaff25888f1f7e2` | — | — | — | — | unmeasured |
7
+ | `hf.co/openbmb/MiniCPM-OCR-1.0-gguf:Q4_K_M` | `1e5957df106945b5aa2da5d5bb1effc45205b50f8878e22f1dfbf30445392adf` | — | — | — | — | unmeasured |
8
+ | `bonsai-2:9b` | `c8b5462f8688647fe0b53568e3c00181ada5f05300aa4bf00695f2902f4d388e` | 6/7 | 4/4 | 4/4 | 3/4 | measured-smoke |
9
+ | `hf.co/nvidia/NVIDIA-Nemotron-3.5-Bolt-E4B-4GB:Q4_K_M` | `139e7d57c1c319f8a244800512f359394c7a4dd6ae52c90bf4c2ae5a4d56cff1` | — | — | — | — | unmeasured |
10
+ | `embeddinggemma-2:740m-q8_0` | `f4981a15b99858ad1f2e0729416e526be7b4f428291b40082b9e4f7b27b5f62f` | — | — | — | — | unmeasured |
11
+ | `lfm3-audio:2b-q4_K_M` | `3327c1a067559929d03d9e6e811cc2bc50b292b295e896b10733990dc6187590` | — | — | — | — | unmeasured |
12
+ | `phonon:en` | `6667dd188d2e30e1448b0476ccbd36bdc8802225a848541d5049f450e2a983e0` | — | — | — | — | unmeasured |
13
+ | `strands-decider:2b-nvfp4` | `c92a6f466917893017ea7ca4d5e6b39d9950d51ec2b346b5e05855d79d87b5e4` | — | — | — | — | unmeasured |
14
+ | `nomic-embed-text:v1.5` | `0a109f422b47e3a30ba2b10eca18548e944e8a23073ee3f3e947efcf3c45e59f` | — | — | — | — | unmeasured |
@@ -1,6 +1,11 @@
1
1
  # FreeLlama cookbooks
2
2
 
3
- Short recipes for one job each: when to use it, which model, the exact call, and how to check the result. To see what is installed and fits right now, ask `models {view:"catalog"}` or run `freellama catalog`.
3
+ Short recipes for one job each: when to use it, which model, the exact call, and how to check the result. To inspect installed candidates and memory previews, ask `models {view:"catalog"}` or run `freellama catalog`.
4
+
5
+ Job/workflow calls without `model` use [machine-local calibrated routing](../MODEL_SELECTION.md#turn-measurements-into-routing-evidence)
6
+ before the portable catalog fallback. Explicit model tags in recipes are examples, not proof of
7
+ installation or current fit. Read the [check-line and tool-calling evidence](../RELIABILITY.md)
8
+ when deciding how to verify a result.
4
9
 
5
10
  | Job | Recipe |
6
11
  |---|---|
@@ -19,4 +24,6 @@ Short recipes for one job each: when to use it, which model, the exact call, and
19
24
  | Let FreeLlama pick the model and prompt for a job | [jobs](jobs.md) |
20
25
  | Memory, context and caching | [memory-and-caching](memory-and-caching.md) |
21
26
 
22
- Every call here is checked against the tool schemas by a test. Measured results come from one machine: an Apple M2 Pro with 32 GB. Measure on yours before you rely on them.
27
+ From a shell, each `run_task` job runs with `freellama run -j <job>` (or `-w <workflow>`); the speech, research and sweep recipes run with `freellama tool audio|delegate_research|sweep '<arguments>'` ([agent CLI](../AGENT_CLI.md)).
28
+
29
+ The [cookbook integration test](../../packages/mcp/test/integration/cookbooks.test.ts) checks the JSON calls against tool schemas; it does not execute their inference or verify model quality. Measured results come from one machine: an Apple M2 Pro with 32 GB. Measure on yours before you rely on them.
@@ -1,6 +1,6 @@
1
1
  # Rewrite, summarize or extract across many texts
2
2
 
3
- **Use when** you have 10 or more similar short texts. Send what they share once, and name each input by path.
3
+ **Use when** you have enough similar short texts that sharing their instructions saves work. Send what they share once, and name each input by path.
4
4
 
5
5
  **Skip it when** a pattern or script can do it exactly: checking a format with a regex beats any model.
6
6
 
@@ -16,4 +16,6 @@ Up to 64 items per call. Top-level `task`, `model`, `systemPrompt`, `questions`,
16
16
 
17
17
  **Read the result:** one `## <id>` section per item, in order.
18
18
 
19
- **Check it:** read 3 to 5, more where a mistake costs more.
19
+ **Check it:** verify representative and difficult items against their sources, and every item
20
+ whose error would matter. Read the [check-line limits](../RELIABILITY.md#accuracy-of-result-checks);
21
+ a clean lexical check does not establish summary correctness.
@@ -6,6 +6,16 @@
6
6
 
7
7
  **Model:** `strands-decider:2b-nvfp4` (1.3 GB). See `models {view:"catalog", job:"classify"}` for what is installed and fits now.
8
8
 
9
+ Question types: `choice` picks one of the `criteria` labels; `noul` is a yes/no question, answered
10
+ as the probability of yes; `score` gives a level from 2 to 10 descriptions, lowest first.
11
+
12
+ From a shell, the same as `ollama run --ask`:
13
+
14
+ ```bash
15
+ freellama run --ask "What kind of issue is this?" --choice bug="Something is broken" --choice feature="A request for new capability" \
16
+ --ask "Does this need action today?" < issue.md
17
+ ```
18
+
9
19
  One item, with the question asked once:
10
20
 
11
21
  ```json
@@ -18,8 +28,14 @@ Many items: send the question once and let each item carry only its own text or
18
28
  {"tool": "run_task", "arguments": {"task": "decision", "model": "strands-decider:2b-nvfp4", "questions": {"kind": {"type": "choice", "instructions": "What kind of issue is this?", "criteria": {"bug": "Something is broken", "feature": "A request for new capability"}}}, "tasks": [{"id": "a", "independent": true, "task": {"files": ["issues/a.md"]}}, {"id": "b", "independent": true, "task": {"files": ["issues/b.md"]}}]}}
19
29
  ```
20
30
 
21
- CLI: `freellama task --task decision --questions @questions.json --input-file issue.md`
31
+ CLI: `freellama task --task decision --questions @questions.json --input-file issue.md` prints the
32
+ JSON receipt; the answers are under `.response.answers`.
22
33
 
23
- **Read the result:** one line per question, such as `kind: bug (p 0.95, confidence 0.79)`.
34
+ **Read the result:** from MCP and `freellama run`, one line per question, such as
35
+ `kind: bug (p 0.95, confidence 0.79)`.
24
36
 
25
- **Check it:** spot-check 3 to 5 answers, and treat a low probability as unknown. Add an explicit `other` option when no listed label may fit. Do not use this model's `score` answers for severity.
37
+ **Check it:** compare representative answers with labeled examples. A `noul` probability near
38
+ zero means a confident **no**, not unknown; values in the 0.35–0.65 band are flagged for review.
39
+ Choice probabilities and reported confidence need model-specific calibration. Add an explicit
40
+ `other` option when no listed label may fit. The historical severity rubric was weak; evaluate
41
+ your own rubric before using `score` for it. See [check-line limits](../RELIABILITY.md#accuracy-of-result-checks).
@@ -4,14 +4,23 @@
4
4
 
5
5
  **Skip it when** the change spans files, needs judgment you must stand behind, or is shorter than describing it. Local code review is unreliable: verify every finding.
6
6
 
7
- **Model:** `lfm3:1.7b-q4_K_M` (1.1 GB, about 3.3 GB available needed). Measured here on 25 small questions over three rounds: lfm3 61 right, `bonsai-2:9b` 55, and Nemotron-3.5-Bolt 68, which needs about 13.5 GB available. Run `models {view:"catalog", job:"coding"}` for what fits now.
7
+ **Historical starting point:** `bonsai-2:9b` (3.2 GB file; the dated catalog preview asked for
8
+ 10.3 GB available). It answered every case in one 2026-11-12 field-test round, with SEARCH/REPLACE
9
+ edits and tool calls; that result does not establish general coding or tool reliability.
10
+ Nemotron-3.5-Bolt scored best on 25 small questions (68 right over three rounds, against 55) but its
11
+ preview asked for 13.5 GB available. `lfm3:1.7b` scored 61 on the questions, then answered workflows
12
+ with tool calls nobody asked for, so it was removed from the portable picks.
13
+
14
+ Inspect `models {view:"catalog", job:"coding"}` for current candidates. Workflows without `model`
15
+ use [local calibration before fallback](../MODEL_SELECTION.md#turn-measurements-into-routing-evidence);
16
+ the [newer tool-calling smoke results](../RELIABILITY.md#measured-on-2026-11-14) are separate evidence.
8
17
 
9
18
  Pass the code by path:
10
19
 
11
20
  ```json
12
- {"tool": "run_task", "arguments": {"task": "coding", "model": "lfm3:1.7b-q4_K_M", "prompt": "Write a unit test for the function in this file. Reply with code only.", "files": ["src/parse.ts"], "options": {"num_predict": 800}}}
21
+ {"tool": "run_task", "arguments": {"task": "coding", "model": "bonsai-2:9b", "prompt": "Write a unit test for the function in this file. Reply with code only.", "files": ["src/parse.ts"], "options": {"num_predict": 800}}}
13
22
  ```
14
23
 
15
- CLI: `freellama task --task coding --model lfm3:1.7b-q4_K_M --input-file prompt.txt`
24
+ CLI: `freellama run -w write-tests -f src/parse.ts` (FreeLlama picks the model), or `freellama run -m bonsai-2:9b -f src/parse.ts "Write a unit test" --think=false`
16
25
 
17
- **Check it:** run the code. Set `num_predict` high enough for a thinking model's reasoning, which counts as output, or pass `think:false` for a short answer: an answer that comes back empty says which.
26
+ **Check it:** run the code. A reply that is a tool call although you sent no tools is not an answer: the CLI exits 1 on it; rerun on a stronger installed pick. Set `num_predict` high enough for a thinking model's reasoning, which counts as output, or pass `think:false` for a short answer: an answer that comes back empty says which.
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Use when** you do not know which file to read and have no exact word to search for. The server embeds the files and returns ranked `path:Lstart-Lend` labels, so you read a few ranges instead of a repository.
4
4
 
5
- **Skip it when** you know an identifier: `localSearch` or `grep` is faster and exact.
5
+ **Skip it when** you know an identifier: `localSearch` or `rg` is faster and exact.
6
6
 
7
7
  **Model:** `embeddinggemma-2:740m-q8_0` (1.3 GB). `nomic-embed-text:v1.5` (0.3 GB) indexes faster but found the right file less often.
8
8
 
@@ -14,8 +14,13 @@ The prefixes belong to the model: `task: search result | query: ` and `title: no
14
14
 
15
15
  CLI, for items one per line: `freellama task --task embedding --model embeddinggemma-2:740m-q8_0 --input-file items.txt --nearest "task: search result | query: saving crashes" --top 5`
16
16
 
17
- **Read the result:** one line per file, best chunk first, with a cosine score.
17
+ **Read the result:** one line per ranked chunk; several chunks may name the same file, with a cosine score.
18
18
 
19
19
  **Check it:** read the top ranges before you rely on them. Measured here on 10 questions about this repository: embeddinggemma put the right file first for 9 and in the top 3 for 9; nomic, 6 and 8. A miss is still normal; widen `top` or rephrase before you conclude anything.
20
20
 
21
- Each call embeds the files again, so narrow the glob. A glob over about 900 chunks took about 67 s with embeddinggemma and 42 s with nomic.
21
+ Eligible file-backed query searches reuse unchanged chunks from the persistent embedding index;
22
+ the query is embedded each time. Reuse requires verified model digest, dimensions, backend and
23
+ execution identity; an unverified identity falls back to fresh embeddings. Deferred calls, raw
24
+ vector requests and certain explicit controls bypass this cache. Narrow the glob for a cold
25
+ search: the historical roughly 900-chunk run took about 67 s with embeddinggemma and 42 s with nomic.
26
+ See the [current index contract](../FEATURES.md#small-agent-context).
@@ -1,10 +1,10 @@
1
1
  # Let FreeLlama pick the model and prompt (job mode)
2
2
 
3
- **Use when** one of the jobs below fits the work and you would rather not write the local model's prompt, options and embedding prefixes yourself. Pass `job` to `run_task`: FreeLlama runs the job's first catalog pick that is installed and fits now, with its own prompt for that job. Any field you pass wins, and `job_profile.applied` in the result lists what job mode filled in.
3
+ **Use when** one of the jobs below fits the work and you would rather not write the local model's prompt, options and embedding prefixes yourself. Pass `job` to `run_task`: FreeLlama first asks the Rust router for a qualifying [machine-local calibrated pick](../MODEL_SELECTION.md#turn-measurements-into-routing-evidence), then falls back to the installed catalog or a capability-qualified untested model. It supplies its own prompt for that job; runtime admission remains authoritative. Any field you pass wins, and `job_profile.applied` in the result lists what job mode filled in.
4
4
 
5
5
  **Skip it when** you need your own wording or decoding: pass `model`, `prompt` and `options` yourself, as the other recipes do.
6
6
 
7
- | `job` | Task | First pick | What job mode fills in |
7
+ | `job` | Task | Catalog fallback default | What job mode fills in |
8
8
  |---|---|---|---|
9
9
  | `classify` | decision | `strands-decider:2b-nvfp4` | task and model; you send `questions` |
10
10
  | `find-code` | embedding | `embeddinggemma-2:740m-q8_0` | `task: code retrieval \| query: ` before your query, `title: none \| text: ` before each chunk |
@@ -12,10 +12,10 @@
12
12
  | `ocr` | vision | `hf.co/openbmb/MiniCPM-OCR-1.0-gguf:Q4_K_M` | prompt `Text Recognition:`; send `Table Recognition:` or `Formula Recognition:` as `prompt` for those |
13
13
  | `image-recognition` | vision | `lfm3-vl:2b-q4_K_M` | a brief-answer system prompt and the card's sampling; you send the question as `prompt` |
14
14
  | `image-search` | embedding | `embeddinggemma-2:740m-q8_0` | `task: search result \| query: ` before your query; images go in bare |
15
- | `coding` | coding | `lfm3:1.7b-q4_K_M` | a system prompt asking for SEARCH/REPLACE edits, and the card's sampling; you send the change as `prompt` |
16
- | `summarize` | completion | `lfm3:1.7b-q4_K_M` | a short-bullets system prompt that quotes numbers and names and says "not stated" rather than guess |
15
+ | `coding` | coding | `bonsai-2:9b` | a system prompt asking for SEARCH/REPLACE edits, and the card's sampling; you send the change as `prompt` |
16
+ | `summarize` | completion | `bonsai-2:9b` | a short-bullets system prompt that quotes numbers and names and says "not stated" rather than guess |
17
17
 
18
- The later picks of each job are the catalog's (`models {view:"catalog", job}`). Every value, with the model card it comes from, is in [local-prompts.ts](../../packages/mcp/src/local-prompts.ts); a sampling value is used only where the model's own card documents it.
18
+ The table names portable catalog defaults, not a guaranteed live choice. `models {view:"catalog", job}` lists its alternatives and memory previews; ordinary calibrated jobs request throughput evidence, while capable workflows and OCR also require quality evidence. Every value, with the model card it comes from, is in [local-prompts.ts](../../packages/mcp/src/local-prompts.ts); a sampling value is used only where the model's own card documents it.
19
19
 
20
20
  Read the text in one image:
21
21
 
@@ -53,8 +53,8 @@ Draft one small change:
53
53
  {"tool": "run_task", "arguments": {"job": "coding", "files": ["/Users/me/.octocode/freellama/handoffs/build-failures.md", "scripts/build.mjs"], "prompt": "Fix the first failure the summary names."}}
54
54
  ```
55
55
 
56
- **When nothing fits now,** the refusal lists each pick, the memory it needs and what is free. Tell the user; pass `model` for an installed model with the same capability, or ask them to approve pulling one exact tag at its size.
56
+ **When selection or admission refuses,** inspect the returned reason and current memory. A catalog preview miss alone may still reach the runtime gate, which can admit, wait or refuse; it reserves nothing during selection. Tell the user; pass `model` for an installed model with the same capability, or ask them to approve pulling one exact tag at its size.
57
57
 
58
- **MCP prompts.** Clients that show prompts (often as slash commands) list one per job: `ocr`, `image`, `classify`, `find-code`, `duplicates`, `coding`, `summarize`, `research`, `github-research` and `sweep`. Each returns the exact call to make; `freellama` explains when to offload and how to check results.
58
+ **MCP prompts.** Clients that show prompts (often as slash commands) list one per workflow (`read-text`, `read-table`, `read-fields`, `answer-image`, `describe-screen`, `change-code`, `fix-bug`, `implement`, `write-tests`, `review-code`, `explain-code`, `summarize-log`, `summarize-text`, `summarize-diff`, `extract-json`), plus `classify`, `find-code`, `duplicates`, `research`, `github-research` and `sweep`. Each returns the exact call to make; `freellama` explains when to offload and how to check results. From a shell, `freellama run -w <workflow>` or `freellama run -j <job>` makes the same call, and `freellama workflows` lists them.
59
59
 
60
- **Check it:** as the job's own recipe says; read 3 to 5 results before relying on the rest.
60
+ **Check it:** follow the job's recipe and the [limits of automated checks](../RELIABILITY.md#accuracy-of-result-checks). Test representative and difficult examples; verify every consequential output before using it.
@@ -22,10 +22,10 @@
22
22
  {"tool": "ollama_manage", "arguments": {"action": "unload", "model": "bonsai-2:9b"}}
23
23
  ```
24
24
 
25
- **Caching.** Reuse needs the same text at the start of the prompt, so put stable text first and append rather than edit. `metrics.cached_prompt_tokens` shows what was reused. Measured here on `gpt-oss:20b`: 1,251 of 1,266 tokens reused, with prompt evaluation falling from 544 ms to under 40 ms.
25
+ **Caching.** Reuse needs the same text at the start of the prompt, so put stable text first and append rather than edit. `metrics.cached_prompt_tokens` reports reuse when the backend supplies the counter; absence remains unknown. Measured here on `gpt-oss:20b`: 1,251 of 1,266 tokens reused, with prompt evaluation falling from 544 ms to under 40 ms.
26
26
 
27
27
  **Context window.** `contextTokens` is input plus output. A larger window uses more memory and can reload the model, so ask for what the prompt needs. FreeLlama never cuts a prompt silently.
28
28
 
29
29
  **When a load is refused,** the message says how much memory is available and needed. Tell the user, and never stop their processes. Retry once they free memory, or use a smaller installed model with the same capability; do not retry in a loop.
30
30
 
31
- Each pick's memory need is `memory_gb` in `models {view:"catalog"}`; measured models and their speeds are in [Choose local models](../MODEL_SELECTION.md).
31
+ The catalog's conservative preview, rather than a reservation, is `memory_gb` in `models {view:"catalog"}`; measured models and their speeds are in [Choose local models](../MODEL_SELECTION.md).
@@ -4,14 +4,14 @@
4
4
 
5
5
  **Skip it when** you need to know what an image shows rather than what it says: see [image recognition](image-recognition.md).
6
6
 
7
- **Model:** `hf.co/openbmb/MiniCPM-OCR-1.0-gguf:Q4_K_M` (1.4 GB), or `glm-ocr:latest` (2.2 GB).
7
+ **Model:** `hf.co/openbmb/MiniCPM-OCR-1.0-gguf:Q4_K_M` (1.4 GB). Use it through this prompt only: as a chat model an OCR model runs on to its output limit.
8
8
 
9
9
  ```json
10
10
  {"tool": "run_task", "arguments": {"task": "vision", "model": "hf.co/openbmb/MiniCPM-OCR-1.0-gguf:Q4_K_M", "prompt": "Text Recognition:", "files": ["screenshots/error.png"]}}
11
11
  ```
12
12
 
13
- Both models document the prompt `Text Recognition:`. Paths must be under the server's working directory, the temp directory or `FREELLAMA_FILE_ROOTS`.
13
+ The model documents the prompts `Text Recognition:`, `Table Recognition:` and `Formula Recognition:`. It answers tables in OTSL tags; the `read-table` workflow returns them as Markdown. Paths must be under the server's working directory, the temp directory or `FREELLAMA_FILE_ROOTS`.
14
14
 
15
- CLI: `freellama task --task vision --model glm-ocr:latest --image shot.png "Text Recognition:"`
15
+ CLI: `freellama run -w read-text -f shot.png`, `freellama run -w read-table -f table.png`, or `freellama run -w read-fields -f receipt.png "date, total"`
16
16
 
17
17
  **Check it:** crop to the text first; a whole page with one line on it can read as garbage. A note that the model looped means low confidence, so check that text. Measured here on clean rendered text only, not scans.
@@ -4,7 +4,10 @@
4
4
 
5
5
  **Skip it when** one search answers it, or when the answer needs your judgment.
6
6
 
7
- **Model:** `bonsai-2:9b` (3.2 GB), needing about 8.6 GB available.
7
+ **Explicit example model:** `bonsai-2:9b` (3.2 GB file). Inspect current residency and the route
8
+ assessment; disk size and historical memory previews do not establish fit. Without `model`, this
9
+ tool checks the configured default, then installed research catalog picks, then routing. This is
10
+ separate from the [calibrated-first job/workflow path](../MODEL_SELECTION.md#turn-measurements-into-routing-evidence).
8
11
 
9
12
  Local code, using the installed Octocode CLI's read-only tools. Pass the project's absolute path; a relative one resolves against the server's working directory, which is often not your project. The path must be under `FREELLAMA_MCP_ALLOWED_ROOTS`, which a published install requires:
10
13
 
@@ -18,10 +21,37 @@ GitHub, without cloning or a `workspacePath`:
18
21
  {"tool": "delegate_research", "arguments": {"question": "Which file in ollama/ollama defines SystemOneRequest?", "adapter": "github", "model": "bonsai-2:9b"}}
19
22
  ```
20
23
 
21
- The agent's instructions are [local](../octocode/LOCAL.md) and [GitHub](../octocode/GITHUB.md), which also work for any agent using the CLI directly.
24
+ The read-only agent's instructions are [local](../octocode/LOCAL.md) and [GitHub](../octocode/GITHUB.md), which also work for any agent using the CLI directly.
22
25
 
23
26
  With `adapter:"bash"` (the default) the model gets structured `search`, `read` and `list` actions that FreeLlama runs correctly and confined (a literal search by default; a path written relative to a package is resolved; a regex sent as a literal is retried as one), plus a read-only shell for `rg`, `grep`, `find`, `sed -n` and `git`. The GitHub adapter also takes the GitHub CLI read-only (`gh search`, `gh repo view`, `gh pr view`, `gh api` GET) through your existing `gh` login.
24
27
 
25
28
  Every run starts with a short workspace overview (top level, file types, source folders). An answer that cites a file that does not exist, or names no source although its results did, gets one repair turn; an answer that still cites a missing file is marked unverified. Bigger models get more time (180 s up to 4 GB, then 20 s per GB); pass `agent.timeoutSeconds` to choose.
26
29
 
30
+ The caller owns decomposition, prompts, dependencies, final judgment and mutation authority.
31
+ The writing exception is `adapter:"coder"`, disabled unless the operator sets
32
+ `FREELLAMA_MCP_ALLOW_CODER=1`. It edits an isolated worktree or copy and runs only the exact
33
+ commands supplied in `agent.commands`; it returns a candidate patch and never applies it to the
34
+ caller's tree. Inspect `diff`, `changedFiles`, `runs` and `runSandbox`, then verify the
35
+ patch before deliberately applying it. Isolation and an allowlisted command do not prove patch
36
+ correctness or make an unsafe command safe. See the [coder contract](../../packages/mcp/src/tools/coder.ts).
37
+
38
+ Every attempted allowed command retains raw combined stdout/stderr in a private file, including
39
+ runs whose inline preview is no longer shown. `runs[].output_audit` records the path, metadata
40
+ path, bytes, SHA-256, byte cap, completion state and reason; `runs[].failed` also covers a nonzero
41
+ exit. Ordering means observed pipe-chunk arrival, not a perfect cross-stream interleaving.
42
+ The model reads bounded head/tail previews through the existing observation paging; the caller
43
+ can inspect the full raw file. Previews do not imply the raw middle was discarded.
44
+
45
+ The default cap is 16 MiB per command; the operator may set
46
+ `FREELLAMA_CODER_MAX_OUTPUT_BYTES` (maximum 256 MiB). A cap or audit-write failure terminates the
47
+ command, marks its output incomplete and returns a tool-error observation. Timeouts and pipes
48
+ still open after shell exit are also explicitly incomplete. If an adapter is interrupted before
49
+ it writes its result, `commandAuditDirectory` still locates retained logs; a sidecar written
50
+ before execution stays incomplete until finalized. This is normal-process retention, not a
51
+ power-loss durability guarantee. Logs survive isolated-copy cleanup, even when no patch exists;
52
+ retain them with the receipt or remove their private temporary directory after review.
53
+ Custom log directories must be outside the caller workspace, the entire disposable copy container
54
+ and every command-writable directory. Per-command caps do not impose a quota on retained logs
55
+ across multiple sessions.
56
+
27
57
  **Check it:** discard `verification.recommendation:"escalate"`, and verify the citations otherwise. Measured here it was often right but also wrong with confidence, so treat answers as leads.
@@ -1,6 +1,6 @@
1
1
  # Turn a recording into text
2
2
 
3
- **Use when** a WAV recording must become text. You cannot hear audio yourself, so this has no self-service alternative.
3
+ **Use when** a WAV recording needs searchable text or a translation.
4
4
 
5
5
  **Model:** `lfm3-audio:2b-q4_K_M` (1.7 GB), or `lfm3-omni:2b-q4_K_M` (2.0 GB), which also does images.
6
6
 
@@ -63,4 +63,7 @@ Re-run next week and see only what happened since:
63
63
  - Keep one model per sweep. `maxParallelism` stays 1 unless the machine has spare slots (`doctor {view:"status"}`).
64
64
  - Split a source of more than 5,000 chunks into several sweeps, for example one per directory.
65
65
 
66
- **Check it:** read 3 to 5 flagged chunks and 2 clear ones before trusting the rest. Raise a threshold with `atLeast` when too much is flagged, and add `verifyModel` when too little of what is flagged holds up.
66
+ **Check it:** compare both flagged and clear chunks against labeled examples. Raising `atLeast`
67
+ can reduce false alarms while increasing misses. `verifyModel` rechecks flagged and unsure chunks;
68
+ it does not recover every missed clear chunk. Keep consequential decisions in the caller's review,
69
+ and treat baseline reuse as saved work rather than new correctness evidence.
@@ -1,8 +1,8 @@
1
1
  Octocode's GitHub tools research public and private repositories without cloning them: find a repo, its code, its history, and its packages.
2
- Call: octocode <tool> '{"queries":[{...}]}' (1-5 queries per call)
3
- Result: JSON with results[].data. Exit 0 found, 1 nothing found, 2 bad input (the message names the field), 3 not found, 4 not logged in (octocode auth login), 7 rate limited (wait).
4
- More: follow a printed next or {"cursor":"..."}; no next and no hasMore means the result is complete.
5
-
2
+ Call: octocode <tool> '{"queries":[{...}]}' (default text; add --json for JSON)
3
+ Result: findings plus status/notes; --json gives results[].data. Exits: 0 success, 1 empty, 2 invalid input, 3 not found, 4 auth required (octocode auth login), 5 execution error, 7 rate limited, 130 interrupted.
4
+ More: run responsePagination.next, then every next.* continuation unchanged; report isPartial, terminalLimit and provider/index limits rather than assuming completeness.
5
+ Checked with local CLI 20.2.0; use octocode <tool> --help before its first call, or schema <tool> for fields.
6
6
  ghSearchRepo: find a repository when you do not know its owner or name.
7
7
  {"operation":"search","keywords":["local llm router"],"filters":{"language":"Rust"}}
8
8
  {"operation":"get","owner":"ollama","repo":"ollama"} one repo: description, stars, default branch
@@ -1,7 +1,8 @@
1
1
  Octocode is a read-only code research CLI: it finds code in a directory so you read a few exact lines, not whole files.
2
- Call: octocode <tool> '{"queries":[{...}]}' (1-5 queries per call; paths relative to the working directory)
3
- Result: lines of findings, then "#" notes. Exit 0 found, 1 nothing found, 2 bad input (the message names the field), 3 path not found.
4
- More: copy a printed {"cursor":"..."} as the whole input. No cursor means the result is complete.
2
+ Call: octocode <tool> '{"queries":[{...}]}' (paths relative to the working directory)
3
+ Result: text findings and "#" notes by default; --json returns JSON. Exits: 0 success, 1 empty, 2 invalid input, 3 not found, 5 execution error, 130 interrupted.
4
+ More: run printed responsePagination.next, then every next.* continuation unchanged; isPartial or terminalLimit still means incomplete coverage.
5
+ Checked with local CLI 20.2.0; use octocode <tool> --help before its first call, or schema <tool> for fields.
5
6
 
6
7
  structureSearch: see the layout or list files, when you do not know where to look.
7
8
  {"operation":"tree","path":".","maxDepth":2}
@@ -17,7 +18,7 @@ astSearch: find code by shape, not by text. Use it to find where something is de
17
18
  {"operation":"symbols","path":".","symbolFilter":{"terms":["run"],"mode":"exact"}} declarations named run
18
19
  {"operation":"match","path":".","rule":{"pattern":"eval($X)"}} every call of this shape
19
20
  lspSearch: who defines, uses or calls a symbol; exact where text search only guesses. Take path and line from an earlier result, never guess them.
20
- {"path":"src/a.rs","symbolName":"run","line":35} its definition
21
+ {"operation":"definition","path":"src/a.rs","symbolName":"run","line":35} its definition
21
22
  {"operation":"references","path":"src/a.rs","symbolName":"run","line":35,"view":"files"} where it is used
22
23
  {"operation":"callers","path":"src/a.rs","symbolName":"run","line":35} also callees, hover, documentSymbols
23
24
 
package/native/index.d.ts CHANGED
@@ -71,7 +71,7 @@ export declare function getScope(endpoint: string | undefined | null, scopeId: s
71
71
  * # Errors
72
72
  * Returns an error for an invalid ID, an expired job, or an unavailable server.
73
73
  */
74
- export declare function getTaskJob(endpoint: string | undefined | null, jobId: string): Promise<string>
74
+ export declare function getTaskJob(endpoint: string | undefined | null, jobId: string, waitMs?: number | undefined | null): Promise<string>
75
75
 
76
76
  /**
77
77
  * Current managed-platform health, including admission and session bounds.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octocodeai/freellama-mcp-server",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "MCP server exposing FreeLlama core as tools, via native NAPI bindings into packages/rust-core.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -50,11 +50,11 @@
50
50
  "zod": "^4.6.7"
51
51
  },
52
52
  "optionalDependencies": {
53
- "@octocodeai/freellama-native-darwin-arm64": "0.10.0",
54
- "@octocodeai/freellama-native-linux-arm64-gnu": "0.10.0",
55
- "@octocodeai/freellama-native-linux-x64-gnu": "0.10.0",
56
- "@octocodeai/freellama-native-win32-arm64-msvc": "0.10.0",
57
- "@octocodeai/freellama-native-win32-x64-msvc": "0.10.0"
53
+ "@octocodeai/freellama-native-darwin-arm64": "0.12.0",
54
+ "@octocodeai/freellama-native-linux-arm64-gnu": "0.12.0",
55
+ "@octocodeai/freellama-native-linux-x64-gnu": "0.12.0",
56
+ "@octocodeai/freellama-native-win32-arm64-msvc": "0.12.0",
57
+ "@octocodeai/freellama-native-win32-x64-msvc": "0.12.0"
58
58
  },
59
59
  "author": "Guy Bary",
60
60
  "license": "Apache-2.0 OR MIT",
@@ -1,40 +0,0 @@
1
- # How FreeLlama compares
2
-
3
- Moved from the root README.
4
-
5
- ## How it compares
6
-
7
- FreeLlama is not an inference engine: Ollama loads and runs the model, FreeLlama decides whether,
8
- where and how each task runs. Other projects' behavior is taken from their docs and source, checked
9
- on 2026-11-01. Moving-branch features may differ from installed releases.
10
-
11
- | Decision | Other local stacks | FreeLlama |
12
- |---|---|---|
13
- | Can this load fit right now? | Ollama already estimates memory, reuses runners, queues work and evicts models ([scheduler](https://github.com/ollama/ollama/blob/main/server/sched.go), [FAQ](https://docs.ollama.com/faq)). llama.cpp has model loading and eviction ([server docs](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md)); llama-swap documents declared capacity pools and cost-based eviction ([config](https://github.com/mostlygeek/llama-swap/blob/main/docs/config.example.yaml)); LocalAI has memory-management policies with backend-dependent estimates ([docs](https://localai.io/docs/advanced/vram-management/)). | Checks each load against live available memory plus a reserve sized to the load, unloading idle runners first. A load that still does not fit waits, then is refused with a reason and a `Retry-After` from measured service time; resident models keep serving. While models are loaded, a background sweep unloads idle ones when the host runs short. |
14
- | Is the machine busy or hot? | Ollama and the llama.cpp router do not gate on host CPU load or heat; llama-swap exports swap and GPU temperature as metrics without acting on them ([metrics](https://github.com/mostlygeek/llama-swap/blob/main/internal/perf/prometheus.go)). | Holds CPU-bound work (all work on a host without a GPU) while the 1-minute load average is at least 1.5 per CPU, and CPU-bound work and new loads under Mac thermal pressure; the receipt names the signal. Another program's CPU load never blocks GPU work. |
15
- | What loads before it is asked for? | llama-swap, the llama.cpp router (`load-on-startup`) and LocalAI (`--load-to-memory`) load a fixed list at startup ([llama-swap](https://github.com/mostlygeek/llama-swap/blob/main/docs/config.example.yaml), [llama.cpp](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md), [LocalAI](https://github.com/mudler/LocalAI/blob/master/docs/content/reference/cli-reference.md)). These examples describe startup configuration, not an exhaustive feature comparison. | A startup list, optionally with a prompt prefix evaluated into the runner's prompt cache, plus the model that usually comes next, loaded only when it fits without unloading anything. |
16
- | Who may spend what? | LiteLLM enforces per-key budgets from its database ([users](https://docs.litellm.ai/docs/proxy/users)); llama-swap and the llama.cpp router accept a static key list. | Named client keys with per-key usage, a daily token budget that excludes prompt-cache reuse, and admin rights for model files, on managed and raw traffic alike. |
17
- | Other engines? | LiteLLM, Olla and LocalAI route across engines and fail over between them ([LocalAI failover](https://github.com/mudler/LocalAI/blob/master/docs/content/features/model-failover.md)). | OpenAI-compatible engines (LM Studio, llama.cpp, vLLM, a cloud API) behind the same `/v1` endpoint, routed by model name. |
18
- | Who goes first? | LiteLLM returns 429 once a deployment's parallel limit is reached, with an optional priority queue ([routing](https://docs.litellm.ai/docs/routing), [scheduler](https://docs.litellm.ai/docs/scheduler)). | Weighted fair admission per backend (interactive 3 : normal 2 : background 1) with starvation prevention and bounded waits; separate GPU and CPU pools. |
19
- | Which model? | Ollama runs the tag it is given. LiteLLM picks among deployments by load, latency or cost; RouteLLM trains a strong/weak router ([RouteLLM](https://github.com/lm-sys/RouteLLM)). | Picks an installed model by capabilities, context window, memory estimate and residency; a model that keeps looping on a task kind ranks last for it. |
20
- | Did it loop? | Ollama aborts some loops with a "token repeat limit" error. | Streams, stops once the output repeats and keeps the text (`stopOnRepetition`); `output_check` on every task. |
21
- | Loading or waiting? | Ollama streams generation and reports final timing; outer admission and host-resource phases belong to the coordinator. | MCP progress notifications (when the client sends a `progressToken`): `queued`, `waiting for memory: need 9.1 GB, 6.4 GB available`, `loading MODEL (~N s)`, `running`; the answer line adds `loaded N s, evicted X`. `GET /ready` answers 503 naming what is missing (`ollama`, `cpu_backend`, `catalog`). |
22
- | What reaches the agent's context? | Ollama returns its native response; presentation and filtering depend on the client. | A compact result (answer, verdict, model, tokens) plus a `response_file` holding thinking, vectors, research observations and receipts, read a section or page at a time with `read_response`. |
23
- | Where did it run? | Ollama exposes running-model memory/placement in `/api/ps` and generation timing in responses. | A receipt with the chosen model and why, queue and resource waits, and the placement Ollama reported in `/api/ps`, so a silent CPU fallback is visible. |
24
-
25
- Limits: FreeLlama does not change Ollama's decode speed, does not fail over between engines, and runs
26
- CPU work only on a second, CPU-only Ollama process (`serve --spawn-cpu-backend` starts and stops one for you).
27
-
28
- Measured on one Apple M2 Pro (32 GB) unless noted; single-machine measurements of specific
29
- workloads, not a general speed claim. The gains come from not loading, waiting or generating what the
30
- task does not need:
31
-
32
- | Workload | Without | With FreeLlama |
33
- |---|---|---|
34
- | OCR of 12 report strips, `glm-ocr`, 1,500-token cap | 12,948 output tokens, 126 s | `stopOnRepetition`: 6,452 tokens, 69 to 103 s, every label still read |
35
- | Resident GPU tasks during a compiler build | 64 to 120 s waits (host-wide CPU-load hold, 0.5.0) | No wait: the CPU-load hold applies only to CPU-assigned work |
36
- | `Retry-After` for a queued burst | 76 s quoted for a 32 s wait (0.5.0) | 32 s |
37
- | A GPU model and a CPU model side by side (M4 Pro, 48 GB) | 38.0 s median, one Ollama process | 28.2 s median with a second CPU-only Ollama process (1.35x; one of three runs was slower) |
38
- | Cost of a managed task over raw Ollama, resident embedding, n=20 (0.8.0, 2026-10-31) | raw passthrough: 2.7–2.9 ms median | 4.0 ms median, 5–7 ms p90, with routing, admission and a receipt (56 ms before the per-task process probe was cached) |
39
- | CPU placement through a second CPU-only Ollama (0.8.0, 2026-10-31) | — | `nomic-embed-text:v1.5` reported `processor: "cpu"`, `size_vram: 0`, verified from `/api/ps`; 265 ms load |
40
- | `gpt-oss:20b` cold load while the host had 12.7 GB available (0.8.0, 2026-10-31) | 0.7.0 admitted it with a memory warning on macOS; a run like this froze the machine | Held (`held_insufficient_capacity`: needs 18.0 GB with the reserve), then refused at the caller's deadline with `Retry-After`; the model never loaded |