@maheidem/model-discovery 0.1.0 → 0.6.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 (4) hide show
  1. package/README.md +172 -22
  2. package/index.ts +1465 -86
  3. package/package.json +9 -3
  4. package/profiles.ts +619 -0
package/README.md CHANGED
@@ -1,15 +1,20 @@
1
1
  # @maheidem/model-discovery
2
2
 
3
- Interactive TUI for discovering and managing local AI model endpoints. Works with llama.cpp, oMLX, Ollama, vLLM, SGLang, LM Studio, and any OpenAI-compatible server.
3
+ Interactive TUI for discovering and managing local AI model endpoints. Works with llama.cpp, oMLX, Ollama, vLLM, SGLang, LM Studio, and other OpenAI-compatible servers.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Auto-detect** server type from headers and model data (no manual config)
8
- - **Read real server-reported configs** — context window, max tokens, reasoning flags, input modalities
9
- - **Fine-tune per-model overrides** — set context window, max tokens, reasoning toggles
10
- - **Multi-endpoint management** — add, scan, and register multiple local servers
11
- - **LLM-callable tool** — the `discover_models` tool lets the agent discover endpoints on your behalf
12
- - **Persistent storage** — providers saved across sessions in `~/.pi/agent/model-discovery.json`
7
+ - **Auto-detect server type** from headers and model data
8
+ - **Read server-reported configuration** — context window, max tokens, reasoning flags, and input modalities
9
+ - **Auto-detect reasoning format** — oMLX servers get `chat_template_kwargs` thinking support automatically
10
+ - **Fine-tune per-model overrides** — context window, max output, reasoning, and vision support
11
+ - **Profile-routed native thinking levels** — Shift-Tab can select complete thinking and sampling presets
12
+ - **Named model presets** — reuse complete thinking/sampling bundles as fixed aliases or adaptive routes
13
+ - **Offline management** — retain the last successful server catalogue for configuration and startup fallback
14
+ - **Authenticated endpoints** — enroll, replace, validate, or clear bearer API keys through masked TUI input
15
+ - **Multi-endpoint management** — add, rename, scan, and remove local model sources
16
+ - **LLM-callable tool** — the `discover_models` tool can register endpoints on the agent's behalf
17
+ - **Persistent storage** in `~/.pi/agent/model-discovery.json`
13
18
 
14
19
  ## Installation
15
20
 
@@ -18,42 +23,187 @@ Interactive TUI for discovering and managing local AI model endpoints. Works wit
18
23
  pi install npm:@maheidem/model-discovery
19
24
 
20
25
  # Via git
21
- pi install git:github.com/Maheidem/model-discovery@v0.1.0
26
+ pi install git:github.com/Maheidem/model-discovery@v0.6.0
22
27
  ```
23
28
 
24
29
  ## Usage
25
30
 
26
- ### Interactive UI
31
+ Run `/discover` in Pi to open the management TUI:
27
32
 
28
- Run `/discover` in pi to open the management TUI:
33
+ - **Add endpoint** enter a URL, choose anonymous or API-key authentication, probe it, review models, and register
34
+ - **Re-scan** — refresh models reported by an existing endpoint
35
+ - **Edit model** — override context, max output, reasoning, or vision support
36
+ - **Manage profiles** — create, edit, rename, or delete named variants
37
+ - **Rename source** — change the provider name shown by `/model`
38
+ - **Remove** — unregister and delete an endpoint
29
39
 
30
- - **Add endpoint** enter a URL, probe it, review models, register
31
- - **Scan existing** — re-scan registered endpoints for fresh model lists
32
- - **Edit per-model** — override context window, max tokens, reasoning flags
33
- - **Remove** — unregister and delete saved endpoints
40
+ You can jump directly into adding an endpoint:
34
41
 
35
- ### With arguments
42
+ ```text
43
+ /discover http://192.168.1.100:8080
44
+ ```
45
+
46
+ Enrollment explicitly asks whether the endpoint is anonymous or requires an API key. API-key input is masked and is sent as `Authorization: Bearer <key>` for both `/v1/models` discovery and inference. The key is stored unencrypted in `~/.pi/agent/model-discovery.json`; the extension writes that file atomically with owner-only (`0600`) permissions. Use **Authentication** on an existing endpoint to replace, validate, or clear its key without losing the cached catalogue.
47
+
48
+ The LLM-callable tool remains available:
36
49
 
50
+ ```text
51
+ discover_models(url="http://192.168.1.100:8080", providerName="my-llama")
37
52
  ```
38
- /discover http://192.168.1.100:8080 # jump straight to adding this endpoint
53
+
54
+ The tool also accepts `apiKey`, but literal tool arguments may be retained in the agent session. Prefer the masked `/discover` flow for secrets.
55
+
56
+ ## Native thinking levels
57
+
58
+ For reasoning-capable Qwen models on oMLX, the base model and sampling-only profiles translate Pi's native Shift-Tab level into request-scoped `chat_template_kwargs`:
59
+
60
+ | Pi level | `enable_thinking` | Qwen `reasoning_effort` |
61
+ | --- | --- | --- |
62
+ | `off` | `false` | omitted |
63
+ | `minimal`, `low` | `true` | `low` |
64
+ | `medium` | `true` | `medium` |
65
+ | `high`, `xhigh`, `max` | `true` | `xhigh` |
66
+
67
+ `preserve_thinking` remains `true`. Fixed-thinking profiles intentionally stay locked to their configured state or effort, while profiles containing only sampling values inherit native Shift-Tab behavior.
68
+
69
+ ### Explicit complete-profile routing
70
+
71
+ Adaptive routing is opt-in and separate from ordinary presets. Creating presets never changes the base model or another alias. In **Thinking & presets**, configure an adaptive alias and explicitly choose a preset for every Pi level. The conventional four-preset helper expands this layout:
72
+
73
+ | Pi level | Selected preset |
74
+ | --- | --- |
75
+ | `off` | instruct/off preset |
76
+ | `minimal`, `low` | low preset |
77
+ | `medium` | medium preset |
78
+ | `high`, `xhigh`, `max` | xhigh preset |
79
+
80
+ The adaptive alias replaces all profile-controlled sampling fields and `chat_template_kwargs` on every request while retaining the same physical server model and conversation. Multiple presets may use the same reasoning effort because the mapping chooses by preset name rather than inference. The base model, sampling-only aliases, and fixed aliases retain their own behavior.
81
+
82
+ The TUI supports cloning presets, hiding preset aliases from `/model`, editing individual level mappings, previewing exact request payloads, disabling routing while preserving its map, and removing the adaptive alias without deleting presets. The footer shows `preset: <slug>` for an adaptive alias and `fixed preset: <slug>` for a fixed alias.
83
+
84
+ Example persisted routing:
85
+
86
+ ```json
87
+ {
88
+ "modelProfileRouting": {
89
+ "Qwen3.8-27B": {
90
+ "enabled": true,
91
+ "aliasSlug": "thinking",
92
+ "levels": {
93
+ "off": "instruct",
94
+ "minimal": "thinking-low",
95
+ "low": "thinking-low",
96
+ "medium": "thinking-medium",
97
+ "high": "thinking-xhigh",
98
+ "xhigh": "thinking-xhigh",
99
+ "max": "thinking-xhigh"
100
+ }
101
+ }
102
+ }
103
+ }
39
104
  ```
40
105
 
41
- ### LLM Tool
106
+ ## Named profiles
42
107
 
43
- The `discover_models` tool can be called by the agent:
108
+ Presets with `exposeAsModel` omitted or `true` appear as fixed models under the same provider. Set `exposeAsModel: false` to keep a preset available to adaptive routing without cluttering `/model`. Given a server model named `Qwen3.8-27B` and a visible preset named `xhigh`, `/model` shows both:
44
109
 
110
+ ```text
111
+ Qwen3.8-27B
112
+ Qwen3.8-27B@xhigh
45
113
  ```
46
- discover_models(url="http://localhost:8080", providerName="my-llama", apiKey="optional-key")
114
+
115
+ The profile request still targets the real server model. For example:
116
+
117
+ ```json
118
+ {
119
+ "modelProfiles": {
120
+ "Qwen3.8-27B": [
121
+ {
122
+ "slug": "xhigh",
123
+ "chatTemplateKwargs": {
124
+ "enable_thinking": true,
125
+ "reasoning_effort": "xhigh",
126
+ "preserve_thinking": false
127
+ },
128
+ "exposeAsModel": false,
129
+ "sampling": {
130
+ "temperature": 0.7,
131
+ "topP": 0.9,
132
+ "topK": 20,
133
+ "minP": 0.05,
134
+ "repetitionPenalty": 1.05,
135
+ "presencePenalty": 0,
136
+ "frequencyPenalty": 0
137
+ }
138
+ }
139
+ ]
140
+ }
141
+ }
47
142
  ```
48
143
 
144
+ Supported thinking values are:
145
+
146
+ - `enable_thinking`: `true` or `false`
147
+ - `reasoning_effort`: `"low"`, `"medium"`, or `"xhigh"`
148
+ - `preserve_thinking`: `true` or `false`
149
+
150
+ Supported sampling values are:
151
+
152
+ - `temperature`: `0–2`; `0` is greedy
153
+ - `topP`: `0–1`; `1` disables top-p filtering
154
+ - `topK`: integer `>= 0`; omit it to keep the backend-specific default
155
+ - `minP`: `0–1`; `0` disables min-p filtering
156
+ - `repetitionPenalty`: `> 0`; `1` disables it
157
+ - `presencePenalty`: `-2–2`; `0` disables it
158
+ - `frequencyPenalty`: `-2–2`; `0` disables it
159
+
160
+ The extension translates these backend-neutral storage names to top-level request fields such as `top_p`, `top_k`, `min_p`, `presence_penalty`, and `frequency_penalty`. Repetition penalty is sent as:
161
+
162
+ - `repeat_penalty` for llama.cpp and LM Studio
163
+ - `repetition_penalty` for oMLX, vLLM, and SGLang
164
+ - `repetition_penalty` as a best-effort fallback for Ollama and unknown OpenAI-compatible servers
165
+
166
+ A configured value is sent exactly. Fixed thinking values take precedence over Pi's current `/think` level, while fixed sampling values take precedence over Pi/request defaults. When every thinking value is omitted, the profile inherits the base model's native Shift-Tab behavior; when any thinking value is configured, only that profile's configured thinking keys are sent. Omitted sampling keys are not sent, leaving them to the server/model default. Profiles may contain thinking values, sampling values, or both. The base model remains independently selectable.
167
+
168
+ Sampling support still depends on the target server. In particular, Ollama's current OpenAI-compatible chat endpoint does not expose `top_k`, `min_p`, or a dedicated repetition-penalty field and may ignore those fallback keys. Omit unsupported controls to retain that backend's defaults.
169
+
170
+ If Pi has an `enabledModels` scope, press **Tab** in `/model` to switch from scoped models to all models, or add the profile alias to `enabledModels`.
171
+
172
+ Profiles are retained if a model temporarily disappears during a re-scan.
173
+
174
+ ## Offline resilience
175
+
176
+ Every successful live scan atomically persists the raw model catalogue as the source's last known-good cache. Saved sources are scanned independently and concurrently at startup. If one source is offline, times out, rejects its credentials, or returns a malformed response:
177
+
178
+ - its cached base models, fixed aliases, and adaptive aliases remain registered;
179
+ - its overrides, presets, and routing remain editable through `/discover`;
180
+ - a failed or empty response never replaces the last known-good cache;
181
+ - the TUI shows the latest failure and time of the last successful scan; and
182
+ - other healthy sources continue loading normally.
183
+
184
+ `Re-scan all` does not unregister a provider before a replacement catalogue has been validated. A source with no previous successful scan is reported as unavailable without affecting any other source. The cache preserves discovery and configuration during an outage; actual inference still requires the model source to become reachable again.
185
+
186
+ Legacy implicit routing created by early v0.6 development builds is migrated once: its sampling-only adaptive alias becomes an explicit router with the same model ID, and its concrete presets are retained. Future presets never activate routing implicitly.
187
+
49
188
  ## Storage
50
189
 
51
- Discovered providers are persisted in `~/.pi/agent/model-discovery.json`.
190
+ Discovered providers, cached catalogues, model overrides, presets, and explicit routing maps are persisted in:
191
+
192
+ ```text
193
+ ~/.pi/agent/model-discovery.json
194
+ ```
52
195
 
53
196
  ## Requirements
54
197
 
55
- - pi coding agent with TUI support
56
- - Access to OpenAI-compatible model servers on your network
198
+ - Pi coding agent **0.84.0 or newer** (`samplingParams` support is required for model aliases)
199
+ - TUI support
200
+ - Network access to an OpenAI-compatible model server
201
+
202
+ ## Development
203
+
204
+ ```bash
205
+ npm test
206
+ ```
57
207
 
58
208
  ## License
59
209