@zenera/cli 1.1.28 → 1.1.29

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 (43) hide show
  1. package/README.md +73 -24
  2. package/dist/audit.d.ts +2 -2
  3. package/dist/audit.js +11 -4
  4. package/dist/candidates.d.ts +9 -0
  5. package/dist/candidates.js +17 -0
  6. package/dist/catalog.d.ts +10 -5
  7. package/dist/catalog.js +93 -12
  8. package/dist/commands/completion.d.ts +9 -0
  9. package/dist/commands/completion.js +70 -0
  10. package/dist/commands/index.js +2 -0
  11. package/dist/commands/init.js +1 -1
  12. package/dist/commands/key.js +142 -11
  13. package/dist/commands/meta.d.ts +3 -0
  14. package/dist/commands/meta.js +134 -29
  15. package/dist/commands/models.js +56 -98
  16. package/dist/completion-install.d.ts +16 -0
  17. package/dist/completion-install.js +85 -0
  18. package/dist/completion.d.ts +9 -0
  19. package/dist/completion.js +93 -0
  20. package/dist/keys.d.ts +27 -4
  21. package/dist/keys.js +63 -3
  22. package/dist/liveness.js +73 -3
  23. package/dist/main.js +22 -0
  24. package/dist/postinstall.d.ts +2 -0
  25. package/dist/postinstall.js +10 -0
  26. package/dist/sandbox.js +4 -3
  27. package/dist/term.d.ts +2 -0
  28. package/dist/term.js +2 -0
  29. package/dist/tui/links.d.ts +2 -0
  30. package/dist/tui/links.js +31 -7
  31. package/dist/tui/models.d.ts +5 -0
  32. package/dist/tui/models.js +21 -14
  33. package/dist/validate.js +2 -2
  34. package/package.json +8 -6
  35. package/postinstall.mjs +7 -0
  36. package/templates/completions/zen.bash +16 -0
  37. package/templates/completions/zen.fish +22 -0
  38. package/templates/completions/zen.zsh +28 -0
  39. package/templates/editor/.github/copilot-instructions.md +5 -4
  40. package/templates/editor/.github/prompts/spec-edit.prompt.md +250 -0
  41. package/templates/editor/.github/skills/zen-cli/SKILL.md +2 -2
  42. package/templates/editor/.github/skills/zen-cli/references/keys.md +27 -2
  43. package/templates/editor/.github/skills/zen-cli/references/models.md +22 -23
@@ -0,0 +1,28 @@
1
+ # zen completion for zsh. Add to ~/.zshrc:
2
+ #
3
+ # eval "$(zen completion zsh)"
4
+ #
5
+ # Everything it offers comes from `zen __complete`; when that has nothing to
6
+ # say, file names are completed instead.
7
+ _zen() {
8
+ local line
9
+ local -a items
10
+ for line in "${(@f)$("${words[1]}" __complete "${(@)words[2,CURRENT]}" 2>/dev/null)}"; do
11
+ [[ -n $line ]] || continue
12
+ if [[ $line == *$'\t'* ]]; then
13
+ items+=("${${line%%$'\t'*}//:/\\:}:${line#*$'\t'}")
14
+ else
15
+ items+=("${line//:/\\:}")
16
+ fi
17
+ done
18
+ if (( $#items )); then
19
+ _describe -t zen-words 'zen' items
20
+ else
21
+ _files
22
+ fi
23
+ }
24
+
25
+ if (( ! $+functions[compdef] )); then
26
+ autoload -Uz compinit && compinit
27
+ fi
28
+ compdef _zen zen zn zenera
@@ -1834,11 +1834,12 @@ zen models test <ref> # one real call, one verdict
1834
1834
  enable …` line.
1835
1835
  - **no answer** - the network. Try again.
1836
1836
 
1837
- Either run the printed fix, or take a model that works and put the ref it prints
1838
- into `agents.yaml`:
1837
+ Either run the printed fix, or take a model that works and put its ref into
1838
+ `agents.yaml`:
1839
1839
 
1840
1840
  ```sh
1841
- zen models pick --embedding # or --chat; the ref goes to stdout, alone
1841
+ zen models ls --embeddings # or --chat; what this account is served
1842
+ zen models test <ref> # the one you chose actually answers
1842
1843
  ```
1843
1844
 
1844
1845
  Then re-run `zen check`.
@@ -1996,7 +1997,7 @@ candidates; these are the judgements to make about each one)**
1996
1997
  | Answers from stale knowledge of the world | Grant `web_search` + `web_read`, and say when - §3.8 |
1997
1998
  | Cites a page it only saw the excerpt of | A prompt line: `web_read` before quoting - §3.8 |
1998
1999
  | Every web call refuses | No Exa key: `zen key add exa` - `zen check` warns - §3.8 |
1999
- | A model or embedder refuses every call | `zen models test <ref>` - if `blocked`, `zen models pick` - §8 |
2000
+ | A model or embedder refuses every call | `zen models test <ref>` - if `blocked`, `zen models ls` - §8 |
2000
2001
  | Answers instead of routing | Router prompt prohibition; check `handoffs:` |
2001
2002
  | Routes to the wrong specialist | The target agents' `description:` fields |
2002
2003
  | Gets stuck in the agent it routed to | The target needs a handoff back - §6.3 |
@@ -0,0 +1,250 @@
1
+ ---
2
+ description: Change SPECIFICATION.md as the request after the command asks - written in the specification's own structure and voice, checked against what the runtime can actually do - and nothing else.
3
+ argument-hint: what to add, change or remove in the specification
4
+ ---
5
+
6
+ Edit `SPECIFICATION.md` the way the request after this command asks. The
7
+ specification is the intent of the project; you are changing the intent, not
8
+ the implementation. Making the project match it is `/spec-sync-project`, which
9
+ runs after this.
10
+
11
+ You change one file: `SPECIFICATION.md`. Not `agents.yaml`, not a prompt, not a
12
+ skill, not `SPECIFICATION-FEEDBACK.md`.
13
+
14
+ ## 0. Everything you need is already attached
15
+
16
+ These files are attached to this prompt so the work starts without a round of
17
+ reads. Use them as they are; do not read them again with a tool.
18
+
19
+ The project:
20
+
21
+ - [SPECIFICATION.md](../../SPECIFICATION.md) - the file you are editing.
22
+ - [SPECIFICATION-FEEDBACK.md](../../SPECIFICATION-FEEDBACK.md) - the questions
23
+ still open against it, and the ones already answered. It may not exist; that
24
+ only means nothing is open.
25
+
26
+ What the runtime can do, so that what you write is something it can build:
27
+
28
+ - [zen-cli](../skills/zen-cli/SKILL.md) - every `zen` command, and
29
+ [its models reference](../skills/zen-cli/references/models.md) - how to find
30
+ which models this machine can actually use.
31
+ - [zen-instructions](../skills/zen-instructions/SKILL.md) - house rules: what
32
+ every agent is told, and what belongs there rather than in a prompt.
33
+ - [zen-topology](../skills/zen-topology/SKILL.md) - one agent or several,
34
+ hand-off or fork, and what each costs.
35
+ - [zen-memory](../skills/zen-memory/SKILL.md) - what memory is, who may read and
36
+ write it, and what a strategy for it has to say.
37
+ - [zen-rag-docs](../skills/zen-rag-docs/SKILL.md) - an index over a folder of
38
+ markdown documents.
39
+ - [zen-rag-schema](../skills/zen-rag-schema/SKILL.md) - an index over an OpenAPI
40
+ description.
41
+ - [zen-sandbox](../skills/zen-sandbox/SKILL.md) - the container: what it mounts,
42
+ what it can reach, what persists.
43
+ - [zen-code-python](../skills/zen-code-python/SKILL.md) - reusable scripts as
44
+ tools, where they live, and which agents own them.
45
+
46
+ If any of these did not arrive attached - your editor does not resolve links in
47
+ prompt files - read all of them in **one** batch of parallel reads before doing
48
+ anything else, `SPECIFICATION-FEEDBACK.md` included if it exists. Never one at a
49
+ time, and never skip one because the request seems not to need it: a request
50
+ about an agent's job can still decide what that agent may remember.
51
+
52
+ In the same first step, run once from the project root and keep the output:
53
+
54
+ ```sh
55
+ zen models && zen models ls --chat && zen models ls --embeddings
56
+ ```
57
+
58
+ That is the list of models with a credential on this machine - the only ones a
59
+ **Models** line may name. A model the request names that is not in it: run
60
+ `zen models search <name>` once; if it is still absent, say so in the chat and
61
+ do not write it.
62
+
63
+ If there is no request after the command, ask what to change and stop.
64
+
65
+ ## 1. Understand the request against what is there
66
+
67
+ Before writing a line, work out:
68
+
69
+ - **Whether this is defining the project from the initial scaffold or editing an
70
+ existing domain specification.** A freshly initialised `SPECIFICATION.md` is a
71
+ generic placeholder ("Carry out work inside a workspace on request…",
72
+ "Currently: no steps", "the only agent; nobody to hand work to") written as
73
+ meta-commentary about what each section does. When the request asks to make or
74
+ define a specification for a project or domain on top of that scaffold, it
75
+ reaches **every** section: replace all generic template sentences and
76
+ meta-explanations with a complete, concrete specification for that domain.
77
+ When `SPECIFICATION.md` already describes a real domain project and the
78
+ request asks for a specific change, keep the pass narrow and touch only the
79
+ sections the change implicates.
80
+ - **Which sections the request touches.** Usually more than the one it names: a
81
+ new agent changes **Agents**, **Tools and boundaries** and **Done means**; an
82
+ index changes **Setup**, **Knowledge** and **Environment**.
83
+ - **What it contradicts.** A sentence already in the specification that the
84
+ request makes false is part of the edit - change it too, and report it.
85
+ - **What it settles in the feedback file.** An open question the request
86
+ answers, or an answered one it reverses. Do not edit the feedback file; say
87
+ which questions in the chat.
88
+ - **Whether the runtime can do it.** Check the request against the skills above.
89
+ Something no tool, agent setting or script can provide is not written into the
90
+ specification as if it could be: say so in the chat, offer the nearest thing
91
+ the runtime does do, and write that only if the request leaves no doubt it is
92
+ wanted.
93
+
94
+ ## 2. The structure of a specification
95
+
96
+ Keep the sections the file already has, in its order. Add a section only when
97
+ the request needs one, at its place in this order, and leave out any section
98
+ that would be empty:
99
+
100
+ ```markdown
101
+ # Specification
102
+
103
+ ## Purpose
104
+
105
+ ## Scope
106
+
107
+ ## Models
108
+
109
+ ## Setup
110
+
111
+ ## Agents
112
+
113
+ ## Tools and boundaries
114
+
115
+ ## Knowledge
116
+
117
+ ## Memory
118
+
119
+ ## Environment
120
+
121
+ ## Testing
122
+
123
+ ## Done means
124
+
125
+ ## Out of scope
126
+ ```
127
+
128
+ What each one answers:
129
+
130
+ - **Purpose** - what the system produces, and for whom, in one paragraph.
131
+ - **Scope** - what one request covers, what is in and what is not, hard numeric
132
+ bounds (when a request is refused with a count rather than truncated), and
133
+ what has to happen before the system acts.
134
+ - **Models** - every chat and embedding model by its full id from `zen models`,
135
+ and which agent or job uses which. Keep the chat model already in
136
+ `SPECIFICATION.md` unless the request asks to change it; add an embedding
137
+ model from `zen models ls --embeddings` whenever the specification uses
138
+ `memory/`, `assets/docs-db`, or `assets/schema-db`.
139
+ - **Setup** - what has to exist before a run: OpenAPI specs or reference
140
+ documents fetched, a `zen rag schema` index built in `assets/schema-db`, a
141
+ `zen rag docs` index built in `assets/docs-db`, or reference files generated.
142
+ Each is a named step `scripts/_setup.sh` runs in order; say what it produces,
143
+ from what inputs, and where it lands.
144
+ - **Agents** - one entry per agent: its name, its one job, who it hands to or
145
+ forks, and the behaviours that are specific to it. Use **zen-topology** to
146
+ choose the right shape: split into focused agents (for example, a lead
147
+ coordinator/analyst, a dedicated quantitative/code agent, and a read-only
148
+ research agent) when tasks have distinct tool boundaries or heavy code
149
+ execution (**zen-code-python**), and specify `fork` (`context: none`) when a
150
+ request compares multiple independent items or runs independent research
151
+ tracks in parallel.
152
+ - **Tools and boundaries** - what each agent may reach for (files, shell,
153
+ reusable scripts in `/workspace/scripts/`, web search/read, memory, indexes,
154
+ external APIs), what is read-only, how transient network/API errors are
155
+ retried and fallen back from, and what nothing may reach. Every capability
156
+ named here has an agent that holds it.
157
+ - **Knowledge** - each index (`assets/schema-db`, `assets/docs-db`), each skill
158
+ under `agents/skills/` (naming the skill and the concrete procedure, formulas,
159
+ API conventions, or `rag_search` rules it holds), and the concrete external
160
+ APIs or data sources the project queries (naming specific zero-key primary
161
+ APIs and endpoints, required headers and rate limits, optional free-tier
162
+ keyed APIs, and fallback order).
163
+ - **Memory** - what is worth remembering (reusable scripts as `file` nodes,
164
+ verified identifiers/mappings, API schemas, workflows) and what is not (or
165
+ how time-sensitive facts are bounded), who may read and write, and when an
166
+ agent recalls before working and commits after it - see **zen-memory**.
167
+ - **Environment** - the sandbox (`sandbox/Dockerfile`, persistence, network),
168
+ the exact languages, CLI tools, and libraries pre-installed in the image so
169
+ agents never install packages at run time, where scripts and data outputs
170
+ live under `/workspace`, and optional environment variables or credentials by
171
+ name - see **zen-sandbox**.
172
+ - **Testing** - how a change to the project is checked: `zen check`,
173
+ `scripts/_setup.sh --check`, `scripts/_setup.sh` run twice in a row reporting
174
+ `skipped` the second time, and a concrete verification request the project
175
+ must handle end-to-end.
176
+ - **Done means** - how a finished job is told from an unfinished one, written as
177
+ concrete acceptance tests in prose that a reviewer could check against a run
178
+ (exact attribution fields, script-computed numbers, verified page reads,
179
+ reusable script paths, and required sections).
180
+ - **Out of scope** - what the runtime could do that this project deliberately
181
+ does not, so nobody adds it because it seemed useful.
182
+
183
+ ## 3. How to write it
184
+
185
+ - **Replace scaffold boilerplate on a greenfield request; change the smallest
186
+ thing on an incremental edit.** When `SPECIFICATION.md` is still the initial
187
+ `zen init` scaffold or the request asks to make a specification for a new
188
+ project, rewrite every section for that domain and remove the scaffold's
189
+ generic meta-commentary ("What the work always needs belongs in the image…",
190
+ "Currently: no steps…", "The reply names what changed, file by file…"). When
191
+ editing an already-written domain specification, leave every sentence the
192
+ request does not reach as it is.
193
+ - **Write in a direct, declarative voice.** Match the clean heading and list
194
+ structure of the specification, stating concrete project rules rather than
195
+ abstract explanations of how Zenera works.
196
+ - **Say what and why, never raw config syntax.** The specification is not
197
+ `agents.yaml` in prose. Name the agents, skills, setup steps, indexes, APIs,
198
+ packages, paths, and behavioural rules clearly, without pasting raw YAML
199
+ snippets or shell implementation internals that `/spec-sync-project` derives.
200
+ - **Turn high-level domain requests into concrete architectural choices.** When
201
+ a request asks to design a project in broad terms (for example, "make a
202
+ specification for financial analytics using open APIs"), do not repeat vague
203
+ phrases like "open APIs" or "packages for data analysis". Make the concrete
204
+ domain choices upfront so `/spec-sync-project` can build a working system
205
+ without guessing:
206
+ - Name specific, working zero-key public APIs and endpoints as primary
207
+ sources (with required headers such as `User-Agent` and rate limits),
208
+ optional keyed free-tier APIs as secondary sources with clean zero-key
209
+ fallback when keys are absent, and `web_search` / `web_read` rules.
210
+ - Name the concrete setup steps (`scripts/<name>.sh`), indexes
211
+ (`assets/schema-db`, `assets/docs-db`), and domain skills under
212
+ `agents/skills/`.
213
+ - Name the exact Python/system libraries to pre-install in
214
+ `sandbox/Dockerfile` and the `/workspace/scripts/` and `/workspace/data/`
215
+ conventions from **zen-code-python**.
216
+ - State explicit numeric limits (such as the maximum entities/tickers per
217
+ request before refusing with a count), retry/fallback rules, and required
218
+ citation fields.
219
+ - **Be specific where a reader could decide either way.** A limit is a number,
220
+ a model is an id, a failure has a stated outcome. "Handles large inputs" is
221
+ not implementable; "a request over 25 tickers is refused with a count, never
222
+ truncated" is.
223
+ - **Never invent a model id or a user-owned secret.** Keep the model already in
224
+ `SPECIFICATION.md` unless the request asks to change it, and take any new
225
+ chat or embedding model strictly from the `zen models` output on this machine,
226
+ never from memory. Ask before editing only when a required value belongs
227
+ exclusively to the user (such as a private server URL or proprietary rule)
228
+ and cannot be satisfied by a standard public default.
229
+ - **Make it checkable.** Every behaviour the request adds gets a line under
230
+ **Done means** that a reviewer could verify against a recorded run.
231
+ - **Name what is now excluded.** When the request narrows the system, the thing
232
+ it rules out goes under **Out of scope**.
233
+ - **Say it once.** If the rule already lives in another section, change it
234
+ there rather than stating it a second time somewhere new.
235
+
236
+ ## 4. Report
237
+
238
+ In the chat:
239
+
240
+ - every section you changed, with each new or changed line quoted
241
+ - every edit the request did not name but made necessary, and why
242
+ - every open question in `SPECIFICATION-FEEDBACK.md` the change settles or
243
+ reopens, by number
244
+ - anything you did not write because the runtime cannot do it, or because it
245
+ needs a value only the reader has
246
+ - then, in one line: send `/spec-sync-project` to make the project match.
247
+
248
+ ## 5. User Request:
249
+
250
+ Following is the user request that the specification should address (if any):
@@ -22,7 +22,7 @@ zen run [project] [prompt] [options]
22
22
  zen run batch --input <file> [--batch-dir <dir>] [--concurrency <n>] [--memory-read-only]
23
23
  zen open [project] [--editor <cmd>] [--wait]
24
24
  zen key <ls|add|use|check|rm|show|env> [ref] [options]
25
- zen models <providers|ls|search|show|test|pick> [ref] [options]
25
+ zen models <providers|ls|search|show|test|browse> [ref] [options]
26
26
  zen check [name|dir] [--project <name|dir>] [--no-sandbox] [--no-models] [--strict] [--quiet]
27
27
  zen inspect [report|graph|node|ask] [run] [--dir <run dir>] [--part <name>] [--full] [--open]
28
28
  zen memory [stats|ls|search|grep|show|export|merge|forget] [args] [options]
@@ -80,7 +80,7 @@ zen export the project as a zip you can send
80
80
  zen import a.zip unpack one somebody sent, run nothing in it
81
81
  zen key ls --check which credentials still work
82
82
  zen models test <ref> whether one model actually answers
83
- zen models pick --embedding the first embedder that does, on stdout
83
+ zen models ls --embeddings the embedders this machine can reach
84
84
  zen meta run acme /analyze --json > analyze.json a stored prompt, the result as JSON
85
85
  ```
86
86
 
@@ -1,7 +1,7 @@
1
1
  # Credentials - `zen key`
2
2
 
3
3
  ```
4
- zen key <ls|add|use|check|rm|show|env> [ref] [options]
4
+ zen key <ls|add|use|mode|check|rm|show|env> [ref] [options]
5
5
  ```
6
6
 
7
7
  Alias: `keys`.
@@ -20,6 +20,7 @@ keys; one of them is active.
20
20
  | `zen key ls [--check]` | Everything stored, and its state |
21
21
  | `zen key add <provider>[/name]` | Read a key from stdin, or ask for it |
22
22
  | `zen key use <provider>/<name>` | Choose which one a run uses |
23
+ | `zen key mode [direct\|bifrost]` | Call vendors directly, or via a gateway |
23
24
  | `zen key check [provider[/name]]` | Ask the provider whether it still works |
24
25
  | `zen key rm <provider>/<name>` | Forget one |
25
26
  | `zen key show <ref> [--reveal]` | Masked by default |
@@ -49,8 +50,32 @@ echo-off prompt and from nowhere else.
49
50
  | `vertex` | `VERTEX_API_KEY` | secret | an express-mode key from GCP |
50
51
  | `openrouter` | `OPENROUTER_API_KEY` | secret | openrouter.ai/settings/keys |
51
52
  | `exa` | `EXA_API_KEY` | secret | dashboard.exa.ai/api-keys |
53
+ | `bifrost` | `BIFROST_API_KEY` | secret | a virtual key from your Bifrost |
52
54
 
53
- `exa` is a service the tools call, not a model provider.
55
+ `exa` is a service the tools call, not a model provider. `bifrost` is a
56
+ gateway: see below.
57
+
58
+ ### Gateway mode - every model through Bifrost
59
+
60
+ ```
61
+ zen key add bifrost --url https://bifrost.example.com # the virtual key, prompted
62
+ zen key mode bifrost # from now on, every run
63
+ zen key mode direct # back to vendor keys
64
+ ```
65
+
66
+ In `bifrost` mode a run exports `BIFROST_API_KEY` and `BIFROST_BASE_URL` and
67
+ **withholds every vendor key**. The runtime then sends every model and every
68
+ embedding through the gateway, each in its own vendor's protocol, and
69
+ `agents.yaml` does not change: `vertex:gemini-3.5-flash` reaches
70
+ `<url>/genai` as `vertex/gemini-3.5-flash`, `anthropic:*` reaches
71
+ `<url>/anthropic`, `openai:*` and `openrouter:*` reach `<url>/openai`.
72
+ Declared providers are rerouted too. `zen check` then reports
73
+ `BIFROST_API_KEY`, not the vendor variables, as the credential in use.
74
+
75
+ The switch is `BIFROST_BASE_URL` itself, so exporting it in a shell or a `.env`
76
+ turns gateway mode on without the keyring. In this mode `zen models` lists only
77
+ what the gateway serves - see `models.md`. The full guide is
78
+ [docs/gateway.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/gateway.md).
54
79
 
55
80
  ### Vertex takes either shape
56
81
 
@@ -1,7 +1,7 @@
1
1
  # Models - `zen models`
2
2
 
3
3
  ```
4
- zen models <providers|ls|search|show|test|pick|browse> [ref] [options]
4
+ zen models <providers|ls|search|show|test|browse> [ref] [options]
5
5
  ```
6
6
 
7
7
  Alias: `model`.
@@ -20,17 +20,14 @@ but a credential.
20
20
  | `zen models search <query>` | Narrow it |
21
21
  | `zen models show <ref>` | One model, every field the vendor gave |
22
22
  | `zen models test <ref> …` | One real minimal call per ref, and a verdict |
23
- | `zen models pick` | The first ref that answers, printed on stdout |
24
23
  | `zen models browse` | Interactive TUI for a person; needs a terminal |
25
24
 
26
25
  Filters, on `ls` and `search`: `--chat`, `--embeddings`, `--images`, `--audio`,
27
26
  `--tools`, `--vision`, `--free`, `--min-context <n>`, `--provider <name>`,
28
27
  `--limit <n>`, `--all`, `--refresh`.
29
28
 
30
- `pick` requires `--chat` or `--embedding`, and takes `--provider` and `--limit`.
31
-
32
29
  `browse` is for a person at a terminal and refuses without one (exit 2). An
33
- agent wants `ls --json`, `search` or `pick` instead.
30
+ agent wants `ls --json` or `search` instead.
34
31
 
35
32
  ## Where the lists come from
36
33
 
@@ -43,6 +40,19 @@ it was - `--json` carries `source` per model and `origin` per provider.
43
40
 
44
41
  `zen models` on its own does **not** go to the network. `ls` and `search` do.
45
42
 
43
+ ### In gateway mode
44
+
45
+ After `zen key mode bifrost`, every listing is **what the gateway serves**,
46
+ not what the vendors do: one `GET <url>/v1/models`, split by its
47
+ `<upstream>/<id>` names back into refs (`vertex/gemini-3.5-flash` lists as
48
+ `vertex:gemini-3.5-flash`). Upstreams no zen provider names (bedrock, groq, ...)
49
+ are left out, and there is no built-in fallback list. Each command says so on
50
+ stderr with a `⇄ bifrost mode` line, `browse` carries the same badge on every
51
+ screen, and `--json` adds a `gateway` field. `zen models` then does go to the
52
+ network, since one request covers every provider; `test` asks through the
53
+ gateway too. The full guide is
54
+ [docs/gateway.md](https://github.com/andreyryabov/ZeneraNeo/blob/main/docs/gateway.md).
55
+
46
56
  ## Testing a model
47
57
 
48
58
  ```
@@ -77,30 +87,19 @@ $ zen models test vertex:gemini-embedding-001
77
87
  vertex:gemini-embedding-001 blocked Vertex AI API has not been used in project my-proj …
78
88
  fix vertex:gemini-embedding-001 gcloud services enable aiplatform.googleapis.com --project my-proj
79
89
  error 1 of 1 did not answer
80
- find one that does: zen models pick --embedding
90
+ see what else there is: zen models ls --embeddings
81
91
  ```
82
92
 
83
- Two ways out. Run the `gcloud` line, or take a different model:
93
+ Two ways out. Run the `gcloud` line, or take a different model: list what the
94
+ account serves, test the one you want, and put its ref where the old one was.
84
95
 
85
96
  ```
86
- $ zen models pick --embedding
87
- openai:text-embedding-3-small
97
+ $ zen models ls --embeddings
98
+ $ zen models test openai:text-embedding-3-small
99
+ openai:text-embedding-3-small answers 412ms 1536 dims
88
100
  ```
89
101
 
90
- `pick` tries a short ordered list one at a time and stops at the first that
91
- works. Sequential on purpose - the goal is one working ref, not a survey. The
92
- ref goes to **stdout alone and unstyled**, so it substitutes directly:
93
-
94
- ```sh
95
- zen rag schema index --embedding "$(zen models pick --embedding)" ./specs/*.yaml
96
- ```
97
-
98
- `zen models pick --embedding --json` gives `{ref, provider, model, role,
99
- dimensions, ms, tried}` - `tried` lists every candidate and why it was passed
100
- over, so a caller can see _why_ a provider was skipped rather than only that it
101
- was.
102
-
103
- When nothing answers, exit `4` and the table of everything tried.
102
+ Test one model, not the whole list - each test is a billable call.
104
103
 
105
104
  ## What it will not do
106
105