@octocodeai/freellama-mcp-server 0.1.0 → 0.5.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/LICENSE-APACHE +202 -0
- package/LICENSE-MIT +18 -0
- package/README.md +203 -33
- package/adapters/agent_context.py +216 -29
- package/adapters/agent_transport.py +131 -0
- package/adapters/bash_agent.py +67 -92
- package/adapters/octocode_agent.py +63 -53
- package/adapters/shell_sandbox.py +487 -0
- package/assets/logo.jpg +0 -0
- package/dist/index.js +1287 -412
- package/docs/ARCHITECTURE.md +169 -26
- package/docs/CLI.md +107 -17
- package/docs/CPU_GPU_ROUTING.md +65 -20
- package/docs/ECONOMICS.md +20 -15
- package/docs/INDEX.md +8 -2
- package/docs/MODEL_METADATA.md +106 -0
- package/docs/MODEL_SELECTION.md +15 -2
- package/docs/MONITORING.md +285 -0
- package/docs/OLLAMA_SIDECAR.md +8 -6
- package/docs/PRODUCTION.md +49 -18
- package/docs/PRODUCT_POSITIONING.md +86 -256
- package/docs/README.md +40 -0
- package/docs/SCOPES_AND_WARMING.md +226 -0
- package/docs/TESTING.md +118 -1
- package/docs/dev/FINDINGS_AND_POSITIONING.md +290 -0
- package/docs/dev/LOCAL_PERFORMANCE_TESTING.md +298 -0
- package/docs/{OLLAMA_SYSTEM_OPTIMIZATION.md → dev/OLLAMA_SYSTEM_OPTIMIZATION.md} +19 -18
- package/native/index.d.ts +31 -0
- package/package.json +13 -10
- /package/docs/{ADR_RESOURCE_AWARE_BACKEND_ROUTING.md → dev/ADR_RESOURCE_AWARE_BACKEND_ROUTING.md} +0 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# Runtime status and live tuning
|
|
2
|
+
|
|
3
|
+
Use runtime status to inspect how FreeLlama manages delegated work: per-backend queues and
|
|
4
|
+
admission, memory pressure, resident models, execution usage, and resource holds. The operator can
|
|
5
|
+
reload supported limits without a restart; the calling agent can use these observations to decide
|
|
6
|
+
whether to wait, narrow a task, or handle it itself.
|
|
7
|
+
|
|
8
|
+
The API endpoints in this reference are served under `/_freellama/v1/` and use the same bearer
|
|
9
|
+
token as the rest of the control API when authentication is enabled.
|
|
10
|
+
|
|
11
|
+
Open **`http://127.0.0.1:11435/_freellama/ui`** (the address `serve` prints at startup) for a live
|
|
12
|
+
page of the same data, refreshed every two seconds: backends and queues, raw traffic, host RAM and
|
|
13
|
+
VRAM, Ollama's settings, loaded models with their current tasks and load times, and the last
|
|
14
|
+
eviction. The page itself is static and needs no token; when auth is on it asks for the bearer
|
|
15
|
+
token and keeps it only for the browser tab.
|
|
16
|
+
|
|
17
|
+
| Endpoint | CLI | MCP | What it returns |
|
|
18
|
+
|---|---|---|---|
|
|
19
|
+
| `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
|
+
| `GET /usage?days=N` | `freellama usage --days N` | `doctor {view:"usage", days:N}` | Totals per day and per model (default 7 days) |
|
|
21
|
+
| `GET /metrics` | | | Prometheus text exposition |
|
|
22
|
+
| `GET /config` | `freellama config` | | Effective runtime settings and the source of each |
|
|
23
|
+
| `POST /config/reload` | `freellama config --reload` | | Re-read the runtime file now; `422` keeps the last good values |
|
|
24
|
+
| `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 |
|
|
26
|
+
| `POST /jobs/:id/cancel` | `freellama jobs --id <uuid> --cancel` | `task_jobs {action:"cancel", jobId}` | Cancellation receipt after local permits are released |
|
|
27
|
+
| `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
|
+
|
|
29
|
+
## Read the live status
|
|
30
|
+
|
|
31
|
+
`status` answers "why is my task waiting?" in one call:
|
|
32
|
+
|
|
33
|
+
- **`backends.gpu` / `backends.cpu`**: admission (units in use, current limit, ceiling, queue depth,
|
|
34
|
+
oldest wait, refusal and timeout counters), the adaptive limiter state, and the circuit breaker
|
|
35
|
+
(`closed`, `open` with seconds remaining, or `half_open`).
|
|
36
|
+
- **`raw_proxy`**: active and waiting raw streams against their cap and wait budget.
|
|
37
|
+
- **`loaded_models`**: Ollama's `/api/ps` with total and VRAM bytes, context length, expiry, and
|
|
38
|
+
whether the model is pinned.
|
|
39
|
+
- **`host`**: available and reserved RAM, whether the pressure gate is holding, and discrete-GPU
|
|
40
|
+
total and free memory (`nvidia-smi` or amdgpu sysfs) when available. Optional `gpu_activity`
|
|
41
|
+
reports driver counters separately from resident memory.
|
|
42
|
+
- **`ollama`**: the Ollama server's effective `OLLAMA_*` settings with a source for each — the
|
|
43
|
+
running process's environment (Linux `/proc/<pid>/environ`, macOS `ps eww` for a same-user
|
|
44
|
+
process), `launchctl getenv` for the macOS app, FreeLlama's own environment, or Ollama's default.
|
|
45
|
+
A remote endpoint is never probed and is reported as unknown.
|
|
46
|
+
- **`usage_today`**: tasks, errors, tokens, and busy time since midnight UTC.
|
|
47
|
+
- **`task_jobs`**: deferred task IDs, selected models, configured backends, priorities, total
|
|
48
|
+
deadlines, states, and waiting reasons. States cover discovery, admission, resources, runner
|
|
49
|
+
transitions, loading, execution, and completion. Metadata excludes the original payload.
|
|
50
|
+
|
|
51
|
+
Use `run_task {defer:true}` in MCP or `task --defer` in the CLI to get a job handle. A list or
|
|
52
|
+
status request omits results; fetching one ID returns its retained result or structured failure.
|
|
53
|
+
Terminal states are `completed`, `failed`, `cancelled`, and `expired`. Cancellation is per task,
|
|
54
|
+
waits for local permits to be released, and does not unload a shared runner. Process-local job
|
|
55
|
+
retention limits are documented in [CLI controls](CLI.md#execute-tasks).
|
|
56
|
+
|
|
57
|
+
Removal uses the same exact job ID. It cancels active work before discarding the record, returns
|
|
58
|
+
`{id, removed:true, status, scope:"process_memory"}`, and omits the saved result. The ID then returns
|
|
59
|
+
`404` on lookup or another removal. Other jobs and installed models are unaffected. Local
|
|
60
|
+
cancellation closes the upstream request; physical computation may continue on a shared runner.
|
|
61
|
+
|
|
62
|
+
`ollama.config` describes the primary process; `ollama.cpu_config` describes the CPU process when
|
|
63
|
+
configured. Process attribution matches `OLLAMA_HOST` to the selected endpoint, so separate
|
|
64
|
+
parallelism and KV cache settings size each backend independently. Fallback sources remain visible
|
|
65
|
+
when process settings cannot be observed.
|
|
66
|
+
|
|
67
|
+
Process settings are cached for five seconds and refreshed on discovery or monitoring requests,
|
|
68
|
+
including after an Ollama restart. Each config receipt includes `observed_at` and
|
|
69
|
+
`observation_scope: "process_snapshot"`. Refresh also updates backend memory estimates and
|
|
70
|
+
invalidates the use of measurements taken under different parallelism or KV cache settings.
|
|
71
|
+
FreeLlama admission limits remain governed by its runtime configuration.
|
|
72
|
+
|
|
73
|
+
`host.gpu_activity` is nullable. When available, it identifies its `source`,
|
|
74
|
+
`scope: "observed_devices_all_processes"`, `window: "driver_defined"`, and individual `devices`.
|
|
75
|
+
Each device has an identity, nullable `busy_percent`, and nullable `memory_busy_percent`.
|
|
76
|
+
An observed zero means the driver reported zero; a missing or malformed counter remains unknown.
|
|
77
|
+
Use `host.sample_age_ms` to check freshness.
|
|
78
|
+
|
|
79
|
+
NVIDIA activity comes from the same bounded `nvidia-smi` query as memory. Apple Silicon activity
|
|
80
|
+
comes from the accelerator's `PerformanceStatistics` in a bounded IORegistry read. Those Apple
|
|
81
|
+
properties are driver-specific and may disappear or change; the read can cover only the devices
|
|
82
|
+
within its retained output. AMD, Windows, unsupported drivers, and unavailable reads report unknown activity. The counters include other processes, use a driver-defined observation
|
|
83
|
+
window, and do not attribute activity to a FreeLlama task or establish bandwidth or energy
|
|
84
|
+
efficiency. They are diagnostics and do not alter admission or pressure decisions.
|
|
85
|
+
|
|
86
|
+
Each backend's admission `queue_depth` includes both `slot_waiters` and `resource_waiters`.
|
|
87
|
+
A resource waiter returns its execution slot after two seconds but remains in the bounded queue
|
|
88
|
+
until capacity recovers, its deadline expires, or it is cancelled.
|
|
89
|
+
|
|
90
|
+
## Record usage
|
|
91
|
+
|
|
92
|
+
Every managed task updates in-memory usage totals and offers one record to a bounded writer queue.
|
|
93
|
+
The record contains time, model, backend, task kind, priority, outcome, HTTP status, prompt and
|
|
94
|
+
output tokens, duration, queue wait, load time, and output tokens per second. It contains no prompt
|
|
95
|
+
or response text. One worker writes records in order; task completion does not wait for disk.
|
|
96
|
+
|
|
97
|
+
The writer queue defaults to 128 records. Configure its positive startup-only capacity through
|
|
98
|
+
`usage_queue_capacity` or `FREELLAMA_USAGE_QUEUE_CAPACITY`; runtime reload does not resize the worker.
|
|
99
|
+
A full queue or unavailable worker drops the record; a disk
|
|
100
|
+
failure records a failed write. Inspect `usage_ledger` in `status`, or `ledger` in `usage`, for
|
|
101
|
+
`pending`, `failed`, `dropped`, `records`, `capacity`, and `last_error`. The durability contract is
|
|
102
|
+
`asynchronous_best_effort`: pending records can be lost on a crash, and in-memory totals can exceed
|
|
103
|
+
persisted totals. Error evidence remains visible after later successful writes.
|
|
104
|
+
|
|
105
|
+
`serve` replays a bounded regular-file ledger at startup and rotates it to `usage.jsonl.1` at
|
|
106
|
+
16 MiB. Successful writes contribute to restart totals; completion is not a zero-loss persistence
|
|
107
|
+
promise. Embedded callers can use the bounded `flush_ledger` barrier for orderly teardown; it
|
|
108
|
+
confirms attempted writes, not recovery of dropped/failed records or a filesystem sync.
|
|
109
|
+
|
|
110
|
+
The ledger lives next to the feedback file in the platform data directory. Choose another path with
|
|
111
|
+
`--usage-file` (or `FREELLAMA_USAGE_FILE`), or keep totals in memory only with `--ephemeral-usage`.
|
|
112
|
+
|
|
113
|
+
## Scrape metrics
|
|
114
|
+
|
|
115
|
+
`/metrics` exposes counters (`freellama_tasks_total`, `freellama_prompt_tokens_total`,
|
|
116
|
+
`freellama_output_tokens_total`, `freellama_task_seconds_total`, `freellama_queue_wait_seconds_total`,
|
|
117
|
+
`freellama_load_seconds_total`, `freellama_raw_requests_total`, `freellama_evictions_total`,
|
|
118
|
+
`freellama_circuit_open_total`, `freellama_concurrency_limit_changes_total`) labelled by model,
|
|
119
|
+
backend, task, and outcome, plus gauges for admission, queues, the raw proxy, host and GPU memory,
|
|
120
|
+
loaded models, and `freellama_ollama_num_parallel`. Point Prometheus, Grafana Agent, or any
|
|
121
|
+
OpenMetrics-compatible scraper at it.
|
|
122
|
+
|
|
123
|
+
## Back-pressure
|
|
124
|
+
|
|
125
|
+
FreeLlama waits for safe capacity within a deadline and bounds the retained backlog:
|
|
126
|
+
|
|
127
|
+
| Situation | Status | `code` |
|
|
128
|
+
|---|---|---|
|
|
129
|
+
| Managed queue full | `429` | `admission_queue_full` |
|
|
130
|
+
| Raw proxy over its cap after `raw_queue_wait_seconds` | `429` | |
|
|
131
|
+
| Managed wait exceeded `max_queue_wait_seconds` (or the task's `max_wait_seconds`) | `503` | `admission_timeout` |
|
|
132
|
+
| Host resources remain held when the waiting budget expires | `503` | `resource_admission_unavailable` |
|
|
133
|
+
| Backend circuit open | `503` | `upstream_circuit_open` |
|
|
134
|
+
|
|
135
|
+
These capacity refusals carry a `Retry-After` header and `retry_after_seconds` in the body. For a queue it
|
|
136
|
+
is estimated from the queue depth, the current limit, and the backend's recent average task time
|
|
137
|
+
(1 to 120 seconds). A task can ask for a shorter wait with `max_wait_seconds` (`maxWaitSeconds`
|
|
138
|
+
in MCP); the server caps it at the configured maximum.
|
|
139
|
+
|
|
140
|
+
## Circuit breaker
|
|
141
|
+
|
|
142
|
+
After `breaker_failures` consecutive upstream failures on a backend (connection errors, `500`,
|
|
143
|
+
`502`, or `504`), its circuit opens for `breaker_cooldown_seconds`; tasks routed there fail fast
|
|
144
|
+
with `503` rather than queueing behind a broken Ollama. When the cooldown ends, one probe request is
|
|
145
|
+
let through: success closes the circuit, failure reopens it. `4xx` responses such as an unknown
|
|
146
|
+
model do not count. Set `breaker_failures = 0` to disable it.
|
|
147
|
+
|
|
148
|
+
## Adaptive concurrency
|
|
149
|
+
|
|
150
|
+
Managed task costs are configurable through the runtime file's `[task_costs]` table. Valid keys
|
|
151
|
+
are `completion`, `coding`, `code_repair`, `tools`, `browser`, `vision`, `embedding`, and
|
|
152
|
+
`long_context`. Each value is a positive integer through 4294967295. Omitted kinds retain their
|
|
153
|
+
defaults: vision four, embeddings one, and other tasks two. Embeddings multiply their base by
|
|
154
|
+
`ceil(input_items/4)`; the acquired charge cannot exceed the pool's current limit.
|
|
155
|
+
|
|
156
|
+
For a qualified light OCR workload, `[task_costs]` with `vision = 2` permits two vision requests
|
|
157
|
+
under a four-unit budget while leaving other task costs unchanged. This is an operator setting,
|
|
158
|
+
not automatic quality or fit qualification. The memory governor and Ollama's final admission
|
|
159
|
+
still apply.
|
|
160
|
+
|
|
161
|
+
A task captures its cost when execution starts. Reload affects tasks that start afterward;
|
|
162
|
+
already queued or active tasks keep their captured cost. `config` reports effective values and
|
|
163
|
+
the runtime-file source; invalid keys, zero,
|
|
164
|
+
or overflow reject the reload and retain the last good configuration. Preview advice, health
|
|
165
|
+
costs, and execution receipts use the resolved policy. Health retains its summary aliases and
|
|
166
|
+
exposes the complete task-kind map under `admission.costs.base_by_task`. Task kinds remain
|
|
167
|
+
caller-declared; these weights are cooperative scheduling policy, not workload classification.
|
|
168
|
+
See the
|
|
169
|
+
[runtime example](../freellama.runtime.example.toml) for the table syntax.
|
|
170
|
+
|
|
171
|
+
With `adaptive_concurrency = "cpu"` (the default) or `"all"`, each pool's limit moves between 1 and
|
|
172
|
+
its configured ceiling:
|
|
173
|
+
|
|
174
|
+
- **Down (halve)** on an upstream error, host memory pressure (PSI or the pressure gate), or output
|
|
175
|
+
throughput below 70% of the matching execution profile's baseline. Decreases are at least
|
|
176
|
+
10 seconds apart.
|
|
177
|
+
- **Up (+1 unit)** after five consecutive comparable healthy rate observations. Generation uses
|
|
178
|
+
output tokens per decode second; embeddings use input tokens per model-reported total second.
|
|
179
|
+
The profile records the metric kind, and unlike kinds cannot train or recover together.
|
|
180
|
+
|
|
181
|
+
Only completed warm executions with verified placement and a comparable observed profile train
|
|
182
|
+
speed baselines or healthy recovery. Identity includes model digest, explicit observed context,
|
|
183
|
+
backend/process settings, effective controls, and admission class. Fresh endpoint-attributed
|
|
184
|
+
process observations bracket candidate serial samples. Unknown identity, changed controls,
|
|
185
|
+
parallel intervals, invalid rate observations, and incomplete or canceled execution break the
|
|
186
|
+
recovery streak. Failures and observed memory pressure retain their safety decreases.
|
|
187
|
+
|
|
188
|
+
Serial samples require one managed task throughout the interval: unchanged admitted/released
|
|
189
|
+
counters, active charge, capacity, and policy epoch reject transient overlap or capacity changes.
|
|
190
|
+
This avoids comparing serial request speed with legitimate parallel decoding. It does not prove
|
|
191
|
+
that no external Ollama client ran concurrently. A successful parallel execution can therefore
|
|
192
|
+
report verified placement and `feedback.accepted:true` while
|
|
193
|
+
`execution.throughput_learning.eligible:false`; it contributes no comparable speed sample.
|
|
194
|
+
|
|
195
|
+
Each backend retains at most one adaptive profile window per task kind. Status exposes
|
|
196
|
+
`adaptive.profile_windows` keyed by task; `baseline_output_tokens_per_second` is a compatibility
|
|
197
|
+
output-only summary by model and can omit additional task windows for the same model. Embedding
|
|
198
|
+
windows report their explicit input-rate kind separately. Use the task windows for learning
|
|
199
|
+
evidence. See [automatic feedback](CPU_GPU_ROUTING.md#understand-automatic-feedback) for
|
|
200
|
+
persisted routing windows.
|
|
201
|
+
|
|
202
|
+
The CPU backend is adaptive by default because oversubscribing it shows up as a throughput collapse
|
|
203
|
+
rather than an error. Every change is counted in metrics and shown in `status`.
|
|
204
|
+
|
|
205
|
+
## Model residency and eviction
|
|
206
|
+
|
|
207
|
+
Omitted managed `keep_alive` values use finite retention informed by measured reuse and loading.
|
|
208
|
+
Explicit values take precedence. For governed prewarming, profile compatibility, and retention
|
|
209
|
+
settings, see [Scope history and model warming](SCOPES_AND_WARMING.md).
|
|
210
|
+
|
|
211
|
+
When a model about to load needs room, FreeLlama unloads idle runners itself (`keep_alive: 0`)
|
|
212
|
+
instead of letting the load wait, fail, or spill to CPU. It does this in three cases: host RAM
|
|
213
|
+
can fall below the reserve, the host is already holding for low memory, or (discrete GPU) the
|
|
214
|
+
model does not fit in free VRAM, where Ollama otherwise chooses its own victim.
|
|
215
|
+
|
|
216
|
+
Which runners go is a small optimisation, in the spirit of llama-swap's `evict_costs` and LocalAI's
|
|
217
|
+
busy-aware LRU:
|
|
218
|
+
|
|
219
|
+
- **Never unloaded:** the model being loaded, `pinned_models`, `keep_alive: -1` runners, runners
|
|
220
|
+
Ollama is still loading, and any model with a FreeLlama task queued or running (unloading it forces an immediate reload). Busy status is checked again right before each unload.
|
|
221
|
+
- **Not for a model bigger than the GPU:** it spills to the CPU whatever is unloaded, so VRAM is
|
|
222
|
+
left alone.
|
|
223
|
+
- **Cost of unloading a runner** = its reload time (Ollama's measured `load_duration` from earlier
|
|
224
|
+
loads, or size ÷ 1.5 GB/s before the first one) × (1 + recent uses, decaying with a 30-minute
|
|
225
|
+
half-life; only tasks served count) × its `eviction_costs` weight (default 1).
|
|
226
|
+
- **Choice:** the set of runners with the lowest total cost that frees enough memory; ties go to
|
|
227
|
+
fewer runners, then less memory freed beyond what is needed. Only the memory that matters is
|
|
228
|
+
counted: VRAM for a GPU fit, the host-RAM part for a spill, the whole runner on CPU or unified
|
|
229
|
+
memory.
|
|
230
|
+
|
|
231
|
+
Every managed receipt that caused an eviction carries the plan under
|
|
232
|
+
`memory_reservation.eviction`: what was unloaded, its cost and reload estimate, and what was kept
|
|
233
|
+
and why. `status` and the page show the latest one that unloaded something. Eviction runs once per
|
|
234
|
+
task, after admission and before the memory wait, and is never cancelled halfway by a deadline.
|
|
235
|
+
Set `evict_idle_models = false` to leave residency entirely to Ollama.
|
|
236
|
+
|
|
237
|
+
## Who decides what: FreeLlama and Ollama
|
|
238
|
+
|
|
239
|
+
Two schedulers that both guess at memory can disagree. The split is:
|
|
240
|
+
|
|
241
|
+
| Decision | Owner | How |
|
|
242
|
+
|---|---|---|
|
|
243
|
+
| Exact memory of a loaded runner | Ollama | Measured; FreeLlama reads it from `/api/ps` |
|
|
244
|
+
| Whether a new load fits | Both, Ollama final | FreeLlama estimates from Ollama's past measurements, then Ollama loads or refuses |
|
|
245
|
+
| Decoding slots per model | Ollama | `OLLAMA_NUM_PARALLEL`; FreeLlama's primary budget defaults to two weighted units per slot |
|
|
246
|
+
| Admission, priority, queue limits, back-pressure | FreeLlama | Weighted pools, 429/503 with `Retry-After` |
|
|
247
|
+
| Which idle runner to unload, and when | FreeLlama | The cost planner above, before Ollama has to choose |
|
|
248
|
+
| Context size | Ollama by default | `num_ctx` is left to Ollama when its default covers the request |
|
|
249
|
+
|
|
250
|
+
To keep the estimates honest, FreeLlama learns from every runner Ollama reports as resident,
|
|
251
|
+
including ones loaded by raw clients, and saves those measurements to `footprints.json` next to the
|
|
252
|
+
usage ledger. After a restart a model it has seen before is sized from Ollama's measurement, not a
|
|
253
|
+
formula. Each measurement records the `OLLAMA_NUM_PARALLEL` and KV-cache type it was taken under and
|
|
254
|
+
is used only while those match, so changing either setting falls back to the formula until Ollama
|
|
255
|
+
measures again. A larger context than any measured one is sized as the measurement plus exactly the extra
|
|
256
|
+
KV cache, when the model's KV shape is known.
|
|
257
|
+
|
|
258
|
+
## Context sizing and Ollama's defaults
|
|
259
|
+
|
|
260
|
+
Sending `num_ctx` on a request pins the runner to that size: a later request for the same model
|
|
261
|
+
with a different or missing `num_ctx` forces Ollama to reload it, and Ollama's automatic
|
|
262
|
+
out-of-memory shrink-and-retry only applies when the context was not requested explicitly.
|
|
263
|
+
|
|
264
|
+
With `context_mode = "ollama_default"` (the default), FreeLlama sizes the context as before but
|
|
265
|
+
omits `num_ctx` when Ollama's own default for the model is known, covers the request, and is at most
|
|
266
|
+
`auto_context_max` (32768). The default is resolved in Ollama's order: the Modelfile's `num_ctx`,
|
|
267
|
+
then `OLLAMA_CONTEXT_LENGTH`, then (discrete GPU only) Ollama's VRAM tier — 4096 below 24 GiB, 32768
|
|
268
|
+
below 48 GiB, 262144 above. Receipts show `context_sizing.num_ctx_sent` and the default used.
|
|
269
|
+
Memory estimates always use the context Ollama can allocate. Use `"explicit"` to always
|
|
270
|
+
send `num_ctx`.
|
|
271
|
+
|
|
272
|
+
## Change settings without a restart
|
|
273
|
+
|
|
274
|
+
Put any of the settings above in a TOML file and start `serve --runtime-config <file>` (or set
|
|
275
|
+
`FREELLAMA_RUNTIME_CONFIG`). Start from
|
|
276
|
+
[`freellama.runtime.example.toml`](../freellama.runtime.example.toml). `serve` checks the file every
|
|
277
|
+
two seconds and applies changes to live admission pools; a waiting task sees the new limit at once.
|
|
278
|
+
|
|
279
|
+
Precedence for every setting, strongest first: CLI flag, `FREELLAMA_*` environment variable, the
|
|
280
|
+
runtime file, the built-in default. A flag or variable pins a value, so editing the file cannot
|
|
281
|
+
override it; `freellama config` shows which source won. A malformed file or an unknown key is
|
|
282
|
+
rejected at reload and the previous values stay in force.
|
|
283
|
+
|
|
284
|
+
The default GPU budget follows the Ollama server: 2 units per `OLLAMA_NUM_PARALLEL` slot (one chat
|
|
285
|
+
per decoding slot), read from the running Ollama process where visible.
|
package/docs/OLLAMA_SIDECAR.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Ollama sidecar boundary
|
|
2
2
|
|
|
3
|
-
FreeLlama
|
|
4
|
-
|
|
3
|
+
FreeLlama exposes task-oriented controls to agents and communicates with Ollama over HTTP.
|
|
4
|
+
It defaults to a loopback sidecar: FreeLlama manages delegation policy and resources around each
|
|
5
|
+
managed request, while Ollama loads the runner and performs inference.
|
|
5
6
|
|
|
6
7
|
```mermaid
|
|
7
8
|
flowchart LR
|
|
@@ -26,6 +27,7 @@ second, process-isolated CPU backend possible without changing arbitrary client
|
|
|
26
27
|
| Capability and memory filtering | FreeLlama managed routes |
|
|
27
28
|
| Evidence policy, confidence, and route receipts | FreeLlama managed routes |
|
|
28
29
|
| Session affinity, per-backend bounded admission, and warm runtime feedback | FreeLlama managed routes |
|
|
30
|
+
| Forecast memory reservations and requests to evict idle unpinned runners | FreeLlama managed routes |
|
|
29
31
|
| Exact model assignment to an optional CPU process | FreeLlama configuration |
|
|
30
32
|
| Guarded CPU/GPU preference within assigned eligible models | FreeLlama managed routes |
|
|
31
33
|
| Authentication and remote exposure | FreeLlama bearer middleware; external ingress owns TLS and tenant authorization |
|
|
@@ -54,9 +56,9 @@ clients that opt into the managed API receive routing and policy behavior.
|
|
|
54
56
|
|
|
55
57
|
## Know the remaining limits
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
In `serve`, mutating passthrough traffic shares the primary transition lock and receives host-pressure
|
|
60
|
+
gating, while managed tasks also reserve forecast memory. Direct Ollama callers bypass these
|
|
61
|
+
controls. FreeLlama cannot preempt inference or constrain other processes. A configured but unreachable CPU backend makes managed catalog discovery fail closed;
|
|
60
62
|
raw primary passthrough remains usable.
|
|
61
63
|
|
|
62
64
|
Runtime feedback is task-specific, token-normalized, and warm-only. It can steer
|
|
@@ -67,7 +69,7 @@ Ollama residency.
|
|
|
67
69
|
|
|
68
70
|
Read [Architecture](ARCHITECTURE.md) for all managed flows,
|
|
69
71
|
[CPU and GPU model routing](CPU_GPU_ROUTING.md) for the two-process procedure, and
|
|
70
|
-
[Ollama and FreeLlama optimization](OLLAMA_SYSTEM_OPTIMIZATION.md) for the full tuning boundary.
|
|
72
|
+
[Ollama and FreeLlama optimization](dev/OLLAMA_SYSTEM_OPTIMIZATION.md) for the full tuning boundary.
|
|
71
73
|
|
|
72
74
|
## Sources
|
|
73
75
|
|
package/docs/PRODUCTION.md
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# Prepare FreeLlama for production
|
|
2
2
|
|
|
3
|
-
This runbook prepares
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
This runbook prepares the FreeLlama management layer for agents using local models in a
|
|
4
|
+
single-operator or trusted-team deployment. Configure the Ollama backends, model evidence,
|
|
5
|
+
authentication, and resource limits before agents submit work.
|
|
6
|
+
|
|
7
|
+
FreeLlama supports authenticated nonloopback listeners. Put TLS and tenant-specific rate limits
|
|
8
|
+
at an external ingress when traffic crosses a machine boundary; FreeLlama's bearer token does
|
|
9
|
+
not provide tenant isolation or billing.
|
|
7
10
|
|
|
8
11
|
## Meet the prerequisites
|
|
9
12
|
|
|
@@ -28,7 +31,15 @@ published tag:
|
|
|
28
31
|
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1 -Version VERSION
|
|
29
32
|
```
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
The [release workflow](../.github/workflows/release.yml) builds CLI and native artifacts for eight
|
|
35
|
+
targets, assembles packages, verifies package contents, and publishes on version tags. The
|
|
36
|
+
[CI workflow](../.github/workflows/ci.yml) runs Rust checks on macOS, Linux, and Windows, plus
|
|
37
|
+
JavaScript/native checks on macOS and Linux. These workflows do not prove driver compatibility or
|
|
38
|
+
complete the hardware promotion checklist below. Release artifact builds depend on the reusable CI checks.
|
|
39
|
+
The publish step also verifies that a version tag matches the workspace version.
|
|
40
|
+
Live E2E and hardware qualification remain separate operator checks; verify those receipts before tagging.
|
|
41
|
+
|
|
42
|
+
For manual assembly, build and test every claimed target in a clean
|
|
32
43
|
environment, place each executable and matching addon under `release-artifacts/<target>/`, run
|
|
33
44
|
`yarn release:assemble release-artifacts release` and `yarn release:verify:publish`, then attach
|
|
34
45
|
`release/SHA256SUMS` and binaries to the release. Publish the eight `@octocodeai/freellama-native-*` packages
|
|
@@ -52,9 +63,13 @@ swap, eviction churn, or unacceptable queueing.
|
|
|
52
63
|
| `OLLAMA_MAX_QUEUE` | Workload-specific, bounded value | Limits Ollama's internal queue independently of FreeLlama admission |
|
|
53
64
|
|
|
54
65
|
Do not set a global `OLLAMA_CONTEXT_LENGTH` merely to maximize the advertised window. Managed
|
|
55
|
-
FreeLlama tasks
|
|
56
|
-
|
|
57
|
-
|
|
66
|
+
FreeLlama text tasks estimate a sufficient context and can omit `num_ctx` when Ollama's known default
|
|
67
|
+
covers the request within the configured automatic bound. Explicit context requests send `num_ctx`.
|
|
68
|
+
A larger context and a larger `OLLAMA_NUM_PARALLEL` multiply K/V-cache memory. See
|
|
69
|
+
[context sizing](MONITORING.md#context-sizing-and-ollamas-defaults) for defaults and receipts.
|
|
70
|
+
Direct Ollama clients still follow the
|
|
71
|
+
server's context configuration. Current context documentation describes VRAM-tiered 4k/32k/256k
|
|
72
|
+
defaults while the FAQ still says 4096, so treat `/api/ps` `context_length` after load as authority.
|
|
58
73
|
|
|
59
74
|
`freellama doctor` returns `local_conservative_config_posture` as a **non-mutating** portable
|
|
60
75
|
starting profile. It names the source of each value (`observed_process` or `configuration_hint`),
|
|
@@ -63,11 +78,13 @@ parallel stream, and a finite internal queue before benchmarking. It also report
|
|
|
63
78
|
`host_runtime_signals` with source and permission scope. Treat unavailable GPU-memory, thermal, or
|
|
64
79
|
power signals as unavailable; do not substitute host RAM or a guessed value.
|
|
65
80
|
|
|
66
|
-
FreeLlama and Ollama have separate queues. FreeLlama
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
81
|
+
FreeLlama and Ollama have separate queues. FreeLlama caps retained managed waiters per backend with
|
|
82
|
+
`--max-queued-tasks`/`--cpu-max-queued-tasks`, then waits for at most
|
|
83
|
+
`--max-queue-wait-seconds`. An admitted request can then enter Ollama's internal queue,
|
|
84
|
+
which is bounded by `OLLAMA_MAX_QUEUE`. Raw compatibility traffic bypasses weighted managed
|
|
85
|
+
admission and enters the primary Ollama queue through a separate one-stream default cap in `serve`.
|
|
86
|
+
Set all limits from observed latency and overload behavior; changing one does not configure the
|
|
87
|
+
others.
|
|
71
88
|
|
|
72
89
|
The following flow shows where each production setting applies:
|
|
73
90
|
|
|
@@ -76,20 +93,22 @@ flowchart LR
|
|
|
76
93
|
C["Client"] --> FQ["FreeLlama admission<br/>weighted budget + wait deadline"]
|
|
77
94
|
FQ -->|"refused"| E503["503 server busy"]
|
|
78
95
|
FQ -->|"admitted"| OQ["Ollama queue<br/>OLLAMA_MAX_QUEUE"]
|
|
79
|
-
RAW["Raw /api/* or /v1/*"] -->
|
|
96
|
+
RAW["Raw /api/* or /v1/*"] --> RC["Raw stream cap<br/>default 1 in serve"]
|
|
97
|
+
RC -->|"refused"| E503
|
|
98
|
+
RC -->|"admitted until EOF/drop"| OQ
|
|
80
99
|
OQ --> S["Ollama scheduler<br/>loaded models + parallel streams"]
|
|
81
100
|
S --> M["Runner memory<br/>num_ctx x K/V cache"]
|
|
82
101
|
```
|
|
83
102
|
|
|
84
103
|
These values are conservative starting points, not universal constants. NVIDIA, AMD, Apple, and
|
|
85
104
|
CPU-only hosts must pass hardware validation before promotion. See
|
|
86
|
-
[Ollama and FreeLlama optimization](OLLAMA_SYSTEM_OPTIMIZATION.md) for the ownership boundary and
|
|
105
|
+
[Ollama and FreeLlama optimization](dev/OLLAMA_SYSTEM_OPTIMIZATION.md) for the ownership boundary and
|
|
87
106
|
[Run models on CPU and GPU](CPU_GPU_ROUTING.md) for device-specific controls.
|
|
88
107
|
|
|
89
108
|
Put the values in the service manager that owns each Ollama process: launchd on macOS, systemd or
|
|
90
109
|
the container definition on Linux, and the Windows service wrapper. Shell exports and
|
|
91
110
|
`launchctl setenv` are useful diagnostics but are login-session state, not a reboot-persistent
|
|
92
|
-
production configuration. After a real service restart, rerun `doctor` and `scripts/check.sh` and
|
|
111
|
+
production configuration. After a real service restart, rerun `doctor` and `skills/freellama/scripts/check.sh` and
|
|
93
112
|
require the same visible values before admitting work.
|
|
94
113
|
|
|
95
114
|
## Create the security and state files
|
|
@@ -122,6 +141,18 @@ Only physically verified warm samples are saved. A corrupt or unsupported snapsh
|
|
|
122
141
|
fail instead of silently discarding routing evidence. Use `--ephemeral-feedback` only for
|
|
123
142
|
disposable tests.
|
|
124
143
|
|
|
144
|
+
## Bound conversation history and residency
|
|
145
|
+
|
|
146
|
+
Scope histories and deferred jobs are process-local and are discarded on restart. Configure
|
|
147
|
+
`[scopes]` and `[warming]` limits in the runtime file from measured workload needs; finite history
|
|
148
|
+
bounds and automatic retention remain separate from host-memory reserves. Warm loads use the same
|
|
149
|
+
admission and placement checks as tasks. See [Scope history and model warming](SCOPES_AND_WARMING.md)
|
|
150
|
+
for expected revisions, forks, explicit history reads, and residency precedence.
|
|
151
|
+
|
|
152
|
+
Usage persistence is asynchronous best effort. Inspect pending, dropped, failed, and error evidence
|
|
153
|
+
in `status.usage_ledger`; task success does not prove its usage record reached disk. See
|
|
154
|
+
[Usage recording](MONITORING.md#record-usage) for replay, rotation, and shutdown boundaries.
|
|
155
|
+
|
|
125
156
|
## Configure MCP
|
|
126
157
|
|
|
127
158
|
Set these values in the MCP host environment:
|
|
@@ -143,7 +174,7 @@ direct Ollama requests, and managed FreeLlama tasks send their own `num_ctx`.
|
|
|
143
174
|
|
|
144
175
|
## Verify lifecycle and placement
|
|
145
176
|
|
|
146
|
-
`keep_alive:0`
|
|
177
|
+
`keep_alive:0` preserves placement evidence. FreeLlama temporarily holds the runner,
|
|
147
178
|
observes `/api/ps`, records eligible feedback, explicitly unloads it, and verifies that it is no
|
|
148
179
|
longer resident before returning. Inspect both `execution.observation` and
|
|
149
180
|
`execution.lifecycle.status`.
|
|
@@ -188,7 +219,7 @@ Promote a release only when all conditions pass:
|
|
|
188
219
|
6. Restart testing proves feedback reloads and a corrupt snapshot fails startup.
|
|
189
220
|
7. Immediate unload reports verified pre-unload placement and verified post-unload absence.
|
|
190
221
|
8. Every claimed hardware row has a real archived acceptance receipt.
|
|
191
|
-
9. The MCP
|
|
222
|
+
9. The MCP schemas match the published tool surface and pass its context-budget contract.
|
|
192
223
|
|
|
193
224
|
Rollback by returning the listener to loopback, stopping the new service, and starting the prior
|
|
194
225
|
checksummed binary with the same policy and feedback snapshot. Never downgrade across an unsupported
|