@octocodeai/freellama-mcp-server 0.6.2 → 0.9.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.
- package/CONFIGURATION.md +11 -3
- package/DEVELOPING.md +6 -6
- package/README.md +224 -402
- package/dist/index.js +11714 -4251
- package/dist/research/bash-agent.js +1495 -71
- package/dist/research/coder-agent.js +4668 -0
- package/dist/research/github-agent.js +2923 -0
- package/dist/research/octocode-agent.js +1407 -116
- package/docs/ARCHITECTURE.md +101 -45
- package/docs/BUILD_AND_NOTES.md +31 -0
- package/docs/CLI.md +76 -27
- package/docs/COMPARISON.md +40 -0
- package/docs/CPU_GPU_ROUTING.md +127 -25
- package/docs/DEFERRED_JOBS.md +79 -0
- package/docs/FEATURES.md +303 -0
- package/docs/LOCAL_MODELS.md +190 -0
- package/docs/MODEL_FORMS_AND_RESULTS.md +55 -0
- package/docs/MODEL_INTROSPECTION.md +128 -0
- package/docs/MODEL_SELECTION.md +74 -22
- package/docs/MONITORING.md +115 -33
- package/docs/PRODUCTION.md +76 -13
- package/docs/README.md +11 -6
- package/docs/SCOPES_AND_WARMING.md +55 -7
- package/docs/TESTING.md +24 -2
- package/docs/TUNING.md +86 -0
- package/docs/cookbooks/README.md +22 -0
- package/docs/cookbooks/batch-text.md +19 -0
- package/docs/cookbooks/classify.md +25 -0
- package/docs/cookbooks/coding.md +17 -0
- package/docs/cookbooks/duplicates.md +17 -0
- package/docs/cookbooks/find-code.md +21 -0
- package/docs/cookbooks/image-recognition.md +15 -0
- package/docs/cookbooks/image-search.md +13 -0
- package/docs/cookbooks/jobs.md +60 -0
- package/docs/cookbooks/memory-and-caching.md +31 -0
- package/docs/cookbooks/ocr.md +17 -0
- package/docs/cookbooks/research-agent.md +27 -0
- package/docs/cookbooks/speech-to-text.md +19 -0
- package/docs/cookbooks/sweep.md +66 -0
- package/docs/cookbooks/text-to-speech.md +15 -0
- package/docs/octocode/GITHUB.md +30 -0
- package/docs/octocode/LOCAL.md +29 -0
- package/native/index.d.ts +1 -11
- package/native/index.js +18 -34
- package/package.json +13 -15
package/README.md
CHANGED
|
@@ -1,445 +1,267 @@
|
|
|
1
|
-
# FreeLlama
|
|
1
|
+
# FreeLlama
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
Agents offload bounded tasks to local Ollama models; FreeLlama handles model selection, resource
|
|
7
|
-
admission, memory checks, and routing to configured CPU/GPU backends. Results include execution
|
|
8
|
-
evidence for the calling agent to inspect.
|
|
5
|
+
**Run your agent's bulk work on local models without overloading your machine.**
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
FreeLlama lets coding agents offload bounded work (embeddings, OCR and vision, bulk rewrites,
|
|
8
|
+
classification, summaries) to local [Ollama](https://ollama.com) models instead of spending paid
|
|
9
|
+
tokens and context. For each task it picks an installed model that fits, loads and switches models
|
|
10
|
+
only when they fit in memory, and returns the result with a receipt of where and how it ran. Your
|
|
11
|
+
agent still decides what to offload and verifies the answer.
|
|
14
12
|
|
|
15
|
-
|
|
13
|
+
```mermaid
|
|
14
|
+
flowchart LR
|
|
15
|
+
agent["Coding agent<br/>Claude Code, Cursor, any MCP host"]
|
|
16
|
+
cli["freellama CLI"]
|
|
17
|
+
raw["Ollama-compatible client"]
|
|
18
|
+
subgraph fl["FreeLlama, on your machine"]
|
|
19
|
+
mcp["MCP server<br/>Node.js + Rust addon"]
|
|
20
|
+
serve["freellama serve<br/>127.0.0.1:11435"]
|
|
21
|
+
research["Research adapter<br/>read-only, allowlisted files"]
|
|
22
|
+
end
|
|
23
|
+
gpu[("Ollama<br/>GPU: Metal, CUDA, ROCm")]
|
|
24
|
+
cpu[("Optional CPU-only Ollama")]
|
|
25
|
+
|
|
26
|
+
agent -->|"MCP over stdio"| mcp
|
|
27
|
+
mcp -->|"control API"| serve
|
|
28
|
+
cli -->|"control API"| serve
|
|
29
|
+
raw -.->|"/api and /v1 stream through"| serve
|
|
30
|
+
mcp -.->|"delegate_research"| research
|
|
31
|
+
research -->|"each model turn is a managed task"| serve
|
|
32
|
+
serve -->|"route, admit, load, run"| gpu
|
|
33
|
+
serve -.->|"operator-assigned models"| cpu
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Why FreeLlama
|
|
16
37
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
[what the MCP layer computes](#what-the-mcp-layer-computes)). `run_task` has four modes: one task,
|
|
21
|
-
`tasks[]` (independent batch), `preview: true` (decision only, no inference), and `warm: true`
|
|
22
|
-
(load an exact installed model, no generation). Preview and execution are separate calls: preview
|
|
23
|
-
accepts routing fields only and rejects task payloads or runtime controls instead of silently
|
|
24
|
-
ignoring them. `ollama_manage` and `ollama_delete` call Ollama's HTTP API directly for lifecycle
|
|
25
|
-
operations the routing layer does not perform.
|
|
38
|
+
Coding agents spend paid tokens and context on work a model on your own machine can do: embedding a
|
|
39
|
+
repository, reading screenshots and scans, summarizing or classifying hundreds of files. Pointing
|
|
40
|
+
the agent straight at Ollama does not fix that, because the agent cannot see:
|
|
26
41
|
|
|
27
|
-
|
|
42
|
+
- **Which model fits the job.** A tag name does not show capabilities, context window or memory
|
|
43
|
+
footprint.
|
|
44
|
+
- **Whether there is room.** One more load can push the machine into swap, several agents can pile
|
|
45
|
+
onto one GPU, and a hot or busy machine slows everything.
|
|
46
|
+
- **Whether it worked.** A model can repeat itself until its token cap, and nothing says whether the
|
|
47
|
+
task ran on the GPU or fell back to the CPU.
|
|
28
48
|
|
|
29
|
-
|
|
49
|
+
FreeLlama answers all three on every call, which makes offloading safe to do by default: the paid
|
|
50
|
+
model keeps the judgment, the local model does the volume, and each answer comes back with a receipt
|
|
51
|
+
you can check. The name means less metered inference, not only Meta's Llama models. More in
|
|
52
|
+
[Features](docs/FEATURES.md#why-freellama).
|
|
30
53
|
|
|
31
|
-
|
|
32
|
-
submitted task; pass that UUID as `jobId` for every subsequent operation.
|
|
54
|
+
## Requirements
|
|
33
55
|
|
|
34
|
-
|
|
|
56
|
+
| You need | Why |
|
|
35
57
|
|---|---|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
39
|
-
|
|
40
|
-
|
|
|
41
|
-
| Stop one task and remove its record | `task_jobs {action:"remove", jobId:"<returned UUID>"}` |
|
|
42
|
-
|
|
43
|
-
Removal waits for local permits to be released before deleting the record. It returns the ID and
|
|
44
|
-
terminal status; subsequent lookup returns `404`. It does not unload a shared Ollama model or
|
|
45
|
-
prove that physical computation has stopped. Receipts are bounded and lost on server restart;
|
|
46
|
-
see [retention and task states](https://github.com/bgauryy/FreeLlama/blob/main/docs/MONITORING.md#read-the-live-status).
|
|
47
|
-
|
|
48
|
-
Follow this workflow. The server's initialization instructions carry a compressed form of the
|
|
49
|
-
same contract (inventory first, preview semantics, evidence levels, ownership, and pull approval):
|
|
50
|
-
|
|
51
|
-
1. Start with `models {view:"installed"}`, then `models {view:"resident"}`. This gives a routing
|
|
52
|
-
agent the smallest current inventory first.
|
|
53
|
-
2. Call `doctor` only for runtime or configuration diagnosis. It returns `summary` by default;
|
|
54
|
-
use `view:"status"` for live queues and limits or `view:"full"` for the complete diagnostic. If Ollama is missing or unreachable, ask the operator to install or start it.
|
|
55
|
-
3. Classify the task. Offload embeddings, OCR/vision, bulk transforms, and sufficiently large
|
|
56
|
-
grounded lookups; retain small lookups and high-stakes judgment in the calling agent.
|
|
57
|
-
4. Prefer a qualified installed model and preview consequential work.
|
|
58
|
-
5. If none fits, collect the operator's modality, quality, context, latency, privacy, disk/download,
|
|
59
|
-
and memory constraints. Search the Ollama library, inspect exact tags and host-memory fit, and
|
|
60
|
-
present at most two candidates.
|
|
61
|
-
6. Ask the operator to approve one exact tag and its reported size before calling
|
|
62
|
-
`ollama_manage {action:"pull"}`. Searching or recommending never authorizes a download.
|
|
63
|
-
7. Execute, inspect the route/execution/admission receipt, and verify the result at the returned
|
|
64
|
-
confidence level.
|
|
65
|
-
|
|
66
|
-
### Use context and delegation deliberately
|
|
67
|
-
|
|
68
|
-
FreeLlama reduces the **calling agent's context burden**. It does not make an Ollama response more
|
|
69
|
-
accurate or eliminate the local model tokens needed to produce it. Its compact text cue avoids a
|
|
70
|
-
second serialized copy of the canonical `structuredContent`; its delegated adapter keeps full tool
|
|
71
|
-
observations on disk and presents them in pages when requested.
|
|
72
|
-
|
|
73
|
-
Use this economical sequence:
|
|
74
|
-
|
|
75
|
-
1. Request `models {view:"installed"}` before `doctor`; inventory is normally the smaller and
|
|
76
|
-
more relevant first decision.
|
|
77
|
-
2. Preview consequential generation with `run_task {preview:true}`. Preview is decision-only: it
|
|
78
|
-
neither generates nor reserves capacity.
|
|
79
|
-
3. Execute in a separate `run_task` call. Set `contextTokens` for the complete Ollama window and
|
|
80
|
-
`options.num_predict` for its output cap. A lower cap or window can lower cost **and** damage a
|
|
81
|
-
difficult answer, so choose it from the task rather than a global default.
|
|
82
|
-
4. Use `delegate_research` only for a self-contained question requiring files under
|
|
83
|
-
`workspacePath`. Bound `agent.maxTurns`, `agent.contextTokens`, and `agent.outputTokens`.
|
|
84
|
-
5. Keep the compact text cue in the active conversation; inspect `structuredContent`, a paged tool
|
|
85
|
-
result, or a bundled documentation resource only when its detail changes the next action.
|
|
86
|
-
|
|
87
|
-
For a delegated agent, estimated usable input is `contextTokens - outputTokens - safetyMarginTokens`
|
|
88
|
-
(the default margin is 256). The adapter pins the system instruction and question, preserves the
|
|
89
|
-
newest observations, compacts older observations into breadcrumbs, and refuses a pinned overflow
|
|
90
|
-
by default. `FREELLAMA_AGENT_PINNED_OVERFLOW=clip` is a deliberate quality-risk override. Initial token counting
|
|
91
|
-
is conservative; successful Ollama calls calibrate later estimates.
|
|
92
|
-
|
|
93
|
-
Do not confuse operational evidence with answer quality. A receipt can prove admission, token
|
|
94
|
-
counts, placement, or unloading. It cannot prove research correctness, coding judgment, sustained
|
|
95
|
-
throughput, or fairness from one run. Check the returned confidence, policy evidence, and benchmark
|
|
96
|
-
evidence before accepting a consequential answer.
|
|
97
|
-
|
|
98
|
-
### Token economics
|
|
99
|
-
|
|
100
|
-
Offloading keeps source material and intermediate tool output out of the calling agent's context;
|
|
101
|
-
the local model still spends tokens, power, and time. Per-call rows below come from one machine
|
|
102
|
-
(M4 Pro, 48 GB unified memory); `~` values are estimates.
|
|
103
|
-
|
|
104
|
-
| Work | Source tokens | Returned tokens | Preserved |
|
|
105
|
-
|---|---:|---:|---:|
|
|
106
|
-
| 6 grounded code questions | 59,208 | 1,742 | **97.1%** |
|
|
107
|
-
| 4 text embeddings (307 ms) | 17,600 | ~200 | **98.9%** |
|
|
108
|
-
| 1 image, OCR, byte-exact | 1,970 | 37 | **98.1%** |
|
|
109
|
-
|
|
110
|
-
A dated MCP-envelope audit (2026-09-03, `characters / 4` as a rough token estimate) measured the
|
|
111
|
-
duplicate text copy FreeLlama does not emit beside `structuredContent`: `doctor {view:"summary"}`
|
|
112
|
-
avoids ~3,064 chars, `doctor {view:"full"}` ~10,651, `models {view:"raw", limit:1}` ~404. These
|
|
113
|
-
are **not billed-token savings** unless the host would otherwise feed both representations to a
|
|
114
|
-
model. The tool schema itself is per-turn rent, bounded by the
|
|
115
|
-
[protocol context-budget test](https://github.com/bgauryy/FreeLlama/blob/main/packages/mcp/test/integration/protocol.test.ts);
|
|
116
|
-
read documentation resources on demand and filter unneeded tools where the client supports it.
|
|
117
|
-
|
|
118
|
-
| Cost side | Measured |
|
|
58
|
+
| [Ollama](https://ollama.com/download) running (`ollama list` works) with at least one model | FreeLlama manages Ollama; it does not install, start or replace it, and never downloads a model without your approval |
|
|
59
|
+
| Node.js 22 or newer | Runs the MCP server and the `freellama` npm launcher |
|
|
60
|
+
| One of the platforms below | npm installs the matching prebuilt binary as an optional dependency; do not install with `--omit=optional` |
|
|
61
|
+
|
|
62
|
+
| Platform | Prebuilt package |
|
|
119
63
|
|---|---|
|
|
120
|
-
|
|
|
121
|
-
|
|
|
122
|
-
|
|
|
123
|
-
|
|
|
124
|
-
|
|
125
|
-
Ollama prefix-cache reuse works on this path (a warm 2,462-token prefix re-prefilled in ~281 ms
|
|
126
|
-
versus ~18.6 s cold, and survived an interleaved conversation), so per-turn cost is new-token
|
|
127
|
-
prefill plus generation. Context compaction rewrites old observations and invalidates the cache
|
|
128
|
-
from that point; leave headroom (for example `OLLAMA_KV_CACHE_TYPE=q8_0`) so compaction stays rare.
|
|
129
|
-
Session-scale projections depend on provider, caching, and pricing; measure the client's actual
|
|
130
|
-
transcript before claiming a token or billing reduction.
|
|
131
|
-
|
|
132
|
-
#### Avoided external cost
|
|
133
|
-
|
|
134
|
-
Every successful `run_task`, batch item, and `delegate_research` result includes `telemetry.local`
|
|
135
|
-
when Ollama reports input/output token counts. To add `telemetry.externalEquivalent`, configure one
|
|
136
|
-
operator-owned rate card when starting the MCP server:
|
|
137
|
-
|
|
138
|
-
```text
|
|
139
|
-
FREELLAMA_EXTERNAL_COST_MODEL=EXTERNAL_MODEL_LABEL
|
|
140
|
-
FREELLAMA_EXTERNAL_COST_INPUT_USD_PER_M=INPUT_USD_PER_MILLION
|
|
141
|
-
FREELLAMA_EXTERNAL_COST_OUTPUT_USD_PER_M=OUTPUT_USD_PER_MILLION
|
|
142
|
-
```
|
|
64
|
+
| macOS, Apple silicon (arm64) | `@octocodeai/freellama-native-darwin-arm64` |
|
|
65
|
+
| Linux x64, glibc | `@octocodeai/freellama-native-linux-x64-gnu` |
|
|
66
|
+
| Linux arm64, glibc | `@octocodeai/freellama-native-linux-arm64-gnu` |
|
|
67
|
+
| Windows x64 | `@octocodeai/freellama-native-win32-x64-msvc` |
|
|
68
|
+
| Windows arm64 | `@octocodeai/freellama-native-win32-arm64-msvc` |
|
|
143
69
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
amortization; it is not a provider bill or net-profit calculation. Partial or invalid rate-card
|
|
148
|
-
configuration stops the MCP server at startup instead of emitting a misleading estimate.
|
|
70
|
+
Intel Macs and musl Linux (such as Alpine) have no prebuilt binary: build from source with Rust 1.89
|
|
71
|
+
or newer ([Build from source](docs/BUILD_AND_NOTES.md#build-from-source)). Optional: a second,
|
|
72
|
+
CPU-only Ollama process for small helper models ([CPU/GPU routing](docs/CPU_GPU_ROUTING.md)).
|
|
149
73
|
|
|
150
|
-
|
|
74
|
+
## Install
|
|
151
75
|
|
|
152
|
-
|
|
153
|
-
`{task:"vision", requiredCapabilities:["vision"], preview:true}` before a consequential image
|
|
154
|
-
task. Execute separately with a prompt and base64 `images` values without data-URI prefixes. The
|
|
155
|
-
`images` field needs an explicit trialed vision `model`, or an operator `[policies.vision]` entry in
|
|
156
|
-
the serve policy file; without either the core refuses rather than trusting a `vision` capability
|
|
157
|
-
tag. Inspect the execution receipt for admission and observed placement.
|
|
76
|
+
### MCP server (for your agent)
|
|
158
77
|
|
|
159
|
-
|
|
160
|
-
FreeLlama adds no stop sequence or other option because of which model was chosen.
|
|
78
|
+
Claude Code:
|
|
161
79
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
length-capped answer that ends in a loop gets `output_check: {repetition_loop: true,
|
|
166
|
-
unique_prefix_chars, period_chars}`. Either way the MCP answer text shows one copy and the
|
|
167
|
-
untrimmed output stays in `structuredContent.response`.
|
|
80
|
+
```bash
|
|
81
|
+
claude mcp add freellama -- npx -y @octocodeai/freellama-mcp-server
|
|
82
|
+
```
|
|
168
83
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
84
|
+
Claude Desktop, Cursor and other hosts:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{ "mcpServers": { "freellama": { "command": "npx", "args": ["-y", "@octocodeai/freellama-mcp-server"] } } }
|
|
88
|
+
```
|
|
172
89
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
installed model build, prompt and decoding settings, context/output budget, and available host
|
|
176
|
-
memory and accelerator performance. Validate representative held-out images on the target machine
|
|
177
|
-
and supply policy/benchmark evidence before automatically accepting a quality-sensitive result.
|
|
90
|
+
At launch the server starts its own FreeLlama service on `127.0.0.1:11435` if none is running, so
|
|
91
|
+
the CLI is optional. It does not install or start Ollama.
|
|
178
92
|
|
|
179
|
-
|
|
180
|
-
|
|
93
|
+
Required for `delegate_research` in a published install: `FREELLAMA_MCP_ALLOWED_ROOTS` lists the
|
|
94
|
+
directories that tool may read (`:`-separated on macOS and Linux, `;` on Windows). Unset, every local
|
|
95
|
+
`delegate_research` call is refused (its `adapter:"github"` runs without a workspace); the other tools
|
|
96
|
+
do not need it, and `run_task` `files` uses `FREELLAMA_FILE_ROOTS` instead. Add it with
|
|
97
|
+
`claude mcp add freellama -e FREELLAMA_MCP_ALLOWED_ROOTS=/absolute/path/to/your-project -- npx -y @octocodeai/freellama-mcp-server`
|
|
98
|
+
or an `"env": { ... }` entry in JSON. All settings: [MCP configuration](packages/mcp/CONFIGURATION.md).
|
|
181
99
|
|
|
182
|
-
|
|
100
|
+
### CLI (for the terminal)
|
|
183
101
|
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
B --> N["native/index.js and platform addon"]
|
|
188
|
-
N -->|"doctor"| L["Rust diagnostics"]
|
|
189
|
-
N -->|"models installed/resident; run_task"| S["freellama serve"]
|
|
190
|
-
S --> G["Primary Ollama"]
|
|
191
|
-
S --> U["Optional CPU Ollama"]
|
|
192
|
-
B -->|"detail, raw; manage; delete"| G
|
|
193
|
-
B -->|"library view"| W["ollama.com library + Hugging Face GGUF"]
|
|
194
|
-
B -->|"delegate_research"| A["allowlisted local adapter subprocess"]
|
|
195
|
-
A --> S
|
|
196
|
-
C -->|"resources/read on demand"| D["packaged docs/*.md"]
|
|
102
|
+
```bash
|
|
103
|
+
npm install -g @octocodeai/freellama
|
|
104
|
+
freellama --version
|
|
197
105
|
```
|
|
198
106
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
bounded adapter against an allowlisted workspace; each adapter model turn re-enters managed
|
|
202
|
-
`run_task` as `coding`, so it shares routing, admission, and placement evidence. The adapters are
|
|
203
|
-
TypeScript in `src/research/`, compiled to `dist/research/{bash-agent,octocode-agent}.js`, and run as
|
|
204
|
-
`node <file>` in their own process group with the server's Node.js; no Python is required.
|
|
205
|
-
|
|
206
|
-
### What the MCP layer computes
|
|
107
|
+
Without installing, prefix commands with `npx @octocodeai/freellama`. Without Node.js, use
|
|
108
|
+
`cargo install freellama-cli` (Rust 1.89+; the command is still `freellama`).
|
|
207
109
|
|
|
208
|
-
|
|
209
|
-
The TypeScript server adds a small set of derived fields on top of core results:
|
|
110
|
+
## Quick start
|
|
210
111
|
|
|
211
|
-
|
|
212
|
-
- answer text, embedding summaries, and optional avoided-cost telemetry for `run_task`;
|
|
213
|
-
- `models {view:"resident"}` placement labels: `gpu_percent` from `resident_vram / resident_size`,
|
|
214
|
-
a processor label (core-observed processor first, otherwise derived from that ratio), and
|
|
215
|
-
mismatch or partial-offload warnings;
|
|
216
|
-
- library-tag `fitsInMemory` against a conservative host-memory budget and a trial candidate;
|
|
217
|
-
- the `delegate_research` verification verdict from per-model evidence and tool-call facts.
|
|
112
|
+
### From your agent
|
|
218
113
|
|
|
219
|
-
|
|
114
|
+
Ask in plain words; the agent picks the tool ([MCP reference](packages/mcp/README.md)):
|
|
220
115
|
|
|
221
|
-
|
|
222
|
-
|
|
116
|
+
- "List my local models and tell me which one fits coding tasks."
|
|
117
|
+
- "Use FreeLlama to summarize these 40 files with a local model, then check three summaries."
|
|
118
|
+
- "Read this screenshot with a local OCR model."
|
|
223
119
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
context. The server fails on startup if the index is absent.
|
|
120
|
+
Or call the tools directly: take the tested pick for the job from the catalog, then run it with
|
|
121
|
+
that `model` (without one, routing picks by capability alone and may choose a model that does
|
|
122
|
+
not fit now).
|
|
228
123
|
|
|
124
|
+
```jsonc
|
|
125
|
+
{ "tool": "models", "arguments": { "view": "catalog", "job": "coding" } }
|
|
126
|
+
{ "tool": "run_task", "arguments": { "task": "coding", "model": "<catalog pick>", "prompt": "Rename foo to bar in: ...", "options": { "num_predict": 512 } } }
|
|
127
|
+
```
|
|
229
128
|
|
|
230
|
-
|
|
129
|
+
`run_task {preview:true}` shows the route without running or reserving anything.
|
|
231
130
|
|
|
232
|
-
|
|
131
|
+
### From the terminal
|
|
233
132
|
|
|
234
133
|
```bash
|
|
235
|
-
|
|
134
|
+
freellama init # check prerequisites, print a first-run plan; changes nothing
|
|
135
|
+
freellama doctor # Ollama reachability, versions, hardware, effective settings
|
|
136
|
+
freellama catalog # tested model picks per job, what is installed, what fits now
|
|
137
|
+
freellama serve # keep running: the service on http://127.0.0.1:11435
|
|
138
|
+
# in another terminal
|
|
139
|
+
freellama ready # can work be served now, or what is it waiting for
|
|
140
|
+
freellama models
|
|
141
|
+
freellama task --task completion --model MODEL_TAG "Reply with exactly OK."
|
|
142
|
+
freellama status # queues, memory holds, loaded models
|
|
236
143
|
```
|
|
237
144
|
|
|
238
|
-
|
|
145
|
+
Replace `MODEL_TAG` with a tag from `models`. `init`, `doctor` and `catalog` work without `serve`.
|
|
146
|
+
Every command has `--help`; the [CLI guide](docs/CLI.md) covers the rest. While `serve` runs, a
|
|
147
|
+
status page is at `http://127.0.0.1:11435/_freellama/ui`.
|
|
239
148
|
|
|
240
|
-
|
|
241
|
-
|
|
149
|
+
## Under the hood
|
|
150
|
+
|
|
151
|
+
Every managed call, from the MCP server, the CLI or the HTTP API, runs through the same Rust core
|
|
152
|
+
and the same gates: route, admit, load, run, observe. Nothing is decided from a model's name.
|
|
153
|
+
|
|
154
|
+
| Owner | Does |
|
|
155
|
+
|---|---|
|
|
156
|
+
| Your agent | Decides what to offload, writes the prompt, verifies the answer |
|
|
157
|
+
| FreeLlama | Picks the model, queues fairly, checks memory and host signals, coordinates loads, writes the receipt |
|
|
158
|
+
| Ollama | Stores models, loads runners, generates tokens |
|
|
159
|
+
|
|
160
|
+
### Life of one task
|
|
161
|
+
|
|
162
|
+
```mermaid
|
|
163
|
+
sequenceDiagram
|
|
164
|
+
autonumber
|
|
165
|
+
participant A as Agent
|
|
166
|
+
participant M as MCP server
|
|
167
|
+
participant S as freellama serve
|
|
168
|
+
participant O as Ollama
|
|
169
|
+
A->>M: run_task (task kind, model, prompt)
|
|
170
|
+
M->>S: POST /_freellama/v1/tasks
|
|
171
|
+
Note over S: Route: filter installed models by capability<br/>and context window, rank by policy,<br/>local benchmarks and loop history
|
|
172
|
+
Note over S: Admit: fair queue per backend, weighted 3/2/1<br/>for interactive, normal and background work,<br/>then memory, swap, CPU-load and heat checks
|
|
173
|
+
alt queue full, no room, or wait budget spent
|
|
174
|
+
S-->>M: 429 or 503 with the reason
|
|
175
|
+
else admitted
|
|
176
|
+
opt model not resident
|
|
177
|
+
S->>O: load it under the backend's load lock
|
|
178
|
+
end
|
|
179
|
+
S->>O: chat, generate or embed
|
|
180
|
+
O-->>S: streamed tokens, checked for loops every 16 tokens<br/>when the repetition stop is on
|
|
181
|
+
S->>O: GET /api/ps
|
|
182
|
+
O-->>S: where the runner actually ran, GPU or CPU
|
|
183
|
+
S-->>M: result + receipt
|
|
184
|
+
end
|
|
185
|
+
M-->>A: answer + receipt: route, admission, timing, placement
|
|
242
186
|
```
|
|
243
187
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
see `FREELLAMA_MCP_AUTOSTART_SERVE` in [Configuration](CONFIGURATION.md#environment-variables).
|
|
188
|
+
An explicit `model` always wins over routing; FreeLlama never swaps in another model. With
|
|
189
|
+
`defer:true` the same path runs in the background and `task_jobs` returns the receipt.
|
|
247
190
|
|
|
248
|
-
|
|
191
|
+
### The memory gate
|
|
249
192
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
}
|
|
193
|
+
A model load has to fit before it starts, so a new load cannot push the machine into swap:
|
|
194
|
+
|
|
195
|
+
```mermaid
|
|
196
|
+
flowchart TD
|
|
197
|
+
T(["Task admitted"]) --> R{"Model already<br/>resident?"}
|
|
198
|
+
R -->|"yes"| Run(["Run on the resident runner<br/>no new memory"])
|
|
199
|
+
R -->|"no"| P{"OS memory pressure,<br/>or swapping on a large load?"}
|
|
200
|
+
P -->|"yes"| Hold["Hold the load"]
|
|
201
|
+
P -->|"no"| F{"Fits in available memory<br/>and leaves the reserve free?"}
|
|
202
|
+
F -->|"yes"| Load(["Load, then run"])
|
|
203
|
+
F -->|"no"| U["Unload idle runners"]
|
|
204
|
+
U --> F2{"Fits now?"}
|
|
205
|
+
F2 -->|"yes"| Load
|
|
206
|
+
F2 -->|"no"| Hold
|
|
207
|
+
Hold --> W{"Room freed before<br/>the deadline?"}
|
|
208
|
+
W -->|"yes"| P
|
|
209
|
+
W -->|"no"| X(["503 naming the hold<br/>and the largest memory users"])
|
|
259
210
|
```
|
|
260
211
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
|
271
|
-
|
|
272
|
-
|
|
|
273
|
-
|
|
|
274
|
-
|
|
|
275
|
-
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
pass `requiredCapabilities: ["tools"]` rather than function definitions.
|
|
318
|
-
- Execution: omit `preview` (or set it to `false`) and pass `prompt`, `systemPrompt`, or `messages` for generative
|
|
319
|
-
tasks or `input` for embeddings, plus any applicable Ollama runtime controls.
|
|
320
|
-
|
|
321
|
-
Preview rejects `prompt`, `systemPrompt`, `messages`, `input`, `images`, `tools`, `keepAlive`, `format`, `think`,
|
|
322
|
-
`options`, `logprobs`, `topLogprobs`, `returnEmbeddings`, `priority`, `maxWaitSeconds`, `timeoutSeconds`,
|
|
323
|
-
`stopOnRepetition`, `defer`, `scopeId`, and `scopeRevision`. This prevents a client from attaching
|
|
324
|
-
work to a decision-only call and mistakenly assuming it ran.
|
|
325
|
-
|
|
326
|
-
`run_task.messages` preserves Ollama message fields beyond `role` and `content`, including images,
|
|
327
|
-
thinking, tool calls, and tool names. Managed requests also accept `format`, `think`, `options`,
|
|
328
|
-
`logprobs`, and `topLogprobs`. Use `contextTokens` for `num_ctx`; placement owns `num_gpu`, so both
|
|
329
|
-
keys are rejected inside `options`. The raw proxy remains available when a caller needs an Ollama
|
|
330
|
-
endpoint or feature that the managed MCP tool does not expose, including streaming.
|
|
331
|
-
|
|
332
|
-
Managed execution waits for a slot and safe host capacity within the server's waiting budget
|
|
333
|
-
(120 seconds by default). Set `maxWaitSeconds` on `run_task` or each batch task to request a
|
|
334
|
-
shorter budget; the server caps it at its configured limit. Resource waiters remain counted in
|
|
335
|
-
the bounded queue after returning their execution slots. They resume when capacity becomes
|
|
336
|
-
available, and session cancellation removes pending work. A full queue or an expired deadline
|
|
337
|
-
returns a capacity error with retry guidance.
|
|
338
|
-
|
|
339
|
-
Set `defer:true` on `run_task` to return a job ID immediately. Use `task_jobs {action:"list"}` for
|
|
340
|
-
metadata, `{action:"get", jobId}` for a retained result, and `{action:"cancel", jobId}` to cancel
|
|
341
|
-
that task and wait for local permits to be released. `get` summarizes embedding vectors by default;
|
|
342
|
-
set `returnEmbeddings:true` to include them. Cancellation does not unload a shared model or confirm
|
|
343
|
-
physical runner shutdown. Jobs expire on restart; see [CLI controls](https://github.com/bgauryy/FreeLlama/blob/main/docs/CLI.md#execute-tasks)
|
|
344
|
-
for input, result, registry, and retention limits. Batch items cannot defer.
|
|
345
|
-
|
|
346
|
-
Set `timeoutSeconds` on a task or batch item for a total deadline covering discovery, queueing,
|
|
347
|
-
loading, and inference. The server caps it at its task timeout. The admission wait budget remains
|
|
348
|
-
separate; a queue refusal can happen before the total deadline. `priority` selects a fair scheduling
|
|
349
|
-
class without bypassing resource checks.
|
|
350
|
-
|
|
351
|
-
You own the task instructions. Pass system prompts as `messages` entries with `role:"system"`,
|
|
352
|
-
or use `systemPrompt` to prepend one caller-supplied system message. FreeLlama preserves existing
|
|
353
|
-
messages and adds no task instructions of its own. A plain `prompt` becomes one user message,
|
|
354
|
-
and a supplied `messages` array takes precedence over `prompt`. This also applies to
|
|
355
|
-
`task:"code_review"` (an alias for `coding`) and `run_task {tasks}` batches: no review wrapper, mandatory
|
|
356
|
-
JSON review format, or review-specific output-token minimum is added.
|
|
357
|
-
|
|
358
|
-
The separate `delegate_research` adapter retains internal protocol prompts for its own bounded job. Those prompts are not injected into `run_task`
|
|
359
|
-
conversations. Ollama can still apply the selected model's own template or Modelfile defaults.
|
|
360
|
-
|
|
361
|
-
`model_type` is a display-oriented value derived from Ollama's additive capabilities:
|
|
362
|
-
`generative`, `multimodal`, `embedding_only`, or `unknown`. Routing continues to use the original
|
|
363
|
-
capability set, not this summary label. Unknown future Ollama capabilities are omitted from the
|
|
364
|
-
typed routing set instead of being treated as a known capability.
|
|
365
|
-
|
|
366
|
-
### Call the control API directly
|
|
367
|
-
|
|
368
|
-
Scripts that bypass MCP post the same fields in snake_case to `POST /_freellama/v1/tasks`:
|
|
369
|
-
`task`, `objective`, `model`, `session_id`, `required_capabilities`, `prompt` or `messages`,
|
|
370
|
-
`images`, `priority`, `keep_alive`, `max_wait_seconds`, `timeout_seconds`, `stop_on_repetition`,
|
|
371
|
-
and `request_options: {options, format, think, logprobs, top_logprobs}`. A batch is
|
|
372
|
-
`POST /_freellama/v1/task-batches` with `{tasks: [{id, independent: true, task: {...}}], max_parallelism}`; sessions are
|
|
373
|
-
`POST /_freellama/v1/sessions` with `{}`. `model` accepts a bare name (`name` resolves to
|
|
374
|
-
`name:latest`, or the one installed tag of that family); an ambiguous or unknown name is refused
|
|
375
|
-
with the installed candidates. See [Request shapes](https://github.com/bgauryy/FreeLlama/blob/main/docs/ARCHITECTURE.md#request-shapes)
|
|
376
|
-
for a full body and the receipt fields.
|
|
377
|
-
|
|
378
|
-
### Retain history and warm models
|
|
379
|
-
|
|
380
|
-
Use `scope {action:"create",messages}` to retain a caller-owned prefix. Pass its returned ID and
|
|
381
|
-
revision as `scopeId` and `scopeRevision` with only the new input to `run_task`; successful execution
|
|
382
|
-
returns the next scope revision. Fork a snapshot before parallel branches. `sessionId` continues to
|
|
383
|
-
mean model affinity only.
|
|
384
|
-
|
|
385
|
-
Use `run_task {warm:true,model,contextTokens,keepAlive?}` for a matching runner profile. It accepts no task
|
|
386
|
-
payload and does not pull a model. Add `defer:true` to inspect its progress through `task_jobs`.
|
|
387
|
-
Explicit `keepAlive` wins over finite adaptive retention. See the canonical
|
|
388
|
-
[Scope history and model warming reference](https://github.com/bgauryy/FreeLlama/blob/main/docs/SCOPES_AND_WARMING.md) for schemas, limits,
|
|
389
|
-
concurrency, privacy, and cache boundaries.
|
|
390
|
-
|
|
391
|
-
### Use CPU assignments through MCP
|
|
392
|
-
|
|
393
|
-
`run_task` delegates to `freellama serve`, so it honors the server's `--cpu-upstream` and
|
|
394
|
-
`--cpu-model` configuration. Exact assigned models can execute on the CPU process while other
|
|
395
|
-
managed tasks execute on the primary GPU-capable process.
|
|
396
|
-
|
|
397
|
-
Set `executionPreference` on `run_task` to `auto` (default), `prefer_cpu`, or `prefer_gpu`. This is a
|
|
398
|
-
guarded hint: only exact operator-assigned CPU models are eligible, explicit model/session pins win,
|
|
399
|
-
and `preview: true` returns `execution.preference_satisfied`, placement, upstream, admission, and a
|
|
400
|
-
reason without generating. Automatic feedback normalizes work by tokens and requires three
|
|
401
|
-
comparable warm serial samples on both backends with a 10% advantage. It matches model digest,
|
|
402
|
-
explicit observed context, effective controls, endpoint-attributed process settings, and managed
|
|
403
|
-
admission class. Unknown identity, parallel intervals, and decision-only payload-free previews
|
|
404
|
-
use capacity and policy signals. Stored legacy totals do not qualify speed hints. Feedback does
|
|
405
|
-
not steer the `quality` objective. See [automatic feedback](https://github.com/bgauryy/FreeLlama/blob/main/docs/CPU_GPU_ROUTING.md#understand-automatic-feedback).
|
|
406
|
-
`minPlacementEvidence:"observed"` fails closed unless resident
|
|
407
|
-
`/api/ps` evidence matches the configured processor; warm cold models once with `"configured"`.
|
|
408
|
-
`keepAlive:"0"` uses an observe-then-unload transaction: FreeLlama retains the runner long enough
|
|
409
|
-
to inspect `/api/ps`, accepts feedback only for verified placement, requests an explicit unload,
|
|
410
|
-
then reports the unload verification in `execution.lifecycle`.
|
|
411
|
-
|
|
412
|
-
Preview `execution.agent_plan` separates `queue_readiness`, `resource_readiness`, and combined
|
|
413
|
-
`dispatch_readiness`. Inspect `execution.resource_assessment` for required bytes and missing telemetry;
|
|
414
|
-
the preview shares execution's footprint estimate but never reserves memory. Low available RAM alone
|
|
415
|
-
never refuses work: previews report `runnable_low_memory_estimate`, and execution dispatches with
|
|
416
|
-
`resource_admission.status: "admitted_low_memory_estimate"`. Local inference requires
|
|
417
|
-
RAM telemetry by default; configure an explicit alternative on `serve`, not in a model prompt.
|
|
418
|
-
Resource errors retain a human-readable `error` plus machine-readable `code` and `resource_admission`
|
|
419
|
-
fields in the HTTP response. MCP preserves JSON refusals in both error text and `structuredContent`,
|
|
420
|
-
including queue-full codes, `retry_after_seconds`, resource assessments, and unload receipts.
|
|
421
|
-
Agents can use those fields to back off or explain a capacity hold without parsing human prose.
|
|
422
|
-
|
|
423
|
-
`models {view: "resident"}` uses the managed catalog, so it includes resident models from both
|
|
424
|
-
Ollama processes and labels explicitly assigned CPU models instead of querying only the primary
|
|
425
|
-
server. The per-model `placement` object is derived in the MCP layer from the catalog's
|
|
426
|
-
`resident_size`/`resident_vram` bytes and the core's placement observation; it is a display summary,
|
|
427
|
-
not new placement evidence.
|
|
428
|
-
|
|
429
|
-
Before relying on that placement, query `/_freellama/v1/health` and require
|
|
430
|
-
`contracts.placement_observation:"ollama_api_ps_after_execution"` and
|
|
431
|
-
`contracts.placement_evidence_gate:"configured_or_observed"`. A missing contract means the running server
|
|
432
|
-
predates the dual-backend build even if the MCP package itself is current.
|
|
433
|
-
|
|
434
|
-
The direct Ollama tools do not infer that assignment. `ollama_manage`, `ollama_delete`, and the
|
|
435
|
-
no-serve model views target their explicit `ollamaEndpoint` or `FREELLAMA_OLLAMA_ENDPOINT`, which
|
|
436
|
-
defaults to the primary Ollama server. Point them at the CPU endpoint only when you intend to
|
|
437
|
-
inspect or modify that separate server. Read
|
|
438
|
-
[CPU and GPU model routing](https://github.com/bgauryy/FreeLlama/blob/main/docs/CPU_GPU_ROUTING.md) for the complete contract.
|
|
439
|
-
|
|
440
|
-
## More
|
|
441
|
-
|
|
442
|
-
- [Configuration](CONFIGURATION.md): environment variables, research-adapter settings, security,
|
|
443
|
-
and runtime evidence.
|
|
444
|
-
- [Developing](DEVELOPING.md): build, test tiers, platform packages, publishing, and why the server
|
|
445
|
-
uses native bindings.
|
|
212
|
+
Resident models keep serving through a hold, except at critical OS memory pressure. Load estimates
|
|
213
|
+
come from model metadata (including the K/V cache at the requested context), and Ollama stays the
|
|
214
|
+
final authority on memory. `--low-memory advisory` admits a tight load with a warning instead of
|
|
215
|
+
waiting. Details: [Architecture](docs/ARCHITECTURE.md#managed-task-execution).
|
|
216
|
+
|
|
217
|
+
## What to offload
|
|
218
|
+
|
|
219
|
+
Offload bounded work whose result your agent can check; keep judgment in the agent.
|
|
220
|
+
|
|
221
|
+
| Offload | Keep in your agent |
|
|
222
|
+
|---|---|
|
|
223
|
+
| Embeddings, search and deduplication | Small lookups (describing the task costs more than doing it) |
|
|
224
|
+
| OCR and image reading | High-stakes judgment: security review, design, merge decisions |
|
|
225
|
+
| Bulk rewrites, summaries, classification of many files | Edits across files |
|
|
226
|
+
| Questions about workspace files (`delegate_research`) | Final verification of any local answer |
|
|
227
|
+
|
|
228
|
+
Many independent items: `run_task {tasks}`. Long work: `run_task {defer:true}` then `task_jobs`.
|
|
229
|
+
Treat local answers as candidates and spot-check some before relying on the rest.
|
|
230
|
+
|
|
231
|
+
## Safety
|
|
232
|
+
|
|
233
|
+
- Never pulls a model without approval for one exact tag and size; never deletes one unless you name
|
|
234
|
+
the exact installed tag.
|
|
235
|
+
- Checks each load against live available memory; a load that does not fit waits, then is refused
|
|
236
|
+
with a reason, and resident models keep serving.
|
|
237
|
+
- Unloads only models it warmed or that you name; idle models are unloaded under memory pressure.
|
|
238
|
+
- Holds CPU-bound work on a busy or hot machine and names the signal in the receipt.
|
|
239
|
+
- Binds to loopback; for remote access see [Production](docs/PRODUCTION.md).
|
|
240
|
+
|
|
241
|
+
## Documentation
|
|
242
|
+
|
|
243
|
+
| Topic | Page |
|
|
244
|
+
|---|---|
|
|
245
|
+
| All guides | [Documentation index](docs/README.md) |
|
|
246
|
+
| CLI commands and flags | [CLI](docs/CLI.md) |
|
|
247
|
+
| MCP tools, schemas, agent workflow | [MCP reference](packages/mcp/README.md), [MCP configuration](packages/mcp/CONFIGURATION.md) |
|
|
248
|
+
| Operating procedure for agents | [FreeLlama skill](skills/freellama/SKILL.md) |
|
|
249
|
+
| Features, routing and admission in depth, why FreeLlama | [Features](docs/FEATURES.md) |
|
|
250
|
+
| How it compares with Ollama, llama.cpp, llama-swap, LocalAI | [Comparison](docs/COMPARISON.md) |
|
|
251
|
+
| Choosing a model | [Model selection](docs/MODEL_SELECTION.md), [local model catalog](docs/LOCAL_MODELS.md) |
|
|
252
|
+
| Model forms, measured results | [Model forms and results](docs/MODEL_FORMS_AND_RESULTS.md) |
|
|
253
|
+
| Recipes per job | [Cookbooks](docs/cookbooks/README.md) |
|
|
254
|
+
| CPU/GPU setup and placement | [CPU/GPU routing](docs/CPU_GPU_ROUTING.md) |
|
|
255
|
+
| Queues, memory, live tuning | [Monitoring](docs/MONITORING.md) |
|
|
256
|
+
| Faster, lighter local models; Ollama settings | [Tuning](docs/TUNING.md) |
|
|
257
|
+
| Background jobs and recovery | [Deferred jobs](docs/DEFERRED_JOBS.md) |
|
|
258
|
+
| History, affinity, warming | [Scopes and warming](docs/SCOPES_AND_WARMING.md) |
|
|
259
|
+
| Deployment and releases | [Production](docs/PRODUCTION.md) |
|
|
260
|
+
| Build from source, operating notes | [Build and notes](docs/BUILD_AND_NOTES.md), [Testing](docs/TESTING.md) |
|
|
261
|
+
| Architecture and ownership | [Architecture](docs/ARCHITECTURE.md) |
|
|
262
|
+
| Embedding the Rust core | [Rust core](packages/rust-core/README.md) |
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
Copyright (c) 2026 Guy Bary. Licensed under [Apache-2.0](LICENSE-APACHE) or [MIT](LICENSE-MIT),
|
|
267
|
+
at your option.
|