evals-lab 0.16.0 → 0.17.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 +29 -0
- package/README.md +12 -11
- package/bin/evals-lab.js +5 -1
- package/bin/update.js +65 -0
- package/lab/VERSION +1 -1
- package/lab/demo/CREDITS.md +4 -3
- package/lab/demo/datasets/recorded-replies.json +39 -0
- package/lab/demo/manifest.json +2 -2
- package/lab/demo/pipelines/recorded-replies.json +89 -0
- package/lab/demo/sources/Demo 1/basketball-hoop.jpg +0 -0
- package/lab/demo/sources/Demo 1/blue-boardwalk.jpg +0 -0
- package/lab/demo/sources/Demo 1/busy-beach.jpg +0 -0
- package/lab/demo/sources/Demo 1/butcher-sign.jpg +0 -0
- package/lab/demo/sources/Demo 1/cactus-flower.jpg +0 -0
- package/lab/demo/sources/Demo 1/corner-shop.jpg +0 -0
- package/lab/demo/sources/Demo 1/crosswalk-cyclist-panorama.jpg +0 -0
- package/lab/demo/sources/Demo 1/cyanotype-room.jpg +0 -0
- package/lab/demo/sources/Demo 1/dead-end-sign.jpg +0 -0
- package/lab/demo/sources/Demo 1/dog-in-snow.jpg +0 -0
- package/lab/demo/sources/Demo 1/empty-bedroom.jpg +0 -0
- package/lab/demo/sources/Demo 1/farmers-market-stall.jpg +0 -0
- package/lab/demo/sources/Demo 1/four-jets.jpg +0 -0
- package/lab/demo/sources/Demo 1/german-shepherd.jpg +0 -0
- package/lab/demo/sources/Demo 1/harbour-bridge-dusk.jpg +0 -0
- package/lab/demo/sources/Demo 1/harrow-on-the-hill-sign.jpg +0 -0
- package/lab/demo/sources/Demo 1/hong-kong-street.jpg +0 -0
- package/lab/demo/sources/Demo 1/house-salisbury-street.jpg +0 -0
- package/lab/demo/sources/Demo 1/infrared-orchard.jpg +0 -0
- package/lab/demo/sources/Demo 1/keyboard-desk.jpg +0 -0
- package/lab/demo/sources/Demo 1/lighthouse-dunes.jpg +0 -0
- package/lab/demo/sources/Demo 1/mountain-lake.jpg +0 -0
- package/lab/demo/sources/Demo 1/museum-skeleton.jpg +0 -0
- package/lab/demo/sources/Demo 1/music-room.jpg +0 -0
- package/lab/demo/sources/Demo 1/old-red-car.jpg +0 -0
- package/lab/demo/sources/Demo 1/parked-car-plate.jpg +0 -0
- package/lab/demo/sources/Demo 1/phone-and-wallet.png +0 -0
- package/lab/demo/sources/Demo 1/phone-box.jpg +0 -0
- package/lab/demo/sources/Demo 1/pink-flamingo.jpg +0 -0
- package/lab/demo/sources/Demo 1/postcards.jpg +0 -0
- package/lab/demo/sources/Demo 1/red-roof-church.jpg +0 -0
- package/lab/demo/sources/Demo 1/roadside-mailboxes.jpg +0 -0
- package/lab/demo/sources/Demo 1/rodeo.jpg +0 -0
- package/lab/demo/sources/Demo 1/running-tap.tif +0 -0
- package/lab/demo/sources/Demo 1/snail-on-stem.jpg +0 -0
- package/lab/demo/sources/Demo 1/two-horses-field.jpg +0 -0
- package/lab/demo/sources/Demo 1/university-sign.jpg +0 -0
- package/lab/demo/sources/Demo 1/vegetable-crates.jpg +0 -0
- package/lab/demo/sources/Demo 1/watermarked-car.jpg +0 -0
- package/lab/demo/sources/Demo 1/watermarked-pills.jpg +0 -0
- package/lab/demo/sources/Demo 1/whiteboard-delegate.jpg +0 -0
- package/lab/demo/sources/Demo 1/whiteboard-germ-layers.jpg +0 -0
- package/lab/demo/sources/Demo 2/aerial-city.jpg +0 -0
- package/lab/demo/sources/Demo 2/alligator-pen.jpg +0 -0
- package/lab/demo/sources/Demo 2/arm-tattoo.jpg +0 -0
- package/lab/demo/sources/Demo 2/bed-and-plant.jpg +0 -0
- package/lab/demo/sources/Demo 2/bright-bedroom.jpg +0 -0
- package/lab/demo/sources/Demo 2/car-headlight.jpg +0 -0
- package/lab/demo/sources/Demo 2/child-in-surf.jpg +0 -0
- package/lab/demo/sources/Demo 2/city-highway.jpg +0 -0
- package/lab/demo/sources/Demo 2/corner-bakery.jpg +0 -0
- package/lab/demo/sources/Demo 2/cyclist-yellow-jacket.jpg +0 -0
- package/lab/demo/sources/Demo 2/excavator-street-signs.jpg +0 -0
- package/lab/demo/sources/Demo 2/globe-closeup.jpg +0 -0
- package/lab/demo/sources/Demo 2/harbour-village.jpg +0 -0
- package/lab/demo/sources/Demo 2/high-street-walkers.jpg +0 -0
- package/lab/demo/sources/Demo 2/hillside-rooftops.jpg +0 -0
- package/lab/demo/sources/Demo 2/house-at-night.jpg +0 -0
- package/lab/demo/sources/Demo 2/ivy-leaves.jpg +0 -0
- package/lab/demo/sources/Demo 2/man-with-alligator.jpg +0 -0
- package/lab/demo/sources/Demo 2/orange-mailbox-hedge.jpg +0 -0
- package/lab/demo/sources/Demo 2/pedal-boats.jpg +0 -0
- package/lab/demo/sources/Demo 2/pink-trees-vignette.jpg +0 -0
- package/lab/demo/sources/Demo 2/please-leave-quietly-sign.jpg +0 -0
- package/lab/demo/sources/Demo 2/railroad-crossing-sign.jpg +0 -0
- package/lab/demo/sources/Demo 2/roadworks-sign.jpg +0 -0
- package/lab/demo/sources/Demo 2/roundabout-sign.jpg +0 -0
- package/lab/demo/sources/Demo 2/sea-cave.jpg +0 -0
- package/lab/demo/sources/Demo 2/shadow-on-sand.jpg +0 -0
- package/lab/demo/sources/Demo 2/signpost-a404.jpg +0 -0
- package/lab/demo/sources/Demo 2/street-fruit-cart.jpg +0 -0
- package/lab/demo/sources/Demo 2/street-sign-parnassusweg.jpg +0 -0
- package/lab/demo/sources/Demo 2/two-horses-close.jpg +0 -0
- package/lab/demo/sources/Demo 2/victorian-house.jpg +0 -0
- package/lab/demo/sources/Demo 2/vintage-dashboard.jpg +0 -0
- package/lab/demo/sources/Demo 2/volcano-at-dusk.jpg +0 -0
- package/lab/demo/sources/Demo 2/wall-camera.jpg +0 -0
- package/lab/demo/sources/Demo 2/watch-for-rocks-sign.jpg +0 -0
- package/lab/demo/sources/Demo 2/waterfall.jpg +0 -0
- package/lab/demo/sources/Demo 2/white-domes.jpg +0 -0
- package/lab/demo/sources/Demo 2/whiteboard-meeting-notes.jpg +0 -0
- package/lab/demo/sources/Demo 2/whiteboard-messages.jpg +0 -0
- package/lab/demo/sources/Demo 2/wooden-house-fence.jpg +0 -0
- package/lab/kinds/list.mjs +11 -3
- package/lab/server.py +19 -1
- package/lab/web/dist/assets/dist-BfJnsQb9.js +1 -0
- package/lab/web/dist/assets/gallery-Dv7iXLfa.js +5 -0
- package/lab/web/dist/assets/main-DS76udej.css +1 -0
- package/lab/web/dist/assets/main-DaObzKJz.js +18 -0
- package/lab/web/dist/assets/tokens-z9rSXnjM.js +64 -0
- package/lab/web/dist/gallery.html +2 -2
- package/lab/web/dist/index.html +3 -3
- package/package.json +3 -3
- package/lab/web/dist/assets/dist-DI3ewZYj.js +0 -1
- package/lab/web/dist/assets/gallery-ICJNZQIZ.js +0 -5
- package/lab/web/dist/assets/main-BOkQWswU.css +0 -1
- package/lab/web/dist/assets/main-rJDsPFWT.js +0 -18
- package/lab/web/dist/assets/tokens-C5ist-xG.js +0 -64
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,35 @@ 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.17.0
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Home's footer says when a newer version is out. The lab asks npm at most
|
|
13
|
+
once a day; `LAB_NO_UPDATE_CHECK=1` turns it off.
|
|
14
|
+
- A demo that grades with no AI Connection: "Demo: recorded replies", whose
|
|
15
|
+
Variants answer with saved replies.
|
|
16
|
+
- An experiment answered only by Echo or Recorded steps runs in a lab with no
|
|
17
|
+
AI Connection.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- The package is about 10 MB, not 46: the demo's images are 1024 px on the
|
|
22
|
+
long side.
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Trim with bullets drops a list's stray square brackets, as in
|
|
27
|
+
`[first, second]`, and a bracketed label before the first item.
|
|
28
|
+
- Results: a Variant's connection wraps in its own column. Experiments ›
|
|
29
|
+
Variants: a long Prompt wraps instead of being cut to one line.
|
|
30
|
+
|
|
31
|
+
## 0.16.1
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- History's Overview shows its Items readably on a phone.
|
|
36
|
+
|
|
8
37
|
## 0.16.0
|
|
9
38
|
|
|
10
39
|
### Upgrade notes
|
package/README.md
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Test what a model, an HTTP endpoint or an API answers, side by side, and score
|
|
4
4
|
it with evals you define in advance. Runs locally in a friendly UI, and
|
|
5
|
-
doesn't send your data anywhere you haven't pointed it.
|
|
6
|
-
|
|
5
|
+
doesn't send your data anywhere you haven't pointed it. The one request of its
|
|
6
|
+
own is a daily look at npm for a newer version, which sends nothing about you or
|
|
7
|
+
your lab ([Options](#options) turns it off).
|
|
7
8
|
An experiment takes items from a **Source** and sends each one to one or more
|
|
8
9
|
**Variants**, then scores the **Responses**.
|
|
9
10
|
|
|
@@ -18,7 +19,7 @@ An experiment takes items from a **Source** and sends each one to one or more
|
|
|
18
19
|
a fresh one at run time.
|
|
19
20
|
|
|
20
21
|
Evals include parsing checks, item counts, comparison with production
|
|
21
|
-
responses, grading by a model, and evals
|
|
22
|
+
responses, grading by a model, and evals shared between
|
|
22
23
|
experiments. Run history is kept and can be exported.
|
|
23
24
|
|
|
24
25
|
The same evals run in CI: `evals-lab run` fails the build when an eval
|
|
@@ -29,8 +30,6 @@ Currently in early release.
|
|
|
29
30
|
Example uses:
|
|
30
31
|
- Checking that an HTTP endpoint or internal API still answers correctly
|
|
31
32
|
after a change, in the lab or on every commit in CI
|
|
32
|
-
- Keywording images with a model's vision, and running evals on the
|
|
33
|
-
keywords it returns
|
|
34
33
|
- Comparing two models, or two prompts, on the same items and seeing which
|
|
35
34
|
scores higher
|
|
36
35
|
- Grading what an API returns against an eval of expected answers
|
|
@@ -45,8 +44,8 @@ npm install -g evals-lab
|
|
|
45
44
|
evals-lab
|
|
46
45
|
```
|
|
47
46
|
|
|
48
|
-
Open <http://localhost:8080>. A new lab starts with
|
|
49
|
-
and its experiment
|
|
47
|
+
Open <http://localhost:8080>. A new lab starts with seven demos, each an eval
|
|
48
|
+
and its experiment. "Demo: recorded replies" runs as it is; the rest run once you add an AI Connection in Setup. Note the first start takes longer while it installs them. Without
|
|
50
49
|
installing: `npx evals-lab`.
|
|
51
50
|
|
|
52
51
|
| Needs | Windows | Linux |
|
|
@@ -84,6 +83,7 @@ evals-lab [--port <n>] [--host <address>] [--data-dir <dir>]
|
|
|
84
83
|
| | `LAB_PASSWORD` | none |
|
|
85
84
|
| | `OLLAMA_URL` | `http://127.0.0.1:11434` |
|
|
86
85
|
| | `PYTHON` | `py -3`, `python` or `python3`, whichever is found |
|
|
86
|
+
| | `LAB_NO_UPDATE_CHECK` | unset; `1` stops the daily look at npm for a newer version |
|
|
87
87
|
|
|
88
88
|
`--host 0.0.0.0` makes the lab reachable from your network and needs `LAB_PASSWORD` to be set (otherwise it refuses connections).
|
|
89
89
|
|
|
@@ -144,7 +144,7 @@ jobs:
|
|
|
144
144
|
# Only when the items are images:
|
|
145
145
|
# - run: sudo apt-get update && sudo apt-get install -y imagemagick
|
|
146
146
|
- run: >
|
|
147
|
-
npx --yes evals-lab@0.
|
|
147
|
+
npx --yes evals-lab@0.17 run evals/
|
|
148
148
|
--junit evals.xml --json evals.json --summary "$GITHUB_STEP_SUMMARY"
|
|
149
149
|
env:
|
|
150
150
|
EVALSLAB_API_KEY_ANTHROPIC: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
@@ -205,9 +205,10 @@ each preset's request fields:
|
|
|
205
205
|
|
|
206
206
|
## Getting started
|
|
207
207
|
|
|
208
|
-
First
|
|
209
|
-
Ollama (local or cloud), OpenAI-compatible, Anthropic,
|
|
210
|
-
endpoint — and give its address, model and key.
|
|
208
|
+
First add an AI Connection: **Setup › Connections › Add connection**, then
|
|
209
|
+
pick its type — Ollama (local or cloud), OpenAI-compatible, Anthropic,
|
|
210
|
+
llama.cpp or an HTTP endpoint — and give its address, model and key. An
|
|
211
|
+
Ollama connection without an address uses `OLLAMA_URL`.
|
|
211
212
|
|
|
212
213
|
Set up your data source(s) in Library.
|
|
213
214
|
|
package/bin/evals-lab.js
CHANGED
|
@@ -21,6 +21,7 @@ const http = require("http");
|
|
|
21
21
|
const net = require("net");
|
|
22
22
|
const os = require("os");
|
|
23
23
|
const path = require("path");
|
|
24
|
+
const updates = require("./update.js");
|
|
24
25
|
|
|
25
26
|
const LAB = path.join(__dirname, "..", "lab");
|
|
26
27
|
// The oldest Python the package's workflow starts the lab on.
|
|
@@ -50,7 +51,8 @@ SOURCE_ALLOW_LOCAL_FILES=1 and SOURCE_ALLOW_LOCAL_COMMANDS=1 let a Source read a
|
|
|
50
51
|
file or run a command on this machine; both are off unless set.
|
|
51
52
|
SOURCE_LOCAL_ROOT=<dir> lets a file Source read only under that directory.
|
|
52
53
|
LAB_IMPORT=<file> imports a lab file each time the lab starts, each
|
|
53
|
-
connection's key from $EVALSLAB_API_KEY_<SLUG
|
|
54
|
+
connection's key from $EVALSLAB_API_KEY_<SLUG>.
|
|
55
|
+
LAB_NO_UPDATE_CHECK=1 stops the daily look at npm for a newer version.`;
|
|
54
56
|
|
|
55
57
|
// Where a lab keeps its store when nobody said: the platform's per-user data
|
|
56
58
|
// directory, so it survives the package being upgraded or reinstalled.
|
|
@@ -210,6 +212,8 @@ async function main() {
|
|
|
210
212
|
// else the PATH holds. Windows spells the variable `Path`.
|
|
211
213
|
const pathKey = Object.keys(env).find(k => k.toUpperCase() === "PATH") || "PATH";
|
|
212
214
|
env[pathKey] = path.dirname(process.execPath) + path.delimiter + (env[pathKey] || "");
|
|
215
|
+
const updateFile = updates.start(o.dataDir, require("../package.json").version);
|
|
216
|
+
if (updateFile) env.LAB_UPDATE_FILE = updateFile;
|
|
213
217
|
// -X utf8: the server reads and writes its files as UTF-8 by default,
|
|
214
218
|
// which Windows' Python otherwise does in the machine's code page.
|
|
215
219
|
const child = spawn(python.cmd[0], [...python.cmd.slice(1), "-X", "utf8", "-u", path.join(LAB, "server.py")],
|
package/bin/update.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Whether a newer evals-lab is out, for Home's footer (docs/distribution.md §
|
|
2
|
+
// Which build a package is). The launcher starts this, so the image and
|
|
3
|
+
// `evals-lab run` never do. It keeps its answer in a file in the data
|
|
4
|
+
// directory, which server.py reads through LAB_UPDATE_FILE: the file is
|
|
5
|
+
// rewritten at every start as well as after a check, so an upgrade clears what
|
|
6
|
+
// the version before it was told.
|
|
7
|
+
const fs = require("fs");
|
|
8
|
+
const path = require("path");
|
|
9
|
+
|
|
10
|
+
const LATEST = "https://registry.npmjs.org/evals-lab/latest";
|
|
11
|
+
const VERSION = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
|
|
12
|
+
const HOUR = 60 * 60 * 1000;
|
|
13
|
+
const DAY = 24 * HOUR;
|
|
14
|
+
|
|
15
|
+
// Whatever the registry answers ends up on the page, so it is held to VERSION.
|
|
16
|
+
async function latestVersion() {
|
|
17
|
+
const r = await fetch(LATEST, { redirect: "error", signal: AbortSignal.timeout(5000) });
|
|
18
|
+
const { version } = await r.json();
|
|
19
|
+
return VERSION.test(version) ? version : null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// A prerelease comes before its release; two prereleases of one release are
|
|
23
|
+
// not told apart, since `latest` only names a prerelease by mistake.
|
|
24
|
+
function isNewer(latest, current) {
|
|
25
|
+
const [a, b] = [latest, current].map(v => v.split("-")[0].split(".").map(Number));
|
|
26
|
+
for (let i = 0; i < 3; i++) if (a[i] !== b[i]) return a[i] > b[i];
|
|
27
|
+
return current.includes("-") && !latest.includes("-");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function read(file) {
|
|
31
|
+
try { return JSON.parse(fs.readFileSync(file, "utf8")) || {}; } catch { return {}; }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function write(file, checked, latest, current) {
|
|
35
|
+
const newer = latest && isNewer(latest, current) ? latest : null;
|
|
36
|
+
try { fs.writeFileSync(file, JSON.stringify({ checked, latest, newer })); } catch { /* it says nothing */ }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// A failed check counts as the day's: offline, it is not retried each hour.
|
|
40
|
+
async function check(file, current, now = Date.now(), get = latestVersion) {
|
|
41
|
+
const was = read(file);
|
|
42
|
+
const checked = Number(was.checked) || 0;
|
|
43
|
+
const latest = VERSION.test(was.latest) ? was.latest : null;
|
|
44
|
+
write(file, checked, latest, current);
|
|
45
|
+
if (now - checked < DAY) return;
|
|
46
|
+
write(file, now, await get().catch(() => null) || latest, current);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function off(env) {
|
|
50
|
+
return /^(1|true|yes|on)$/i.test(env.LAB_NO_UPDATE_CHECK || "");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Starts checking, and returns the file the answer lands in; null when turned
|
|
54
|
+
// off. Not awaited: nothing about starting the lab waits on the registry. A
|
|
55
|
+
// lab left running stays told, by looking each hour for a day having passed.
|
|
56
|
+
function start(dataDir, current, env = process.env, get = latestVersion) {
|
|
57
|
+
if (off(env)) return null;
|
|
58
|
+
const file = path.join(dataDir, "update.json");
|
|
59
|
+
const tick = () => check(file, current, Date.now(), get);
|
|
60
|
+
tick();
|
|
61
|
+
setInterval(tick, HOUR).unref();
|
|
62
|
+
return file;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = { start, check, isNewer, off, LATEST };
|
package/lab/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.17.0 (2026.11.11-1029)
|
package/lab/demo/CREDITS.md
CHANGED
|
@@ -5,9 +5,10 @@ need no attribution; the sources are listed so each one can be traced.
|
|
|
5
5
|
|
|
6
6
|
## Images
|
|
7
7
|
|
|
8
|
-
The images of `Demo 1/` and `Demo 2/`. Files were resized to
|
|
9
|
-
|
|
10
|
-
and TIFF
|
|
8
|
+
The images of `Demo 1/` and `Demo 2/`. Files were resized to 1024 pixels on
|
|
9
|
+
the long side (JPEG quality 75), which keeps the npm package small, and their
|
|
10
|
+
metadata stripped; the panorama is a crop, and the PNG and TIFF (JPEG
|
|
11
|
+
compressed) are conversions.
|
|
11
12
|
|
|
12
13
|
| File | Source | Author | Licence |
|
|
13
14
|
|---|---|---|---|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "evals-lab/eval-group",
|
|
3
|
+
"version": 9,
|
|
4
|
+
"group": {
|
|
5
|
+
"name": "Demo: recorded replies evals",
|
|
6
|
+
"body": {
|
|
7
|
+
"version": 9,
|
|
8
|
+
"scoring": {
|
|
9
|
+
"mode": "all",
|
|
10
|
+
"threshold": null
|
|
11
|
+
},
|
|
12
|
+
"grader": null,
|
|
13
|
+
"every": [
|
|
14
|
+
{
|
|
15
|
+
"type": "contains",
|
|
16
|
+
"value": "Mercury",
|
|
17
|
+
"ignoreCase": true
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"type": "contains",
|
|
21
|
+
"value": "Venus",
|
|
22
|
+
"not": true,
|
|
23
|
+
"ignoreCase": true
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "regex",
|
|
27
|
+
"pattern": "^\\W*Mercury\\W*$",
|
|
28
|
+
"flags": "i"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "latency",
|
|
32
|
+
"max": 10000
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"run": [],
|
|
36
|
+
"cases": []
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
package/lab/demo/manifest.json
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"version": 1,
|
|
4
4
|
"id": "demo",
|
|
5
5
|
"name": "Demo",
|
|
6
|
-
"packVersion": "2026.10
|
|
6
|
+
"packVersion": "2026.11.10",
|
|
7
7
|
"requires": {
|
|
8
8
|
"lab": ">=19",
|
|
9
9
|
"plugins": []
|
|
10
10
|
},
|
|
11
|
-
"description": "
|
|
11
|
+
"description": "Seven demos, each a dataset with a starter pipeline: two sets of public-domain images, short texts to classify, one question in four wordings, the same question's replies recorded earlier (runs with no AI Connection), a dynamic Source's snapshot, and PDFs to check and sort."
|
|
12
12
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 20,
|
|
3
|
+
"id": "recorded-replies",
|
|
4
|
+
"name": "Demo: recorded replies pipeline",
|
|
5
|
+
"steps": [
|
|
6
|
+
{
|
|
7
|
+
"type": "getItems",
|
|
8
|
+
"id": "items-j1",
|
|
9
|
+
"content": {
|
|
10
|
+
"type": "prompt"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"type": "request",
|
|
15
|
+
"id": "j1",
|
|
16
|
+
"name": "",
|
|
17
|
+
"cell": {
|
|
18
|
+
"type": "echo",
|
|
19
|
+
"prompt": "Mercury"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "readResponse",
|
|
24
|
+
"id": "read-j1",
|
|
25
|
+
"request": "j1",
|
|
26
|
+
"out": {
|
|
27
|
+
"kind": "text"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
],
|
|
31
|
+
"variants": [
|
|
32
|
+
{
|
|
33
|
+
"id": "s1",
|
|
34
|
+
"name": "",
|
|
35
|
+
"connection": null,
|
|
36
|
+
"profile": null,
|
|
37
|
+
"overrides": {}
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "s2",
|
|
41
|
+
"name": "",
|
|
42
|
+
"connection": null,
|
|
43
|
+
"profile": null,
|
|
44
|
+
"overrides": {
|
|
45
|
+
"j1": {
|
|
46
|
+
"prompt": "Mercury is closest to the Sun."
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"id": "s3",
|
|
52
|
+
"name": "",
|
|
53
|
+
"connection": null,
|
|
54
|
+
"profile": null,
|
|
55
|
+
"overrides": {
|
|
56
|
+
"j1": {
|
|
57
|
+
"prompt": "Venus"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"id": "s4",
|
|
63
|
+
"name": "",
|
|
64
|
+
"connection": null,
|
|
65
|
+
"profile": null,
|
|
66
|
+
"overrides": {
|
|
67
|
+
"j1": {
|
|
68
|
+
"prompt": "The innermost planet is Mercury."
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
"evals": [
|
|
74
|
+
{
|
|
75
|
+
"id": "t1",
|
|
76
|
+
"name": "",
|
|
77
|
+
"type": "group",
|
|
78
|
+
"continueOnFailure": true,
|
|
79
|
+
"group": {
|
|
80
|
+
"id": "recorded-replies",
|
|
81
|
+
"name": "Demo: recorded replies evals"
|
|
82
|
+
},
|
|
83
|
+
"pin": null
|
|
84
|
+
}
|
|
85
|
+
],
|
|
86
|
+
"pass": {
|
|
87
|
+
"mode": "all"
|
|
88
|
+
}
|
|
89
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lab/kinds/list.mjs
CHANGED
|
@@ -766,16 +766,24 @@ export function filterV4(f ) {
|
|
|
766
766
|
// ---- the modifiers -------------------------------------------------------------
|
|
767
767
|
|
|
768
768
|
/** What an item's numbering looks like: "[1] suv", "(2) car", "3. dirt",
|
|
769
|
-
"4) trees", "5: sky" -- and not "1950s car" or "5.1 surround".
|
|
770
|
-
|
|
769
|
+
"4) trees", "5: sky" -- and not "1950s car" or "5.1 surround". A
|
|
770
|
+
bracketed label is numbering too when a space follows it ("[x] done",
|
|
771
|
+
"[items] suv"), but not a markdown link's "[text](url)". */
|
|
772
|
+
const NUMBERING = /^(?:\[\d+\]|\[[^[\]]*\](?=\s)|\(\d+\)|\d+[.):](?!\d))\s*/;
|
|
771
773
|
|
|
772
774
|
/** One item as Tidy items leaves it: a leading bullet, its numbering, stray
|
|
773
|
-
quotes and
|
|
775
|
+
quotes, stops and brackets at the ends, and runs of whitespace gone. A
|
|
776
|
+
stray bracket is one whose pair is not in the item: a list written as an
|
|
777
|
+
array, "[a, b, c]", split on its commas leaves "[a" and "c]", while
|
|
778
|
+
"[text](url)" keeps its own. */
|
|
774
779
|
export function tidy(item ) {
|
|
775
780
|
let t = item.trim();
|
|
776
781
|
for (const p of ["-", "*", "•"]) if (t.startsWith(p)) t = t.slice(p.length);
|
|
777
782
|
t = t.trim().replace(NUMBERING, "");
|
|
778
783
|
t = trimEnds(t.trim(), ".\"'`");
|
|
784
|
+
if (t.startsWith("[") && !t.includes("]")) t = t.slice(1);
|
|
785
|
+
if (t.endsWith("]") && !t.includes("[")) t = t.slice(0, -1);
|
|
786
|
+
t = trimEnds(t.trim(), ".\"'`");
|
|
779
787
|
return t.replace(/\s+/g, " ").trim();
|
|
780
788
|
}
|
|
781
789
|
|