@zenera/cli 1.1.37 → 1.1.40
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/README.md +158 -900
- package/dist/commands/index.js +6 -7
- package/dist/commands/sandbox.js +5 -5
- package/dist/external.js +1 -1
- package/dist/podman.js +3 -3
- package/dist/resources.d.ts +2 -2
- package/dist/resources.js +5 -5
- package/package.json +7 -7
- package/templates/editor/.github/skills/zen-cli/SKILL.md +3 -3
- package/templates/editor/.github/skills/zen-cli/references/frame.md +2 -2
- package/templates/editor/.github/skills/zen-cli/references/{faker.md → gym.md} +45 -40
- package/templates/editor/.github/skills/zen-cli/references/keys.md +2 -2
- package/templates/editor/.github/skills/zen-cli/references/models.md +1 -1
- package/templates/editor/.github/skills/zen-cli/references/rag.md +1 -1
- package/templates/editor/.vscode/agents.schema.json +1 -1
package/dist/commands/index.js
CHANGED
|
@@ -56,19 +56,18 @@ export const ALIASES = {
|
|
|
56
56
|
mem: 'memory',
|
|
57
57
|
edit: 'open',
|
|
58
58
|
code: 'open',
|
|
59
|
-
mock: 'faker',
|
|
60
59
|
pack: 'export',
|
|
61
60
|
archive: 'export',
|
|
62
61
|
unpack: 'import',
|
|
63
62
|
share: 'export',
|
|
64
63
|
};
|
|
65
64
|
export const EXTERNAL = {
|
|
66
|
-
|
|
67
|
-
package: '@zenera/
|
|
68
|
-
summary: '
|
|
69
|
-
usage: 'zen
|
|
70
|
-
install: 'npm i -g @zenera/
|
|
71
|
-
banner: { head: 'Zenera', accent: '
|
|
65
|
+
gym: {
|
|
66
|
+
package: '@zenera/gym',
|
|
67
|
+
summary: 'Simulated API environments for agent training and evaluation.',
|
|
68
|
+
usage: 'zen gym <serve|build|cache|model> [spec...]',
|
|
69
|
+
install: 'npm i -g @zenera/gym',
|
|
70
|
+
banner: { head: 'Zenera', accent: 'Gym', subtitle: 'Agent Environments', hue: 'mint' },
|
|
72
71
|
},
|
|
73
72
|
rag: {
|
|
74
73
|
package: '@zenera/rag',
|
package/dist/commands/sandbox.js
CHANGED
|
@@ -136,7 +136,7 @@ async function status(project, image, asJson) {
|
|
|
136
136
|
const found = await podmanStatus({ image });
|
|
137
137
|
const all = found.ready ? await ownedContainers(found.engine) : [];
|
|
138
138
|
// A container belongs to a session, and a session belongs to a project, so
|
|
139
|
-
// a report about one project must not list another's — or the
|
|
139
|
+
// a report about one project must not list another's — or the gym's,
|
|
140
140
|
// which wears the same label and belongs to no project at all.
|
|
141
141
|
const containers = project ? ofProject(project.dir, all) : all;
|
|
142
142
|
const idle = all.length > 0 ? idleContainers(all, await sessionOwners()) : [];
|
|
@@ -507,18 +507,18 @@ function projectRows(projects, loose) {
|
|
|
507
507
|
]);
|
|
508
508
|
}
|
|
509
509
|
if (loose.length > 0) {
|
|
510
|
-
// Containers whose session directory is gone, and
|
|
510
|
+
// Containers whose session directory is gone, and gym's, which are
|
|
511
511
|
// labelled the same way and belong to no project at all.
|
|
512
512
|
const size = loose.reduce((n, c) => n + (c.size ?? 0), 0);
|
|
513
|
-
const
|
|
513
|
+
const gyms = loose.filter((c) => c.key?.startsWith('gym-')).length;
|
|
514
514
|
rows.push([
|
|
515
515
|
dim('(unclaimed)'),
|
|
516
516
|
dim('—'),
|
|
517
517
|
dim('—'),
|
|
518
518
|
dim(String(loose.length)),
|
|
519
519
|
dim(bytes(size)),
|
|
520
|
-
dim(
|
|
521
|
-
? `zen
|
|
520
|
+
dim(gyms === loose.length
|
|
521
|
+
? `zen gym ${gyms === 1 ? 'server' : 'servers'}, no project`
|
|
522
522
|
: 'no session owns these'),
|
|
523
523
|
]);
|
|
524
524
|
}
|
package/dist/external.js
CHANGED
|
@@ -11,7 +11,7 @@ import { CliError, EXIT, bold } from "./term.js";
|
|
|
11
11
|
// Loading a command out of a sibling package
|
|
12
12
|
//
|
|
13
13
|
// The specifier is built rather than written, and that is the whole mechanism:
|
|
14
|
-
// a literal `import('@zenera/
|
|
14
|
+
// a literal `import('@zenera/gym/command')` would make the sibling a
|
|
15
15
|
// compile-time dependency of `zen` — a project reference, a package.json entry,
|
|
16
16
|
// and a cycle, since the sibling already depends on `zen`. Built, it is
|
|
17
17
|
// resolved by Node at the moment the user asks for it and by nobody before.
|
package/dist/podman.js
CHANGED
|
@@ -485,9 +485,9 @@ export function idleContainers(containers, owners) {
|
|
|
485
485
|
if (c.state !== 'running') {
|
|
486
486
|
return true;
|
|
487
487
|
}
|
|
488
|
-
const
|
|
489
|
-
if (
|
|
490
|
-
return !pidAlive(Number(
|
|
488
|
+
const gym = /^gym-(\d+)$/.exec(c.key ?? '');
|
|
489
|
+
if (gym) {
|
|
490
|
+
return !pidAlive(Number(gym[1]));
|
|
491
491
|
}
|
|
492
492
|
const dir = c.key === undefined ? undefined : owners.get(c.key);
|
|
493
493
|
return dir !== undefined && !isBusy(dir);
|
package/dist/resources.d.ts
CHANGED
|
@@ -91,7 +91,7 @@ export interface MachineView {
|
|
|
91
91
|
export interface ContainerView {
|
|
92
92
|
name: string;
|
|
93
93
|
id: string;
|
|
94
|
-
kind: 'zen' | '
|
|
94
|
+
kind: 'zen' | 'gym' | 'other';
|
|
95
95
|
project?: string;
|
|
96
96
|
orphaned: boolean;
|
|
97
97
|
/** percent of one core */
|
|
@@ -128,7 +128,7 @@ export interface ResourceView {
|
|
|
128
128
|
totals: {
|
|
129
129
|
running: number;
|
|
130
130
|
zen: number;
|
|
131
|
-
|
|
131
|
+
gym: number;
|
|
132
132
|
other: number;
|
|
133
133
|
orphaned: number;
|
|
134
134
|
memory: number;
|
package/dist/resources.js
CHANGED
|
@@ -352,7 +352,7 @@ export function viewOf(now, before) {
|
|
|
352
352
|
const prior = before?.stats.find((p) => p.id === s.id);
|
|
353
353
|
const span = prior ? s.systemNano - prior.systemNano : 0;
|
|
354
354
|
const measured = prior !== undefined && span > 0;
|
|
355
|
-
const kind = !own ? 'other' : own.key?.startsWith('
|
|
355
|
+
const kind = !own ? 'other' : own.key?.startsWith('gym-') ? 'gym' : 'zen';
|
|
356
356
|
return {
|
|
357
357
|
name: s.name,
|
|
358
358
|
id: s.id,
|
|
@@ -393,7 +393,7 @@ export function viewOf(now, before) {
|
|
|
393
393
|
totals: {
|
|
394
394
|
running: containers.length,
|
|
395
395
|
zen: containers.filter((c) => c.kind === 'zen').length,
|
|
396
|
-
|
|
396
|
+
gym: containers.filter((c) => c.kind === 'gym').length,
|
|
397
397
|
other: containers.filter((c) => c.kind === 'other').length,
|
|
398
398
|
orphaned: containers.filter((c) => c.orphaned).length,
|
|
399
399
|
memory: containers.reduce((n, c) => n + c.memory, 0),
|
|
@@ -684,7 +684,7 @@ function containerHead(l, v, o) {
|
|
|
684
684
|
const t = v.totals;
|
|
685
685
|
const kinds = [
|
|
686
686
|
t.zen ? `${t.zen} zen` : '',
|
|
687
|
-
t.
|
|
687
|
+
t.gym ? `${t.gym} gym` : '',
|
|
688
688
|
t.other ? `${t.other} other` : '',
|
|
689
689
|
]
|
|
690
690
|
.filter(Boolean)
|
|
@@ -700,7 +700,7 @@ function containerHead(l, v, o) {
|
|
|
700
700
|
.filter(Boolean)
|
|
701
701
|
.join(' · '));
|
|
702
702
|
l.intro('Running ones only: a stopped container keeps its files but uses no memory or cpu. ' +
|
|
703
|
-
'zen makes one per session; zen
|
|
703
|
+
'zen makes one per session; zen gym servers and anything else in podman are listed too.');
|
|
704
704
|
if (t.running === 0) {
|
|
705
705
|
return;
|
|
706
706
|
}
|
|
@@ -796,7 +796,7 @@ const COLUMNS = [
|
|
|
796
796
|
width: 14,
|
|
797
797
|
align: 'left',
|
|
798
798
|
keep: 5,
|
|
799
|
-
cell: (c) => [sp(clipTo(c.project ?? (c.kind === '
|
|
799
|
+
cell: (c) => [sp(clipTo(c.project ?? (c.kind === 'gym' ? '(gym)' : '—'), 14))],
|
|
800
800
|
},
|
|
801
801
|
];
|
|
802
802
|
/** The columns that fit, in order, dropping the least needed until the name has room. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenera/cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.40",
|
|
4
4
|
"description": "Command-line front end for @zenera/neo: agentic projects you can run, share and commit.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
"access": "public"
|
|
16
16
|
},
|
|
17
17
|
"author": "Andrey Ryabov",
|
|
18
|
-
"homepage": "https://github.com/
|
|
18
|
+
"homepage": "https://github.com/zenera-ai/ZeneraNeo#readme",
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "git+https://github.com/
|
|
21
|
+
"url": "git+https://github.com/zenera-ai/ZeneraNeo.git",
|
|
22
22
|
"directory": "packages/cli"
|
|
23
23
|
},
|
|
24
|
-
"bugs": "https://github.com/
|
|
24
|
+
"bugs": "https://github.com/zenera-ai/ZeneraNeo/issues",
|
|
25
25
|
"type": "module",
|
|
26
26
|
"bin": {
|
|
27
27
|
"zen": "./dist/main.js",
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"@google/genai": "^2.30.0",
|
|
55
55
|
"@inkjs/ui": "^2.0.0",
|
|
56
56
|
"@openrouter/sdk": "^1.4.25",
|
|
57
|
-
"@zenera/engine": "^1.1.
|
|
58
|
-
"@zenera/neo": "^1.1.
|
|
59
|
-
"@zenera/view": "^1.1.
|
|
57
|
+
"@zenera/engine": "^1.1.40",
|
|
58
|
+
"@zenera/neo": "^1.1.40",
|
|
59
|
+
"@zenera/view": "^1.1.40",
|
|
60
60
|
"google-auth-library": "^10.0.0",
|
|
61
61
|
"ink": "^7.1.1",
|
|
62
62
|
"openai": "^6.0.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zen-cli
|
|
3
|
-
description: How to drive this project from the terminal with `zen` - running it, validating it, credentials, the sandbox, run reports, and the `
|
|
3
|
+
description: How to drive this project from the terminal with `zen` - running it, validating it, credentials, the sandbox, run reports, and the `gym` and `rag` modules.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# The `zen` command line
|
|
@@ -33,7 +33,7 @@ zen version
|
|
|
33
33
|
|
|
34
34
|
zen meta <run|prompts|resume|model|dataset> [project] [args]
|
|
35
35
|
|
|
36
|
-
zen
|
|
36
|
+
zen gym <serve|build|cache|model> [spec...]
|
|
37
37
|
zen rag schema <index|restore|ready|search|list|grep|trace|show|stats> [spec...]
|
|
38
38
|
zen rag docs <index|restore|ready|search|list|grep|show|stats> [path...]
|
|
39
39
|
```
|
|
@@ -61,7 +61,7 @@ guess a flag, and do not read them all.
|
|
|
61
61
|
| The evaluation dataset: cases, drift, notes, drawing a sample | [dataset.md](./references/dataset.md) (and `zen-dataset` skill) |
|
|
62
62
|
| Tuning the prose on the dataset: workers, applies, STATUS.md | [finetune.md](./references/finetune.md) |
|
|
63
63
|
| Sharing a project: archives, what travels, importing one safely | [export.md](./references/export.md) |
|
|
64
|
-
| `zen
|
|
64
|
+
| `zen gym` - a mock API from an OpenAPI/Swagger document | [gym.md](./references/gym.md) |
|
|
65
65
|
| `zen rag` - searching an API description, or a pile of markdown | [rag.md](./references/rag.md) |
|
|
66
66
|
|
|
67
67
|
## The short version
|
|
@@ -37,7 +37,7 @@ Not listed in help, but they work.
|
|
|
37
37
|
| `validate`, `doctor` | `check` |
|
|
38
38
|
| `report` | `inspect` |
|
|
39
39
|
| `edit`, `code` | `open` |
|
|
40
|
-
| `mock` | `
|
|
40
|
+
| `mock` | `gym` |
|
|
41
41
|
|
|
42
42
|
## stdout is the answer, stderr is the narration
|
|
43
43
|
|
|
@@ -103,7 +103,7 @@ A real environment variable always beats the keyring.
|
|
|
103
103
|
projects.json the registry: name -> directory
|
|
104
104
|
keys.json credentials (0600)
|
|
105
105
|
keys/ key files, for providers that hold a file
|
|
106
|
-
|
|
106
|
+
gym/ generator cache for `zen gym`
|
|
107
107
|
|
|
108
108
|
<project>/
|
|
109
109
|
zenera.json { version, name }
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Agent API environments - `zen gym`
|
|
2
2
|
|
|
3
3
|
```
|
|
4
|
-
zen
|
|
4
|
+
zen gym <serve|build|cache|model> [spec...]
|
|
5
5
|
```
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
`zen
|
|
7
|
+
Provided by `@zenera/gym` - `npm i -g @zenera/gym` if
|
|
8
|
+
`zen gym` says it is not installed.
|
|
9
9
|
|
|
10
10
|
Serves a mock API from one or more OpenAPI/Swagger documents. For each
|
|
11
11
|
operation a **model writes a Python generator**, which is self-tested inside a
|
|
@@ -14,17 +14,18 @@ plausible, not `"string"` repeated.
|
|
|
14
14
|
|
|
15
15
|
## Subcommands
|
|
16
16
|
|
|
17
|
-
| Command | What it does
|
|
18
|
-
| ----------------- |
|
|
19
|
-
| `serve <spec...>` | Serve the documents. Generators are written on demand
|
|
20
|
-
| `build <spec...>` | Write every generator now and exit
|
|
21
|
-
| `cache ls\|clear` | What has been generated, or throw it away
|
|
17
|
+
| Command | What it does |
|
|
18
|
+
| ----------------- | ---------------------------------------------------------- |
|
|
19
|
+
| `serve <spec...>` | Serve the documents. Generators are written on demand |
|
|
20
|
+
| `build <spec...>` | Write every generator now and exit |
|
|
21
|
+
| `cache ls\|clear` | What has been generated, or throw it away |
|
|
22
|
+
| `model [ref]` | Show or set the model; `--clear` forgets the stored choice |
|
|
22
23
|
|
|
23
24
|
```
|
|
24
|
-
zen
|
|
25
|
-
zen
|
|
26
|
-
zen
|
|
27
|
-
zen
|
|
25
|
+
zen gym serve openapi.yaml
|
|
26
|
+
zen gym serve api/*.yaml --port 9000 --seed 7
|
|
27
|
+
zen gym build openapi.yaml --concurrency 8
|
|
28
|
+
zen gym cache clear
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
`build` is the one to run in CI or before a demo: it pays for every generator up
|
|
@@ -32,23 +33,25 @@ front and exits non-zero, with a table, if any could not be written.
|
|
|
32
33
|
|
|
33
34
|
## Options
|
|
34
35
|
|
|
35
|
-
| Flag | Default
|
|
36
|
-
| ------------------- |
|
|
37
|
-
| `--port <n>` | `8787`
|
|
38
|
-
| `--host <h>` | `127.0.0.1`
|
|
39
|
-
| `--model <ref>` | project default
|
|
40
|
-
| `--image <ref>` | a baked image
|
|
41
|
-
| `--cache <dir>` | `~/.zenera/neo/
|
|
42
|
-
| `--seed <n>` | -
|
|
43
|
-
| `--attempts <n>` | `3`
|
|
44
|
-
| `--concurrency <n>` | `4`
|
|
45
|
-
| `--timeout <s>` | `30`
|
|
46
|
-
| `--max-body <n>` | 1 MB
|
|
47
|
-
| `--rebuild` | -
|
|
48
|
-
| `--no-cache` | -
|
|
49
|
-
| `--quiet` | -
|
|
36
|
+
| Flag | Default | Meaning |
|
|
37
|
+
| ------------------- | ------------------- | ----------------------------------------------- |
|
|
38
|
+
| `--port <n>` | `8787` | Port to listen on |
|
|
39
|
+
| `--host <h>` | `127.0.0.1` | Anything else is reachable off-machine |
|
|
40
|
+
| `--model <ref>` | project default | Which model writes the generators |
|
|
41
|
+
| `--image <ref>` | a baked image | Skip the baked image and use this one |
|
|
42
|
+
| `--cache <dir>` | `~/.zenera/neo/gym` | Where generators live |
|
|
43
|
+
| `--seed <n>` | - | Answer the same request the same way every time |
|
|
44
|
+
| `--attempts <n>` | `3` | Tries per generator before giving up |
|
|
45
|
+
| `--concurrency <n>` | `4` | Generators written at once |
|
|
46
|
+
| `--timeout <s>` | `30` | Seconds one generator may take |
|
|
47
|
+
| `--max-body <n>` | 1 MB | Largest request body accepted, in bytes |
|
|
48
|
+
| `--rebuild` | - | Ignore what is cached and write it again |
|
|
49
|
+
| `--no-cache` | - | Do not record what is written |
|
|
50
|
+
| `--quiet` | - | No narration |
|
|
50
51
|
|
|
51
52
|
Credentials come from the `zen` keyring - see [keys.md](keys.md).
|
|
53
|
+
Model selection: `--model`, `ZENERA_GYM_MODEL`, `~/.zenera/neo/gym.json`,
|
|
54
|
+
then the best model the available keys support.
|
|
52
55
|
|
|
53
56
|
## Serving
|
|
54
57
|
|
|
@@ -56,17 +59,19 @@ Binds the loopback address by default. On start it prints a table per document:
|
|
|
56
59
|
paths, methods, and how many operations have a response schema and therefore get
|
|
57
60
|
a generator.
|
|
58
61
|
|
|
59
|
-
| Endpoint
|
|
60
|
-
|
|
|
61
|
-
| `/
|
|
62
|
-
| `/
|
|
62
|
+
| Endpoint | Answers |
|
|
63
|
+
| --------------- | ------------------------- |
|
|
64
|
+
| `/__gym/routes` | Every route it will serve |
|
|
65
|
+
| `/__gym/health` | Whether it is up |
|
|
63
66
|
|
|
64
67
|
Response headers:
|
|
65
68
|
|
|
66
|
-
| Header
|
|
67
|
-
|
|
|
68
|
-
| `x-
|
|
69
|
-
| `x-
|
|
69
|
+
| Header | Meaning |
|
|
70
|
+
| ----------------- | ----------------------------------------------------- |
|
|
71
|
+
| `x-gym-operation` | The `operationId` that answered |
|
|
72
|
+
| `x-gym-cache` | `hit` or `miss` - whether this call cost a model turn |
|
|
73
|
+
|
|
74
|
+
Gym provides simulation, not task scoring, rewards, or a training loop.
|
|
70
75
|
|
|
71
76
|
Incoming headers are filtered: `authorization`, `cookie` and anything matching
|
|
72
77
|
`key|token|secret|password|credential` never reach a generator.
|
|
@@ -91,7 +96,7 @@ Probes are synthetic on purpose - real request bodies never reach a prompt.
|
|
|
91
96
|
|
|
92
97
|
## The cache
|
|
93
98
|
|
|
94
|
-
Generators live in the machine's shared cache, `~/.zenera/neo/cache/
|
|
99
|
+
Generators live in the machine's shared cache, `~/.zenera/neo/cache/gym-generator/`,
|
|
95
100
|
keyed by the operation's shape - so the same spec served from two directories is
|
|
96
101
|
written once, and a spec edit produces a new key rather than a stale answer. A
|
|
97
102
|
generator that a model gave up on is remembered for the life of the process, so
|
|
@@ -99,17 +104,17 @@ a hopeless operation is not re-asked on every request; a _transient_ failure - a
|
|
|
99
104
|
429, a dropped socket - is not, because it is about this minute rather than this
|
|
100
105
|
operation.
|
|
101
106
|
|
|
102
|
-
`~/.zenera/neo/
|
|
107
|
+
`~/.zenera/neo/gym/` is the container's workspace, and scratch: a cache hit is
|
|
103
108
|
copied into it, because the container can only run what is under its mount.
|
|
104
109
|
|
|
105
|
-
`zen
|
|
110
|
+
`zen gym cache ls` lists what has been generated. `zen gym cache clear`
|
|
106
111
|
removes the generators, the workspace and the container together. They have to
|
|
107
112
|
go together: the container's name is a hash of its configuration, so deleting
|
|
108
113
|
the workspace alone would leave a stopped container bind-mounted onto a
|
|
109
114
|
directory that no longer exists, and every generator would fail with
|
|
110
115
|
`python3: can't open file '/workspace/generators/…/gen.py'`.
|
|
111
116
|
|
|
112
|
-
`zen cache ls --kind
|
|
117
|
+
`zen cache ls --kind gym-generator` reaches the same entries from the other
|
|
113
118
|
side, along with everything else this machine has cached.
|
|
114
119
|
|
|
115
120
|
## Documents it accepts
|
|
@@ -77,7 +77,7 @@ turns gateway mode on without the keyring - and `zen key mode`/`ls`/`check`
|
|
|
77
77
|
report and probe it (`bifrost/$BIFROST_API_KEY`), with nothing stored. In this
|
|
78
78
|
mode `zen models` lists only
|
|
79
79
|
what the gateway serves - see `models.md`. The full guide is
|
|
80
|
-
[docs/gateway.md](https://github.com/
|
|
80
|
+
[docs/gateway.md](https://github.com/zenera-ai/ZeneraNeo/blob/main/docs/gateway.md).
|
|
81
81
|
|
|
82
82
|
### Vertex takes either shape
|
|
83
83
|
|
|
@@ -141,6 +141,6 @@ The frame does **not** materialise the keyring for you - each command that needs
|
|
|
141
141
|
a credential opens the store itself. If `zen key ls` shows a key as live and a
|
|
142
142
|
command still says `provider "openai": no api key - set OPENAI_API_KEY`, the
|
|
143
143
|
credential is fine and the command is at fault. Everything that runs a model
|
|
144
|
-
(`run`, `check`, `models`, `
|
|
144
|
+
(`run`, `check`, `models`, `gym`, `rag`) already does this.
|
|
145
145
|
|
|
146
146
|
Exit code `4` means no usable credential for what was asked.
|
|
@@ -58,7 +58,7 @@ stderr with a `⇄ bifrost mode` line, `browse` carries the same badge on every
|
|
|
58
58
|
screen, and `--json` adds a `gateway` field. `zen models` then does go to the
|
|
59
59
|
network, since one request covers every provider; `test` asks through the
|
|
60
60
|
gateway too. The full guide is
|
|
61
|
-
[docs/gateway.md](https://github.com/
|
|
61
|
+
[docs/gateway.md](https://github.com/zenera-ai/ZeneraNeo/blob/main/docs/gateway.md).
|
|
62
62
|
|
|
63
63
|
## Testing a model
|
|
64
64
|
|
|
@@ -34,7 +34,7 @@ zen rag schema index <spec...> [--embedding <ref>] [-o <dir>] [--batch <n>]
|
|
|
34
34
|
zen rag schema index openapi.yaml --embedding openai:text-embedding-3-small
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
Unlike the
|
|
37
|
+
Unlike the gym, `$ref`s are **bundled, not dereferenced**: component names are
|
|
38
38
|
the node ids and the cycles between them are the edges. `discriminator` is kept -
|
|
39
39
|
it is what turns a `oneOf` into a tagged union a compiler can narrow.
|
|
40
40
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://raw.githubusercontent.com/
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/zenera-ai/ZeneraNeo/main/packages/cli/templates/editor/.vscode/agents.schema.json",
|
|
4
4
|
"title": "Zenera Neo agents.yaml",
|
|
5
5
|
"description": "Who exists in this project, what they may reach for, and which model answers for them. Written by `zen init` and replaced by every `zen init` and `zen open`, so it describes the version of `zen` in hand. The runtime is the authority: `zen check` reads the project the way a run does.",
|
|
6
6
|
"type": "object",
|