A pi extension that auto-discovers a running mlxcel-server (the Rust MLX runner from lablup/mlxcel, OpenAI-compatible) and registers its served models with pi — reading the real context window from Hugging Face metadata so you never type ctx-size manually.
Supports both http and https endpoints, local and remote servers. Works with any OpenAI-compatible MLX server (mlxcel, mlx-lm, etc.).
- Probes each configured server URL (
/v1/models), defaulthttp://127.0.0.1:8080. - For each model id:
- Fetches metadata from Hugging Face (
config.json,tokenizer_config.json,chat_template.jinja). Results are cached permanently — model metadata doesn't change. - Bare model names (no slash) are resolved by trying
MLXCEL_DEFAULT_ORG/<name>first (defaultmlx-community), then the HF search API if that 404s. This handles models from any org automatically. - Extracts the context window from
max_position_embeddings(top-level, thentext_config.*). - Detects vision from
vision_configor tokenizer image/video tokens. - Detects reasoning from chat template tokens (
enable_thinking,reasoning_content,think, etc.).
- Fetches metadata from Hugging Face (
- Registers a provider
mlxcel-auto(default URL) ormlxcel-auto-<host>-<port>viapi.registerProvider()withopenai-completionsand safecompatflags. - Caches results under
~/.pi/agent/extensions-data/mlxcel-auto-cache.json. - Re-probes on
session_startso a freshly started server is picked up automatically.
pi install git:github.com/sng2c/pi-mlxcel-autoThen in pi:
/reload
/model
mlxcel serve --model mlx-community/gemma-3-4b-it-qat-4bit
# or: mlxcel-server -m mlx-community/Qwen3.5-0.8B-4bit --port 8080MLXCEL_AUTO_BASEURLS=https://ml.my-server.com:8443MLXCEL_AUTO_BASEURLS=http://127.0.0.1:8080,https://ml.my-server.com:8443Run pi (or /reload if already running). Re-probe manually with /mlxcel-auto.
Select mlxcel-auto/<model> in /model. The context window is auto-detected — no manual entry.
| Variable | Default | Purpose |
|---|---|---|
MLXCEL_AUTO_BASEURLS |
http://127.0.0.1:8080 |
Comma-separated server base URLs. Supports http and https. Scheme is optional (defaults to http). |
MLXCEL_AUTO_APIKEY |
not-needed |
API key sent to the server |
MLXCEL_AUTO_MAXOUT |
32768 |
Cap on maxTokens; also used as fallback context window when detection fails |
MLXCEL_AUTO_NO_REASONING |
(off) | 1 disables automatic reasoning/thinking detection |
MLXCEL_AUTO_NO_CACHE |
(off) | 1 disables the on-disk config cache |
MLXCEL_DEFAULT_ORG |
mlx-community |
Org tried first for bare model names. Falls back to HF search API on 404 |
- reasoning: detected from chat template tokens (
enable_thinking/reasoning_content/clear_thinking/think). When detected,reasoning: true,compat.thinkingFormat: "qwen-chat-template", andthinkingLevelMaphides intermediate levels (minimal/low/medium/xhigh→null) keeping onlyoff(disable) +high(enable), since MLX treatsenable_thinkingas a boolean toggle. SetMLXCEL_AUTO_NO_REASONING=1to opt out. - context window: resolved from the server's effective per-slot
context_size(/healthor/slots) when--ctx-sizeis set explicitly; otherwise falls back to the model's max fromconfig.json(max_position_embeddings). This prevents pi from assuming a larger window than the server actually allocated. - vision: detected from
vision_configor tokenizer image/video tokens. Maps toinput: ["text","image"]. Video/audio are not expressible in pi's modelinputfield (text/image only). - stop-token trim: a
message_endhook strips trailing leaked stop tokens (e.g. Qwen<|im_end|>, Gemma<end_of_turn>, GLM ``) from finalized assistant messages formlxcel-automodels only. Per-model string `eos_token` from config/tokenizer_config is also used when available. - metadata source: remote-only (Hugging Face). Bare names are resolved as
MLXCEL_DEFAULT_ORG/<name>(defaultmlx-community). Models not found on HF (404) are skipped — they won't appear in/model. No local file reading — works identically for mlxcel, mlx-lm, or any OpenAI-compatible server. - default org:
mlxcel-serverreports the bare snapshot directory name in/v1/modelseven when launched with a fullowner/namerepo id. Bare names are resolved asMLXCEL_DEFAULT_ORG/<name>(defaultmlx-community). If the org guess is wrong (404), fallback context is used. Override withMLXCEL_DEFAULT_ORG. reasoningdefaults tofalsewhen not detected. Add amlxcelprovider in~/.pi/agent/models.jsonto override per model — this extension uses themlxcel-autoprovider id so there is no collision.- If you launch with
--alias <custom>the id is not a repo id and cannot be resolved; fall back to a manualmodels.jsonentry in that case. - HTTPS: set
MLXCEL_AUTO_BASEURLS=https://...to connect to a remote or TLS-terminated mlxcel-server. Bothhttpandhttpsare fully supported.
~/.pi/agent/extensions-data/mlxcel-auto-cache.json maps each model id (as returned by /v1/models) to:
| field | description |
|---|---|
modelMaxCtx |
model max context from config.json (max_position_embeddings, top-level or text_config.*), else tokenizer_config.model_max_length, else MLXCEL_AUTO_MAXOUT |
vision |
from vision_config, tokenizer image/video tokens, or chat-template ids |
reasoning |
from chat-template ids (enable_thinking / reasoning_content / clear_thinking / think); disabled by MLXCEL_AUTO_NO_REASONING=1 |
eosToken |
config.eos_token_id or tokenizer_config.eos_token (string or id array); used for stop-token trim |
The registered contextWindow is the server's effective per-slot context_size (/health or /slots) when --ctx-size is set explicitly, otherwise modelMaxCtx.
- Cache hit: cached metadata is used as-is. Hugging Face is never re-queried — even if the model is later removed from HF, the cached entry keeps the model working locally.
- Cache miss + HF found: metadata is fetched and cached permanently.
- Cache miss + HF 404: the model is skipped — it won't appear in
/model. - Manual refresh: delete
~/.pi/agent/extensions-data/mlxcel-auto-cache.json(or the specific entry) and re-run/mlxcel-auto.
Inspect from pi with /mlxcel-auto-info [substring].
MIT