modelsdesk 0.0.0-stage → 0.2.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 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.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.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,149 @@
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
+ | `strata` | own tiers (q2_0, iq3_s, gyro-s…) | macOS/Linux/Windows | `curl … install.sh \| sh` (Strata) |
75
+ | `mistral-rs` | GGUF + safetensors | macOS/Linux/Windows | `curl … mistralrs.dev/install.sh \| sh` |
76
+ | `vllm` | safetensors/GGUF | Linux/Windows (CUDA) | `pip install vllm` |
77
+ | `sglang` | safetensors/GGUF | Linux (CUDA) | `pip install 'sglang[all]'` |
78
+
79
+ `start`, `setup`, and `doctor --fix` install a missing backend automatically
80
+ (OS + distro detected at runtime). Minimum versions are gated (mlx-dspark
81
+ ≥0.17, llama.cpp ≥b5000); older backends warn but still run. GGUF weights for
82
+ llama.cpp download into `~/.cache/modeldesk/gguf/` (Q4_K_M preferred).
83
+
84
+ ## Profiles (stored model configs)
85
+
86
+ Profiles live in `config.toml` (see `modelsd profile list` for the path).
87
+ Each profile: `name + provider + repo + drafter? + kv_bits + context_window? +
88
+ temperature? + mode?`.
89
+
90
+ ```bash
91
+ modeldesk profile add lfm-2.5-8b LiquidAI/LFM2.5-8B-A1B-MLX-4bit \
92
+ --drafter LiquidAI/LFM2.5-8B-A1B-DSpark
93
+ modeldesk profile add mistral-7b ./models/mistral-7b.Q4_K_M.gguf \
94
+ --provider llama-cpp --context-window 8192
95
+ modeldesk use lfm-2.5-8b
96
+ ```
97
+
98
+ `profile add` validates format/provider/arch **before saving** — a bad
99
+ combo is rejected with the reason, never stored.
100
+
101
+ ## Freshness (outdated detection)
102
+
103
+ - `modelsd outdated`: live check of backend releases (PyPI / brew
104
+ livecheck / GitHub releases) + cached-model staleness (HF `lastModified`
105
+ vs cache mtime, 24h grace for metadata-only bumps).
106
+ - **Ambient warnings:** every other command prints cached `! outdated: …`
107
+ stderr warnings when something is stale. Cache is 6 hours, refreshed by a
108
+ detached background worker that never blocks or fails the command. Skipped
109
+ for `outdated` itself, completions, and `--json` runs.
110
+
111
+ ## Compatibility rules (also in `references/compatibility.md`)
112
+
113
+ - Format is detected from the repo name: `-MLX-`/`mlx-` → MLX,
114
+ `.gguf`/`-GGUF` → GGUF, else Safetensors/Unknown.
115
+ - `mlx-dspark` / `mlx-lm`: MLX weights only. Apple Silicon + macOS 14+ only.
116
+ - `llama-cpp`: GGUF only. `ollama`: own registry names, `ollama pull` first.
117
+ - RAM is estimated from param count × quant + drafter + overhead;
118
+ `doctor` fails above 85% of machine RAM, warns above 60%.
119
+ - Hot-swap (`POST /admin/load`) is same-backend only (mlx-dspark).
120
+ A provider change always does stop + full restart.
121
+
122
+ ## Wiring agents to the server
123
+
124
+ The server is OpenAI-compatible at `http://127.0.0.1:<port>/v1`
125
+ (default port 8090) plus an Anthropic endpoint at `/v1/messages`.
126
+
127
+ - **OpenCode** (`~/.config/opencode/opencode.json`): provider with
128
+ `"npm": "@ai-sdk/openai-compatible"`, `"baseURL": "http://127.0.0.1:8090/v1"`,
129
+ model id = the served repo short name.
130
+ - **jcode**: `jcode provider add <name> --base-url http://127.0.0.1:8090/v1
131
+ --model <model-id> --api-key-stdin` (any dummy key; the server ignores it,
132
+ but jcode's discovery probe requires the header). Note: jcode `auth-test`
133
+ FAILs on its `/v1/models` probe (no bearer sent) while chat completions
134
+ work — verify with a real `run`, not `auth-test`.
135
+
136
+ `modelsd sync-agents` rewrites both configs to the active profile;
137
+ `modelsd use` runs it automatically after every switch.
138
+
139
+ ## Safety rules
140
+
141
+ - `stop` matches backend binaries on modeldesk's port only. A non-backend
142
+ process (Expo, another tool) can never match — it is reported by name,
143
+ never killed blindly.
144
+ - `doctor` runs before every `start` when the setup changed.
145
+ - Spinners degrade to plain lines when piped — scripts always see results.
146
+ - Memory pressure on 16 GB Macs is normal with 8B models — suggest closing
147
+ apps or a smaller quant before blaming the server.
148
+ - Reasoning models put thinking in `reasoning_content`, leaving `content`
149
+ 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
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.