pi-llamacpp-infra 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Javier Noguerol
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,255 @@
1
+ # llamacpp-infra — Discovery, Metrics & Control for llama.cpp Servers
2
+
3
+ **llamacpp-infra** turns pi into a first-class citizen of local llama.cpp infrastructure. It probes any number of machines — localhost, LAN or Tailscale — discovers every model served by llama.cpp and its variants, registers them into pi's native `/model` list, and gives you live Prometheus metrics, per-model thinking budgets, vision detection and a full configuration UI — all without leaving the pi prompt.
4
+
5
+ ---
6
+
7
+ ## Supported Servers
8
+
9
+ Every endpoint llamacpp-infra talks to runs llama.cpp or a direct variant:
10
+
11
+ | Server | Detection | Notes |
12
+ |--------|-----------|-------|
13
+ | **llama.cpp** | `GET /v1/models` with `meta.n_ctx` | Single-model and router/multi-model modes |
14
+ | **ZINC** | `owned_by: "zinc"` | Payload workaround: empty model field + tool normalization |
15
+ | **DwarfStar / ds4** | Opt-in ping to `/v1/chat/completions` | antirez's ds4-server for DeepSeek V4 (per-server `probeDs4` flag) |
16
+ | **lucebox** | `GET /props` with `server.name: "luce-*"` | DeepSeek dflash server with rich metadata |
17
+
18
+ Anything else (LM Studio, vLLM, Ollama, cloud APIs…) is out of scope — use pi's built-in providers for those.
19
+
20
+ ## Features
21
+
22
+ - **Multi-machine discovery** — configurable list of servers (host, ports, API key, options); probes all of them at startup and on demand
23
+ - **Single-model & router modes** — llama.cpp single-model mode (one GGUF per instance) and router mode (multiple models per server, with per-model status and args)
24
+ - **Per-model metadata badges** — 👁️ vision (mmproj / modalities), 🚀 drafter (speculative decoding), 🗜️ quant tag from GGUF filename, 🧠 KV cache quantization (from server args or `/proc`)
25
+ - **Live Prometheus metrics** — polls `/metrics` (or `/stats`) and renders a compact widget with instantaneous prompt/gen throughput; auto-activates for llamacpp-infra models only
26
+ - **Thinking budgets** — llama.cpp accepts `thinking_budget_tokens` per request; configure budgets per thinking level (minimal/low/medium/high/xhigh/max) per model; models with budgets are registered with reasoning enabled
27
+ - **Header warmup** — pre-caches the system prompt KV on llama.cpp-family servers so the first real request is faster
28
+ - **ZINC workaround** — ZINC rejects non-empty model IDs; the payload hook rewrites the request and normalizes tool definitions automatically
29
+ - **Vision detection** — scans `/proc` for local llama-server processes launched with `--mmproj` and marks those models as image-capable; also reads server-reported `modalities` / `input_modalities`
30
+ - **Native configuration UI** — everything configurable through `/llamacpp-infra config` with pi's native menus; no config file editing required
31
+ - **Legacy migration** — auto-migrates an existing `~/.pi/agent/local-models.json` on first run
32
+
33
+ ## Install
34
+
35
+ llamacpp-infra is a [pi package](https://pi.dev/packages): one extension (`src/index.ts`) plus an inlined warmup module, declared in `package.json`.
36
+
37
+ ```bash
38
+ # From GitHub
39
+ pi install git:github.com/noguerol/llamacpp-infra
40
+
41
+ # Pin a tag/commit
42
+ pi install git:github.com/noguerol/llamacpp-infra@v1.0.0
43
+
44
+ # From npm
45
+ pi install npm:pi-llamacpp-infra
46
+
47
+ # Local checkout (development)
48
+ pi install /path/to/llamacpp-infra
49
+
50
+ # Try it for one run only
51
+ pi -e git:github.com/noguerol/llamacpp-infra
52
+ ```
53
+
54
+ ```bash
55
+ pi list # show installed packages
56
+ pi remove npm:pi-llamacpp-infra
57
+ ```
58
+
59
+ > **Security:** pi packages run with full system access. Install only packages you trust and review the source.
60
+
61
+ **Requirements:** a working pi installation and at least one llama.cpp-family server running somewhere accessible (localhost, LAN or Tailscale).
62
+
63
+ ## Quick Start
64
+
65
+ ```
66
+ /llamacpp-infra config # open the config menu → add your first server
67
+ /llamacpp-infra scan # discover models now
68
+ /llamacpp-infra list # see what was found
69
+ ```
70
+
71
+ That's it. On the next pi startup, llamacpp-infra probes your servers automatically and registers every model into `/model`. Switch models with `/model` as usual.
72
+
73
+ ## Commands
74
+
75
+ | Command | Description |
76
+ |---------|-------------|
77
+ | `/llamacpp-infra` | Quick status (servers, discovered models, metrics) |
78
+ | `/llamacpp-infra config` | ⚙️ Interactive configuration menu |
79
+ | `/llamacpp-infra scan` | Rescan all servers now |
80
+ | `/llamacpp-infra status` | Detailed per-endpoint report |
81
+ | `/llamacpp-infra list` | List discovered models with metadata badges |
82
+ | `/llamacpp-infra metrics` | Toggle the live metrics widget |
83
+ | `/llamacpp-infra help` | Command help |
84
+
85
+ ### `/llamacpp-infra config`
86
+
87
+ The main config menu branches into submenus:
88
+
89
+ - **🖥️ Servers** — add/remove/edit servers; per-server settings (host, ports, API key, probeDs4, label)
90
+ - **🔄 Scan** — rescan all servers now
91
+ - **📋 Models** — per-model options (thinking budgets, replace/remove)
92
+ - **🧪 Test** — connectivity test of all configured servers
93
+ - **🧠 Thinking budgets** — configure per-model thinking_budget_tokens per level
94
+ - **📈 Metrics** — enable/disable widget, poll interval
95
+ - **⚙️ Settings** — discovery timeout, poll interval/budget, startup grace, fail limit, vision detection, prefix model IDs, name badges, unloaded router models, header warmup
96
+ - **ℹ️ About** — extension info
97
+
98
+ ### `/llamacpp-infra list`
99
+
100
+ Shows every discovered model with metadata badges:
101
+
102
+ ```
103
+ 📋 Discovered models (8)
104
+
105
+ 1. local:8080/Qwen3.6-27B-UD-Q3_K_XL 👁️ 🗜️ UD-Q3_K_XL
106
+ 2. local:8081/DeepSeek-V4-Flash 🗜️ ROCMFP2
107
+ 3. myserver:8080/Meta-Llama-3.1-8B 🚀 draft-model 🗜️ Q4_K_M
108
+ 4. myserver:8081/gemma-3-4b-it 👁️ 🗜️ Q4_K_M
109
+ ```
110
+
111
+ ### `/llamacpp-infra status`
112
+
113
+ Detailed per-endpoint report:
114
+
115
+ ```
116
+ 🖥️ Server status
117
+
118
+ local (127.0.0.1)
119
+ :8080 ✅ llama.cpp b3421 2 models 👁️ vision
120
+ :8081 ✅ lucebox dflash 1 model
121
+
122
+ myserver (192.168.1.20)
123
+ :8080 ✅ llama.cpp b3421 1 model 🚀 drafter
124
+ :8081 ❌ timeout
125
+ ```
126
+
127
+ ## Configuration
128
+
129
+ Everything is configurable through the UI, but the persisted file is `~/.pi/agent/llamacpp-infra.json`:
130
+
131
+ ```json
132
+ {
133
+ "servers": [
134
+ {
135
+ "id": "local",
136
+ "host": "127.0.0.1",
137
+ "label": "Local",
138
+ "ports": [8000, 8001, 8002, 8080, 8081, 8082],
139
+ "enabled": true,
140
+ "probeDs4": false
141
+ },
142
+ {
143
+ "id": "myserver",
144
+ "host": "myserver",
145
+ "label": "My Server",
146
+ "ports": [8080, 8081],
147
+ "enabled": true,
148
+ "probeDs4": true,
149
+ "apiKey": "optional-bearer-token"
150
+ }
151
+ ],
152
+ "settings": {
153
+ "discoveryTimeoutMs": 2000,
154
+ "pollIntervalMs": 4000,
155
+ "pollMaxMs": 90000,
156
+ "startupGraceMs": 40000,
157
+ "knownGoodFailLimit": 3,
158
+ "detectVision": true,
159
+ "prefixModelIds": true,
160
+ "showBadgesInNames": true,
161
+ "includeUnloadedRouterModels": false,
162
+ "warmup": true,
163
+ "metricsEnabled": true,
164
+ "metricsPollMs": 5000
165
+ },
166
+ "modelOptions": {
167
+ "myserver:8080/Qwen3.6-27B": {
168
+ "thinkingBudgets": {
169
+ "minimal": 256,
170
+ "low": 1024,
171
+ "medium": 4096,
172
+ "high": 16384
173
+ }
174
+ }
175
+ }
176
+ }
177
+ ```
178
+
179
+ ### Server fields
180
+
181
+ | Field | Default | Description |
182
+ |-------|---------|-------------|
183
+ | `id` | required | Unique short id (used in model IDs and logs) |
184
+ | `host` | required | Hostname, tailnet name or IP |
185
+ | `label` | `host` | Friendly name shown in menus |
186
+ | `ports` | required | Array of ports to probe |
187
+ | `enabled` | `true` | Whether to probe this server |
188
+ | `probeDs4` | `false` | Opt-in: ping `/v1/chat/completions` for DwarfStar/ds4 servers |
189
+ | `apiKey` | — | Optional bearer token sent on discovery and per-model requests |
190
+
191
+ ### Settings
192
+
193
+ | Setting | Default | Description |
194
+ |---------|---------|-------------|
195
+ | `discoveryTimeoutMs` | `2000` | Per-request timeout when probing endpoints |
196
+ | `pollIntervalMs` | `4000` | Background re-poll rate while servers load models |
197
+ | `pollMaxMs` | `90000` | Max total polling time |
198
+ | `startupGraceMs` | `40000` | Keep trying at startup while nothing has answered |
199
+ | `knownGoodFailLimit` | `3` | Consecutive failures before a live endpoint is dropped |
200
+ | `detectVision` | `true` | Scan `/proc` for `--mmproj` + read server-reported modalities |
201
+ | `prefixModelIds` | `true` | `host:port/model` format to avoid cross-server collisions |
202
+ | `showBadgesInNames` | `true` | Append 👁️🚀💤 badges to model display names |
203
+ | `includeUnloadedRouterModels` | `false` | Router mode: list models that are not currently loaded |
204
+ | `warmup` | `true` | Pre-cache system prompt KV on llama.cpp servers |
205
+ | `metricsEnabled` | `true` | Auto-show live metrics widget for llamacpp-infra models |
206
+ | `metricsPollMs` | `5000` | How often `/metrics` is fetched |
207
+
208
+ ### Thinking budgets
209
+
210
+ llama.cpp accepts `thinking_budget_tokens` per request. Configure budgets per thinking level per model through the config menu (`🧠 Thinking budgets` → select model → set level). Models with any budget configured are registered with `reasoning: true`, and pi sends the budget automatically when the thinking level matches.
211
+
212
+ Levels: `minimal`, `low`, `medium`, `high`, `xhigh`, `max`.
213
+
214
+ ## Model ID Format
215
+
216
+ With `prefixModelIds: true` (default), every model ID is `host:port/model`, e.g. `myserver:8080/Qwen3.6-27B-UD-Q3_K_XL`. This avoids collisions when the same GGUF is served on multiple machines. Localhost servers (`127.0.0.1`, `localhost`) use `local:port/model` for readability.
217
+
218
+ ## Live Metrics Widget
219
+
220
+ When enabled, the metrics widget appears automatically when the active model is from llamacpp-infra:
221
+
222
+ ```
223
+ 📊 local:8080 ⚡ 42.3 t/s prompt · 38.1 t/s gen · 1.2k tokens
224
+ ```
225
+
226
+ It polls the server's Prometheus `/metrics` endpoint (or JSON `/stats`) and shows instantaneous throughput. The poll interval is configurable (default 5s).
227
+
228
+ ## Architecture
229
+
230
+ ```
231
+ llamacpp-infra/
232
+ ├── package.json # pi package manifest (pi-package)
233
+ ├── LICENSE # MIT
234
+ ├── README.md
235
+ └── src/
236
+ ├── index.ts # Extension entry point (~2400 lines)
237
+ └── prompt-warmup.ts # Header warmup module (inlined, ~600 lines)
238
+ ```
239
+
240
+ Two-file extension with zero external dependencies (only pi's bundled `@earendil-works/pi-coding-agent` + Node built-ins):
241
+
242
+ - **Discovery engine** — multi-server probing with timeouts, retry budgets, and per-server kind detection (llama.cpp, ZINC, DwarfStar, lucebox)
243
+ - **Router support** — single-model and multi-model llama.cpp modes with per-model status, args parsing and metadata extraction
244
+ - **Metrics subsystem** — Prometheus endpoint discovery, polling, and compact widget rendering
245
+ - **Thinking budgets** — per-model per-level configuration with automatic `reasoning` registration
246
+ - **Config persistence** — `~/.pi/agent/llamacpp-infra.json` with one-time migration from `local-models.json`
247
+ - **/proc scanner** — local llama-server process detection for vision, KV cache quant, and drafter flags
248
+
249
+ ## Migration from local-models
250
+
251
+ If you have an existing `~/.pi/agent/local-models.json`, llamacpp-infra migrates it automatically on first run — your servers and settings are preserved. The old `local-models` extension can be removed after migration.
252
+
253
+ ## License
254
+
255
+ [MIT](LICENSE) © Javier Noguerol
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "pi-llamacpp-infra",
3
+ "version": "1.0.0",
4
+ "description": "Discovery, metrics and control of llama.cpp-family servers for pi: probes any number of machines (localhost, LAN, Tailscale), registers every model into pi's native /model list, and provides live Prometheus metrics, per-model thinking budgets, vision detection and a native config UI. Supports llama.cpp, ZINC, DwarfStar/ds4 and lucebox.",
5
+ "keywords": [
6
+ "pi-package",
7
+ "llamacpp",
8
+ "llama.cpp",
9
+ "local-models",
10
+ "discovery",
11
+ "metrics",
12
+ "tailscale",
13
+ "vision",
14
+ "thinking"
15
+ ],
16
+ "author": "Javier Noguerol <https://github.com/noguerol>",
17
+ "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/noguerol/llamacpp-infra"
21
+ },
22
+ "homepage": "https://github.com/noguerol/llamacpp-infra",
23
+ "bugs": {
24
+ "url": "https://github.com/noguerol/llamacpp-infra/issues"
25
+ },
26
+ "pi": {
27
+ "extensions": [
28
+ "./src/index.ts"
29
+ ]
30
+ },
31
+ "files": [
32
+ "src"
33
+ ],
34
+ "peerDependencies": {
35
+ "@earendil-works/pi-coding-agent": "*"
36
+ }
37
+ }