@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
@@ -4,6 +4,10 @@ To separate GPU work from CPU helpers, configure two Ollama processes and assign
4
4
  tags to the secondary process. FreeLlama routes managed tasks within those assignments, applies
5
5
  `num_gpu: 0` to CPU requests, and reports both the selected backend and observed processor placement.
6
6
 
7
+ This guide describes the Ollama backend contract. The [llama.cpp adapter](LLAMACPP.md) shares
8
+ CPU/GPU admission pools by operator assignment, but does not inject Ollama controls, observe
9
+ physical placement, manage lifecycle, or participate in automatic placement learning.
10
+
7
11
  The calling agent submits tasks and placement preferences. FreeLlama coordinates admission,
8
12
  memory checks, and model transitions for each backend; the operator configures the processes and
9
13
  eligible tags. A configured CPU backend is intent: inspect the placement observation before
@@ -56,8 +60,10 @@ flowchart TB
56
60
  CP --> CPU["CPU runner"]
57
61
  ```
58
62
 
59
- FreeLlama does not rewrite raw passthrough request bodies or route them by model. A direct Ollama client that
60
- needs model-aware CPU placement must use the managed task endpoint instead.
63
+ Native Ollama passthrough does not apply `--cpu-model` assignments; a direct Ollama client that
64
+ needs model-aware CPU placement must use managed tasks. Configured OpenAI-compatible `/v1/*`
65
+ upstreams are a separate model-routing path, and `/v1/systemone` has an asset-translation exception.
66
+ See [API passthrough](API.md#ollama-compatible-passthrough).
61
67
 
62
68
  ## Start the backends
63
69
 
@@ -150,6 +156,9 @@ The defaults above admit one ordinary primary-backend chat (cost 2) and one CPU
150
156
  at the same time. They are conservative workload units for the common `OLLAMA_NUM_PARALLEL=1`
151
157
  layout, not a profile of the development Mac. Increase them only after measuring queue wait,
152
158
  resident memory, and Ollama's own parallel setting on the target host.
159
+ A task waiting for host memory releases execution units while retaining one bounded queue
160
+ registration; returning to admission transfers that ticket atomically. Cancellation removes it.
161
+ This protects execution capacity without creating an uncounted memory-wait backlog.
153
162
  Queue cardinality and wait time are separate bounds: excess waiters are refused immediately, while
154
163
  an admitted waiter may remain until `--max-queue-wait-seconds`. Automatic backend selection checks
155
164
  that the actual task cost fits the current slot snapshot before following historical speed.
@@ -274,7 +283,7 @@ the entire pool's ceiling. Default vision weight four can serialize two vision r
274
283
  four-unit budget even when Ollama has two slots. A lower weight requires a qualified workload;
275
284
  it does not add engine slots or relax memory checks. See
276
285
  [monitoring controls](MONITORING.md#adaptive-concurrency).
277
- Raw generation requests follow the same rules on the primary backend. A raw request for a runner
286
+ Raw Ollama generation requests follow the same rules on the primary backend. A raw request for a runner
278
287
  Ollama already holds at a matching digest and context takes no lock. A raw load takes the load lock
279
288
  and receives 503 (`proxy busy: another model load is active`) if it stays busy past the raw queue
280
289
  wait. Metadata GET/HEAD, `/api/show`, model-store calls (pull, push, copy, delete), and empty
@@ -312,9 +321,10 @@ The rules that follow:
312
321
  - Observing runner readiness wakes resource waiters to re-size their demand. A same-model follower
313
322
  waiting for a cold-load forecast can then share the runner while its first request still decodes.
314
323
 
315
- A cold task reads `/api/ps` six times in all: discovery, the receipt's capacity preview, the
316
- dispatch-time forecast, the observation before the lock, the observation after winning it, and the
317
- placement observation after the run. A resident task skips the post-lock read.
324
+ Ollama residency is observed during discovery, capacity planning, dispatch preparation and
325
+ post-run placement checks. The cold path rechecks after acquiring the load lock; a resident task
326
+ skips that read. Revalidation and readiness polling can add observations, so the count is not a
327
+ fixed per-task API contract.
318
328
 
319
329
  ### Degraded runner identity
320
330
 
@@ -347,7 +357,7 @@ alike (`PlacementRule`). Placement is judged from the same `/api/ps` entry's `si
347
357
 
348
358
  ### Raw generation whose allocation cannot be forecast
349
359
 
350
- A raw generation is admitted only with a memory forecast. When the model's metadata cannot be read
360
+ A raw Ollama generation is admitted only with a memory forecast. When the model's metadata cannot be read
351
361
  in time, or the request body names a model the proxy cannot resolve (a multipart body, say) and
352
362
  could still load one, nothing could size or serialize that load. It is refused with HTTP 503,
353
363
  `Retry-After: 1` and `code: "model_forecast_unavailable"` instead of being admitted with a zero-byte
@@ -391,7 +401,8 @@ cold load: when the faster backend's model is not loaded but the other backend's
391
401
  the loaded one runs (`resident_backend_avoids_cold_load`); warm the faster model to switch. The CLI
392
402
  keeps the bounded, versioned, prompt-free snapshot in the shared database by default; `--ephemeral`
393
403
  opts into reset-on-restart behavior. Aggregate duration counters are diagnostic only and do not
394
- qualify learned hints; a snapshot of another schema version is refused. Health's
404
+ qualify learned hints. A corrupt or unsupported feedback snapshot is rejected with a warning;
405
+ the server starts with empty feedback and preserves the rejected snapshot. Health's
395
406
  `decision_ready` describes the stored profile window; the current request must independently
396
407
  match it before routing can use its speed. `GET /_freellama/v1/health` exposes profile identity,
397
408
  profile sample counts, persistence status, and per-backend admission capacity. Task receipts include
@@ -483,7 +494,9 @@ If an assigned model does not appear, check the following conditions:
483
494
 
484
495
  A configured but unreachable CPU backend causes model discovery to fail closed. GPU-managed tasks
485
496
  can also be unavailable until the secondary server returns. Raw passthrough to the primary server
486
- continues to work because it does not depend on catalog discovery.
497
+ continues to work because it does not depend on catalog discovery. Explicit configured llama.cpp
498
+ previews and tasks also bypass Ollama catalog discovery; use their route preview rather than the
499
+ Ollama-oriented overall readiness endpoint.
487
500
 
488
501
  For the surrounding Ollama settings, see [Production](PRODUCTION.md#configure-ollama-explicitly). For
489
502
  all `serve` flags, see the [CLI reference](CLI.md).
@@ -1,6 +1,6 @@
1
1
  # Deferred jobs and recovery
2
2
 
3
- FreeLlama's deferred jobs keep one accepted task identity through polling, cancellation and result retrieval. A missing result or an uncertain outcome never authorizes automatic inference replay. Ollama still owns execution and physical cancellation; these records coordinate the FreeLlama worker.
3
+ FreeLlama's deferred jobs keep one accepted task identity through polling, cancellation and result retrieval. A missing result or an uncertain outcome never authorizes automatic inference replay. The configured inference server owns execution and physical cancellation; these records coordinate the FreeLlama worker. The [llama.cpp adapter](LLAMACPP.md) supports only its documented bounded text subset, even when deferred.
4
4
 
5
5
  ## Enable durable receipts
6
6
 
@@ -14,9 +14,9 @@ The journal persists receipts, bounded results/errors, and keyed hashes of reque
14
14
 
15
15
  `POST /_freellama/v1/tasks` with `defer:true` returns `deferred:true`, a `job` containing its `id`, and `retention` limits. Use `GET /_freellama/v1/jobs/{id}` for its result and `GET /_freellama/v1/jobs` for a metadata-only list. The list strips result/error payloads in SQLite before loading recovered records into the control plane.
16
16
 
17
- An embedding task may carry `nearest` (`{query?, top?, min_score?, labels?}`, with `return_embeddings` to keep the vectors). The core embeds the items (the query first, in slices of 32 pinned to one verified runner identity), ranks them by cosine similarity and stores `nearest: {mode, matches|pairs}` in place of vectors, so a deferred job's result is ranked and small. The whole input is one job and must fit the 16 MiB job input limit; without a query at most 4,000 items are compared pairwise. A malformed `nearest` is refused at submission. Through MCP, `run_task {defer:true, tasks:[...]}` submits every item as its own job and returns `{deferred:true, jobs:[{id, job}]}`; the HTTP `/tasks/batch` endpoint still refuses deferred items.
17
+ An embedding task may carry `nearest` (`{query?, top?, min_score?, labels?}`, with `return_embeddings` to keep the vectors). The core embeds the items (the query first, in slices of 32 pinned to one verified runner identity), ranks them by cosine similarity and stores `nearest: {mode, matches|pairs}` in place of vectors, so a deferred job's result is ranked and small. The whole input is one job and must fit the 16 MiB job input limit; without a query at most 4,000 items are compared pairwise. A malformed `nearest` is refused at submission. Through MCP, `run_task {defer:true, tasks:[...]}` submits every item as its own job and returns `{deferred:true, jobs:[{id, job}]}`; the HTTP `/task-batches` endpoint still refuses deferred items.
18
18
 
19
- `POST /_freellama/v1/jobs/{id}/cancel` requests cancellation and waits for the attached worker to settle and release local permits. It also waits for pending terminal persistence. A result already committed by the execution path retains its completed status. Acknowledged local cancellation is not proof that Ollama physically stopped accepted work.
19
+ `POST /_freellama/v1/jobs/{id}/cancel` requests cancellation and waits for the attached worker to settle and release local permits. It also waits for pending terminal persistence. A result already committed by the execution path retains its completed status. Acknowledged local cancellation is not proof that the inference server physically stopped accepted work.
20
20
 
21
21
  `DELETE /_freellama/v1/jobs/{id}` first settles locally owned work, then hides the record and removes its retained payload. With persistence enabled, its idempotency tombstone remains until expiry. An unattached worker with an unknown outcome cannot be removed early. A failed terminal database commit also prevents removal of its still-unfinished durable record.
22
22
 
@@ -26,10 +26,23 @@ MCP task cancellation and managed research use addressable jobs regardless of wh
26
26
 
27
27
  ## Idempotency
28
28
 
29
- With persistence enabled, the HTTP task request may include `idempotency_key`, containing 1–128 UTF-8 bytes. It requires `defer:true`; synchronous requests and servers without durable jobs reject the field. The current MCP tool schema does not add an idempotency-key argument.
29
+ With persistence enabled, the HTTP task request may include `idempotency_key`, containing 1–128 UTF-8 bytes. It requires `defer:true`; synchronous requests and servers without durable jobs reject the field. MCP passes it as `run_task {defer:true, idempotencyKey}` and the agent commands as `freellama run --defer --idempotency-key KEY`; both refuse a key without `defer`. A batch (`tasks`, `--each`) takes no key: each item is its own job.
30
30
 
31
31
  Keys are hashed (HMAC-SHA256, see [request hashes](#request-hashes)) with authenticated caller identity and scoped to a server topology: listen address, primary endpoint, CPU endpoint and configured CPU model list. Keep that configuration and caller identity stable when recovering jobs. Task input is serialized and hashed after removing the key, together with the set of explicitly supplied fields. Retries must preserve both values and field presence: omission can inherit scope defaults while an explicit default overrides them. Reusing a key with changed input returns `task_job_idempotency_conflict`.
32
32
 
33
+ Managed llama.cpp configuration participates in the **input hash**, while the lookup namespace
34
+ stays stable. The fingerprint covers each managed engine's name, URL, model, processor and
35
+ context/output/memory bounds, sorted by name. Declaration order, API-key rotation and passthrough-only
36
+ upstreams do not change it. Adding, removing or changing a managed mapping returns a conflict for a
37
+ retained key instead of returning a result from different settings or silently running new work.
38
+ The old job remains readable by ID. All managed mappings are included conservatively because a
39
+ scope can inherit a model: even changing an unrelated managed engine can invalidate a retry.
40
+
41
+ Ollama-only installations preserve their existing input hashes. After upgrading an installation
42
+ with managed engines from a version without this fingerprint, retained keys conflict; retrieve
43
+ and inspect the original job first. Use a new key only for intentionally new work. The fingerprint
44
+ describes operator configuration, not a llama.cpp weight digest or physical execution attestation.
45
+
33
46
  A repeated key returns the original job, including a retained terminal result, before checking local registry capacity. Claiming the key and reserving its durable record is one transaction. Concurrent requests cannot both claim that key. A new durable claim rejected by local capacity is recorded as failed with `execution_outcome:"not_started"` and `retry_safe:true`; repeating the key returns that original refusal instead of starting work.
34
47
 
35
48
  After restart, only recorded terminal outcomes are recoverable as settled results. An unfinished record becomes a read-time `failed` receipt with reason `execution_outcome_unknown`, error code `task_job_outcome_unknown`, its original `job_id`, and `retry_safe:false`. It may represent an interrupted worker, a worker still attached to another server, or a submission interrupted around acceptance. No worker is resumed or recreated. If the original worker later commits a terminal record, subsequent retrieval can observe it.
package/docs/FEATURES.md CHANGED
@@ -1,15 +1,16 @@
1
1
  # FreeLlama features and how it works
2
2
 
3
- Moved from the root README. For install and a first task, start with the [README](../README.md).
3
+ For install and a first task, start with the [README](../README.md). The
4
+ [end-to-end review](OLLAMA_REVIEW.md) records feature coverage and current limits.
4
5
 
5
6
  ![A brown cartoon llama stands on a pastel cloud background.](../assets/logo.jpg)
6
7
 
7
8
  **Run your agent's bulk work on local models without overloading your machine.**
8
9
 
9
- FreeLlama sits between an AI agent and [Ollama](https://ollama.com). For each task it picks an
10
- installed model that fits, admits the task against live memory, CPU and heat signals, runs it on the
11
- GPU or a CPU-only Ollama, and returns the result with a receipt of where and how it ran. Any Ollama
12
- model works.
10
+ FreeLlama sits between an AI agent and local inference servers. Its full Ollama path selects an
11
+ eligible installed model, checks memory and pressure, and returns a result with execution evidence.
12
+ An explicit [llama.cpp adapter](LLAMACPP.md) supports bounded text tasks with the same admission
13
+ and memory governor. Capabilities, context and backend support determine which tasks can run.
13
14
 
14
15
  ```mermaid
15
16
  flowchart LR
@@ -22,8 +23,8 @@ flowchart LR
22
23
  ## Why FreeLlama
23
24
 
24
25
  Coding agents spend paid tokens and context on work a local model can do: embedding files, reading
25
- screenshots and scans, rewriting or summarizing many files. Calling Ollama directly, an agent cannot
26
- tell:
26
+ screenshots and scans, rewriting or summarizing many files. A direct Ollama caller must assemble
27
+ metadata, host observations and result verification to answer:
27
28
 
28
29
  - **Which model:** tag names do not show capabilities, context window or memory footprint.
29
30
  - **Whether there is room:** a new load can push the machine into swap, several agents can pile onto
@@ -55,8 +56,9 @@ flowchart TD
55
56
 
56
57
  ### The smart flow
57
58
 
58
- Every managed task passes the same gates, each deciding from installed metadata, live host signals
59
- and observed behavior, never from a model's name.
59
+ Every managed task passes core admission and resource checks. The Ollama path below selects from
60
+ installed metadata and qualified evidence. llama.cpp uses explicit operator configuration and
61
+ refuses capabilities outside its [documented subset](LLAMACPP.md#supported-contract-and-limits).
60
62
 
61
63
  ```mermaid
62
64
  flowchart LR
@@ -76,29 +78,35 @@ An explicit `model` always wins over routing.
76
78
  ## Features
77
79
 
78
80
  Each feature is reachable from MCP, the CLI and the HTTP control API under `/_freellama/v1` unless a
79
- cell says otherwise.
81
+ cell says otherwise. Every MCP tool is also reachable from a shell with `freellama tool <name> JSON`, and
82
+ `run_task` with `freellama run` ([agent CLI](AGENT_CLI.md)).
80
83
 
81
84
  | Feature | What you get | MCP tool | CLI | HTTP |
82
85
  |---|---|---|---|---|
83
- | [Model selection](#model-selection) | The right installed model for the task, with a confidence level | `run_task {preview:true}`, `models` | `route`, `models` | `POST /routes`, `GET /models` |
86
+ | [Model selection](#model-selection) | An eligible installed model with an evidence grade | `run_task {preview:true}`, `models` | `route`, `models` | `POST /routes`, `GET /models` |
87
+ | [Fallback chains](#fallback-chains) | An ordered list of models to try when the one before is refused before it runs (no room, input too long, not installed); never after a model started | `run_task {fallbackModels}` | `task --fallback-model`, `freellama run --fallback` | `fallback_models` on `POST /tasks` |
84
88
  | [Resource admission](#resource-admission) | Tasks run, wait or are refused with a reason | every `run_task` receipt, `doctor {view:"status"}` | `status`, `ready` | `GET /health` (liveness), `GET /ready` (can serve now), `GET /status` |
85
89
  | [CPU and GPU backends](#cpu-and-gpu-backends) | Helper models on CPU next to GPU work, with proof of where each ran | `run_task {executionPreference}` | `serve --cpu-upstream --cpu-model` | `POST /tasks` |
86
90
  | Decisions | Label, triage or yes/no-check items with a decision model: one forward pass, one line per answer | `run_task {task:"decision", state, questions}` | `task --task decision --questions` | `POST /tasks` |
87
91
  | Ranked search and duplicates | Embed files or texts and get the closest items to a query, or the most similar pairs, as labels with scores instead of vectors; files are chunked by lines and labelled `path:Lstart-Lend` | `run_task {task:"embedding", files, nearest}` | `task --task embedding --input-file F --nearest QUERY` | — |
88
- | Speech | Transcribe or translate a WAV, or speak text to a WAV file, on a local audio model | `audio` | — | Ollama `/v1/audio/*` through serve |
92
+ | Speech | Transcribe or translate a WAV, or speak text to a WAV file, on a local audio model | `audio` | `freellama tool audio` | Ollama `/v1/audio/*` through serve |
89
93
  | Inputs by path | The server reads the files an agent names, so logs, screenshots and source files are never pasted into its output | `run_task {files}` | `task --input-file`, `--image` | — |
90
- | [Loop control](#loop-control) | A repeating answer stops early with every token kept | `run_task {stopOnRepetition}` | `task --stop-on-repetition` | `stop_on_repetition` |
94
+ | [Loop control](#loop-control) | Detect repeated output and stop a known looper; the retained result records the stop reason | `run_task {stopOnRepetition}` | `task --stop-on-repetition` | `stop_on_repetition` |
91
95
  | [Machine awareness](#machine-awareness) | GPU, cores, memory, GPU load and heat read from the OS | `doctor` | `machine`, `doctor` | `GET /machine` |
92
96
  | [Batches, jobs and history](#batches-jobs-and-history) | Fan-out, submit now and collect later, multi-turn chat without resending history | `run_task {tasks}` / `{defer}`, `task_jobs`, `scope`, `session` | `task --defer`, `jobs`, `scope`, `session` | `/task-batches`, `/jobs`, `/scopes`, `/sessions` |
93
97
  | Warm-up and unload | Load a model ahead of use through the same memory checks; unload a resident one once its tasks finish (never loads first) | `ollama_manage {action:"warm"}`, `ollama_manage {action:"unload"}` | `warm`, `unload` | `POST /warm`, `POST /unload` |
94
98
  | Model catalog and cookbooks | Tested picks per job with their evidence, what is installed and fits now, and a recipe for each | `models {view:"catalog"}`, `freellama://docs/cookbooks/<job>` | `catalog [--job JOB]`, [docs/cookbooks](cookbooks/README.md) | — |
95
- | Find and install models | ollama.com and Hugging Face GGUF search, every tag with its size and memory fit, pulls only on approval | `models {view:"library"}`, `ollama_pull`, `ollama_delete` | MCP only | MCP only |
96
- | Job mode and prompts | Name a job and FreeLlama runs its first catalog pick that is installed and fits, with its documented prompt, options and embedding prefixes; your fields win. MCP prompts give each job's call, and `saveAs` hands an answer to the next task as a file | `run_task {job, saveAs}`, MCP prompts, [cookbook](cookbooks/jobs.md) | MCP only | MCP only |
97
- | Chunked sweeps | A local model checks a code tree, log or docs site chunk by chunk in the background, saves every result, re-checks flags with a stronger model and, against a baseline, reports only what changed | `sweep`, [cookbook](cookbooks/sweep.md) | MCP only | MCP only |
98
- | [Grounded research](#grounded-research) | Read-only repository answers with file and line citations | `delegate_research` | MCP only | MCP only |
99
+ | Find and install models | ollama.com and Hugging Face GGUF search, every tag with its size and memory fit, pulls only on approval | `models {view:"library"}`, `ollama_pull`, `ollama_delete` | `freellama tool models\|ollama_pull\|ollama_delete` (same approvals) | — |
100
+ | Job mode and prompts | Name a job: use a qualified machine-local Rust route when available, otherwise a portable catalog/capability fallback, with documented prompts and options; your fields win. MCP prompts give each job's call, and `saveAs` hands an answer to the next task as a file | `run_task {job, saveAs}`, MCP prompts, [cookbook](cookbooks/jobs.md) | `freellama run -j JOB\|-w WORKFLOW --save-as NAME`, `freellama workflows` | — |
101
+ | [Your own workflows](PROMPTS.md#your-own-workflows) | A Markdown file per workflow in `~/.octocode/freellama/workflows/`: a job, a title and the instructions. It runs like a built-in, replaces a built-in of the same name, and the receipt names the file and its digest | `run_task {workflow}` | `freellama run -w NAME`, `freellama workflows` | gateway `freellama/NAME` |
102
+ | Chunked sweeps | A local model checks a code tree, log or docs site chunk by chunk in the background, saves every result, re-checks flags with a stronger model and, against a baseline, reports only what changed | `sweep`, [cookbook](cookbooks/sweep.md) | `freellama tool sweep` | — |
103
+ | [Grounded research](#grounded-research) | Read-only repository answers with file and line citations | `delegate_research` | `freellama tool delegate_research` | — |
99
104
  | [Small agent context](FEATURES.md#small-agent-context) | Compact results and paged details instead of raw dumps | every tool, `read_response` | JSON on stdout | JSON |
100
105
  | [Observe and evaluate](#observe-and-evaluate) | Live status, usage, metrics, benchmarks, routing policy from evaluations | `doctor {view:"usage"}` | `status`, `usage`, `config`, `bench-all`, `policy from-eval` | `/status`, `/usage`, `/metrics`, `/config`, `/_freellama/ui` |
101
- | Ollama passthrough | Any Ollama `/api/*` or `/v1/*` call, byte-preserving, with retries and a stream cap | — | `serve`, `proxy` | Ollama's own paths |
106
+ | Ollama passthrough | Any Ollama `/api/*` or `/v1/*` call, byte-preserving, with retries and a stream cap; `freellama gateway` also serves `freellama/<workflow\|job\|auto>` virtual models over Ollama, OpenAI `/v1/chat/completions` and `/v1/responses`, and Anthropic `/v1/messages` | — | `serve`, `proxy`, `freellama gateway` | Ollama's own paths |
107
+
108
+ Features involving model lifecycle, tool calls, media, embeddings, streaming and automatic
109
+ selection below describe Ollama. The llama.cpp adapter supports explicit text tasks only.
102
110
 
103
111
  ### Model selection
104
112
 
@@ -107,20 +115,59 @@ window, routing policy and memory fit, and reports a confidence level. `minConfi
107
115
  refuses weakly evidenced routes, `objective:"quality"` requires a policy-backed model, and `model`
108
116
  pins one. A bare name resolves as in Ollama: `name:latest`, or the only installed tag of that family.
109
117
 
110
- Routing never ranks by a model's name or architecture and adds no model-specific request options. A
118
+ Rust routing never ranks by a model's name or architecture. Operator policy can supply per-model
119
+ request defaults; explicit caller options take precedence. Shipped MCP job prompts and portable
120
+ catalog picks are a separate opt-in layer. A
111
121
  model that loops on a task kind (at least two loops in at most twice as many runs) ranks last for that
112
122
  kind; `models` lists the evidence as `observed_loops`. See [model selection](MODEL_SELECTION.md).
113
123
 
124
+ Machine-local throughput rankings require matching host/hardware identity, loopback endpoint and
125
+ model digest; legacy or mismatched reports do not qualify. Throughput is not correctness evidence.
126
+ See [model selection](MODEL_SELECTION.md) and [reliability evidence](RELIABILITY.md).
127
+
128
+ ### Fallback chains
129
+
130
+ `fallbackModels` (HTTP `fallback_models`, CLI `--fallback-model`, agent CLI `--fallback`) is an
131
+ explicit, ordered list of up to 4 models. The next one runs only when the one before it was refused
132
+ before anything executed:
133
+
134
+ | Refusal | Code |
135
+ |---|---|
136
+ | No room in memory by the wait deadline | `resource_admission_unavailable` |
137
+ | The input exceeds the model's context window | `context_window_exceeded`, `embedding_item_exceeds_context` |
138
+ | The model file alone exceeds the host budget | `model_exceeds_host_budget` |
139
+ | Not installed, or lacks the task's capability | `model_not_installed`, `model_not_eligible` |
140
+ | The backend's circuit is open | `upstream_circuit_open` |
141
+
142
+ Anything else stops the chain: a timeout, a cancellation, a busy queue or an error after the model
143
+ started never moves to another model, so no work is replayed after an uncertain outcome. The receipt's
144
+ `fallback` lists every attempt with its code, and the answer gets a `check:` line naming the model
145
+ that answered. Each attempt waits as a single task would, so set a short `maxWaitSeconds` to move on
146
+ sooner; `timeoutSeconds` bounds the whole chain. While one model is tried, the models after it count
147
+ as busy, so making room for an attempt that is then refused never unloads the model that would run
148
+ next. An entry equal to the first model (which may be a scope default, a job's pick or the model
149
+ routing chose) is skipped, and every attempt names the model it really used; a model listed twice
150
+ is refused. A chain that fails is charged in usage to the model that failed last. When an embedding task runs in slices and a later slice is refused,
151
+ part of the work already ran, so the chain stops there. A chain cannot be combined with a pinned
152
+ digest or backend, and MCP refuses one over separately sliced embeddings so one answer comes from one
153
+ model. Batch items and `task_jobs` results carry the receipt's `fallback` too.
154
+
155
+ ```jsonc
156
+ { "tool": "run_task", "arguments": { "model": "lfm3:1.7b", "fallbackModels": ["bonsai-2:9b"], "files": ["big.log"], "prompt": "summarize", "maxWaitSeconds": 20 } }
157
+ ```
158
+
114
159
  ### Resource admission
115
160
 
116
- A task queues fairly, waits for budget units on its backend and for the host signals that apply to
117
- it, then runs or is refused with `Retry-After`.
161
+ A task queues fairly, waits for budget units on its assigned pool and for applicable host signals,
162
+ then runs or is refused. Resource waiters release execution units and retain bounded queue tickets;
163
+ cancellation returns those tickets and reservations. Busy and resource refusals carry retry guidance.
118
164
 
119
165
  - **Budget.** Each Ollama decoding slot (`OLLAMA_NUM_PARALLEL`) is worth two units: a chat costs 2, a
120
166
  vision task 4 (capped to the budget), an embedding 1 per four inputs. The GPU queue holds 16 tasks,
121
167
  the CPU queue 8. A task waits at most 120 s, or `maxWaitSeconds`.
122
- - **Fairness.** Priority classes get 3, 2 and 1 turns per round, FIFO within a class. After six
123
- bypasses the oldest blocked task reserves capacity, so nothing starves. In a live run, 4
168
+ - **Fairness.** Priority classes get 3, 2 and 1 turns per round. Bounded model affinity can reorder
169
+ a class before aging restores FIFO. After six capacity bypasses the oldest blocked task reserves
170
+ released capacity, preventing indefinite bypass by smaller tasks. In a live run, 4
124
171
  interactive tasks submitted last finished before the normal and background tasks queued ahead.
125
172
  - **Fast refusals.** A full queue answers 429 at once, an expired wait 503. Both carry `Retry-After`
126
173
  from the tasks ahead, how many of that cost run at once, and recent service time.
@@ -132,32 +179,32 @@ Each host signal holds only the work it affects:
132
179
  | OS memory pressure (macOS `kern.memorystatus_vm_pressure_level`, Linux PSI) at warning | new model loads; at critical, everything |
133
180
  | Low available RAM | judged per load: a new load runs if it leaves its own reserve, else waits; a loaded model keeps serving |
134
181
  | Active swapping | new loads of 1 GiB or more, or of unknown size; a loaded model keeps serving, raw passthrough included |
135
-
136
- A load that waits for memory is told who holds it: the 503, the progress message and the route
137
- preview name the largest programs (`node: tsserver.js ×3 3.8 GB, rust-analyzer ×2 2.3 GB`).
138
- | CPU load | CPU-bound work only, never a GPU load or GPU inference |
182
+ | CPU load | CPU-assigned work; all work when no accelerator is observed |
139
183
  | Thermal throttling (macOS) | CPU-bound work and new loads |
140
184
 
185
+ An Ollama load waiting for memory can report the largest observed memory holders in its refusal,
186
+ progress and preview (for example, `node: tsserver.js ×3 3.8 GB`). Missing observations stay unknown.
187
+
141
188
  A new load must leave a reserve free: 15% of RAM, at least 1 GiB, capped at the load's own size. If
142
- it does not fit, idle models are unloaded first; if it still does not fit, it waits and is refused at
189
+ an Ollama load does not fit, eligible idle Ollama models are unloaded first; if it still does not fit, it waits and is refused at
143
190
  its deadline, on every OS. On macOS the available figure already includes reclaimable pages
144
191
  (inactive, speculative, purgeable), so loading past it means compression and swap.
145
192
  `serve --low-memory advisory` (or `FREELLAMA_LOW_MEMORY=advisory`) restores admit-with-warning.
146
193
  While any model is loaded, `serve` also samples the host itself: under low memory, OS pressure or
147
194
  swapping it unloads the cheapest idle models (audit trigger `pressure_sweep`), never pinned,
148
- `keep_alive: -1` or busy ones. Because of the reserve, a load can wait while the OS still shows free
195
+ `keep_alive: -1` or busy ones, nor one another client used in the last 15 s. Because of the reserve, a load can wait while the OS still shows free
149
196
  memory ([admission controls](CLI.md#bound-admission)). Total deadlines (`timeoutSeconds`) and
150
197
  per-backend circuit breakers complete admission; see [monitoring and tuning](MONITORING.md).
151
198
 
152
199
  ### Model memory and switching
153
200
 
154
- A loaded model answers at once, a cold one first pays its load time, and loading past what the
155
- machine holds swaps and stalls everything. FreeLlama decides what stays loaded:
201
+ On the Ollama path, compatible residency avoids a cold load but still requires admission and
202
+ applicable pressure checks. FreeLlama coordinates which Ollama runners stay loaded:
156
203
 
157
204
  ```mermaid
158
205
  flowchart TD
159
206
  Req(["Request names a model<br/>managed task or raw Ollama call"]) --> Res{"Loaded at a<br/>compatible context?"}
160
- Res -->|yes| Serve(["Serve now<br/>memory holds never apply"])
207
+ Res -->|yes| Serve(["Reuse runner<br/>admission and critical pressure still apply"])
161
208
  Res -->|no| Size["Size the load<br/>Ollama's measured footprint, else file + KV + graph"]
162
209
  Size --> Room{"Room needed?"}
163
210
  Room -->|"GPU VRAM short"| Plan
@@ -182,9 +229,9 @@ flowchart TD
182
229
  - **Audit.** `status` shows the budget in use, loads, unloads and evictions by cause, switch time per
183
230
  model, and models swapped back and forth. Every MCP result carries `timing` (wall time, plus queue,
184
231
  load, prompt and output time for a task).
185
- - **Learned per model.** Each model revision's output needs (reasoning included), load time, memory
186
- footprint and loops are measured from its runs and saved. FreeLlama sends no output cap of its own;
187
- a model that ran out of room gets twice as much next time.
232
+ - **Learned per model.** Ollama model-revision output needs, load time and memory footprint can be
233
+ retained from qualified runs. Repetition-loop counters are process-local. Ollama text tasks have
234
+ no automatic output cap unless the caller or policy sets one; llama.cpp always has an operator cap.
188
235
  - **Preload.** `preload.startup` loads listed models at startup; with `messages` (such as a long
189
236
  system prompt) it also evaluates them into the runner's prompt cache. Predictive preload counts
190
237
  model-to-model switches and, once a successor is clear, loads it in the background, only when it
@@ -192,7 +239,8 @@ flowchart TD
192
239
  `ollama_manage {action:"warm", model, systemPrompt}`.
193
240
  - **Shared state.** Measured sizes, load times, placement feedback, usage and the audit live in one
194
241
  `SQLite` file, `~/.octocode/freellama/freellama.sqlite`, shared by every FreeLlama process on the
195
- machine.
242
+ machine. Admission pools and memory reservations remain process-local; shared SQLite does not
243
+ coordinate competing servers' execution capacity.
196
244
 
197
245
  Measured switch times on an Apple M2 Pro (32 GB) through `serve`, model files in the OS file cache:
198
246
 
@@ -220,7 +268,8 @@ model, or give helpers their own backend.
220
268
  request for `lmstudio/qwen3-8b` goes to upstream `lmstudio` as `qwen3-8b`; a bare name goes to
221
269
  Ollama when Ollama has it, else to the engine that lists it. `GET /v1/models` lists all. A local
222
270
  engine waits out host holds as a loaded model would. The caller's FreeLlama token never leaves;
223
- each engine gets its own key, sent only over HTTPS or to this machine.
271
+ each engine gets its own key, sent only over HTTPS or to this machine. A local llama.cpp server
272
+ can opt into [managed text execution](LLAMACPP.md) with shared admission and memory reservations.
224
273
 
225
274
  ```toml
226
275
  # ~/.octocode/freellama/clients.toml
@@ -237,8 +286,8 @@ url = "http://127.0.0.1:1234/v1"
237
286
 
238
287
  ### CPU and GPU backends
239
288
 
240
- An optional second, CPU-only Ollama runs exact helper models, such as an embedder, so they never
241
- compete with GPU work: `serve --spawn-cpu-backend --cpu-model TAG` starts it on loopback, waits for it
289
+ An optional second, CPU-configured Ollama runs exact helper models alongside GPU work; both can
290
+ still contend for host memory, bandwidth and power: `serve --spawn-cpu-backend --cpu-model TAG` starts it on loopback, waits for it
242
291
  and stops it with `serve`, or point `--cpu-upstream` at one you run. Each backend has its own budget, queue and model-transition lock. The operator
243
292
  assigns models; agents can only state an `executionPreference`. Ask for
244
293
  `minPlacementEvidence:"observed"` when placement matters, and trust the receipt's observed placement
@@ -249,7 +298,7 @@ over the configuration. See [CPU/GPU routing](CPU_GPU_ROUTING.md).
249
298
  Some models answer correctly, then repeat the answer until their output limit (a `num_predict` cap or
250
299
  the end of their context). With the repetition stop, FreeLlama streams the answer, checks it every 16
251
300
  tokens, and stops once the text has repeated twice over at least 96 characters; closing the
252
- connection cancels generation in Ollama. It is on by default for free text with no output cap (JSON
301
+ connection requests cancellation in Ollama; local closure is not proof of physical stop. It is on by default for free text with no output cap (JSON
253
302
  and tool calls are left whole); `stopOnRepetition:false` (CLI `--stop-on-repetition false`) turns it
254
303
  off, `true` turns it on for a capped task. Nothing is trimmed: `response` holds the full text and
255
304
  `output_check` says where the first copy ends. A loop that ran to the limit without the stop is
@@ -277,7 +326,10 @@ privileges:
277
326
  | Keep related calls on one model | `session {action:"create"}`, then `run_task {sessionId}` |
278
327
  | Hot model before latency-sensitive work | `ollama_manage {action:"warm", model, contextTokens}` |
279
328
 
280
- Scopes, sessions and deferred jobs live in memory and are lost when the service restarts. See
329
+ Scopes and sessions live in memory and are lost when the service restarts. Deferred jobs are
330
+ process-local by default; with `FREELLAMA_DURABLE_JOBS=1` their finished receipts survive a restart,
331
+ an unfinished one reads back as an unknown outcome (never replayed), and `idempotencyKey` makes a
332
+ resubmission return the original job ([deferred jobs](DEFERRED_JOBS.md)). See
281
333
  [scopes and warming](SCOPES_AND_WARMING.md).
282
334
 
283
335
  ### Grounded research
@@ -291,7 +343,8 @@ computed verdict. Discard `escalate` results and verify the citations on the res
291
343
  `run_task` and `delegate_research` return a compact view unless `receipt:"full"`; every tool saves its
292
344
  whole result to a `response_file`, which `read_response` pages by section. Embedding vectors are
293
345
  omitted unless `returnEmbeddings:true`. The optional `telemetry.externalEquivalent` estimates avoided
294
- API cost from a rate card you configure. See [token economics](../packages/mcp/README.md#token-economics).
346
+ API cost from a rate card you configure with the `FREELLAMA_EXTERNAL_COST_*` variables in
347
+ [MCP configuration](../packages/mcp/CONFIGURATION.md#environment-variables).
295
348
 
296
349
  ### Observe and evaluate
297
350
 
@@ -300,4 +353,5 @@ API cost from a rate card you configure. See [token economics](../packages/mcp/R
300
353
  - **Evaluation:** `bench-all` benchmarks installed models; `policy from-eval` writes a routing policy
301
354
  from quality-evaluation results. See [model selection](MODEL_SELECTION.md).
302
355
  - **Ollama compatible:** `/api/*` and `/v1/*` reach Ollama byte-for-byte, streaming included;
303
- FreeLlama never rewrites raw bodies. See [Ollama sidecar](ARCHITECTURE.md#ollama-sidecar).
356
+ configured `/v1/*` upstream routing and `/v1/systemone` asset translation are explicit exceptions
357
+ to byte-preserving primary passthrough. See [Ollama sidecar](ARCHITECTURE.md#ollama-sidecar).
@@ -0,0 +1,133 @@
1
+ # Managed llama.cpp text tasks
2
+
3
+ FreeLlama can run bounded text tasks on one local, operator-run `llama-server`. Configure the
4
+ server in `upstreams.toml`, then explicitly select `name/model` through `freellama task` or the
5
+ managed HTTP API. The Rust core owns weighted admission, host memory reservations, total deadlines,
6
+ usage accounting and result normalization. llama.cpp owns model loading and physical execution.
7
+
8
+ Mock HTTP contracts verify admission, deadlines, refusal paths and result normalization. One live
9
+ managed completion also passed on 2026-11-14 with llama.cpp 0.8.0, build 11960, commit `8642541b2`,
10
+ using an existing 1.1 GB GGUF: preview returned HTTP 200 without inference, then the managed task
11
+ returned `hello` with 17 prompt tokens and 4 output tokens. The primary Ollama endpoint was
12
+ intentionally unreachable. Both temporary processes exited cleanly. See the
13
+ [configuration and raw receipts](assets/llamacpp-managed-smoke-2026-11-14.json).
14
+
15
+ That single smoke test establishes this basic protocol path on that build. It does not qualify
16
+ throughput, task accuracy, physical placement or the external server's cancellation behavior.
17
+
18
+ ## Configure a server
19
+
20
+ Start a single-model llama-server using a GGUF file you already have. For example, after checking
21
+ your installed llama.cpp build's help:
22
+
23
+ ```bash
24
+ llama-server --model /absolute/path/model.gguf --alias text-model \
25
+ --host 127.0.0.1 --port 8080 --ctx-size 4096 --parallel 1 --n-gpu-layers 0
26
+ ```
27
+
28
+ This example selects CPU execution. FreeLlama does not run this command or download a model.
29
+ Keep the server configuration stable while tasks are active. Use a separate endpoint for each
30
+ model; router mode and automatic model switching are outside this adapter's supported contract.
31
+
32
+ Add this to `upstreams.toml` in the FreeLlama home, or pass its path with `serve --upstreams`:
33
+
34
+ ```toml
35
+ [[upstream]]
36
+ name = "cpp"
37
+ url = "http://127.0.0.1:8080/v1"
38
+ # api_key_file = "keys/llamacpp.key"
39
+
40
+ [upstream.llamacpp]
41
+ model = "text-model"
42
+ processor = "cpu"
43
+ context_tokens = 4096
44
+ max_output_tokens = 256
45
+ memory_bytes = 4294967296
46
+ ```
47
+
48
+ Choose `memory_bytes` for your actual model and server configuration. The example's 4 GiB is an
49
+ illustration, not a sizing recommendation. It is a conservative reservation for each active
50
+ request, covering a possible model load and runtime buffers. FreeLlama takes no residency credit,
51
+ so an already loaded model can be counted twice. The operator must choose sufficient headroom;
52
+ this reservation does not prove fit or measure llama.cpp allocation. Concurrent requests each
53
+ reserve this amount. Host pressure and memory policy apply through the same governor as Ollama.
54
+ A request blocked on resources releases its execution units after the initial bounded telemetry
55
+ check. It keeps one ticket in the shared bounded queue, then reacquires execution capacity after
56
+ reserving memory. Cancellation releases the ticket and any reservation; a full queue refuses new
57
+ waiting work.
58
+
59
+ `processor` selects the existing CPU or GPU admission pool and pressure policy. It never changes
60
+ the server's placement. `observed_processor` stays null and physical placement stays unknown.
61
+ `min_placement_evidence:"observed"` refuses the request.
62
+
63
+ The URL must be loopback HTTP(S), end in `/v1`, and contain no URL credentials, query or fragment.
64
+ An optional key file follows the existing owner-only secret-file rules. FreeLlama sends only that
65
+ upstream key to llama.cpp; it never forwards the caller's FreeLlama token.
66
+
67
+ ## Preview and execute
68
+
69
+ ```bash
70
+ freellama serve --upstreams ./upstreams.toml
71
+ ```
72
+
73
+ In another terminal:
74
+
75
+ ```bash
76
+ freellama route --model cpp/text-model --task completion
77
+ freellama task --model cpp/text-model --task completion "Explain this function in one sentence."
78
+ ```
79
+
80
+ Equivalent HTTP calls to a default local server:
81
+
82
+ ```bash
83
+ curl http://127.0.0.1:11435/_freellama/v1/routes \
84
+ -H 'Content-Type: application/json' \
85
+ -d '{"model":"cpp/text-model","task":"completion"}'
86
+
87
+ curl http://127.0.0.1:11435/_freellama/v1/tasks \
88
+ -H 'Content-Type: application/json' \
89
+ -d '{"model":"cpp/text-model","task":"completion","prompt":"Say hello.","timeout_seconds":30,"request_options":{"options":{"num_predict":32}}}'
90
+ ```
91
+
92
+ Add your bearer token if the FreeLlama listener requires authentication. Preview verifies readiness
93
+ and the model listing, returns a capacity snapshot, and reserves nothing. Execution repeats the
94
+ observation, acquires the shared weighted pool and memory reservation, and sends one generation
95
+ POST. Explicit llama.cpp routes and tasks do not require Ollama to be reachable. The general model
96
+ catalog, auto-selection, benchmark qualification and overall `/ready` health remain Ollama-oriented.
97
+ Use the explicit route preview to check this engine.
98
+
99
+ The result retains `response.message.content`, `response.done_reason`, usage token counts and
100
+ `execution.engine:"llamacpp"`. `finish_reason:"length"` is retained as `done_reason:"length"`;
101
+ callers must treat it as a potentially truncated answer. Repetition is checked after completion.
102
+ Failures and uncertain POST outcomes are never automatically replayed.
103
+
104
+ Deferred jobs and text-only scopes use the core's [job](DEFERRED_JOBS.md) and
105
+ [history](SCOPES_AND_WARMING.md) contracts. They do not add engine capabilities: retained messages
106
+ must still be text-only and the fixed context restriction still applies. Built-in MCP jobs or
107
+ workflows can add Ollama-specific options such as thinking or structured-output controls, so use a
108
+ plain explicit text task unless every resulting field is supported. Automatic job selection does
109
+ not discover this engine.
110
+
111
+ ## Supported contract and limits
112
+
113
+ | Surface | Behavior |
114
+ |---|---|
115
+ | Task kinds | `completion`, `coding`, `long_context`; explicit configured model only |
116
+ | Input | Nonempty `prompt`, or text-only `messages` with system/user/assistant roles |
117
+ | Output bound | Positive `max_output_tokens` is mandatory; `num_predict` can lower it |
118
+ | Sampling | `request_options.options.temperature`, `top_p`, `seed`, `stop` |
119
+ | Context | Fixed operator context; an explicit `context_tokens` must match it; exact input token fit is not verified by FreeLlama |
120
+ | Deadlines | Shared task deadline and queue cap; cancellation closes the upstream connection and releases core permits; the external server owns physical cancellation |
121
+ | Response buffering | Discovery is capped at 64 KiB; generation uses `FREELLAMA_MAX_REQUEST_BYTES` as its response cap too |
122
+ | Tool calling, `code_repair`, images, embeddings, decision tasks | Refused before dispatch |
123
+ | Streaming, early repetition stop, format/schema, thinking/logprobs controls | Refused before dispatch; output always has a finite token cap |
124
+ | Warm/unload, model download/delete, identity pins | Unsupported on the managed adapter; server lifecycle remains operator-owned |
125
+ | Placement and confidence | Configured assignment only; observed placement and benchmark confidence requirements refuse |
126
+ | Automatic routing and learning | No auto-selection; llama.cpp results do not train Ollama preload/residency/placement facts |
127
+
128
+ An upstream without `[upstream.llamacpp]` remains OpenAI-compatible passthrough only. Raw `/v1/*`
129
+ requests still use that passthrough contract and do not inherit this adapter's managed task limits.
130
+
131
+ The wire behavior follows the [llama.cpp server reference](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md):
132
+ `/v1/health`, `/v1/models`, and nonstreaming `/v1/chat/completions`. The adapter requires a ready
133
+ server listing exactly one model with the configured ID; a reported model status must be `loaded`.