modelsdesk 0.0.0-stage → 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/bin/modelsd.js +33 -0
- package/package.json +26 -4
- package/skills/modeldesk/SKILL.md +145 -0
- package/skills/modeldesk/references/compatibility.md +59 -0
- package/README.md +0 -3
package/bin/modelsd.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// modeldesk bin shim (platform-binary pattern): resolve this platform's
|
|
3
|
+
// native binary from the matching @modelsdesk/<platform>
|
|
4
|
+
// optionalDependency and hand it the argv verbatim. Clear, actionable error
|
|
5
|
+
// when the binary is missing — never a raw stack trace.
|
|
6
|
+
import { spawnSync } from "node:child_process";
|
|
7
|
+
import { createRequire } from "node:module";
|
|
8
|
+
|
|
9
|
+
const SUPPORTED = new Set(["darwin-arm64"]);
|
|
10
|
+
|
|
11
|
+
const platform = `${process.platform}-${process.arch}`;
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
|
|
14
|
+
let bin;
|
|
15
|
+
try {
|
|
16
|
+
bin = require.resolve(`@modelsdesk/${platform}/bin/modelsd`);
|
|
17
|
+
} catch (err) {
|
|
18
|
+
console.error(`modelsd: no native binary for ${platform}.`);
|
|
19
|
+
if (!SUPPORTED.has(platform)) {
|
|
20
|
+
console.error(
|
|
21
|
+
` ${platform} is not supported yet (supported: ${[...SUPPORTED].sort().join(", ")}).`,
|
|
22
|
+
);
|
|
23
|
+
console.error(` Linux/Windows follow the provider-agnostic core — track releases.`);
|
|
24
|
+
} else {
|
|
25
|
+
console.error(
|
|
26
|
+
` Install the platform package: npm install -g @modelsdesk/${platform}`,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const result = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
|
|
33
|
+
process.exit(result.status ?? 1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "modelsdesk",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "One CLI to find, install, serve, and monitor local LLMs — macOS first, provider-agnostic core.",
|
|
5
|
+
"license": "GPL-3.0-or-later",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"modelsd": "bin/modelsd.js"
|
|
9
|
+
},
|
|
10
|
+
"optionalDependencies": {
|
|
11
|
+
"@modelsdesk/darwin-arm64": "0.1.0"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=20"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"bin/",
|
|
18
|
+
"skills/"
|
|
19
|
+
],
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/talha7k/modelsdesk.git"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/talha7k/modelsdesk#readme",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/talha7k/modelsdesk/issues"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: modeldesk
|
|
3
|
+
description: >-
|
|
4
|
+
Manage local LLM servers with the modeldesk CLI: search Hugging Face,
|
|
5
|
+
set up models end-to-end, start/stop/health, switch models, sync agent
|
|
6
|
+
configs, check backend/model freshness. Use when the user runs models
|
|
7
|
+
locally, asks about local inference, needs a model server for
|
|
8
|
+
OpenCode/jcode/agents, or mentions modeldesk, mlx-dspark, llama.cpp,
|
|
9
|
+
ollama, or local model health.
|
|
10
|
+
|
|
11
|
+
Trigger phrases include "local model", "local llm", "start the model",
|
|
12
|
+
"model server", "model health", "switch model", "which models fit",
|
|
13
|
+
"find a model", "model outdated", "update the backend", "modeldesk"
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# ModelDesk
|
|
17
|
+
|
|
18
|
+
`modelsd` (the modelsdesk CLI) is a Rust CLI that manages local LLM inference servers —
|
|
19
|
+
macOS first (MLX + mlx-dspark), provider-agnostic core (llama.cpp,
|
|
20
|
+
Ollama work cross-platform).
|
|
21
|
+
|
|
22
|
+
- **Install:** `cargo install modelsdesk` (crates.io) or
|
|
23
|
+
`cargo install --path .` from https://github.com/talha7k/modelsdesk
|
|
24
|
+
- **Source:** https://github.com/talha7k/modelsdesk (GPL-3.0-or-later)
|
|
25
|
+
|
|
26
|
+
## Command map
|
|
27
|
+
|
|
28
|
+
| Task | Command |
|
|
29
|
+
|---|---|
|
|
30
|
+
| Find runnable models on HF | `modelsd search <terms> [--limit N]` |
|
|
31
|
+
| Set up end-to-end (verify → install → download → serve) | `modelsd setup <repo> [--name N] [--provider ID] [--drafter R] [--start]` |
|
|
32
|
+
| What's installed (+versions) | `modelsd providers` |
|
|
33
|
+
| What's downloaded | `modelsd models` |
|
|
34
|
+
| Validate before launch | `modelsd doctor [name] [--fix]` |
|
|
35
|
+
| Start (validated, auto-installs backend) | `modelsd start [--foreground] [--no-install]` |
|
|
36
|
+
| Stop | `modelsd stop` |
|
|
37
|
+
| Restart | `modelsd restart` |
|
|
38
|
+
| Health probe | `modelsd health` (alias `status`) |
|
|
39
|
+
| Switch model (hot-swap + agent re-sync) | `modelsd use <name> [--provider <id>] [--restart]` |
|
|
40
|
+
| Pre-fetch weights | `modelsd pull [name]` |
|
|
41
|
+
| Backend + model freshness | `modelsd outdated` |
|
|
42
|
+
| Sync OpenCode/jcode to active model | `modelsd sync-agents` |
|
|
43
|
+
| Live console | `modelsd watch` (q to quit) |
|
|
44
|
+
| Logs | `modelsd logs [n] [--follow]` |
|
|
45
|
+
| Profiles | `modelsd profile <list\|show\|add\|remove>` |
|
|
46
|
+
| Completions | `modelsd completions <bash\|zsh\|fish\|powershell\|elvish>` |
|
|
47
|
+
|
|
48
|
+
Append `--json` to health/models/providers/use/doctor/search/outdated/sync-agents
|
|
49
|
+
for machine output. Append `--verbose` for stderr diagnostics.
|
|
50
|
+
`MODELDESK_NO_INSTALL=1` disables auto-install everywhere.
|
|
51
|
+
|
|
52
|
+
## Setup flow (the happy path)
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
modelsd search qwen3 8b # annotated HF hits
|
|
56
|
+
modelsd setup mlx-community/Qwen3-8B-8bit --name qwen3-8b --start
|
|
57
|
+
modeldesk health
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`setup` verifies the repo exists on HF, recommends (or takes) the backend,
|
|
61
|
+
installs the backend when missing (brew/pipx, with progress), runs the full
|
|
62
|
+
doctor validation, downloads weights, saves the profile, and optionally
|
|
63
|
+
starts serving. `search` annotates each hit with format, recommended backend,
|
|
64
|
+
backend install status, RAM estimate vs this machine, and cache state.
|
|
65
|
+
|
|
66
|
+
## Backends and auto-install
|
|
67
|
+
|
|
68
|
+
| Backend | Weights | Platforms | Install (automatic) |
|
|
69
|
+
|---|---|---|---|
|
|
70
|
+
| `mlx-dspark` | MLX (+ DSpark drafter) | macOS arm64, macOS 14+ | `pipx install mlx-dspark` |
|
|
71
|
+
| `mlx-lm` | MLX | macOS arm64, macOS 14+ | `brew install mlx-lm` |
|
|
72
|
+
| `llama-cpp` | GGUF (auto-downloaded) | macOS/Linux/Windows | brew / apt / dnf / pacman / winget / choco |
|
|
73
|
+
| `ollama` | registry names | macOS/Linux/Windows | brew / install script / winget |
|
|
74
|
+
|
|
75
|
+
`start`, `setup`, and `doctor --fix` install a missing backend automatically
|
|
76
|
+
(OS + distro detected at runtime). Minimum versions are gated (mlx-dspark
|
|
77
|
+
≥0.17, llama.cpp ≥b5000); older backends warn but still run. GGUF weights for
|
|
78
|
+
llama.cpp download into `~/.cache/modeldesk/gguf/` (Q4_K_M preferred).
|
|
79
|
+
|
|
80
|
+
## Profiles (stored model configs)
|
|
81
|
+
|
|
82
|
+
Profiles live in `config.toml` (see `modelsd profile list` for the path).
|
|
83
|
+
Each profile: `name + provider + repo + drafter? + kv_bits + context_window? +
|
|
84
|
+
temperature? + mode?`.
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
modeldesk profile add lfm-2.5-8b LiquidAI/LFM2.5-8B-A1B-MLX-4bit \
|
|
88
|
+
--drafter LiquidAI/LFM2.5-8B-A1B-DSpark
|
|
89
|
+
modeldesk profile add mistral-7b ./models/mistral-7b.Q4_K_M.gguf \
|
|
90
|
+
--provider llama-cpp --context-window 8192
|
|
91
|
+
modeldesk use lfm-2.5-8b
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`profile add` validates format/provider/arch **before saving** — a bad
|
|
95
|
+
combo is rejected with the reason, never stored.
|
|
96
|
+
|
|
97
|
+
## Freshness (outdated detection)
|
|
98
|
+
|
|
99
|
+
- `modelsd outdated`: live check of backend releases (PyPI / brew
|
|
100
|
+
livecheck / GitHub releases) + cached-model staleness (HF `lastModified`
|
|
101
|
+
vs cache mtime, 24h grace for metadata-only bumps).
|
|
102
|
+
- **Ambient warnings:** every other command prints cached `! outdated: …`
|
|
103
|
+
stderr warnings when something is stale. Cache is 6 hours, refreshed by a
|
|
104
|
+
detached background worker that never blocks or fails the command. Skipped
|
|
105
|
+
for `outdated` itself, completions, and `--json` runs.
|
|
106
|
+
|
|
107
|
+
## Compatibility rules (also in `references/compatibility.md`)
|
|
108
|
+
|
|
109
|
+
- Format is detected from the repo name: `-MLX-`/`mlx-` → MLX,
|
|
110
|
+
`.gguf`/`-GGUF` → GGUF, else Safetensors/Unknown.
|
|
111
|
+
- `mlx-dspark` / `mlx-lm`: MLX weights only. Apple Silicon + macOS 14+ only.
|
|
112
|
+
- `llama-cpp`: GGUF only. `ollama`: own registry names, `ollama pull` first.
|
|
113
|
+
- RAM is estimated from param count × quant + drafter + overhead;
|
|
114
|
+
`doctor` fails above 85% of machine RAM, warns above 60%.
|
|
115
|
+
- Hot-swap (`POST /admin/load`) is same-backend only (mlx-dspark).
|
|
116
|
+
A provider change always does stop + full restart.
|
|
117
|
+
|
|
118
|
+
## Wiring agents to the server
|
|
119
|
+
|
|
120
|
+
The server is OpenAI-compatible at `http://127.0.0.1:<port>/v1`
|
|
121
|
+
(default port 8090) plus an Anthropic endpoint at `/v1/messages`.
|
|
122
|
+
|
|
123
|
+
- **OpenCode** (`~/.config/opencode/opencode.json`): provider with
|
|
124
|
+
`"npm": "@ai-sdk/openai-compatible"`, `"baseURL": "http://127.0.0.1:8090/v1"`,
|
|
125
|
+
model id = the served repo short name.
|
|
126
|
+
- **jcode**: `jcode provider add <name> --base-url http://127.0.0.1:8090/v1
|
|
127
|
+
--model <model-id> --api-key-stdin` (any dummy key; the server ignores it,
|
|
128
|
+
but jcode's discovery probe requires the header). Note: jcode `auth-test`
|
|
129
|
+
FAILs on its `/v1/models` probe (no bearer sent) while chat completions
|
|
130
|
+
work — verify with a real `run`, not `auth-test`.
|
|
131
|
+
|
|
132
|
+
`modelsd sync-agents` rewrites both configs to the active profile;
|
|
133
|
+
`modelsd use` runs it automatically after every switch.
|
|
134
|
+
|
|
135
|
+
## Safety rules
|
|
136
|
+
|
|
137
|
+
- `stop` matches backend binaries on modeldesk's port only. A non-backend
|
|
138
|
+
process (Expo, another tool) can never match — it is reported by name,
|
|
139
|
+
never killed blindly.
|
|
140
|
+
- `doctor` runs before every `start` when the setup changed.
|
|
141
|
+
- Spinners degrade to plain lines when piped — scripts always see results.
|
|
142
|
+
- Memory pressure on 16 GB Macs is normal with 8B models — suggest closing
|
|
143
|
+
apps or a smaller quant before blaming the server.
|
|
144
|
+
- Reasoning models put thinking in `reasoning_content`, leaving `content`
|
|
145
|
+
empty on short replies — agents expecting `content` may show blanks.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# ModelDesk compatibility reference
|
|
2
|
+
|
|
3
|
+
How `modeldesk doctor` and `profile add` decide whether a model runs on a
|
|
4
|
+
backend. Same logic lives in `src/compat.rs` — this file is the human copy.
|
|
5
|
+
|
|
6
|
+
## Format detection (from repo string, lowercased)
|
|
7
|
+
|
|
8
|
+
| Signal | Format |
|
|
9
|
+
|---|---|
|
|
10
|
+
| ends with `.gguf`, contains `.gguf` or `-gguf` | GGUF |
|
|
11
|
+
| contains `-mlx`, `mlx-`, `/mlx-` | MLX |
|
|
12
|
+
| ends with `.safetensors` or contains `safetensors` | Safetensors |
|
|
13
|
+
| none of the above | Unknown (treated as MLX/Safetensors with a warning) |
|
|
14
|
+
|
|
15
|
+
## Provider matrix
|
|
16
|
+
|
|
17
|
+
| Backend | Accepts | Platforms | Notes |
|
|
18
|
+
|---|---|---|---|
|
|
19
|
+
| `mlx-dspark` | MLX (+ converted Safetensors from `LiquidAI/`, `mlx-community/`) | macOS arm64 only | DSpark speculative decoding; needs a drafter for speedup, runs without one in baseline |
|
|
20
|
+
| `mlx-lm` | MLX (+ converted Safetensors, same rule) | macOS arm64 only | Plain decoding, no speculation |
|
|
21
|
+
| `llama-cpp` | GGUF only | macOS, Linux, Windows | Needs a local `.gguf` file path or HF GGUF repo; `--ctx-size` from profile |
|
|
22
|
+
| `ollama` | Ollama registry names only | macOS, Linux, Windows | Managed daemon: `ollama pull <name>` first; modeldesk does not download for it |
|
|
23
|
+
|
|
24
|
+
## RAM estimation
|
|
25
|
+
|
|
26
|
+
`params × bytes-per-param + 1.5 GB overhead + 1.5 GB if drafter`
|
|
27
|
+
|
|
28
|
+
- Param count parsed from the repo name (`8b` → 8B, `2.6b` → 2.6B …; default 8B).
|
|
29
|
+
- Bytes/param: 4-bit/q4 → 0.55, 8-bit/q8 → 1.05, bf16/fp16/f16 → 2.1, default 1.05.
|
|
30
|
+
- `doctor` FAILS above 85% of machine RAM, WARNS above 60%.
|
|
31
|
+
|
|
32
|
+
## Hot-swap vs restart
|
|
33
|
+
|
|
34
|
+
- Same backend + provider supports `POST /admin/load` (mlx-dspark): hot-swap, port stays.
|
|
35
|
+
- Anything else (provider change, llama-cpp, ollama, mlx-lm): full stop + boot.
|
|
36
|
+
- `modeldesk use <name> --restart` forces the full cycle.
|
|
37
|
+
|
|
38
|
+
## Backend installation (runtime layer)
|
|
39
|
+
|
|
40
|
+
`start`, `setup`, and `doctor --fix` install a missing backend automatically
|
|
41
|
+
unless `--no-install` / `MODELDESK_NO_INSTALL=1`. OS, version, arch, distro,
|
|
42
|
+
and available package managers are detected at runtime (`src/runtime_env.rs`):
|
|
43
|
+
|
|
44
|
+
- macOS: brew → pipx → uv (MLX needs macOS 14+ on arm64, enforced)
|
|
45
|
+
- Linux: brew → pipx/uv → apt / dnf / pacman / zypper / apk by distro
|
|
46
|
+
- Windows: winget → choco → scoop
|
|
47
|
+
|
|
48
|
+
Minimum versions: mlx-dspark ≥0.17, llama.cpp ≥b5000. Older backends warn
|
|
49
|
+
(`old, want ≥X` in `providers`/`doctor`) but still run. Versions resolve via
|
|
50
|
+
binary → pipx → brew since MLX binaries have no `--version`.
|
|
51
|
+
|
|
52
|
+
## Freshness model
|
|
53
|
+
|
|
54
|
+
- Backends: PyPI (mlx-dspark, mlx-lm fallback) / `brew livecheck` (mlx-lm,
|
|
55
|
+
ollama) / GitHub releases (llama.cpp, ollama fallback).
|
|
56
|
+
- Models: HF `lastModified` vs cache snapshot mtime, 24h grace for
|
|
57
|
+
metadata-only bumps (prevents false "stale" on README edits).
|
|
58
|
+
- `outdated` is always live; ambient warnings use a 6h cache refreshed by a
|
|
59
|
+
detached worker (`outdated --refresh-cache`, hidden flag).
|
package/README.md
DELETED