evals-lab 0.10.0 → 0.11.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/CHANGELOG.md +41 -1
- package/README.md +8 -2
- package/bin/run.js +15 -15
- package/lab/VERSION +1 -1
- package/lab/demo/pipelines/demo-1.json +5 -3
- package/lab/demo/pipelines/demo-2.json +5 -3
- package/lab/evals-core.mjs +512 -155
- package/lab/flows/record.mjs +16 -4
- package/lab/kinds/list.mjs +32 -23
- package/lab/run-evals.js +3 -3
- package/lab/server.py +433 -69
- package/lab/web/dist/assets/gallery-DKy8QK3o.js +5 -0
- package/lab/web/dist/assets/main-BGmSu7aS.css +1 -0
- package/lab/web/dist/assets/main-DdGON-yl.js +16 -0
- package/lab/web/dist/assets/tokens-BmytrwxE.js +60 -0
- package/lab/web/dist/assets/tokens-DBN7I0ru.css +1 -0
- package/lab/web/dist/gallery.html +3 -3
- package/lab/web/dist/index.html +4 -4
- package/package.json +10 -2
- package/lab/web/dist/assets/gallery-BcvmOPqb.js +0 -3
- package/lab/web/dist/assets/main-BBUxHZ-D.js +0 -16
- package/lab/web/dist/assets/main-CMoyjImZ.css +0 -1
- package/lab/web/dist/assets/tokens-B7N4NvmM.css +0 -1
- package/lab/web/dist/assets/tokens-CiJkwD3V.js +0 -60
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,44 @@ Newest first. Read a release's **Upgrade notes** before installing it: an
|
|
|
5
5
|
upgrade can rewrite what the lab keeps in your data directory, and an older
|
|
6
6
|
version cannot always read it back.
|
|
7
7
|
|
|
8
|
+
## 0.11.0
|
|
9
|
+
|
|
10
|
+
### Upgrade notes
|
|
11
|
+
|
|
12
|
+
- **Copy your data directory before upgrading** (see "User data" in the
|
|
13
|
+
README). A pipeline 0.11.0 saves is pipeline version 16, which 0.10.x
|
|
14
|
+
cannot read. To go back, reinstall 0.10.0 and restore the copy.
|
|
15
|
+
- On first start, each Target profile becomes an AI Connection (its type,
|
|
16
|
+
address, key and model), keeping its key and who it is shared with, plus a
|
|
17
|
+
Connection Profile where it changed any model or image setting. The old
|
|
18
|
+
profiles stay stored, unused.
|
|
19
|
+
- A pipeline's target names a Connection and a Profile. Pipelines read as
|
|
20
|
+
version 16, and are saved as it at their next edit; a run from before
|
|
21
|
+
shows its Target profile as its Profile.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Setup › Connections holds AI Connections and Connection Profiles: a
|
|
26
|
+
connection is where to send and with which key, and a profile is how to
|
|
27
|
+
ask. A target picks one of each, so one connection serves several
|
|
28
|
+
profiles.
|
|
29
|
+
- Every pipeline, prompt, run, profile and wizard has its own address, and
|
|
30
|
+
Copy link copies it.
|
|
31
|
+
- A run's Responses read as a flow, one ordered table a stage, and name the
|
|
32
|
+
stage and filter that discarded a reply. Move to filter set… and Move all
|
|
33
|
+
turn a filter into part of a filter set.
|
|
34
|
+
- A Call is viewed, edited, renamed and cloned in one dialog, and a
|
|
35
|
+
workflow or dynamic Source's settings are edited where they were made.
|
|
36
|
+
- The package page gives a contact address and links to its home page.
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- File on disk never reads `/proc`, and a Call holding the lab's own secret
|
|
41
|
+
is refused.
|
|
42
|
+
- Importing a version-15 YAML pipeline keeps each target's profile.
|
|
43
|
+
- A Target profile from before reply limits keeps its 160-token cap when it
|
|
44
|
+
becomes a connection.
|
|
45
|
+
|
|
8
46
|
## 0.10.0
|
|
9
47
|
|
|
10
48
|
### Upgrade notes
|
|
@@ -42,7 +80,9 @@ version cannot always read it back.
|
|
|
42
80
|
lab warns at start when one is on while it listens beyond this machine
|
|
43
81
|
without `LAB_PASSWORD`. `SOURCE_LOCAL_ROOT=<dir>` lets File on disk read only
|
|
44
82
|
under that directory. A command runs without a shell, in an empty
|
|
45
|
-
directory,
|
|
83
|
+
directory, with the lab's own secrets out of its environment -- but it
|
|
84
|
+
can still read them from the lab's, so turn Command on only where
|
|
85
|
+
everyone who can reach the lab may see them.
|
|
46
86
|
- Copy or move… copies or moves a pipeline, dataset, filter set, prompt or
|
|
47
87
|
Source to another workspace, and says first what a move would leave broken.
|
|
48
88
|
- A run's view opens on an Evals summary, and Show details shows what came
|
package/README.md
CHANGED
|
@@ -111,9 +111,9 @@ evals-lab run <bundle-dir | pipeline.yaml> [--items <dir>] [--json <file|->]
|
|
|
111
111
|
| `--min-pass` | an eval passes when this share of its items pass |
|
|
112
112
|
| `--progress` | a line per item as it finishes |
|
|
113
113
|
|
|
114
|
-
The bundle holds no key. Each
|
|
114
|
+
The bundle holds no key. Each AI Connection's key comes from
|
|
115
115
|
`EVALSLAB_API_KEY_` and its slug in Setup, in capitals with hyphens as
|
|
116
|
-
underscores: a
|
|
116
|
+
underscores: a connection slugged `anthropic` reads `EVALSLAB_API_KEY_ANTHROPIC`,
|
|
117
117
|
and `gpt-4o-mini` reads `EVALSLAB_API_KEY_GPT_4O_MINI`. A table of results
|
|
118
118
|
goes to stderr.
|
|
119
119
|
|
|
@@ -237,6 +237,12 @@ npm install -g evals-lab@latest # upgrade
|
|
|
237
237
|
npm uninstall -g evals-lab # remove; your data directory stays
|
|
238
238
|
```
|
|
239
239
|
|
|
240
|
+
## Contact
|
|
241
|
+
|
|
242
|
+
[evals-lab@grainbox.com](mailto:evals-lab@grainbox.com) for questions,
|
|
243
|
+
problems and feedback. More at
|
|
244
|
+
<https://www.grainbox.com/products/evals-lab/>.
|
|
245
|
+
|
|
240
246
|
## Licence
|
|
241
247
|
|
|
242
248
|
Copyright 2026 Grainbox Limited, under the
|
package/bin/run.js
CHANGED
|
@@ -62,7 +62,7 @@ const USAGE = `Usage: evals-lab run <bundle-dir | pipeline.yaml> [options]
|
|
|
62
62
|
--progress need it.
|
|
63
63
|
--help this.
|
|
64
64
|
|
|
65
|
-
A bundle's
|
|
65
|
+
A bundle's connection keys come from $EVALSLAB_API_KEY_<SLUG>. Exit
|
|
66
66
|
codes: 0 pass (or queued, without --wait), 1 an eval failed, 2 incomplete (an
|
|
67
67
|
item missing, one that did not run, or the run cancelled), 3 broken or
|
|
68
68
|
refused.`;
|
|
@@ -392,16 +392,20 @@ async function runOnLab(core, o, { env, stdout, say }) {
|
|
|
392
392
|
}
|
|
393
393
|
const call = labApi(base, env, workspace);
|
|
394
394
|
|
|
395
|
-
// What the page reads before it submits: the lab's pipelines
|
|
396
|
-
//
|
|
395
|
+
// What the page reads before it submits: the lab's pipelines, AI
|
|
396
|
+
// Connections and Connection Profiles, the Source the pipeline reads and
|
|
397
|
+
// the eval groups it may link. Slugged, as RunsTab's submit has them, so
|
|
398
|
+
// the run carries the slug its keys are spelt from (#253).
|
|
397
399
|
const docs = (await call("GET", "/api/state")).docs ?? {};
|
|
398
|
-
const setup = docs["promptlab.
|
|
399
|
-
const
|
|
400
|
+
const setup = docs["promptlab.connections"]?.body ?? {};
|
|
401
|
+
const connections = core.withSlugs(Array.isArray(setup.list) ? setup.list : []);
|
|
402
|
+
const held = docs["promptlab.connectionProfiles"]?.body?.list;
|
|
403
|
+
const answers = core.answersOf(connections, Array.isArray(held) ? held : []);
|
|
400
404
|
const saved = docs["promptlab.workflows"]?.body?.list;
|
|
401
405
|
const found = pipelineNamed(Array.isArray(saved) ? saved : [], o.pipeline, base);
|
|
402
|
-
const
|
|
403
|
-
|
|
404
|
-
const g =
|
|
406
|
+
const doc = core.upgradePipeline(found.work, { profileType: id => answers.connection(id)?.type,
|
|
407
|
+
connectionSplit: answers.split });
|
|
408
|
+
const g = answers.connection(setup.grader);
|
|
405
409
|
const grader = g ? { id: g.id, name: g.name } : null;
|
|
406
410
|
const content = core.contentOf(doc);
|
|
407
411
|
let source = null;
|
|
@@ -411,18 +415,14 @@ async function runOnLab(core, o, { env, stdout, say }) {
|
|
|
411
415
|
const files = source ? source.files.map(f => f.name) : undefined;
|
|
412
416
|
const { datasets } = await call("GET", "/api/datasets");
|
|
413
417
|
const problems = core.validatePipeline(doc, {
|
|
414
|
-
profiles:
|
|
418
|
+
profiles: answers.resolve, connections: answers.connection,
|
|
415
419
|
sources: id => (source && id === content.ref.id ? { name: source.name, type: source.type, files } : null),
|
|
416
420
|
grader, groups: datasets ?? [],
|
|
417
421
|
});
|
|
418
422
|
if (problems.length) throw new Refused(`${found.name} cannot run: ${problems.join("; ")}`);
|
|
419
|
-
// As RunsTab's submit resolves it:
|
|
420
|
-
// its keys are spelt from (#253), and keyless -- the lab fills each key in
|
|
423
|
+
// As RunsTab's submit resolves it: keyless -- the lab fills each key in
|
|
421
424
|
// from its own store.
|
|
422
|
-
const
|
|
423
|
-
const run = core.resolvePipeline(doc, {
|
|
424
|
-
profiles: id => slugged.find(p => p.id === id) ?? null, grader, ...(files ? { files } : {}),
|
|
425
|
-
});
|
|
425
|
+
const run = core.resolvePipeline(doc, { profiles: answers.resolve, grader, ...(files ? { files } : {}) });
|
|
426
426
|
|
|
427
427
|
const queued = (await call("POST", "/api/queue", run)).run;
|
|
428
428
|
say(`evals-lab run: ${found.name} is queued on ${base} as run ${queued.id}`);
|
package/lab/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.11.0 (2026.10.11-671)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 16,
|
|
3
3
|
"id": "demo-1",
|
|
4
4
|
"name": "Demo 1",
|
|
5
5
|
"jobs": [
|
|
@@ -105,10 +105,11 @@
|
|
|
105
105
|
{
|
|
106
106
|
"id": "s1",
|
|
107
107
|
"name": "",
|
|
108
|
-
"
|
|
108
|
+
"connection": {
|
|
109
109
|
"id": "vision",
|
|
110
110
|
"name": "Vision"
|
|
111
111
|
},
|
|
112
|
+
"profile": null,
|
|
112
113
|
"steps": [
|
|
113
114
|
{
|
|
114
115
|
"type": "prompt",
|
|
@@ -119,10 +120,11 @@
|
|
|
119
120
|
{
|
|
120
121
|
"id": "s2",
|
|
121
122
|
"name": "",
|
|
122
|
-
"
|
|
123
|
+
"connection": {
|
|
123
124
|
"id": "vision",
|
|
124
125
|
"name": "Vision"
|
|
125
126
|
},
|
|
127
|
+
"profile": null,
|
|
126
128
|
"steps": [
|
|
127
129
|
{
|
|
128
130
|
"type": "prompt",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 16,
|
|
3
3
|
"id": "demo-2",
|
|
4
4
|
"name": "Demo 2",
|
|
5
5
|
"jobs": [
|
|
@@ -105,10 +105,11 @@
|
|
|
105
105
|
{
|
|
106
106
|
"id": "s1",
|
|
107
107
|
"name": "",
|
|
108
|
-
"
|
|
108
|
+
"connection": {
|
|
109
109
|
"id": "vision",
|
|
110
110
|
"name": "Vision"
|
|
111
111
|
},
|
|
112
|
+
"profile": null,
|
|
112
113
|
"steps": [
|
|
113
114
|
{
|
|
114
115
|
"type": "prompt",
|
|
@@ -119,10 +120,11 @@
|
|
|
119
120
|
{
|
|
120
121
|
"id": "s2",
|
|
121
122
|
"name": "",
|
|
122
|
-
"
|
|
123
|
+
"connection": {
|
|
123
124
|
"id": "vision",
|
|
124
125
|
"name": "Vision"
|
|
125
126
|
},
|
|
127
|
+
"profile": null,
|
|
126
128
|
"steps": [
|
|
127
129
|
{
|
|
128
130
|
"type": "prompt",
|