@octocodeai/freellama-mcp-server 0.1.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/README.md +426 -0
- package/adapters/agent_context.py +663 -0
- package/adapters/agent_transport.py +84 -0
- package/adapters/bash_agent.py +370 -0
- package/adapters/octocode_agent.py +394 -0
- package/dist/index.js +22971 -0
- package/docs/ADR_RESOURCE_AWARE_BACKEND_ROUTING.md +55 -0
- package/docs/ARCHITECTURE.md +416 -0
- package/docs/CLI.md +219 -0
- package/docs/CPU_GPU_ROUTING.md +352 -0
- package/docs/ECONOMICS.md +105 -0
- package/docs/INDEX.md +15 -0
- package/docs/MODEL_SELECTION.md +65 -0
- package/docs/OLLAMA_SIDECAR.md +76 -0
- package/docs/OLLAMA_SYSTEM_OPTIMIZATION.md +254 -0
- package/docs/PRODUCTION.md +195 -0
- package/docs/PRODUCT_POSITIONING.md +291 -0
- package/docs/TESTING.md +125 -0
- package/native/index.d.ts +158 -0
- package/native/index.js +45 -0
- package/native/package.json +7 -0
- package/package.json +69 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# Product positioning
|
|
2
|
+
|
|
3
|
+
FreeLlama is a **governed local-model delegation layer for developers who run AI agents on
|
|
4
|
+
Ollama**. It helps an agent decide whether local inference is appropriate and select an eligible
|
|
5
|
+
installed model. It executes within machine and policy limits and returns evidence about what happened.
|
|
6
|
+
|
|
7
|
+
The shortest accurate description is:
|
|
8
|
+
|
|
9
|
+
> Ollama runs local models. FreeLlama helps agents use them deliberately.
|
|
10
|
+
|
|
11
|
+
This positioning is intentionally narrower than “AI gateway” and more useful than “Ollama proxy.”
|
|
12
|
+
FreeLlama preserves Ollama's API, but its distinctive work is the decision and evidence layer around
|
|
13
|
+
inference: model qualification, fail-closed routing, admission, CPU/GPU placement, grounded
|
|
14
|
+
research, and execution receipts.
|
|
15
|
+
|
|
16
|
+
## Product category decision
|
|
17
|
+
|
|
18
|
+
| Question | Decision |
|
|
19
|
+
|---|---|
|
|
20
|
+
| Product category | Local-model delegation control plane |
|
|
21
|
+
| Primary audience | Developers operating coding or research agents with Ollama |
|
|
22
|
+
| Core job | Move suitable work to local models without silently lowering quality or losing control of the machine |
|
|
23
|
+
| Primary alternative | Call Ollama directly and implement routing, verification, and resource coordination in every agent |
|
|
24
|
+
| Product promise | Make local delegation explicit, bounded, observable, and measurable |
|
|
25
|
+
| Not the product | A chat UI, an Ollama fork, a hosted inference service, or a generic multi-provider gateway |
|
|
26
|
+
|
|
27
|
+
“Trustworthy local-model delegation” is the clearest value phrase. “Localhost control plane” is an
|
|
28
|
+
accurate architectural phrase, but it supports the explanation rather than leads it.
|
|
29
|
+
|
|
30
|
+
## How the product fits
|
|
31
|
+
|
|
32
|
+
```mermaid
|
|
33
|
+
flowchart LR
|
|
34
|
+
U["Developer"] --> A["AI agent or application"]
|
|
35
|
+
A -->|"MCP, CLI, Rust, or control API"| F["FreeLlama"]
|
|
36
|
+
F --> D{"Delegate?\nWhich model?\nWhich backend?"}
|
|
37
|
+
D -->|"qualified GPU task"| G["Primary Ollama\nGPU-capable runner"]
|
|
38
|
+
D -->|"explicit CPU assignment"| C["Secondary Ollama\nCPU runner"]
|
|
39
|
+
D -->|"guard fails"| X["Refuse before inference"]
|
|
40
|
+
G --> E["Answer + execution receipt"]
|
|
41
|
+
C --> E
|
|
42
|
+
X --> E
|
|
43
|
+
E --> A
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
[Ollama](https://docs.ollama.com/api/introduction) owns model execution and its API. FreeLlama
|
|
47
|
+
owns the policy around managed use of that runtime. The [Model Context Protocol
|
|
48
|
+
(MCP)](https://modelcontextprotocol.io/specification/2025-06-18/architecture) makes those controls
|
|
49
|
+
available to compatible agent hosts as seven bounded tools. Native Ollama requests can still pass
|
|
50
|
+
through unchanged to the primary upstream.
|
|
51
|
+
|
|
52
|
+
See [FreeLlama architecture](ARCHITECTURE.md) for the complete responsibility and request-flow
|
|
53
|
+
contracts.
|
|
54
|
+
|
|
55
|
+
## Audience hierarchy
|
|
56
|
+
|
|
57
|
+
### Primary: developers operating AI agents
|
|
58
|
+
|
|
59
|
+
The strongest user is a developer who already uses a capable cloud or local agent and wants to
|
|
60
|
+
delegate bounded work to Ollama. Examples include grounded repository research, embeddings, OCR,
|
|
61
|
+
bulk transforms, and helper-model tasks.
|
|
62
|
+
|
|
63
|
+
Their job is not merely “run a model.” It is:
|
|
64
|
+
|
|
65
|
+
1. Determine whether a local model is suitable for the task.
|
|
66
|
+
2. Avoid sending work to an incapable, unmeasured, or oversized model.
|
|
67
|
+
3. Keep large files, vectors, images, and intermediate tool output out of the orchestrator's
|
|
68
|
+
context.
|
|
69
|
+
4. Coordinate concurrent work without uncontrolled model loads or memory pressure.
|
|
70
|
+
5. Receive citations, verdicts, placement, queue, and timing signals that the agent can inspect.
|
|
71
|
+
|
|
72
|
+
FreeLlama fits this user because its MCP server, CLI, agent skill, and control API expose exactly
|
|
73
|
+
those decisions. The core job-to-be-done is:
|
|
74
|
+
|
|
75
|
+
> When my agent encounters expensive but bounded work, decide whether a local model can handle it,
|
|
76
|
+
> run it under explicit limits, and give the agent enough evidence to trust or reject the result.
|
|
77
|
+
|
|
78
|
+
### Secondary: Ollama power users and local-AI operators
|
|
79
|
+
|
|
80
|
+
An operator with several installed models can use FreeLlama to diagnose environment drift, inspect
|
|
81
|
+
residency, preview routes, coordinate admission, assign selected helpers to a CPU backend, and turn
|
|
82
|
+
benchmark results into routing policy.
|
|
83
|
+
|
|
84
|
+
This audience can use the CLI without an MCP host. The relevant value is machine-aware operation,
|
|
85
|
+
not agent integration alone. FreeLlama discovers the current host and observes Ollama state instead
|
|
86
|
+
of embedding assumptions from the development Mac. See [model selection](MODEL_SELECTION.md) and
|
|
87
|
+
[CPU/GPU routing](CPU_GPU_ROUTING.md).
|
|
88
|
+
|
|
89
|
+
### Secondary: developers embedding local-model policy
|
|
90
|
+
|
|
91
|
+
Library and tool authors can use the Rust core, Node native boundary, or HTTP control API instead
|
|
92
|
+
of rebuilding discovery, routing, admission, and evaluation. This is an integration audience, not
|
|
93
|
+
the clearest first-run story.
|
|
94
|
+
|
|
95
|
+
### Adjacent: Ollama developers and contributors
|
|
96
|
+
|
|
97
|
+
FreeLlama can help Ollama contributors as a downstream compatibility and workload testbed. Its
|
|
98
|
+
diagnostics expose version drift, native passthrough tests protect API compatibility, and its
|
|
99
|
+
dual-process experiments document observed runner placement.
|
|
100
|
+
|
|
101
|
+
Ollama developers are not the primary audience. FreeLlama does not replace Ollama's scheduler,
|
|
102
|
+
runner, model storage, accelerator backends, or token generation. It is a sidecar that exercises
|
|
103
|
+
and governs Ollama from the client side. Describe the relationship as complementary:
|
|
104
|
+
|
|
105
|
+
> Ollama makes local inference possible; FreeLlama makes agent delegation to it governable.
|
|
106
|
+
|
|
107
|
+
### Not a target: mainstream users
|
|
108
|
+
|
|
109
|
+
FreeLlama is not a mainstream local-AI product. It has no end-user chat interface. Meaningful use
|
|
110
|
+
assumes familiarity with Ollama and its model tags. Users also need a terminal or MCP host and an
|
|
111
|
+
understanding of policy or benchmark concepts.
|
|
112
|
+
[Open WebUI](https://github.com/open-webui/open-webui) already addresses approachable self-hosted
|
|
113
|
+
AI interfaces.
|
|
114
|
+
|
|
115
|
+
A separate desktop or web interface can sit on top of FreeLlama as a new product layer. Keep that
|
|
116
|
+
layer from blurring the current audience or forcing consumer concerns into the control plane.
|
|
117
|
+
|
|
118
|
+
## The gap FreeLlama fills
|
|
119
|
+
|
|
120
|
+
Calling Ollama directly is the correct path when the caller already knows the exact model
|
|
121
|
+
and request. FreeLlama becomes useful when the caller has to make and defend a delegation decision.
|
|
122
|
+
|
|
123
|
+
| Direct Ollama question | FreeLlama question |
|
|
124
|
+
|---|---|
|
|
125
|
+
| Which model tag receives this request? | Which installed model qualifies for this task and confidence threshold? |
|
|
126
|
+
| Did the request return HTTP 200? | Was it admitted, where did it execute, and what did it cost? |
|
|
127
|
+
| Can the model call tools? | Did bounded research read evidence and produce verifiable citations? |
|
|
128
|
+
| Can Ollama load this model? | Does it fit the discovered machine and current resident workload? |
|
|
129
|
+
| Can I set request options? | Can this managed model use the explicitly assigned CPU backend without changing raw traffic? |
|
|
130
|
+
|
|
131
|
+
This distinction also separates FreeLlama from a broad gateway such as
|
|
132
|
+
[LiteLLM](https://github.com/BerriAI/litellm). LiteLLM unifies many providers and adds centralized
|
|
133
|
+
authentication, budgets, spend tracking, and load balancing. FreeLlama is Ollama-specific,
|
|
134
|
+
machine-aware, and centered on agent delegation evidence. Its bearer boundary supports a trusted
|
|
135
|
+
operator or team; it does not attempt LiteLLM's tenant, spend, or provider-management scope.
|
|
136
|
+
|
|
137
|
+
[RouteLLM](https://github.com/lm-sys/RouteLLM) is the closer routing-specific comparison. It trains
|
|
138
|
+
and evaluates routers that select between stronger and weaker model endpoints. FreeLlama does not
|
|
139
|
+
implement a learned prompt router. It applies deterministic local eligibility and operator policy,
|
|
140
|
+
then adds host fit, admission, physical CPU/GPU placement evidence, and grounded-research receipts.
|
|
141
|
+
|
|
142
|
+
## The product loop
|
|
143
|
+
|
|
144
|
+
The flexible part of FreeLlama is not an unconstrained agent choosing hardware. It is a guarded
|
|
145
|
+
feedback loop with explicit operator and policy boundaries.
|
|
146
|
+
|
|
147
|
+
```mermaid
|
|
148
|
+
flowchart TD
|
|
149
|
+
T["Agent describes task, objective, and constraints"] --> P["Preview route"]
|
|
150
|
+
P --> Q{"Capability, policy, confidence,\nand capacity qualify?"}
|
|
151
|
+
Q -->|"no"| R["Refuse with reasons"]
|
|
152
|
+
Q -->|"yes"| A["Admit on selected backend"]
|
|
153
|
+
A --> O["Ollama executes"]
|
|
154
|
+
O --> V["Return result, placement, queue,\nand timing evidence"]
|
|
155
|
+
V --> F["Record normalized warm feedback"]
|
|
156
|
+
F -.->|"auto; fastest or balanced only\nafter enough samples"| P
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
An agent can request `auto`, `prefer_cpu`, or `prefer_gpu`, but the request remains a preference.
|
|
160
|
+
Explicit model choice, session affinity, capability requirements, policy, confidence, and operator
|
|
161
|
+
CPU assignments remain authoritative. Runtime feedback only influences eligible `auto` routes for
|
|
162
|
+
speed-oriented objectives after comparable warm samples exist; it never overrides a quality
|
|
163
|
+
objective. This design lets the system adapt to another machine without turning resource placement
|
|
164
|
+
into an opaque autonomous decision.
|
|
165
|
+
|
|
166
|
+
## Message hierarchy
|
|
167
|
+
|
|
168
|
+
Use one message at each level:
|
|
169
|
+
|
|
170
|
+
| Context | Message |
|
|
171
|
+
|---|---|
|
|
172
|
+
| Category | Local-model delegation control plane |
|
|
173
|
+
| One line | FreeLlama helps AI agents use Ollama deliberately, with routing, resource limits, and evidence. |
|
|
174
|
+
| Problem | Local inference is direct to call but hard to delegate to safely across different models and machines. |
|
|
175
|
+
| Promise | Move suitable work local without silently lowering quality or destabilizing the runtime. |
|
|
176
|
+
| Mechanism | Qualify, preview, admit, execute, and return a receipt. |
|
|
177
|
+
| Boundary | Ollama runtime underneath; FreeLlama policy around it. |
|
|
178
|
+
|
|
179
|
+
Good headline directions are outcome-first:
|
|
180
|
+
|
|
181
|
+
- **Use local models without lowering your standards.**
|
|
182
|
+
- **Give your AI agent a governed path to Ollama.**
|
|
183
|
+
- **Delegate locally. Keep the evidence.**
|
|
184
|
+
|
|
185
|
+
Avoid “AI orchestration platform.” It is broad enough to hide the product. Avoid leading with
|
|
186
|
+
“proxy,” because raw passthrough is a compatibility feature rather than the principal value.
|
|
187
|
+
|
|
188
|
+
## Build credible attention
|
|
189
|
+
|
|
190
|
+
Create interest through short, reproducible contrasts rather than market-size or
|
|
191
|
+
speed claims.
|
|
192
|
+
|
|
193
|
+
### Demonstration 1: refuse before wasting work
|
|
194
|
+
|
|
195
|
+
Show an agent previewing a task, rejecting an unqualified model, and returning the reason without
|
|
196
|
+
an inference call. The story is not “the router is smart”; it is “a weak local model cannot quietly
|
|
197
|
+
produce a confident answer.”
|
|
198
|
+
|
|
199
|
+
### Demonstration 2: preserve frontier context
|
|
200
|
+
|
|
201
|
+
Give `delegate_research` a narrow repository question. Show the local adapter reading allowlisted
|
|
202
|
+
files and returning an answer, citations, and a verification verdict instead of returning all source
|
|
203
|
+
material and intermediate tool output to the orchestrator.
|
|
204
|
+
|
|
205
|
+
One measured six-question run reduced 59,208 source tokens to 1,742 returned tokens, or 97.1%
|
|
206
|
+
context offload. That is a single measured workload, not a universal savings rate. The durable
|
|
207
|
+
claim is context isolation; see [token economics](ECONOMICS.md).
|
|
208
|
+
|
|
209
|
+
### Demonstration 3: use the machine as a system
|
|
210
|
+
|
|
211
|
+
Run a large GPU completion and a small CPU helper concurrently, then show both placement receipts.
|
|
212
|
+
On the measured 48 GB Apple M4 Pro, three warmed trials reduced median wall time from 37.997 to
|
|
213
|
+
28.233 seconds, a 1.346-times speedup. One of the three parallel trials was slower than sequential,
|
|
214
|
+
so the claim is “these workloads can overlap,” not “CPU/GPU mode is always faster.” See the full
|
|
215
|
+
[CPU/GPU measurement](CPU_GPU_ROUTING.md#interpret-the-measured-mac-result).
|
|
216
|
+
|
|
217
|
+
These demonstrations map directly to three memorable benefits: **trust, context, and resources**.
|
|
218
|
+
Turn them into a short terminal recording, copyable README recipes, and versioned benchmark
|
|
219
|
+
receipts. Each demo needs the command, machine profile, model tags, policy, result, and
|
|
220
|
+
failure conditions.
|
|
221
|
+
|
|
222
|
+
## Adoption path
|
|
223
|
+
|
|
224
|
+
The first-use sequence needs to reveal value before asking for sophisticated configuration:
|
|
225
|
+
|
|
226
|
+
```mermaid
|
|
227
|
+
flowchart LR
|
|
228
|
+
I["Install beside Ollama"] --> D["doctor\nsee machine and drift"]
|
|
229
|
+
D --> P["preview\nsee a route and reasons"]
|
|
230
|
+
P --> T["run one managed task\nsee the receipt"]
|
|
231
|
+
T --> G["delegate research\nsee citations and verdict"]
|
|
232
|
+
G --> B["benchmark\nmeasure local models"]
|
|
233
|
+
B --> Y["policy\nallow proven routes"]
|
|
234
|
+
Y --> R["resource tuning\nCPU/GPU and admission"]
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
The product must not require a new user to understand every tool, KV-cache setting, or routing
|
|
238
|
+
objective before the first managed task. Advanced controls become relevant after the first receipt
|
|
239
|
+
makes the control loop visible.
|
|
240
|
+
|
|
241
|
+
## Claim and naming guardrails
|
|
242
|
+
|
|
243
|
+
| Do not say | Say instead |
|
|
244
|
+
|---|---|
|
|
245
|
+
| Free local inference | Local inference uses hardware, power, memory, and time; FreeLlama can preserve paid frontier context. |
|
|
246
|
+
| Automatically picks the optimal model | Routes among eligible installed models using explicit policy and available evidence. |
|
|
247
|
+
| Makes Ollama faster | Can improve workload efficiency; it does not increase one model's decode speed. |
|
|
248
|
+
| Runs CPU and GPU in parallel on every machine | Can overlap explicitly assigned workloads when the host and Ollama backends support them; measure the result. |
|
|
249
|
+
| Works the same on any hardware | Uses platform-specific host discovery on macOS, Linux, and Windows. Portable defaults do not remove the need to observe accelerator behavior. |
|
|
250
|
+
| Replaces Ollama | Runs beside Ollama and preserves its native API. |
|
|
251
|
+
| For everyone | Built first for developers and local-AI operators. |
|
|
252
|
+
| Llama models only | Works with qualifying models exposed by Ollama; “Llama” is the product name, not a model-family restriction. |
|
|
253
|
+
|
|
254
|
+
Use the word “Free” to refer to reducing reliance on metered frontier inference, not zero-cost
|
|
255
|
+
computing. Readers can misread “Llama” as Meta Llama-only, so put the Ollama relationship and model
|
|
256
|
+
agnosticism within Ollama near the first description.
|
|
257
|
+
|
|
258
|
+
## Product decision
|
|
259
|
+
|
|
260
|
+
Narrow the story before broadening the product:
|
|
261
|
+
|
|
262
|
+
1. Lead with developers operating AI agents, not all developers.
|
|
263
|
+
2. Make trustworthy delegation the category-defining job.
|
|
264
|
+
3. Use MCP as the primary agent integration and the CLI as the operator surface.
|
|
265
|
+
4. Treat Ollama power users and embedders as secondary audiences.
|
|
266
|
+
5. Treat Ollama contributors as an adjacent ecosystem audience, not the main customer.
|
|
267
|
+
6. Do not pursue a mainstream chat interface until the developer onboarding loop is clear and
|
|
268
|
+
repeatable.
|
|
269
|
+
|
|
270
|
+
This decision matches the code that exists today. The Rust core, CLI, MCP server, proxy, agent
|
|
271
|
+
skill, benchmark harnesses, and policy system all support a developer control plane. Positioning it
|
|
272
|
+
as a consumer app promises a product surface the repository does not provide.
|
|
273
|
+
|
|
274
|
+
## Related documentation
|
|
275
|
+
|
|
276
|
+
- [Architecture](ARCHITECTURE.md): ownership boundaries and request flows
|
|
277
|
+
- [MCP server](../packages/mcp/README.md): six agent-facing tools and their contracts
|
|
278
|
+
- [CLI](CLI.md): operator commands and control-plane workflows
|
|
279
|
+
- [Model selection](MODEL_SELECTION.md): evidence, qualification, and recommendation
|
|
280
|
+
- [CPU/GPU routing](CPU_GPU_ROUTING.md): portable configuration, feedback, and measured limits
|
|
281
|
+
- [Testing](TESTING.md): verification tiers and live-runtime boundaries
|
|
282
|
+
- [Token economics](ECONOMICS.md): measured context isolation and its limits
|
|
283
|
+
|
|
284
|
+
## Sources
|
|
285
|
+
|
|
286
|
+
- [Ollama API introduction](https://docs.ollama.com/api/introduction)
|
|
287
|
+
- [Ollama tool calling](https://docs.ollama.com/capabilities/tool-calling)
|
|
288
|
+
- [Model Context Protocol architecture](https://modelcontextprotocol.io/specification/2025-06-18/architecture)
|
|
289
|
+
- [Open WebUI](https://github.com/open-webui/open-webui)
|
|
290
|
+
- [LiteLLM](https://github.com/BerriAI/litellm)
|
|
291
|
+
- [RouteLLM](https://github.com/lm-sys/RouteLLM)
|
package/docs/TESTING.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Test FreeLlama
|
|
2
|
+
|
|
3
|
+
FreeLlama separates fast deterministic checks from live-system tests. Run the narrowest relevant
|
|
4
|
+
tier during development, then run the full matrix before release.
|
|
5
|
+
|
|
6
|
+
```mermaid
|
|
7
|
+
flowchart LR
|
|
8
|
+
U["Unit and Rust contracts"] --> A["Local-agent context<br/>and action contracts"]
|
|
9
|
+
A --> T["Type check, format, and Clippy"]
|
|
10
|
+
T --> I["MCP integration against live Ollama"]
|
|
11
|
+
I --> E["End-to-end tools against serve and Ollama"]
|
|
12
|
+
E --> L["Optional live CPU/GPU workload evaluation"]
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Install and build
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
yarn install
|
|
19
|
+
yarn build
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The root build compiles the host Rust release binary, NAPI addon, and single-file MCP JavaScript
|
|
23
|
+
bundle. The native `.node` addon remains external to the JavaScript bundle because it is selected
|
|
24
|
+
by platform triple at runtime. Published packages resolve it from an OS/CPU/libc-specific optional
|
|
25
|
+
dependency rather than compiling Rust during installation.
|
|
26
|
+
|
|
27
|
+
## Run the test tiers
|
|
28
|
+
|
|
29
|
+
| Tier | Command | External requirements |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| JavaScript unit | `yarn test` | None |
|
|
32
|
+
| JavaScript watch | `yarn test:watch` | None |
|
|
33
|
+
| Rust contracts | `yarn test:rust` | Rust toolchain |
|
|
34
|
+
| Local-agent contracts | `yarn test:agents` | Python 3 standard library |
|
|
35
|
+
| TypeScript | `yarn typecheck` | None after install |
|
|
36
|
+
| MCP integration | `yarn test:integration` | Ollama on `127.0.0.1:11434` |
|
|
37
|
+
| MCP end to end | `yarn test:e2e` | Ollama, `freellama serve`, and required models |
|
|
38
|
+
| All configured tiers | `yarn test:all` | Requirements of every included tier |
|
|
39
|
+
| Production verification | `yarn verify:production` | Build, formatting, strict Clippy, all test tiers, and package verification |
|
|
40
|
+
|
|
41
|
+
The end-to-end suite checks behavior rather than schema shape: confidence refusal happens before
|
|
42
|
+
generation, embedding vectors are withheld by default, impossible models are excluded by memory,
|
|
43
|
+
and models with unusable research evidence are refused without tool calls. Tests that require a
|
|
44
|
+
specific unavailable model report a skip reason.
|
|
45
|
+
|
|
46
|
+
## Run static Rust checks
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cargo fmt --all --check
|
|
50
|
+
cargo clippy --all-targets -- -D warnings
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Routing regressions run in the default Rust suite; none are hidden behind `#[ignore]`. Add a
|
|
54
|
+
focused contract test for each repaired behavior and keep it enabled in ordinary release checks.
|
|
55
|
+
The local-agent tier runs all context fitting, compaction, pagination, repeat-suppression, and
|
|
56
|
+
strict action-shape contracts. It is included in `yarn test:all`, so adapter regressions cannot be
|
|
57
|
+
missed by the root release matrix.
|
|
58
|
+
|
|
59
|
+
`yarn test:all` does not run formatting, Clippy, a release build, or package inspection. Use
|
|
60
|
+
`yarn verify:production` for the complete local promotion gate.
|
|
61
|
+
|
|
62
|
+
Before claiming platform support, run the deterministic Rust and JavaScript/native lanes from a
|
|
63
|
+
clean checkout on macOS, Linux, and Windows. The machine profile contract test requires a positive
|
|
64
|
+
CPU count, host-memory value, and free-disk value on each machine; it reports unified memory only
|
|
65
|
+
on Apple-silicon macOS. This catches an OS branch that compiles but returns no usable capacity to
|
|
66
|
+
recommendations. Record the commands, toolchain versions, commit, and results with the release.
|
|
67
|
+
|
|
68
|
+
`platform_contract` also pins the resource-control loop: a CPU preference is honored only for an
|
|
69
|
+
operator-assigned eligible model, an explicit model overrides that hint and reports the fallback,
|
|
70
|
+
two warm samples do not steer `auto`, the third sample on both backends enables a token-normalized
|
|
71
|
+
comparison, differences of 10% or less remain noise, and one GPU plus one CPU request overlap even
|
|
72
|
+
when both admission pools contain one unit.
|
|
73
|
+
|
|
74
|
+
## Validate CPU and GPU concurrency
|
|
75
|
+
|
|
76
|
+
Start the two Ollama processes and FreeLlama as described in
|
|
77
|
+
[CPU and GPU model routing](CPU_GPU_ROUTING.md). Verify placement with both backend `/api/ps`
|
|
78
|
+
responses, then compare matched sequential and concurrent requests. Record at least three warmed
|
|
79
|
+
trials and use the median so one cold load does not decide the result.
|
|
80
|
+
|
|
81
|
+
The local validated workload used a CPU-assigned `nomic-embed-text:latest` request and a resident
|
|
82
|
+
GPU `qwen3.8:27b-mlx` completion. It measured a 1.346-times median speedup with successful responses,
|
|
83
|
+
zero FreeLlama queue wait, `size_vram: 0` for the CPU runner, and positive `size_vram` for the GPU
|
|
84
|
+
runner.
|
|
85
|
+
|
|
86
|
+
The placement guard recorded 19,175,677,668 GPU-resident bytes for Qwen, identical GPU output
|
|
87
|
+
length across all trials, correct upstream receipts, and primary Ollama 0.33.2 through raw
|
|
88
|
+
passthrough. A separate small-helper trial returned the CPU embedding in 60 ms while the cold GPU
|
|
89
|
+
completion continued to 7.391 seconds.
|
|
90
|
+
|
|
91
|
+
After rebuilding the release, a fresh concurrent smoke check completed both managed requests in
|
|
92
|
+
8.303 seconds. It returned HTTP 200, zero queue wait, the expected upstream receipts, `OK` from
|
|
93
|
+
Qwen, one embedding from Nomic, positive Qwen VRAM, zero Nomic VRAM, and primary Ollama 0.33.2
|
|
94
|
+
through raw passthrough.
|
|
95
|
+
|
|
96
|
+
For promotion, use the portable [hardware acceptance runner](../benchmark/hardware/README.md) and
|
|
97
|
+
archive its JSON receipt with the release evidence. Compilation alone does not validate a driver,
|
|
98
|
+
physical placement, shared-memory contention, or OCR quality.
|
|
99
|
+
|
|
100
|
+
## Verify release packages
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Collect each target's `freellama` executable and `freellama.<target>.node`
|
|
104
|
+
# under release-artifacts/<target>/, then stage all eight platform packages.
|
|
105
|
+
yarn release:assemble release-artifacts release
|
|
106
|
+
yarn release:verify:publish
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Build every claimed CLI/native target in a clean environment, assemble `SHA256SUMS`, run the full
|
|
110
|
+
deterministic suite, and inspect every platform package dry run before publishing explicitly.
|
|
111
|
+
Publish the eight `@octocodeai/freellama-native-*` packages before `@octocodeai/freellama` and `@octocodeai/freellama-mcp-server`, all
|
|
112
|
+
at the exact same version. A successful local pack dry run proves package contents; it does not
|
|
113
|
+
prove registry publication or another hardware class.
|
|
114
|
+
|
|
115
|
+
## Test one layer while iterating
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
yarn build:native
|
|
119
|
+
yarn workspace @octocodeai/freellama-mcp-server build
|
|
120
|
+
yarn workspace @octocodeai/freellama-mcp-server test
|
|
121
|
+
yarn workspace @octocodeai/freellama test
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The MCP integration and end-to-end setup rebuilds its bundle. The CLI package tests its launcher and
|
|
125
|
+
published-file contract; Rust tests own the executable's command and routing behavior.
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// Hand-written type declarations for the native module (see index.js for why these are
|
|
2
|
+
// hand-written rather than tool-generated). Mirrors packages/rust-core/src/napi.rs's public function signatures
|
|
3
|
+
// exactly — keep the two in sync if you change one. `npm run build` no longer overwrites this
|
|
4
|
+
// file (it previously did, silently emptying it — see package.json's build script comment).
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Runs `freellama doctor` against Ollama directly — no running `freellama serve` required.
|
|
8
|
+
* Cross-checks the Ollama CLI and server versions and confirms the endpoint is reachable.
|
|
9
|
+
* @param endpoint Ollama endpoint, defaults to http://127.0.0.1:11434
|
|
10
|
+
* @returns Pretty-printed JSON string
|
|
11
|
+
*/
|
|
12
|
+
export function doctor(endpoint?: string | undefined | null): Promise<string>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Machine profile (chip, host memory, memory kind, CPU count, and disk) from `freellama serve`.
|
|
16
|
+
* @param endpoint FreeLlama serve endpoint, defaults to http://127.0.0.1:11435
|
|
17
|
+
*/
|
|
18
|
+
export function machine(endpoint?: string | undefined | null): Promise<string>;
|
|
19
|
+
|
|
20
|
+
/** Current managed-platform health, including admission and session bounds. */
|
|
21
|
+
export function health(endpoint?: string | undefined | null): Promise<string>;
|
|
22
|
+
|
|
23
|
+
/** Create a bounded, idle-expiring model-affinity handle; it stores no prompt history or KV. */
|
|
24
|
+
export function createSession(endpoint?: string | undefined | null): Promise<string>;
|
|
25
|
+
|
|
26
|
+
/** Release a model-affinity handle after related work has completed. */
|
|
27
|
+
export function deleteSession(
|
|
28
|
+
endpoint: string | undefined | null,
|
|
29
|
+
sessionId: string,
|
|
30
|
+
): Promise<void>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Installed-model inventory with capabilities, residency, and advertised context.
|
|
34
|
+
* @param endpoint FreeLlama serve endpoint, defaults to http://127.0.0.1:11435
|
|
35
|
+
*/
|
|
36
|
+
export function listModels(endpoint?: string | undefined | null): Promise<string>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Deterministic model selection for a task.
|
|
40
|
+
* @param endpoint FreeLlama serve endpoint, defaults to http://127.0.0.1:11435
|
|
41
|
+
* @param task e.g. "completion" | "code_repair" | "vision" | "embedding"
|
|
42
|
+
* @param objective "fastest" | "balanced" | "quality", defaults to "balanced"
|
|
43
|
+
* @param model Optional explicit model name to force
|
|
44
|
+
* @param sessionId Optional session id for model affinity
|
|
45
|
+
* @param contextTokens Optional minimum context window required
|
|
46
|
+
* @param requiredCapabilities Optional list of capabilities the model must advertise (e.g. ["vision"])
|
|
47
|
+
* @param minConfidence Optional floor ("low" | "medium"); the core gate refuses below it
|
|
48
|
+
* @param executionPreference Guarded backend hint: "auto" | "prefer_cpu" | "prefer_gpu"
|
|
49
|
+
* @param minPlacementEvidence "configured" (default) or fail-closed physical "observed"
|
|
50
|
+
* @param minPlacementEvidence "configured" (default) or fail-closed physical "observed"
|
|
51
|
+
*/
|
|
52
|
+
export function route(
|
|
53
|
+
endpoint: string | undefined | null,
|
|
54
|
+
task: string,
|
|
55
|
+
objective?: string | undefined | null,
|
|
56
|
+
model?: string | undefined | null,
|
|
57
|
+
sessionId?: string | undefined | null,
|
|
58
|
+
contextTokens?: number | undefined | null,
|
|
59
|
+
requiredCapabilities?: Array<string> | undefined | null,
|
|
60
|
+
minConfidence?: string | undefined | null,
|
|
61
|
+
executionPreference?: string | undefined | null,
|
|
62
|
+
minPlacementEvidence?: string | undefined | null,
|
|
63
|
+
): Promise<string>;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Side-effect-free install recommendation for a task. Never runs `ollama pull` itself.
|
|
67
|
+
* @param endpoint FreeLlama serve endpoint, defaults to http://127.0.0.1:11435
|
|
68
|
+
* @param task e.g. "completion" | "code_repair" | "vision" | "embedding"
|
|
69
|
+
* @param objective "fastest" | "balanced" | "quality", defaults to "balanced"
|
|
70
|
+
* @param model Optional explicit model name to filter to
|
|
71
|
+
* @param contextTokens Optional minimum context window required
|
|
72
|
+
* @param requiredCapabilities Optional list of capabilities the model must advertise (e.g. ["vision"])
|
|
73
|
+
* @param executionPreference Guarded backend hint: "auto" | "prefer_cpu" | "prefer_gpu"
|
|
74
|
+
* @param minPlacementEvidence "configured" (default) or fail-closed physical "observed"
|
|
75
|
+
*/
|
|
76
|
+
export function recommend(
|
|
77
|
+
endpoint: string | undefined | null,
|
|
78
|
+
task: string,
|
|
79
|
+
objective?: string | undefined | null,
|
|
80
|
+
model?: string | undefined | null,
|
|
81
|
+
contextTokens?: number | undefined | null,
|
|
82
|
+
requiredCapabilities?: Array<string> | undefined | null,
|
|
83
|
+
executionPreference?: string | undefined | null,
|
|
84
|
+
minPlacementEvidence?: string | undefined | null,
|
|
85
|
+
): Promise<string>;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Routes AND executes a chat/generate/embed call in one shot — unlike `route`/`recommend`, this
|
|
89
|
+
* actually does work. Provide `prompt` for a single message, or `messages` (an array of
|
|
90
|
+
* `{role, content}` objects) for multi-turn history. For task "embedding", set `input` instead.
|
|
91
|
+
* @param endpoint FreeLlama serve endpoint, defaults to http://127.0.0.1:11435
|
|
92
|
+
* @param task e.g. "completion" | "code_repair" | "vision" | "embedding"
|
|
93
|
+
* @param objective "fastest" | "balanced" | "quality", defaults to "balanced"
|
|
94
|
+
* @param model Optional explicit model name to force
|
|
95
|
+
* @param sessionId Optional session id for model affinity
|
|
96
|
+
* @param contextTokens Optional minimum context window required
|
|
97
|
+
* @param requiredCapabilities Optional list of capabilities the model must advertise
|
|
98
|
+
* @param prompt Single-turn user message
|
|
99
|
+
* @param images Base64-encoded images (no data-URI prefix) attached to the `prompt` message — pair with requiredCapabilities: ["vision"]
|
|
100
|
+
* @param messages Multi-turn message history, wins over `prompt` if both are set
|
|
101
|
+
* @param input Embedding input (string or array of strings), for task "embedding"
|
|
102
|
+
* @param tools Optional tool/function definitions for function-calling tasks
|
|
103
|
+
* @param keepAlive Overrides Ollama's model residency window, e.g. "0" or "-1"
|
|
104
|
+
* @param minConfidence Optional floor ("low" | "medium"); the core gate refuses before generation
|
|
105
|
+
* @param executionPreference Guarded backend hint: "auto" | "prefer_cpu" | "prefer_gpu"
|
|
106
|
+
*/
|
|
107
|
+
export function runTask(
|
|
108
|
+
endpoint: string | undefined | null,
|
|
109
|
+
task: string,
|
|
110
|
+
objective?: string | undefined | null,
|
|
111
|
+
model?: string | undefined | null,
|
|
112
|
+
sessionId?: string | undefined | null,
|
|
113
|
+
contextTokens?: number | undefined | null,
|
|
114
|
+
requiredCapabilities?: Array<string> | undefined | null,
|
|
115
|
+
prompt?: string | undefined | null,
|
|
116
|
+
images?: Array<string> | undefined | null,
|
|
117
|
+
messages?: unknown | undefined | null,
|
|
118
|
+
input?: unknown | undefined | null,
|
|
119
|
+
tools?: unknown | undefined | null,
|
|
120
|
+
keepAlive?: string | undefined | null,
|
|
121
|
+
minConfidence?: string | undefined | null,
|
|
122
|
+
executionPreference?: string | undefined | null,
|
|
123
|
+
minPlacementEvidence?: string | undefined | null,
|
|
124
|
+
): Promise<string>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Object-based managed task API. Supports the full typed task request including lossless message
|
|
128
|
+
* history and request_options (format, think, runtime options, logprobs).
|
|
129
|
+
* @param endpoint FreeLlama serve endpoint, defaults to http://127.0.0.1:11435
|
|
130
|
+
* @param request Complete `/_freellama/v1/tasks` request object
|
|
131
|
+
*/
|
|
132
|
+
export function runTaskRequest(
|
|
133
|
+
endpoint: string | undefined | null,
|
|
134
|
+
request: unknown,
|
|
135
|
+
): Promise<string>;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Executes explicitly independent tasks with a bounded, priority-fair dispatcher. Individual
|
|
139
|
+
* task failures are returned as result entries so unaffected sibling work is preserved.
|
|
140
|
+
* @param endpoint FreeLlama serve endpoint, defaults to http://127.0.0.1:11435
|
|
141
|
+
* @param request Complete `/_freellama/v1/task-batches` request object
|
|
142
|
+
*/
|
|
143
|
+
export function runTaskBatchRequest(
|
|
144
|
+
endpoint: string | undefined | null,
|
|
145
|
+
request: unknown,
|
|
146
|
+
): Promise<string>;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Converts a free-text natural-language intent into a route.
|
|
150
|
+
* @param endpoint FreeLlama serve endpoint, defaults to http://127.0.0.1:11435
|
|
151
|
+
* @param text Free-text description of what's needed
|
|
152
|
+
* @param sessionId Optional session id for model affinity
|
|
153
|
+
*/
|
|
154
|
+
export function naturalRoute(
|
|
155
|
+
endpoint: string | undefined | null,
|
|
156
|
+
text: string,
|
|
157
|
+
sessionId?: string | undefined | null,
|
|
158
|
+
): Promise<string>;
|
package/native/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// Hand-written glue: napi-rs CLI did not emit JS bindings for this crate/cli pair, so this
|
|
2
|
+
// file re-exports the compiled `.node`. Rebuild with `npm run build` from the repo root.
|
|
3
|
+
// See packages/mcp/README.md.
|
|
4
|
+
const { existsSync } = require("node:fs");
|
|
5
|
+
const path = require("node:path");
|
|
6
|
+
const { createRequire } = require("node:module");
|
|
7
|
+
const requireFromHere = createRequire(__filename);
|
|
8
|
+
|
|
9
|
+
// napi-rs filenames: `freellama.<platform>-<arch>[-<abi>].node`. ABI suffix is present on
|
|
10
|
+
// Linux/Windows, absent on macOS. On Linux try both gnu and musl — Node's glibc probe does not
|
|
11
|
+
// have to match how the addon was compiled.
|
|
12
|
+
const ABI_SUFFIXES = {
|
|
13
|
+
linux: process.report?.getReport()?.header?.glibcVersionRuntime ? ["-gnu", "-musl"] : ["-musl", "-gnu"],
|
|
14
|
+
win32: ["-msvc"],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
function candidateIds() {
|
|
18
|
+
const { platform, arch } = process;
|
|
19
|
+
const suffixes = ABI_SUFFIXES[platform] ?? [];
|
|
20
|
+
return [...new Set(suffixes.concat("").map((suffix) => `${platform}-${arch}${suffix}`))];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const candidates = candidateIds();
|
|
24
|
+
const found = candidates.find((id) => existsSync(path.join(__dirname, `freellama.${id}.node`)));
|
|
25
|
+
|
|
26
|
+
if (!found) {
|
|
27
|
+
const failures = [];
|
|
28
|
+
for (const id of candidates) {
|
|
29
|
+
const packageName = `@octocodeai/freellama-native-${id}`;
|
|
30
|
+
try {
|
|
31
|
+
module.exports = requireFromHere(packageName);
|
|
32
|
+
return;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
failures.push(`${packageName}: ${error?.message ?? error}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
throw new Error(
|
|
38
|
+
`freellama: no usable native addon for ${process.platform}-${process.arch}.\n` +
|
|
39
|
+
`Tried local development artifacts and optional packages: ${candidates.map((id) => `@octocodeai/freellama-native-${id}`).join(", ")}.\n` +
|
|
40
|
+
"Reinstall without --omit=optional. From a source checkout, run `yarn build:native`.\n" +
|
|
41
|
+
`Load failures:\n ${failures.join("\n ")}`,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = require(`./freellama.${found}.node`);
|