1---
2name: updating-llm-client-model-lists
3description: Synchronizes model configurations across Zed, Crush, Pi, and ECA from Plexus' /v1/models endpoint. Use when the user asks to update model lists, sync models, refresh available models, or mentions Plexus model availability.
4---
5
6Updates four LLM client configs from the Plexus proxy's available models.
7
8## max_completion_tokens
9
10Always use `floor(context_length * 0.2)` as the max_completion_tokens value for all clients. Do NOT use the `top_provider.max_completion_tokens` field from the API — some models report their entire context window as max completion tokens, which is not a sensible default. 20% of context length is a more practical cap.
11
12## Network reachability
13
141. Ping `harp-willow.snowy-egret.ts.net` once
152. If unreachable and Tailscale DNS is disabled, enable it:
16 ```bash
17 tailscale set --accept-dns=true
18 ```
193. Test ping again. If still unreachable, STOP and inform the user
20
21Remember to disable after finishing the whole process if it was previously disabled.
22
23```bash
24tailscale set --accept-dns=false
25```
26
27## Fetch Plexus models
28
29```bash
30curl -s http://harp-willow.snowy-egret.ts.net:4000/v1/models | \
31 jq -r '.data[]
32 | select(.id | IN("nomic-embed-text-v1.5", "diff-apply", "fix-json") | not)
33 | select(.context_length != null and .context_length > 0)
34 | [.id, (.name // .id), (.context_length | tostring),
35 ((.context_length * 0.2 | floor | tostring)),
36 (if (.supported_parameters | index("reasoning")) then "reasoning" else "" end),
37 (if (.architecture.input_modalities | index("image")) then "image" else "" end)]
38 | @tsv' | column -t -s $'\t'
39```
40
41This should provide all the info you need in a table. The data in this table is the same as what you'd get directly querying Plexus. The display names are the same. You do not need to query Plexus any other way. Review the display names in the table, and if they need modification, make the modification while editing the configs.
42
43## Rules
44
45- Always exclude `nomic-embed-text-v1.5` (embedding model, not supported by any client)
46- Exclude `diff-apply` and `fix-json` from all client model lists
47- Exclude models with no `context_length` field (e.g. voxtral-small, mistral-ocr) unless the user provides values manually
48- Assume every listed model supports tools, regardless of whether Plexus reports `tools` in `supported_parameters`
49- Omit special characters from display names. For example, "MiniMax-M2.7" should become "MiniMax M2.7". "nemotron-3-super" becomes "Nemotron 3 Super".
50
51## Update Zed config
52
53File: `~/.config/zed/settings.json`
54
55Update `language_models.openai_compatible.Plexus.available_models[]`. Each entry:
56
57```json
58{
59 "name": "<id>",
60 "display_name": "<name>",
61 "max_tokens": <context_length>,
62 "max_completion_tokens": <max_completion_tokens>,
63 "capabilities": {
64 "chat_completions": true,
65 "prompt_cache_key": false,
66 "tools": true,
67 "parallel_tool_calls": true,
68 "images": <true if "image">
69 }
70}
71```
72
73## Update Crush config
74
75File: `~/.local/share/chezmoi/dot_config/crush/crush.json`
76
77Update `providers.plexus.models[]`. Each entry:
78
79```json
80{
81 "id": "<id>",
82 "name": "<name>",
83 "context_window": <context_length>,
84 "default_max_tokens": <max_completion_tokens>,
85 "can_reason": <true if "reasoning">,
86 "supports_attachments": <true if "image">
87}
88```
89
90After editing: `chezmoi apply ~/.config/crush/crush.json`
91STOP if chezmoi has any output other than success.
92
93## Update Pi config
94
95File: `~/.local/share/chezmoi/dot_config/pi/models.json`
96
97Update `providers.plexus.models[]`. Each entry:
98
99```json
100{
101 "id": "<id>",
102 "name": "<name>",
103 "reasoning": <true if "reasoning">,
104 "input": <["text"] or ["text", "image"]>,
105 "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 },
106 "contextWindow": <context_length>,
107 "maxTokens": <max_completion_tokens>,
108 "compat": {
109 "supportsReasoningEffort": <true if "reasoning">,
110 "supportsDeveloperRole": false
111 }
112}
113```
114
115After editing: `chezmoi apply ~/.config/pi/models.json`
116NEVER use `--force` with chezmoi apply. If it reports the file has changed since last write, STOP and inform the user — they may have local changes not yet added to chezmoi.
117
118## Update ECA config
119
120Reference docs: <https://eca.dev/config/introduction/> and <https://eca.dev/config/models/>
121
122File: `~/.config/eca/config.json`
123
124Update `providers.plexus`. ECA custom providers use an OpenAI-compatible provider config with a static model map:
125
126```json
127{
128 "api": "openai-chat",
129 "url": "http://100.77.116.78:4000/v1",
130 "key": "${cmd:fnox get PLEXUS_API_KEY}",
131 "reasoningHistory": "all",
132 "fetchModels": false,
133 "models": {
134 "<id>": {}
135 }
136}
137```
138
139ECA's custom-provider docs list `api`, `url`, `key`, and `models` as the important fields for OpenAI-compatible providers. Use `api: "openai-chat"` for Plexus, because Plexus exposes `/v1/chat/completions`. Set `fetchModels: false` so ECA uses the Plexus model list from this config rather than attempting dynamic discovery from models.dev.