@matchbox-ai/train 0.1.0 → 0.2.1

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 (119) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +1 -1
  3. package/THIRD-PARTY-NOTICES.md +1 -1
  4. package/dist/define-pipeline-D6I-jAE_.js +20 -0
  5. package/dist/define-pipeline-D6I-jAE_.js.map +1 -0
  6. package/dist/encoders/index.d.ts +0 -1
  7. package/dist/encoders/index.d.ts.map +1 -1
  8. package/dist/evaluate-sequence-ZCwyomzQ.js.map +1 -1
  9. package/dist/evaluation/evaluate-sequence.d.ts.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +7 -11
  13. package/dist/index.js.map +1 -1
  14. package/dist/load-project.d.ts +0 -4
  15. package/dist/load-project.d.ts.map +1 -1
  16. package/dist/models/presets.d.ts +6 -6
  17. package/dist/models/presets.d.ts.map +1 -1
  18. package/dist/models/record/fit.d.ts +6 -99
  19. package/dist/models/record/fit.d.ts.map +1 -1
  20. package/dist/models/record/run.d.ts +1 -57
  21. package/dist/models/record/run.d.ts.map +1 -1
  22. package/dist/models/record/verify-export.d.ts +1 -2
  23. package/dist/models/record/verify-export.d.ts.map +1 -1
  24. package/dist/models/sequence/fit-sequence.d.ts +9 -116
  25. package/dist/models/sequence/fit-sequence.d.ts.map +1 -1
  26. package/dist/models/sequence/prepare-supervision.d.ts +10 -0
  27. package/dist/models/sequence/prepare-supervision.d.ts.map +1 -0
  28. package/dist/models/sequence/run-sequence.d.ts +3 -71
  29. package/dist/models/sequence/run-sequence.d.ts.map +1 -1
  30. package/dist/models/sequence/types.d.ts +4 -0
  31. package/dist/models/sequence/types.d.ts.map +1 -1
  32. package/dist/native/fit.d.ts +15 -0
  33. package/dist/native/fit.d.ts.map +1 -0
  34. package/dist/native/index.d.ts +3 -0
  35. package/dist/native/index.d.ts.map +1 -0
  36. package/dist/native/record.d.ts +12 -0
  37. package/dist/native/record.d.ts.map +1 -0
  38. package/dist/package-model-CPj0qnQs.js.map +1 -1
  39. package/dist/packaging/package-model.d.ts.map +1 -1
  40. package/dist/pipeline/define-pipeline.d.ts +2 -5
  41. package/dist/pipeline/define-pipeline.d.ts.map +1 -1
  42. package/dist/project/artifact.d.ts +21 -67
  43. package/dist/project/artifact.d.ts.map +1 -1
  44. package/dist/project/config.d.ts +1 -4
  45. package/dist/project/config.d.ts.map +1 -1
  46. package/dist/project/discover.d.ts +2 -0
  47. package/dist/project/discover.d.ts.map +1 -1
  48. package/dist/project/entry.d.ts +5 -0
  49. package/dist/project/entry.d.ts.map +1 -0
  50. package/dist/project/index.d.ts +1 -1
  51. package/dist/project/index.d.ts.map +1 -1
  52. package/dist/project/index.js +2 -2
  53. package/dist/{project-BP331m20.js → project-BR13wXHr.js} +51 -18
  54. package/dist/project-BR13wXHr.js.map +1 -0
  55. package/dist/{record-BTZ5LWHF.js → record-MCYVi9O6.js} +60 -114
  56. package/dist/record-MCYVi9O6.js.map +1 -0
  57. package/dist/{run-Cwa7vD_T.js → run-PB_jiKnw.js} +4 -6
  58. package/dist/run-PB_jiKnw.js.map +1 -0
  59. package/dist/run.d.ts +4 -128
  60. package/dist/run.d.ts.map +1 -1
  61. package/dist/sequence-DGoGU7kG.js +219 -0
  62. package/dist/sequence-DGoGU7kG.js.map +1 -0
  63. package/dist/train.d.ts +4 -128
  64. package/dist/train.d.ts.map +1 -1
  65. package/dist/types.d.ts +0 -2
  66. package/dist/types.d.ts.map +1 -1
  67. package/docs/README.md +12 -7
  68. package/docs/agent-skill.md +8 -4
  69. package/docs/cli.md +85 -28
  70. package/docs/contributing.md +43 -0
  71. package/docs/dataset-format.md +4 -2
  72. package/docs/evaluation.md +66 -5
  73. package/docs/example-evaluation.md +47 -0
  74. package/docs/example-results.json +280 -0
  75. package/docs/examples/money.md +19 -0
  76. package/docs/examples/time.md +43 -0
  77. package/docs/getting-started.md +48 -54
  78. package/docs/native-packages.md +31 -0
  79. package/docs/neural-training.md +1 -1
  80. package/docs/parser-api.md +16 -16
  81. package/docs/pipelines.md +5 -6
  82. package/docs/primitives/README.md +12 -11
  83. package/docs/project-structure.md +17 -3
  84. package/docs/react.md +49 -7
  85. package/docs/reference/README.md +25 -0
  86. package/docs/reference/configuration.md +43 -0
  87. package/docs/reference/evaluation.md +21 -0
  88. package/docs/reference/pipeline.md +43 -0
  89. package/docs/reference/runtime.md +56 -0
  90. package/docs/reference/supervision.md +87 -0
  91. package/docs/reference/training.md +26 -0
  92. package/docs/reference/vite.md +20 -0
  93. package/docs/releases.md +6 -16
  94. package/docs/repository-design.md +2 -2
  95. package/docs/runtime-backends.md +8 -11
  96. package/docs/training.md +73 -0
  97. package/docs/website-deployment.md +11 -0
  98. package/native.cjs +1 -0
  99. package/package.json +10 -5
  100. package/prebuilds/darwin-arm64/node.napi.node +0 -0
  101. package/prebuilds/darwin-x64/node.napi.node +0 -0
  102. package/prebuilds/linux-arm64/node.napi.glibc.node +0 -0
  103. package/prebuilds/linux-arm64/node.napi.musl.node +0 -0
  104. package/prebuilds/linux-x64/node.napi.glibc.node +0 -0
  105. package/prebuilds/linux-x64/node.napi.musl.node +0 -0
  106. package/prebuilds/win32-arm64/node.napi.node +0 -0
  107. package/prebuilds/win32-x64/node.napi.node +0 -0
  108. package/dist/define-pipeline-Colvwt7u.js +0 -32
  109. package/dist/define-pipeline-Colvwt7u.js.map +0 -1
  110. package/dist/encoders/word-tokens.d.ts +0 -5
  111. package/dist/encoders/word-tokens.d.ts.map +0 -1
  112. package/dist/models/sequence/create-network.d.ts +0 -3
  113. package/dist/models/sequence/create-network.d.ts.map +0 -1
  114. package/dist/project-BP331m20.js.map +0 -1
  115. package/dist/record-BTZ5LWHF.js.map +0 -1
  116. package/dist/run-Cwa7vD_T.js.map +0 -1
  117. package/dist/sequence-C_WfVGO1.js +0 -251
  118. package/dist/sequence-C_WfVGO1.js.map +0 -1
  119. package/docs/filter-research.md +0 -63
package/docs/cli.md CHANGED
@@ -1,54 +1,111 @@
1
- # CLI
1
+ # CLI reference
2
2
 
3
- Run Matchbox inside an existing React, Next.js, or other JavaScript application. Your application keeps its own dev server and framework configuration. The command is provided by the matchbox-ai development dependency. Pipeline authoring and training APIs remain in @matchbox-ai/train. The CLI uses Commander for commands and Ink for interactive setup and status.
3
+ Install through `bunx matchbox-ai init` or run the installed `matchbox-ai` binary. Bun 1.4.2+ and Node.js 24+ are required for training.
4
4
 
5
- ## Add a task
5
+ ## Commands
6
+
7
+ | Command | Purpose |
8
+ | --------------------- | ------------------------------------------------------- |
9
+ | [`init`](#init) | Add a task to an existing app and install dependencies. |
10
+ | [`dev`](#dev) | Open the local browser workbench. |
11
+ | [`train`](#train) | Train, validate, and package. |
12
+ | [`eval`](#eval) | Evaluate the saved model against the test split. |
13
+ | [`parse`](#parse) | Return a prediction. |
14
+ | [`inspect`](#inspect) | Show model recognition and the final result. |
15
+ | [`info`](#info) | Show resolved paths and strategy. |
16
+ | [`save`](#save) | Add or replace a training example. |
17
+
18
+ ## Common options
19
+
20
+ `-h, --help` works on every command. `-v, --version` prints the package version from the root command.
21
+
22
+ Every command except `init` accepts `[task]`, a task name, directory, or config path, and `-c, --config <path>` as an alternative. Do not combine a task argument with `--config`. Omitting the task works when discovery finds exactly one; interactive `dev` also offers a task picker.
23
+
24
+ Every command except `dev` accepts `--json`. JSON goes to stdout; diagnostics and installer output go to stderr. Bare `matchbox-ai` lists tasks and next actions without creating files.
25
+
26
+ ## init
6
27
 
7
28
  ```sh
8
- matchbox-ai init
9
- matchbox-ai init money --template money
10
- matchbox-ai init intent --template blank
29
+ bunx matchbox-ai init [name] --template money
30
+ bunx matchbox-ai init intent --template blank --directory ./my-app
11
31
  ```
12
32
 
13
- Interactive setup offers the money example or a blank task. In scripts, specify `--template`. `--directory <path>` selects an existing application directory containing package.json. Matchbox preserves existing scripts, adds `matchbox:dev`, `matchbox:train`, and `matchbox:eval` if absent, and ignores `.matchbox/`. It refuses to replace an existing task directory. It installs dependencies automatically using the app’s package-manager declaration or lockfile, including workspace ancestors. With neither, it uses the invoking package manager, then Bun as a fallback. Use `--skip-install` to handle installation yourself. Installer logs go to stderr so `--json` stays machine-readable. If installation fails, the scaffold remains and the CLI prints the command to retry.
33
+ | Option | Default | Behavior |
34
+ | -------------------- | ---------------------------------------------------- | -------------------------------------------------------------- |
35
+ | `[name]` | `money` for the money template; `my-task` for blank. | Names the task directory. Pass a name to override the default. |
36
+ | `--template <name>` | Interactive choice. | `money` or `blank`; specify in scripts. |
37
+ | `--directory <path>` | Current directory. | Existing application with a `package.json`. |
38
+ | `--skip-install` | False. | Write files without installing dependencies. |
39
+ | `--json` | False. | Print scaffold results as JSON. |
14
40
 
15
- Package-manager build-script policies still apply. With pnpm, run `pnpm approve-builds` and select `@tensorflow/tfjs-node` before training.
41
+ Adds `matchbox/<name>/`, ignores `.matchbox/`, and adds missing `matchbox:dev`, `matchbox:train`, and `matchbox:eval` scripts. Existing task directories are never overwritten. Framework config stays unchanged.
16
42
 
17
- The money template has an explicit token model, supervision, and decoder. The blank template has an editable label schema, an explicit word-feature classifier, and empty datasets. Write examples and independent evals before training it. Names do not select learning strategies.
43
+ Installs core as an application dependency and train/CLI as development dependencies. Package-manager selection uses the app declaration or lockfile (including workspace ancestors), then the invoking package manager, then Bun. Failed installation preserves the scaffold and prints a retry command.
18
44
 
19
- ## Open the workbench
45
+ The blank template requires examples and evals before training. The money template includes token supervision and an application-owned decoder. No time template ships in 0.1.0; the time example is available in the repository.
46
+
47
+ ## dev
20
48
 
21
49
  ```sh
22
- matchbox-ai dev money
23
- matchbox-ai dev money --port 4191 --no-open
50
+ bunx matchbox-ai dev [task] --port 4190 --no-open
24
51
  ```
25
52
 
26
- The browser workbench runs on loopback, alongside your app. Try inputs, inspect recognition, save explicit corrections, train, evaluate, and measure browser inference. Source changes mark the model as stale. Training remains an explicit action. A successful training run reloads the model.
53
+ `--port <number>` defaults to `4190`. The browser opens unless `--no-open` is set. The workbench listens on loopback and runs alongside your app's own dev server. It supports training, prediction, corrections, evaluation, and browser timing. Changes mark an artifact stale; training remains explicit.
27
54
 
28
- Predictions and timing run through TensorFlow.js CPU in the browser. Training and evaluation run in local child processes with fresh task modules. The speed measurement repeats the current input 100 times after 20 warmups; it excludes model loading and does not measure accuracy.
55
+ Browser timing uses the current input, 20 warmups, and 100 measured predictions. It excludes loading and does not measure accuracy. `dev` has no JSON mode.
29
56
 
30
- Saving validates output and rejects held-out inputs. It only changes training data. Token pipelines also need matching supervision from their authored recipe; the save result points to that file. Matchbox does not infer labels or normalization rules from a correction.
57
+ ## train
31
58
 
32
- ## Train and evaluate
59
+ ```sh
60
+ bunx matchbox-ai train [task] --verbose --json
61
+ ```
62
+
63
+ `--verbose` shows epoch loss outside JSON mode. Training validates datasets and token annotations, fits a model, gates on validation accuracy and size, and writes the artifact, TypeScript wrapper, declarations, and report.
64
+
65
+ Validation-gate failure stops export and exits nonzero. An independent test score below the threshold is reported after packaging; use `eval` to enforce the test threshold in CI.
66
+
67
+ ## eval
33
68
 
34
69
  ```sh
35
- matchbox-ai train money
36
- matchbox-ai train money --verbose
37
- matchbox-ai eval money
38
- matchbox-ai eval money --json
70
+ bunx matchbox-ai eval [task] --json
39
71
  ```
40
72
 
41
- Training validates datasets, fits the model, checks validation requirements, and exports a model plus a report. Failing validation stops export. The separate test set measures the selected model without influencing training. `eval` exits with status 1 if exact accuracy is below the configured threshold and includes expected/actual failures. `--verbose` reveals epoch loss. JSON output stays on stdout; diagnostics go to stderr.
73
+ Evaluates the saved artifact against the configured test file. Reports exact accuracy, acceptance, abstention, invalid outputs, and expected/actual failures. Exits `1` when exact accuracy is below `minAccuracy`. It does not retrain.
42
74
 
43
- ## Inspect and script
75
+ ## parse
44
76
 
45
77
  ```sh
46
- matchbox-ai parse money "fifteen euros" --json
47
- matchbox-ai inspect money "eleven grand" --json
48
- matchbox-ai info money
49
- matchbox-ai save money "twenty euros please" '{"amount":20,"currency":"EUR","approximate":false}'
78
+ bunx matchbox-ai parse money 'twenty dollars' --json
50
79
  ```
51
80
 
52
- A task argument can be a name, task directory, or config file. Omit the name when discovery finds exactly one task. Interactive `dev` offers a picker for multiple tasks; scripts require a name. `--config` selects an explicit path and cannot be combined with a task argument. Each command has its own `--help`.
81
+ Returns a [ParseResult](reference/runtime.md). Uncertainty is a prediction result and does not itself cause a nonzero exit. The CLI uses local inference, not a browser timing measurement.
82
+
83
+ ## inspect
84
+
85
+ ```sh
86
+ bunx matchbox-ai inspect money 'eleven grand' --json
87
+ ```
88
+
89
+ Returns `{ input, ...diagnostics, result }`. Token models include labeled tokens and the decoded candidate; field models expose their strategy-specific diagnostics. `result` is the validated prediction. Diagnostics are for debugging and should not be treated as a stable application contract.
90
+
91
+ ## info
92
+
93
+ ```sh
94
+ bunx matchbox-ai info [task] --json
95
+ ```
96
+
97
+ Returns resolved `config`, `authoring`, `pipeline`, `task`, `train`, `validation`, `eval`, and `output` paths. It does not require a trained artifact.
98
+
99
+ ## save
100
+
101
+ ```sh
102
+ bunx matchbox-ai save money 'twenty euros please' '{"amount":20,"currency":"EUR","approximate":false}' --json
103
+ ```
104
+
105
+ Validates both values, then adds or replaces a matching input in training data. Matching ignores surrounding whitespace and case. Rejects held-out inputs and ambiguous duplicate training rows. Returns `{ saved, action, example, next }` where `action` is `added` or `updated`.
106
+
107
+ It does not retrain. Token pipelines also require updated recipe supervision before training. Corrections never modify validation or test data.
108
+
109
+ ## Exit status
53
110
 
54
- Bare `matchbox-ai` shows available tasks and next actions. It does not create files. Use the one-shot commands for machine-readable results.
111
+ Successful commands exit `0`, including uncertain predictions. Invalid arguments, missing tasks/artifacts, malformed data, training failures, and failed eval thresholds exit nonzero. `--help` and `--version` exit `0`.
@@ -0,0 +1,43 @@
1
+ # Contributing
2
+
3
+ Matchbox uses a shared Rust engine for native training and browser inference, with TypeScript authoring and application APIs.
4
+
5
+ ## Project structure
6
+
7
+ ```text
8
+ Cargo.toml # The Rust workspace owns the shared dependency versions.
9
+ crates/
10
+ matchbox-engine/src/ # Burn model, training and record serialization.
11
+ matchbox-node/src/ # Node-API training adapter and native parity checks.
12
+ matchbox-wasm/src/ # Browser inference adapter.
13
+ packages/
14
+ core/src/runtime/burn/ # Loading, typed prediction and disposal.
15
+ train/src/native/ # TypeScript calls into the native addon.
16
+ cli/ # Existing commands and workbench.
17
+ scripts/
18
+ build-rust.ts # Builds the native addon and browser WASM module.
19
+ copy-rust.ts # Copies binaries into npm package output.
20
+ ```
21
+
22
+ TypeScript continues to own task schemas, tokenization, authored supervision, decoding and validation. Burn owns the embedding network, autodiff, Adam, model records and execution. The adapters share the same model implementation. They do not implement a separate inference engine.
23
+
24
+ A contributor compiles the native addon and WASM runtime once. Training produces model data, without compiling Rust for each task. Published packages bundle native binaries for the supported platforms.
25
+
26
+ ## Local development
27
+
28
+ Install Bun and Rust through rustup or Homebrew. The repository discovers Rust tools from PATH, Homebrew rustup and the Cargo bin directory without changing your shell configuration. The checked-in toolchain file pins Rust and requests the WASM target.
29
+
30
+ ```sh
31
+ bun install --frozen-lockfile
32
+ bun run setup:rust
33
+ bun run dev
34
+ bun run check
35
+ MATCHBOX_PREBUILT=1 bun run test:browser
36
+ bun run eval:examples
37
+ ```
38
+
39
+ `bun run setup:rust` is a one-time contributor setup for the pinned wasm-bindgen CLI. Subsequent `bun run dev`, builds and checks locate the installed tools automatically. Package consumers use bundled prebuilds and do not need Rust.
40
+
41
+ Generated native binaries, WASM output, Cargo build output and model artifacts are ignored by Git. `Cargo.lock` pins Rust dependencies. `bun run check` includes Rust formatting, Clippy and engine tests.
42
+
43
+ See [native package distribution](native-packages.md) for platform coverage and release verification.
@@ -9,6 +9,8 @@ Matchbox dataset format version 1 uses separate local `train.jsonl` and `evals.j
9
9
 
10
10
  `input` must satisfy the task's string schema. `output` must satisfy its structured output schema. There are no row headers, split labels, IDs, or metadata properties in version 1. Application-specific fields belong inside `output` and must be declared by the task.
11
11
 
12
+ The conventional training workflow uses `data/train.jsonl`, `evals/validation.jsonl`, and `evals/test.jsonl`. The two-source validation API below is a lower-level utility, not the complete training configuration.
13
+
12
14
  ## Authoring rules
13
15
 
14
16
  Write UTF-8 text without a byte-order mark, with LF or CRLF line endings. Empty and whitespace-only lines are ignored. Diagnostics still count those physical lines. Each split must contain at least one example. A final newline is optional.
@@ -49,10 +51,10 @@ The function accepts text and performs no filesystem access, network requests, o
49
51
 
50
52
  ## Train and eval separation
51
53
 
52
- Both splits are explicit and required. Matchbox does not shuffle, merge, deduplicate, or automatically split them. Keep held-out examples separate from training and synthetic expansion. Authors are responsible for preventing overlap and paraphrase leakage; validation establishes structural correctness, not evaluation independence. Automatic holdout selection and leakage diagnostics can be designed with the training ticket.
54
+ Both splits are explicit and required. Matchbox does not shuffle, merge, deduplicate, or automatically split them. Keep held-out examples separate from training and synthetic expansion. Authors are responsible for preventing overlap and paraphrase leakage; validation establishes structural correctness, not evaluation independence. The training workflow additionally rejects inputs shared across splits after trimming and case folding. The lower-level `parseDatasets` API performs structural validation only.
53
55
 
54
56
  ## Versioning
55
57
 
56
58
  The required `formatVersion: 1` in the dataset configuration describes both sources. Keep that configuration under version control alongside the JSONL files and task definition. Raw JSONL files are not self-describing; preserve their configuration when sharing them. No implicit version is assumed. Missing or unsupported versions throw a `RangeError` before rows are read. Invalid rows return validation issues instead.
57
59
 
58
- Breaking changes to row structure or interpretation require a new format version and explicit migration. Do not silently reinterpret existing files. Dataset format versions are independent of package versions and the task metadata's format version. Business-schema changes require revalidation of both datasets against the updated task. Artifact hashes and provenance belong to the build metadata ticket.
60
+ Breaking changes to row structure or interpretation require a new format version and explicit migration. Do not silently reinterpret existing files. Dataset format versions are independent of package versions and the task metadata's format version. Business-schema changes require revalidation of both datasets against the updated task. Build reports include artifact and dataset hashes.
@@ -1,9 +1,70 @@
1
- # Evaluation
1
+ # Evaluate a model
2
2
 
3
- Training fits vocabulary, field domains, and weights using data/train.jsonl only. Validation in evals/validation.jsonl gates artifact export. Independent evals/test.jsonl measures the selected model. Input overlap across these splits is rejected.
3
+ Evaluation checks an existing model against inputs with known answers. It does not update weights or train on your test data.
4
4
 
5
- Run matchbox-ai eval money to evaluate saved artifacts without retraining or requiring the training data. A failing accuracy threshold produces a nonzero exit code. Optional evals/baseline.ts exports a parser with the same parse contract. Optional evals/challenges.json contains abstention cases with input and output: null. Other research formats must have distinct filenames and explicit runners.
5
+ ## Run the test split
6
6
 
7
- Reports include accuracy, abstention, invalid-output rate, artifact bytes, loss, export parity, dataset hashes, and control-model results where supported. Confidence is uncalibrated. Zero confidence for unfamiliar vocabulary means the current model declines to answer; it does not prove the input is invalid or diagnose the only cause.
7
+ After [training](training.md), run:
8
8
 
9
- When evaluating new numeric representations, withhold complete output values and meaningful input compositions. Never teach test answers through a dictionary or rewrite evals to make training pass. Schema validity establishes output shape, not semantic correctness.
9
+ ```sh
10
+ bunx matchbox-ai eval money
11
+ bunx matchbox-ai eval money --json
12
+ ```
13
+
14
+ This loads the saved artifact and scores `evals/test.jsonl`. It does not require the training dataset. The command exits `1` when exact accuracy is below the configured `minAccuracy`, making it suitable for a CI gate.
15
+
16
+ The workbench's **Evaluate** action runs the same test evaluation. The programmatic [`evaluate`](reference/evaluation.md) API returns metrics without applying an acceptance gate.
17
+
18
+ ## Keep the splits separate
19
+
20
+ | Split | Used for |
21
+ | ------------------------ | ---------------------------------------------------------------------- |
22
+ | `data/train.jsonl` | Learning vocabulary, output domains, and weights. |
23
+ | `evals/validation.jsonl` | Checking accuracy and size requirements before exporting a candidate. |
24
+ | `evals/test.jsonl` | Measuring the selected model without influencing fitting or selection. |
25
+
26
+ Withhold meaningful input compositions and complete output values where the chosen strategy supports unseen values. Avoid near-duplicate paraphrases across splits. A low test score should lead to better training coverage or a different explicit pipeline, not edited test answers.
27
+
28
+ ## Read the results
29
+
30
+ | Metric | Meaning |
31
+ | ------------------- | ----------------------------------------------------------------------------------- |
32
+ | Exact accuracy | The fraction of complete outputs matching the expected value. |
33
+ | Accepted accuracy | Accuracy among answers the parser returned; `null` when it returned none. |
34
+ | Abstention rate | The fraction of inputs on which the parser declined to answer. |
35
+ | Invalid-output rate | The fraction of returned answers that fail output validation. |
36
+ | Failures | Inputs with their expected output and actual result. Uncertainty appears as `null`. |
37
+
38
+ Read accuracy and abstention together. A model that answers only easy inputs can have high accepted accuracy and poor coverage. Schema validity guarantees an output's shape, not that its meaning is correct.
39
+
40
+ ## Test uncertainty
41
+
42
+ Confidence is an uncalibrated model score. Zero confidence means the current model declined to answer; it does not establish that the input is invalid or that training coverage is the only problem.
43
+
44
+ For sequence models, add negative cases in `evals/challenges.json`:
45
+
46
+ ```json
47
+ [{ "input": "sometime soon", "output": null }]
48
+ ```
49
+
50
+ Training includes these in the report's separate `challenges` section. They do not become training examples or select the model. The CLI `eval` command scores the configured test split; it does not automatically rerun the challenge file.
51
+
52
+ The programmatic evaluator also accepts expected `null` for abstention cases. This is an evaluation convention, not a change to the task's successful output schema.
53
+
54
+ ## Measure browser speed
55
+
56
+ Use **Measure browser speed** in the workbench or the benchmark controls on the examples page. They run inference through Burn WASM CPU on the current device, including output validation.
57
+
58
+ These measurements exclude model loading and UI rendering. Record the input, sample count, browser, and device with the result. The workbench uses 100 timed runs after 20 warmups; the website demo uses 300 timed runs after 20 warmups. Repeated-input latency is separate from held-out accuracy.
59
+
60
+ See the [evaluation API](reference/evaluation.md) for exact metric fields and return types.
61
+
62
+ ## Repository example audit
63
+
64
+ After `bun run train`, run `bun run eval:examples`. It writes `.matchbox/example-evaluation.json` with all predictions that disagree with expected outputs, slice metrics, false accepts, source hashes, and token-sequence overlap with training. Each example owns a frozen `evals/generalization.json` file. Treat those files as audit data; create new development fixtures when fixing failures and obtain a fresh independent evaluation before claiming improvement.
65
+
66
+ A held-out string can still be identical to training at the model's input representation. Word tokenization maps all numbers to `<number>`. Changing 15 to 90 tests deterministic copying and arithmetic, not learned numerical generalization. Report accuracy on feature-novel inputs separately.
67
+
68
+ The audit evaluates model outputs against the task’s expected results. Positive coverage, accuracy among accepted answers, and false acceptance of negative examples matter alongside exact match. A high abstention rate can hide an ineffective parser. Threshold curves are diagnostics, not permission to pick a threshold on test data.
69
+
70
+ See [the measured example audit](example-evaluation.md) for current results and limitations.
@@ -0,0 +1,47 @@
1
+ # Example evaluation
2
+
3
+ The examples are evaluated against expected structured outputs and rejection cases. Timing in the demo measures execution speed on your device, independently of these accuracy checks.
4
+
5
+ ## Current results
6
+
7
+ These small, synthetic suites are regression evidence. Known failures informed training coverage and candidate selection. The evaluation fixtures were preserved, but their scores are not independent estimates of performance on user traffic. Exact match includes correct abstentions.
8
+
9
+ | Example | Audit exact match | Language test | False accepts on audit negatives |
10
+ | ------- | ----------------- | --------------- | -------------------------------- |
11
+ | is-even | 8/8 | Not applicable. | 0/3 |
12
+ | Money | 19/20 | 12/12 | 0/8 |
13
+ | Time | 20/20 | 12/12 | 0/8 |
14
+ | Filters | 16/16 | 11/12 | 0/6 |
15
+
16
+ All three language-development suites pass 12/12. No language-test negative case is falsely accepted. Confidence remains uncalibrated.
17
+
18
+ Money still abstains on “Henrik paid 19 dollars yesterday”. Filters still abstain on “show me all companies based in Norway” in the language test. These are valid requests with incomplete model coverage.
19
+
20
+ ## Training coverage
21
+
22
+ Money training includes payment framing, subscriptions and bounds that must be rejected rather than returned as exact amounts. Time includes mixed day/hour expressions and sentence framing. Filters include country/location phrasing and exclusion supervision. These are authored training examples; runtime decoders and the model architecture were unchanged.
23
+
24
+ Two money and six time language-test inputs match training token sequences after numeric normalization. Novel quantities are not necessarily novel model inputs. Even a new full sentence can consist of familiar three-token windows. Country normalization uses an application-owned reference.
25
+
26
+ ## Model size
27
+
28
+ Sizes include metadata, vocabulary and float32 model records. The shared WASM runtime and application decoders are additional downloads. The website reads these figures from the current build.
29
+
30
+ | Example | Parameters | Artifact bytes |
31
+ | ------- | ---------: | -------------: |
32
+ | is-even | 530 | 3898 |
33
+ | money | 1530 | 10351 |
34
+ | time | 1287 | 9188 |
35
+ | filters | 7760 | 58555 |
36
+
37
+ ## Reproduce
38
+
39
+ ```sh
40
+ bun run train
41
+ bun scripts/evaluate-language.ts development
42
+ bun scripts/evaluate-language.ts test
43
+ bun run eval:examples
44
+ bun run test:browser
45
+ ```
46
+
47
+ [Current results](example-results.json) include case and artifact hashes, failures and feature-overlap counts. The evaluation scripts write fresh reports into the ignored .matchbox directory.
@@ -0,0 +1,280 @@
1
+ {
2
+ "provenance": "Synthetic regression fixtures. Known failures informed training coverage and candidate selection. These are not independent production accuracy estimates. Evaluation fixtures were preserved.",
3
+ "examples": [
4
+ {
5
+ "name": "is-even",
6
+ "parameters": 530,
7
+ "bytes": 3898,
8
+ "artifactSha256": "c659fbf61017dc88037e8314335c4e73622006c3549620f23ca459bc4098cb6f",
9
+ "caseSha256": "93cff9748ccc3ce575274f04dec41861ac59f7bcdd42d35bbcfe86f026774177",
10
+ "evaluation": {
11
+ "examples": 8,
12
+ "invalidOutputRate": 0,
13
+ "exactAccuracy": 1,
14
+ "accepted": 5,
15
+ "acceptedAccuracy": 1,
16
+ "abstentionRate": 0.375,
17
+ "correctAbstentions": 3,
18
+ "failures": [],
19
+ "negatives": 3,
20
+ "falseAccepts": 0
21
+ }
22
+ },
23
+ {
24
+ "name": "money",
25
+ "parameters": 1530,
26
+ "bytes": 10351,
27
+ "artifactSha256": "8aab74105bda77422fb3ab10a67adb96fe589142bf21d3bfb244cce0aaba2db4",
28
+ "caseSha256": "c8b46c03eee72e24e8a297771cb8c7b026c9f3de31c2ea1822e681c87458e234",
29
+ "evaluation": {
30
+ "examples": 20,
31
+ "invalidOutputRate": 0,
32
+ "exactAccuracy": 0.95,
33
+ "accepted": 11,
34
+ "acceptedAccuracy": 1,
35
+ "abstentionRate": 0.44999999999999996,
36
+ "correctAbstentions": 8,
37
+ "failures": [
38
+ {
39
+ "input": "Henrik paid 19 dollars yesterday",
40
+ "expected": {
41
+ "amount": 19,
42
+ "currency": "USD",
43
+ "approximate": false
44
+ },
45
+ "actual": null
46
+ }
47
+ ],
48
+ "negatives": 8,
49
+ "falseAccepts": 0
50
+ },
51
+ "language": {
52
+ "name": "money",
53
+ "split": "test",
54
+ "artifactSha256": "8aab74105bda77422fb3ab10a67adb96fe589142bf21d3bfb244cce0aaba2db4",
55
+ "caseSha256": "21463aad45c9584858acca629aeee7d96f300bd8937268cbb17b9552bff695a0",
56
+ "featureEquivalent": ["invoice 718 totals SEK 54", "from 16 to 28 dollars"],
57
+ "novelOnly": {
58
+ "examples": 10,
59
+ "invalidOutputRate": 0,
60
+ "exactAccuracy": 1,
61
+ "accepted": 5,
62
+ "acceptedAccuracy": 1,
63
+ "abstentionRate": 0.5,
64
+ "correctAbstentions": 5,
65
+ "failures": []
66
+ },
67
+ "examples": 12,
68
+ "invalidOutputRate": 0,
69
+ "exactAccuracy": 1,
70
+ "accepted": 6,
71
+ "acceptedAccuracy": 1,
72
+ "abstentionRate": 0.5,
73
+ "correctAbstentions": 6,
74
+ "failures": [],
75
+ "falseAccepts": 0
76
+ },
77
+ "development": {
78
+ "name": "money",
79
+ "split": "development",
80
+ "artifactSha256": "8aab74105bda77422fb3ab10a67adb96fe589142bf21d3bfb244cce0aaba2db4",
81
+ "caseSha256": "8f0b9f5cfa2bfbb202d27579c13c822f1962f64a428771ff5c9f42c3d72480c9",
82
+ "featureEquivalent": ["invoice 657 totals $ 91", "between 18 and 29 euros"],
83
+ "novelOnly": {
84
+ "examples": 10,
85
+ "invalidOutputRate": 0,
86
+ "exactAccuracy": 1,
87
+ "accepted": 5,
88
+ "acceptedAccuracy": 1,
89
+ "abstentionRate": 0.5,
90
+ "correctAbstentions": 5,
91
+ "failures": []
92
+ },
93
+ "examples": 12,
94
+ "invalidOutputRate": 0,
95
+ "exactAccuracy": 1,
96
+ "accepted": 6,
97
+ "acceptedAccuracy": 1,
98
+ "abstentionRate": 0.5,
99
+ "correctAbstentions": 6,
100
+ "failures": [],
101
+ "falseAccepts": 0
102
+ }
103
+ },
104
+ {
105
+ "name": "time",
106
+ "parameters": 1287,
107
+ "bytes": 9188,
108
+ "artifactSha256": "1aca94d5192cd70ddca6dca6e0a3a1a38b1d8c0e0cd8849b5cbaf1942da1d2e5",
109
+ "caseSha256": "9735ba19d8feb772fa074a0cbee03cb7d8b6fb009bdb734d0128a0836739487f",
110
+ "evaluation": {
111
+ "examples": 20,
112
+ "invalidOutputRate": 0,
113
+ "exactAccuracy": 1,
114
+ "accepted": 12,
115
+ "acceptedAccuracy": 1,
116
+ "abstentionRate": 0.4,
117
+ "correctAbstentions": 8,
118
+ "failures": [],
119
+ "negatives": 8,
120
+ "falseAccepts": 0
121
+ },
122
+ "language": {
123
+ "name": "time",
124
+ "split": "test",
125
+ "artifactSha256": "1aca94d5192cd70ddca6dca6e0a3a1a38b1d8c0e0cd8849b5cbaf1942da1d2e5",
126
+ "caseSha256": "ba60a69928392d1ba8d0f3f7b961135791b157f00d35bd08504deacfdef66ade",
127
+ "featureEquivalent": [
128
+ "please wait for 0.25 hours",
129
+ "the reminder is in 41 minutes",
130
+ "tomorrow at 6:37 pm please",
131
+ "in minus 38 seconds",
132
+ "tomorrow at 27:19",
133
+ "for 3 days or 22 minutes"
134
+ ],
135
+ "novelOnly": {
136
+ "examples": 6,
137
+ "invalidOutputRate": 0,
138
+ "exactAccuracy": 1,
139
+ "accepted": 5,
140
+ "acceptedAccuracy": 1,
141
+ "abstentionRate": 0.16666666666666663,
142
+ "correctAbstentions": 1,
143
+ "failures": []
144
+ },
145
+ "examples": 12,
146
+ "invalidOutputRate": 0,
147
+ "exactAccuracy": 1,
148
+ "accepted": 8,
149
+ "acceptedAccuracy": 1,
150
+ "abstentionRate": 0.33333333333333337,
151
+ "correctAbstentions": 4,
152
+ "failures": [],
153
+ "falseAccepts": 0
154
+ },
155
+ "development": {
156
+ "name": "time",
157
+ "split": "development",
158
+ "artifactSha256": "1aca94d5192cd70ddca6dca6e0a3a1a38b1d8c0e0cd8849b5cbaf1942da1d2e5",
159
+ "caseSha256": "d0c0d22b10a8707ab48b3983a6973ef104447ed49427026ed01575ed2581e0c8",
160
+ "featureEquivalent": [
161
+ "please wait for 13 minutes",
162
+ "in 1.25 hours",
163
+ "in minus 12 minutes",
164
+ "tomorrow at 26:11",
165
+ "for 5 hours or 18 minutes"
166
+ ],
167
+ "novelOnly": {
168
+ "examples": 7,
169
+ "invalidOutputRate": 0,
170
+ "exactAccuracy": 1,
171
+ "accepted": 6,
172
+ "acceptedAccuracy": 1,
173
+ "abstentionRate": 0.1428571428571429,
174
+ "correctAbstentions": 1,
175
+ "failures": []
176
+ },
177
+ "examples": 12,
178
+ "invalidOutputRate": 0,
179
+ "exactAccuracy": 1,
180
+ "accepted": 8,
181
+ "acceptedAccuracy": 1,
182
+ "abstentionRate": 0.33333333333333337,
183
+ "correctAbstentions": 4,
184
+ "failures": [],
185
+ "falseAccepts": 0
186
+ }
187
+ },
188
+ {
189
+ "name": "filters",
190
+ "parameters": 7760,
191
+ "bytes": 58555,
192
+ "artifactSha256": "489334acf5e497fd07e51bdc4ff04313e3f094342c5eca92e15df056bb00b321",
193
+ "caseSha256": "5c47c1e8b9cca57c904a21523a7f975ced84cbc418af12afd4e38ea2e3f0203c",
194
+ "evaluation": {
195
+ "examples": 16,
196
+ "invalidOutputRate": 0,
197
+ "exactAccuracy": 1,
198
+ "accepted": 10,
199
+ "acceptedAccuracy": 1,
200
+ "abstentionRate": 0.375,
201
+ "correctAbstentions": 6,
202
+ "failures": [],
203
+ "negatives": 6,
204
+ "falseAccepts": 0
205
+ },
206
+ "language": {
207
+ "name": "filters",
208
+ "split": "test",
209
+ "artifactSha256": "489334acf5e497fd07e51bdc4ff04313e3f094342c5eca92e15df056bb00b321",
210
+ "caseSha256": "f4974e1ae31abf497acb0fe4b66033f81ba94fe26fde429d7c620d56ba778b4b",
211
+ "featureEquivalent": [],
212
+ "novelOnly": {
213
+ "examples": 12,
214
+ "invalidOutputRate": 0,
215
+ "exactAccuracy": 0.9166666666666666,
216
+ "accepted": 7,
217
+ "acceptedAccuracy": 1,
218
+ "abstentionRate": 0.41666666666666663,
219
+ "correctAbstentions": 4,
220
+ "failures": [
221
+ {
222
+ "input": "show me all companies based in Norway",
223
+ "expected": {
224
+ "field": "country",
225
+ "operator": "eq",
226
+ "value": "NO"
227
+ },
228
+ "actual": null
229
+ }
230
+ ]
231
+ },
232
+ "examples": 12,
233
+ "invalidOutputRate": 0,
234
+ "exactAccuracy": 0.9166666666666666,
235
+ "accepted": 7,
236
+ "acceptedAccuracy": 1,
237
+ "abstentionRate": 0.41666666666666663,
238
+ "correctAbstentions": 4,
239
+ "failures": [
240
+ {
241
+ "input": "show me all companies based in Norway",
242
+ "expected": {
243
+ "field": "country",
244
+ "operator": "eq",
245
+ "value": "NO"
246
+ },
247
+ "actual": null
248
+ }
249
+ ],
250
+ "falseAccepts": 0
251
+ },
252
+ "development": {
253
+ "name": "filters",
254
+ "split": "development",
255
+ "artifactSha256": "489334acf5e497fd07e51bdc4ff04313e3f094342c5eca92e15df056bb00b321",
256
+ "caseSha256": "7b3dcb7b5898d40594322fef3c98e4a5f06622d6764d8e77191390cbd9543c6d",
257
+ "featureEquivalent": [],
258
+ "novelOnly": {
259
+ "examples": 12,
260
+ "invalidOutputRate": 0,
261
+ "exactAccuracy": 1,
262
+ "accepted": 8,
263
+ "acceptedAccuracy": 1,
264
+ "abstentionRate": 0.33333333333333337,
265
+ "correctAbstentions": 4,
266
+ "failures": []
267
+ },
268
+ "examples": 12,
269
+ "invalidOutputRate": 0,
270
+ "exactAccuracy": 1,
271
+ "accepted": 8,
272
+ "acceptedAccuracy": 1,
273
+ "abstentionRate": 0.33333333333333337,
274
+ "correctAbstentions": 4,
275
+ "failures": [],
276
+ "falseAccepts": 0
277
+ }
278
+ }
279
+ ]
280
+ }
@@ -0,0 +1,19 @@
1
+ # Money parsing
2
+
3
+ The money template trains a token recognizer for amounts, currencies, and multipliers. Its decoder converts recognized number words and applies arithmetic.
4
+
5
+ ```sh
6
+ bunx matchbox-ai init money --template money
7
+ bunx matchbox-ai train money
8
+ bunx matchbox-ai dev money
9
+ ```
10
+
11
+ Try `invoice 31415 totals € 28.65`, `in 2026 we paid USD 59.20`, or `around twenty six grand in euros`. The first two require distinguishing money from other numbers.
12
+
13
+ The output is `{ amount: number, currency: "EUR" | "USD" | "GBP" | "SEK", approximate: boolean }`. In this example `$` means USD. English number words below one hundred are supported by application code. Conflicting currencies and undecodable amounts cause uncertainty.
14
+
15
+ Read `parser.ts` for the output contract, `pipeline.ts` for the learning strategy, `recipe.ts` for supervision, and `decode/decode.ts` for normalization. Add training annotations when adding examples. Evals stay independent.
16
+
17
+ The recognizer is learned; number conversion and multiplication are authored. Training a different domain does not automatically inherit these rules.
18
+
19
+ Training includes explicit neutral spans, rejection examples, and unknown-token masking. These choices are visible in the recipe and generator. The original test cases are development regressions. The frozen `evals/generalization.json` cases check new contexts and rejection behavior. See [the example audit](../example-evaluation.md).