@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
@@ -0,0 +1,43 @@
1
+ # Date, time, and duration parsing
2
+
3
+ This repository example trains a token model for durations, relative offsets, and clock times on today or tomorrow. The output stays relative to avoid choosing an application timezone or reference date.
4
+
5
+ | Input | Output |
6
+ | --------------------- | ----------------------------------------------------------- |
7
+ | `for 90 minutes` | `{ kind: "duration", seconds: 5400 }`. |
8
+ | `in two hours` | `{ kind: "relative", seconds: 7200 }`. |
9
+ | `tomorrow at 3:30 pm` | `{ kind: "datetime", dayOffset: 1, hour: 15, minute: 30 }`. |
10
+
11
+ ## Run the example
12
+
13
+ From the Matchbox repository:
14
+
15
+ ```sh
16
+ bun install
17
+ bun run build:packages
18
+ bun run matchbox train examples/time
19
+ bun run matchbox eval examples/time
20
+ bun run matchbox dev examples/time
21
+ ```
22
+
23
+ The website's [examples page](/training) runs the exported model. This is a repository example, not a CLI template in 0.1.0.
24
+
25
+ ## What learns, what is code
26
+
27
+ The model learns quantity, unit, duration/offset cue, day, clock, and meridiem labels from annotated examples. Training-only annotations live in `data/train-spans.json`.
28
+
29
+ The browser decoder in `decode/` reads those labels, converts digits or a small explicit number-word vocabulary, multiplies units, and validates clock ranges. It can produce numeric amounts absent from training because it copies recognized input spans instead of classifying finite output values.
30
+
31
+ A duration is elapsed seconds. A relative result is an offset in seconds from a reference instant your app chooses. A datetime result is a local clock time on a relative calendar day. The application must resolve timezone, reference date, and daylight-saving ambiguity. Do not treat a calendar day as a fixed 24-hour offset.
32
+
33
+ ## Limits
34
+
35
+ This first model covers English seconds, minutes, hours, and elapsed days, up to seven days. The authored quantity helper supports digits, decimals, one through twenty, `a`, `an`, and `half`. Calendar output supports today and tomorrow, 24-hour clocks, and AM/PM.
36
+
37
+ Weekdays, named months, absolute dates, timezones, recurrence, and fuzzy phrases such as “sometime soon” are outside the example. Unsupported interpretations should return uncertainty. Confidence is uncalibrated, and familiar words in a novel arrangement can still produce a wrong answer.
38
+
39
+ ## Evaluation
40
+
41
+ The generator writes only training data. Validation, test, and negative challenge fixtures are maintained separately. The test split checks held-out quantities and clock values; all twelve original test inputs have token sequences present in training after numeric normalization. They are regression checks, not evidence of compositional generalization. Training reports include accuracy, loss and export validation. Browser speed is measured by the demo on your device.
42
+
43
+ The frozen `evals/generalization.json` suite tests new contexts, unit combinations, and rejection cases. Run `bun run eval:examples` after training for accuracy, coverage, and rejection measurements. See [the example audit](../example-evaluation.md).
@@ -1,88 +1,82 @@
1
1
  # Getting started
2
2
 
3
- Matchbox is a TypeScript framework for building small models that run in the browser. Start with the money example inside your existing application, train it locally, and import the result.
3
+ Train the included money parser, try it locally, and call it from your app. You need an existing JavaScript project with a `package.json`, Bun 1.4.2+, and Node.js 24+ for native Burn training. No API key is required.
4
4
 
5
- The CLI requires Bun 1.4.2 or newer and Node 24 or newer for the local training toolchain.
5
+ ## 1. Add a task
6
6
 
7
- ## Add Matchbox to your app
8
-
9
- Once the first release is published, run this inside your existing React or Next.js app:
7
+ Run from your application's root:
10
8
 
11
9
  ```sh
12
10
  bunx matchbox-ai init money --template money
13
- bunx matchbox-ai dev money
14
11
  ```
15
12
 
16
- The CLI installs `@matchbox-ai/core` as an application dependency and `@matchbox-ai/train` and `matchbox-ai` as development dependencies, using your package manager. It preserves existing scripts and framework configuration. Run your app's dev server separately. Use `--skip-install` to defer installation.
17
-
18
- When developing Matchbox itself, run `bun install` and `bun run build:packages` in this repository. Run `bun run matchbox init money --template money --directory /path/to/app --skip-install` to inspect a scaffold before the packages are published. It writes registry versions; it does not vendor a copy of the checkout.
13
+ You can also launch the CLI with `npx matchbox-ai` or `pnpm dlx matchbox-ai`. Bun is still required by the training toolchain. Initialization installs dependencies using your app's package manager and adds these files:
19
14
 
20
- ## Train in the workbench
15
+ ```text
16
+ matchbox/money/
17
+ parser.ts # Valid input and output.
18
+ pipeline.ts # Explicit learning strategy.
19
+ recipe.ts # Training token labels.
20
+ decode/decode.ts # Convert recognized spans to output.
21
+ data/train.jsonl
22
+ data/train-spans.json
23
+ evals/validation.jsonl # Gate model export.
24
+ evals/test.jsonl # Measure the selected model.
25
+ ```
21
26
 
22
- Choose **Train model**. Once training finishes, try `$15` or `around twenty six grand in euros`. Predictions run in your browser. Choose **Evaluate** to check independent test examples, or **Measure browser speed** to time the current input.
27
+ Your framework config and dev server stay as they are.
23
28
 
24
- The same operations are available in the terminal:
29
+ ## 2. Train and try it
25
30
 
26
31
  ```sh
27
32
  bunx matchbox-ai train money
33
+ bunx matchbox-ai parse money '$15' --json
28
34
  bunx matchbox-ai eval money
29
35
  ```
30
36
 
31
- ## Understand the authored task
37
+ Training writes `.matchbox/money/model.ts`, `model.matchbox`, and `report.json`. On a successful parse, `result.value` contains:
32
38
 
33
- ```text
34
- matchbox/money/
35
- parser.ts
36
- pipeline.ts
37
- lib/recipe.ts
38
- lib/decode.ts
39
- data/train.jsonl
40
- data/train-spans.json
41
- evals/validation.jsonl
42
- evals/test.jsonl
43
- .matchbox/money/
44
- model.matchbox
45
- model.ts
46
- report.json
39
+ ```json
40
+ { "amount": 15, "currency": "USD", "approximate": false }
47
41
  ```
48
42
 
49
- The parser defines valid output. The pipeline explicitly selects a token model. The recipe supplies supervised token labels; the decoder normalizes recognized spans. New training examples may need new token annotations. Read the generated task README before extending it.
43
+ The full result also includes `status` and an uncalibrated `confidence` score.
50
44
 
51
- Use `matchbox-ai init my-task --template blank` to author another task. The blank starter explicitly uses word features and finite field classification; replace that pipeline if it does not suit your task. Schemas do not automatically select numeric encodings or transformations.
45
+ For a browser workbench, run `bunx matchbox-ai dev money`. It opens at `http://localhost:4190`. Try inputs, inspect recognized tokens, and measure inference on your device. Training runs locally; predictions run in the browser.
52
46
 
53
- ## Import into React or Next.js
47
+ ## 3. Use it in your app
54
48
 
55
- The generated TypeScript wrapper needs no bundler plugin. This example assumes a component at your application root; adjust the relative path for your component's location. In Next.js, use a client component:
49
+ The generated TypeScript module works without a bundler plugin. From a file in your application root:
56
50
 
57
- ```tsx
58
- "use client";
51
+ ```ts
52
+ import money from "./.matchbox/money/model";
59
53
 
60
- import { useMatchbox } from "@matchbox-ai/core/react";
54
+ const result = await money.parse("twenty dollars");
55
+ if (result.status === "ok") {
56
+ console.log(result.value.amount); // Typed as number.
57
+ } else {
58
+ console.log(result.reason); // Ask for clarification or use a fallback.
59
+ }
60
+ ```
61
61
 
62
- const loadMoney = () => import("./.matchbox/money/model");
62
+ Adjust the relative import for your file's location. In Next.js, import the model from a client component. See [React integration](react.md) for loading state and `useMatchbox`.
63
63
 
64
- export function MoneyButton() {
65
- const { parse, status } = useMatchbox(loadMoney);
64
+ ## 4. Change the behavior
66
65
 
67
- return (
68
- <button
69
- disabled={status !== "ready"}
70
- onClick={async () => {
71
- const result = await parse("twenty dollars");
72
- if (result.status === "ok") console.log(result.value.amount);
73
- else console.log(result.reason);
74
- }}
75
- >
76
- Parse an amount
77
- </button>
78
- );
79
- }
66
+ Add input/output rows to `data/train.jsonl`. In this token-based example, add corresponding token labels to `data/train-spans.json`. Run `train` again, then `eval`. Keep validation and test examples separate from training.
67
+
68
+ The model learns which spans represent an amount, currency, or multiplier. `decode/decode.ts` does the arithmetic. Read [the money example](examples/money.md) before extending its supported number formats.
69
+
70
+ To start your own task:
71
+
72
+ ```sh
73
+ bunx matchbox-ai init intent --template blank
80
74
  ```
81
75
 
82
- Train before your application build. Generated artifacts remain ignored, so CI needs to train or restore a previously evaluated artifact. Import training helpers only in the authored pipeline and training scripts, never in client components. For `.matchbox` imports with Vite, the optional [Vite integration](react.md) remains available.
76
+ The blank template uses a finite field classifier and empty datasets. Define your labels, add training and independent eval examples, then train. [Choose a pipeline](pipelines.md) before using it for numeric or compositional output.
83
77
 
84
- ## Run the repository showcase
78
+ ## 5. Build and deploy
85
79
 
86
- From the Matchbox checkout, `bun run dev` trains the examples and starts the showcase. The home page demonstrates customer filtering; `/training` demonstrates money parsing and the parity training check.
80
+ Generated models are ignored by Git. Train before your app build, for example `bunx matchbox-ai train money && npm run build`, or restore a previously evaluated artifact together with its matching schema and decoder.
87
81
 
88
- Continue with [CLI](cli.md), [Evaluation](evaluation.md), [Training pipelines](pipelines.md), or [Project structure](project-structure.md).
82
+ Continue with [Training](training.md), [Evaluating](evaluation.md), [CLI commands](cli.md), [API reference](reference/README.md), or [project configuration](reference/configuration.md).
@@ -0,0 +1,31 @@
1
+ # Native packages
2
+
3
+ The training package bundles prebuilt Node-API binaries. Installing Matchbox does not download executables from GitHub, run an install script, or compile Rust. The loader selects the binary for the operating system, CPU architecture and Linux libc. Browser inference continues to use the separate WASM asset in the core package.
4
+
5
+ ## Platform coverage
6
+
7
+ The build and installed-package checks run on these targets:
8
+
9
+ | Platform | Architectures | Verification environment |
10
+ | ----------- | ------------- | ------------------------- |
11
+ | macOS | x64 and ARM64 | macOS 15. |
12
+ | Linux glibc | x64 and ARM64 | Ubuntu 22.04. |
13
+ | Linux musl | x64 and ARM64 | Node 24 Alpine container. |
14
+ | Windows | x64 | Windows Server 2025. |
15
+ | Windows | ARM64 | Windows 11 ARM. |
16
+
17
+ Node 24 runs the installed-package checks on every target. Bun checks additionally run on macOS, glibc Linux and Windows x64. This matrix does not claim Bun support on Windows ARM64 or Alpine. Older operating systems and other architectures are outside the verified support matrix.
18
+
19
+ All binaries ship inside @matchbox-ai/train. This increases the development dependency's download size, but keeps installation independent of optional dependencies and install-script permissions. These binaries do not enter the browser bundle.
20
+
21
+ ## Building and verifying
22
+
23
+ `scripts/native-targets.json` defines the supported targets and artifact names. The native workflow compiles each target, then exercises sequence and record training through its loader. Musl builds use a dynamic C runtime and run in Alpine rather than being tested against glibc.
24
+
25
+ The packed-package workflow assembles all binaries, packs the three npm packages, and installs those archives in isolated directories with `--ignore-scripts`. It trains through @matchbox-ai/train and runs the generated model, including WASM inference. These directories contain no Rust sources or build output. Every target must pass before the release pack job runs.
26
+
27
+ The release workflow also checks that all eight binaries are present before Changesets packs. Model binaries and generated WASM remain ignored by Git. Contributors still need Rust to build from source; package consumers do not.
28
+
29
+ Run `bun run build:rust` for the local platform. A missing platform binary produces a loader error identifying the operating system, architecture and libc. There is no automatic compilation fallback.
30
+
31
+ The packaging convention follows [prebuild's bundled distribution](https://github.com/prebuild/prebuildify) and uses [node-gyp-build](https://github.com/prebuild/node-gyp-build) only as a loader.
@@ -1,3 +1,3 @@
1
1
  # Neural training
2
2
 
3
- See [pipelines](pipelines.md) for the supported native TensorFlow trainers and [evaluation](evaluation.md) for dataset separation and export checks. Examples use explicit pipeline.ts declarations; recipes and decoders are application-owned.
3
+ See [pipelines](pipelines.md) for the supported native Burn trainers and [evaluation](evaluation.md) for dataset separation and export checks. Examples use explicit pipeline.ts declarations; recipes and decoders are application-owned.
@@ -13,9 +13,6 @@ const task = defineParser({
13
13
  minimum: z.number().nonnegative(),
14
14
  owner: z.string().nullable().optional(),
15
15
  }),
16
- fields: {
17
- minimum: { type: "money", aliases: ["ARR"] },
18
- },
19
16
  });
20
17
 
21
18
  type Output = InferOutput<typeof task>;
@@ -34,7 +31,21 @@ const metadata = task.toJSON();
34
31
  const serialized = JSON.stringify(task); // Uses the same metadata representation.
35
32
  ```
36
33
 
37
- Validation returns a discriminated `ValidationResult<T>`. Invalid task definitions throw `TypeError` at definition time with a schema path. Invalid example values return issues rather than being silently normalized. There is no `parse(text)` inference method yet.
34
+ Validation returns a discriminated `ValidationResult<T>`. Invalid task definitions throw `TypeError` at definition time with a schema path. Invalid example values return issues rather than being silently normalized. The task definition has no inference method; call `parse` on the generated model instead.
35
+
36
+ ## Arguments and return value
37
+
38
+ `defineParser(config: ParserConfig<Output>): ParserDefinition<Output>` is exported from `@matchbox-ai/core`.
39
+
40
+ | Argument | Required | Contract |
41
+ | -------- | -------- | ----------------------------------------------------- |
42
+ | `input` | Yes. | `z.ZodString`, with supported constraints. |
43
+ | `output` | Yes. | A supported structured Zod schema. |
44
+ | `fields` | No. | `Record<string, FieldMetadata>`; inert metadata only. |
45
+
46
+ `FieldMetadata` has optional `type: string`, `aliases: readonly string[]`, and `description: string`. Metadata never enables money parsing or other domain behavior.
47
+
48
+ The result exposes `kind: "parser"`, `input`, `output`, `validateInput(unknown)`, `validateOutput(unknown)`, and `toJSON()`. Validation returns `{ success: true, data }` or `{ success: false, issues }`, where every `ValidationIssue` has `code`, `path`, and `message`. `InferOutput<typeof task>` derives the validated output type. `ParserMetadata` is the detached JSON representation shown below.
38
49
 
39
50
  ## Supported schemas
40
51
 
@@ -70,17 +81,6 @@ The serialized definition contains:
70
81
 
71
82
  Metadata is captured at definition time. Every `toJSON()` call returns a detached copy. Treat the supplied Zod schemas as immutable after definition; use Zod's schema-building methods to create a new task when its contract changes.
72
83
 
73
- The format version identifies Matchbox's metadata representation, not a model or dataset version. A future loader must reject unsupported versions. This ticket provides serialization only; it does not reconstruct executable validators from JSON.
84
+ The format version identifies Matchbox's metadata representation, not a model or dataset version. Artifact loading rejects unsupported format versions. The generated wrapper imports the authored task to validate model output.
74
85
 
75
86
  Zod's global metadata registry is intentionally excluded. `.meta()` must not override structural keywords or inject values that are not JSON. Descriptions, aliases, and semantic types belong in the optional `fields` object for now. Those hints are inert, copied JSON. Matchbox does not infer a field-to-output mapping or normalize money/countries from their names.
76
-
77
- ## Dependency boundary
78
-
79
- Zod 4.6.3 is an explicit, pinned core dependency and is external to the Rolldown bundle. The API uses a small isolated portion of Zod Core's schema/check definitions to reject unsupported behavior before JSON conversion. Zod upgrades must run the contract suite, including negative cases.
80
-
81
- Validation uses Zod's non-JIT path. The browser smoke check exercises definition, validation, and metadata serialization through the built package. This is the task-authoring API; its dependency size is not a claim about the future generated inference runtime.
82
-
83
- ## References
84
-
85
- - [Zod JSON Schema conversion](https://zod.dev/json-schema) documents representable schemas and conversion controls.
86
- - [Zod Core](https://zod.dev/packages/core) documents schema and check introspection.
package/docs/pipelines.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # Explicit pipelines
2
2
 
3
- The parser defines valid input and output. The pipeline defines how the model learns. Matchbox requires pipeline.ts for conventional tasks; the scaffold writes it visibly.
3
+ The parser defines valid input and output. The pipeline defines how the model learns. Matchbox requires `pipeline.ts` or `pipeline/pipeline.ts` for conventional tasks; the scaffold writes it visibly.
4
4
 
5
5
  ```ts
6
- import { definePipeline, wordTokens, fieldClassifier } from "@matchbox-ai/train";
6
+ import { definePipeline, fieldClassifier } from "@matchbox-ai/train";
7
7
  export default definePipeline({
8
- input: wordTokens(),
9
8
  prediction: fieldClassifier(),
10
9
  acceptance: { minAccuracy: 0.95, maxBytes: 64000 },
11
10
  });
@@ -18,13 +17,13 @@ An explicit token pipeline uses application-owned supervision and decoding:
18
17
  ```ts
19
18
  import { definePipeline, tokenClassifier } from "@matchbox-ai/train";
20
19
  export default definePipeline({
21
- prediction: tokenClassifier({ recipe: "./lib/recipe.ts", decode: "./lib/decode.ts" }),
20
+ prediction: tokenClassifier(),
22
21
  acceptance: { minAccuracy: 0.85, maxBytes: 24000 },
23
22
  });
24
23
  ```
25
24
 
26
- Paths resolve relative to the task. The recipe supplies tokenizer, labels, readout, and annotation alignment. The decoder receives labeled spans and returns a candidate output or null. Matchbox verifies training annotations decode to the supplied training outputs. Recipe code runs during training; decoder code ships with the browser artifact and must remain browser-safe.
25
+ Matchbox discovers `recipe.ts` or `recipe/recipe.ts`, and `decode.ts` or `decode/decode.ts`. Explicit path overrides resolve relative to the task directory. The recipe supplies tokenizer, labels, readout, and annotation alignment. The decoder receives labeled spans and returns a candidate output or null. Matchbox verifies training annotations decode to the supplied training outputs. Recipe code runs during training; decoder code ships with the browser artifact and must remain browser-safe.
27
26
 
28
27
  These are two existing, evaluated presets. Decimal codecs, arbitrary graphs, automatic architecture search, and hidden domain normalizers are not implemented. New primitives should demonstrate their limitations and held-out behavior before becoming defaults.
29
28
 
30
- Programmatic training uses await train("money", { onProgress }) from @matchbox-ai/train and follows the same validation and packaging path as the CLI. Importing the authoring helpers does not initialize native TensorFlow; training loads it when invoked.
29
+ Programmatic training uses await train("money", { onProgress }) from @matchbox-ai/train and follows the same validation and packaging path as the CLI. Importing the authoring helpers does not initialize native Burn; training loads it when invoked.
@@ -2,18 +2,19 @@
2
2
 
3
3
  Import these from @matchbox-ai/train:
4
4
 
5
- | Primitive | Contract |
6
- | --------------- | ------------------------------------------------------------------------------ |
7
- | definePipeline | Validates an explicit pipeline declaration and acceptance thresholds. |
8
- | wordTokens | Selects literal word features for field classification. |
9
- | fieldClassifier | Selects independent categorical output heads over training values. |
10
- | tokenClassifier | Selects the sequence trainer with explicit recipe and decoder module paths. |
11
- | tokenize | Shares the portable tokenizer with annotation generators. |
12
- | train | Runs project discovery, native training, validation, and packaging. |
13
- | evaluate | Evaluates a parser against examples and a supplied output-validation function. |
14
- | SequenceRecipe | Types application-owned sequence supervision. |
15
- | OutputDecoder | Types a browser-safe sequence-to-output decoder. |
5
+ | Primitive | Contract |
6
+ | --------------- | --------------------------------------------------------------------------------------- |
7
+ | definePipeline | Validates an explicit pipeline declaration and acceptance thresholds. |
8
+ | fieldClassifier | Selects independent categorical output heads over training values. |
9
+ | tokenClassifier | Selects the sequence trainer with conventionally discovered recipe and decoder modules. |
10
+ | tokenize | Shares the portable tokenizer with annotation generators. |
11
+ | train | Runs project discovery, native training, validation, and packaging. |
12
+ | evaluate | Evaluates a parser against examples and a supplied output-validation function. |
13
+ | SequenceRecipe | Types application-owned sequence supervision. |
14
+ | OutputDecoder | Types a browser-safe sequence-to-output decoder. |
16
15
 
17
16
  The field classifier derives its field names and value domains from training outputs. The output schema still independently validates predictions. The sequence recipe owns tokenization, so it cannot also specify a separate input encoder.
18
17
 
19
18
  Tensor shapes, exported weight readers, and architecture-specific predictors belong to @matchbox-ai/core/internal. That subpath supports coordinated framework packages and research tests; application code should use the documented task, pipeline, and runtime interfaces.
19
+
20
+ See [token supervision](../reference/supervision.md) for explicit rejection examples and optional training token masking.
@@ -13,8 +13,10 @@ my-app/
13
13
  data/train.jsonl
14
14
  evals/validation.jsonl
15
15
  evals/test.jsonl
16
- evals/baseline.ts # Optional.
17
- lib/ # Optional application-owned helpers.
16
+ recipe.ts # Token-classifier supervision.
17
+ decode/
18
+ decode.ts # Browser-side output construction.
19
+ number-words.ts # Decoder helper.
18
20
  .matchbox/money/
19
21
  model.matchbox
20
22
  model.ts
@@ -22,7 +24,7 @@ my-app/
22
24
  report.json
23
25
  ```
24
26
 
25
- The CLI discovers these paths. Multiple tasks require an explicit name; it never silently chooses the first one. Commands can also target a project directory, task directory, or explicit matchbox.config.ts. A task-local config may override paths; ordinary examples need only parser.ts and pipeline.ts.
27
+ The CLI discovers these paths. Multiple tasks require an explicit name; it never silently chooses the first one. Commands can also target a project directory, task directory, or explicit matchbox.config.ts. A task-local config may override paths; field-classifier tasks need parser and pipeline modules; token classifiers also need recipe and decode modules.
26
28
 
27
29
  Generated artifacts are ignored. Validation gates packaging; test data does not select the model. Data generators live in the project-level scripts/ directory and write only matchbox/<task>/data/, preserving evals/ independently.
28
30
 
@@ -39,3 +41,15 @@ export default {
39
41
  ```
40
42
 
41
43
  The config overrides paths and acceptance settings. Keep the encoder, supervision, prediction strategy, and decoder explicit in `pipeline.ts`. The current loader supports TypeScript configuration; there is no separate JSON config format.
44
+
45
+ ## Named entry points
46
+
47
+ Parser, pipeline, recipe, and decode modules each use the same convention: `X.ts` for a small module, or `X/X.ts` alongside supporting files. For example, `decode.ts` can become `decode/decode.ts` without changing `tokenClassifier()` in the pipeline. Matchbox rejects both forms existing at once. No `index.ts` is required or discovered.
48
+
49
+ `tokenClassifier()` discovers the recipe and decoder by name. The recipe still explicitly defines tokenization, labels, readout, and supervision. The decoder still owns application-specific output construction. File discovery makes no learning or normalization choices.
50
+
51
+ Keep helpers with the module that owns them. Shared domain code can have its own named folder: the filter example's `countries/` is used by the schema, training recipe, browser decoder. It is ordinary application code, not another framework-discovered entry point.
52
+
53
+ Import named authored modules directly, such as `./decode/decode`. Task directories do not need a barrel exporting training and runtime internals together. Applications consume the generated `.matchbox/<task>/model.ts` wrapper.
54
+
55
+ Generated wrappers import the concrete parser and decoder entry files. Recipe and training dependencies remain outside those browser imports.
package/docs/react.md CHANGED
@@ -1,16 +1,58 @@
1
- # @matchbox-ai/core/react
1
+ # React integration
2
2
 
3
- Load typed Matchbox parsers in React with `useMatchbox`.
3
+ `useMatchbox` loads a parser and exposes initialization state. Use a stable loader outside the component. The generated TypeScript module needs no bundler plugin.
4
4
 
5
5
  ```tsx
6
+ "use client";
7
+
8
+ import { useState } from "react";
6
9
  import { useMatchbox } from "@matchbox-ai/core/react";
7
10
 
8
- const loadFilters = () => import("./generated/filters.matchbox");
11
+ const loadMoney = () => import("./.matchbox/money/model");
12
+
13
+ export function MoneyInput() {
14
+ const { parse, status, error } = useMatchbox(loadMoney);
15
+ const [message, setMessage] = useState("");
9
16
 
10
- function Search() {
11
- const parser = useMatchbox(loadFilters);
12
- return <input onChange={async (event) => console.log(await parser.parse(event.target.value))} />;
17
+ return (
18
+ <div>
19
+ <button
20
+ disabled={status !== "ready"}
21
+ onClick={async () => {
22
+ try {
23
+ const result = await parse("twenty dollars");
24
+ setMessage(
25
+ result.status === "ok"
26
+ ? `${result.value.amount} ${result.value.currency}`
27
+ : result.reason,
28
+ );
29
+ } catch (cause) {
30
+ setMessage(String(cause));
31
+ }
32
+ }}
33
+ >
34
+ Parse twenty dollars
35
+ </button>
36
+ <output aria-live="polite">{error ?? message}</output>
37
+ </div>
38
+ );
13
39
  }
14
40
  ```
15
41
 
16
- The hook exposes loading, ready, and error state. Keep the loader outside the component. React is a peer dependency of this package; core and training do not depend on React. See the [end-to-end guide](end-to-end.md).
42
+ The path above assumes a component at the app root. Adjust it for your file's location. In Next.js, keep inference in a client component as shown. For direct artifact imports in Vite, see [the Vite plugin](reference/vite.md).
43
+
44
+ ## useMatchbox contract
45
+
46
+ `useMatchbox<Output>(loader: () => Promise<{ default: MatchboxParser<Output> }>)` is exported from `@matchbox-ai/core/react`.
47
+
48
+ | Return field | Type | Behavior |
49
+ | ------------ | -------------------------------------------------- | ----------------------------------------------- |
50
+ | `status` | `"loading"`, `"ready"`, or `"error"`. | Reflects the current loader and initialization. |
51
+ | `error` | `string` or `null`. | Loading error message. |
52
+ | `parse` | `(input: string) => Promise<ParseResult<Output>>`. | Runs inference; call failures reject. |
53
+
54
+ The hook calls optional `load` on mount. It does not store prediction results, debounce requests, catch parse errors, or dispose shared module instances. Applications own those behaviors. React 19 is the current peer requirement.
55
+
56
+ ## Continuous input
57
+
58
+ For parsing while typing, keep the latest input in state and start a parse in an effect. Ignore results from an effect that has already cleaned up so an older prediction cannot overwrite a newer one. The hook's `status` describes model initialization, not an individual prediction.
@@ -0,0 +1,25 @@
1
+ # API reference
2
+
3
+ The examples use these public exports. Each page lists imports, arguments, return values, and failure behavior.
4
+
5
+ | Package | Export | Reference |
6
+ | ---------------------------- | ------------------------------------------------------------------ | --------------------------------------------------- |
7
+ | `@matchbox-ai/core` | `defineParser`, parser and validation types | [Task definition](../parser-api.md) |
8
+ | `@matchbox-ai/core` | `parseDatasets`, dataset types | [Datasets](../dataset-format.md) |
9
+ | `@matchbox-ai/core/runtime` | `createParser`, `MatchboxParser`, `ParseResult` | [Runtime](runtime.md) |
10
+ | `@matchbox-ai/core/runtime` | `Token`, `TaggedToken`, `SequenceDecoder` | [Token supervision](supervision.md) |
11
+ | `@matchbox-ai/core/runtime` | `compileClauses`, `Predicate`, `FilterExpression` | [Filter compilation](runtime.md#compileclauses) |
12
+ | `@matchbox-ai/core/react` | `useMatchbox` | [React](../react.md) |
13
+ | `@matchbox-ai/core/vite` | `matchbox` | [Vite](vite.md) |
14
+ | `@matchbox-ai/train` | `definePipeline`, `Pipeline`, `fieldClassifier`, `tokenClassifier` | [Pipeline API](pipeline.md) |
15
+ | `@matchbox-ai/train` | `SequenceRecipe`, `OutputDecoder`, `tokenize` | [Token supervision](supervision.md) |
16
+ | `@matchbox-ai/train` | `train`, `TrainingConfig` | [Training API](training.md) |
17
+ | `@matchbox-ai/train` | `evaluate` | [Evaluation API](evaluation.md) |
18
+ | `@matchbox-ai/train/project` | `discover`, `listTasks`, `loadConfig`, `loadArtifact` | [Project tooling](configuration.md#project-tooling) |
19
+ | `matchbox-ai` | Eight CLI commands | [CLI reference](../cli.md) |
20
+
21
+ `@matchbox-ai/core/internal` is for coordinated framework packages and research tests. Application code should use the entry points above.
22
+
23
+ `version` is exported from `@matchbox-ai/core` and contains the installed core package version.
24
+
25
+ Inputs are currently strings. Support for structured features requires a separate input and encoder contract.
@@ -0,0 +1,43 @@
1
+ # Project configuration
2
+
3
+ Conventional tasks need parser and pipeline entry points, each authored as `X.ts` or `X/X.ts`. Add `matchbox.config.ts` only to override paths or acceptance settings. The default export must satisfy `TrainingConfig` from `@matchbox-ai/train`.
4
+
5
+ ```ts
6
+ import type { TrainingConfig } from "@matchbox-ai/train";
7
+ export default {
8
+ train: "../../datasets/training.jsonl",
9
+ validation: "../../datasets/validation.jsonl",
10
+ eval: "../../datasets/test.jsonl",
11
+ } satisfies TrainingConfig;
12
+ ```
13
+
14
+ Paths resolve relative to the config's directory, normally `matchbox/<task>/`. Task config overrides pipeline acceptance values, which override defaults.
15
+
16
+ | Field | Type | Default |
17
+ | ------------- | -------------------------------------- | -------------------------------------------------------------------------------------------- |
18
+ | `task` | String path. | `parser.ts` or `parser/parser.ts`. |
19
+ | `train` | String path. | `./data/train.jsonl`. |
20
+ | `validation` | String path. | `./evals/validation.jsonl`. |
21
+ | `eval` | String path. | `./evals/test.jsonl`. |
22
+ | `output` | Path ending in `.matchbox`. | Project-level `.matchbox/<task>/model.matchbox`. |
23
+ | `minAccuracy` | Number from 0 to 1. | `0.95`, unless set in the pipeline. |
24
+ | `maxBytes` | Positive number. | `64000`, unless set in the pipeline. |
25
+ | `challenges` | Optional JSON path. | `./evals/challenges.json` if present. |
26
+ | `sequence` | `{ recipe: string, decoder: string }`. | Derived from the token pipeline. This is a legacy configuration route; prefer `pipeline.ts`. |
27
+
28
+ Unknown properties are rejected. JSON configuration files are not supported. Challenge JSON is an array of `{ input: string, output: null }` used by sequence reports.
29
+
30
+ ## Project tooling
31
+
32
+ These APIs support CLI and build integrations. Import from `@matchbox-ai/train/project` in Node/Bun only.
33
+
34
+ | Function | Arguments | Return value |
35
+ | -------------- | ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
36
+ | `discover` | `target?: string, cwd?: string` | Promise of an absolute task directory or config path. Walks ancestors from `cwd` (default `process.cwd()`). Multiple tasks require an explicit target. |
37
+ | `listTasks` | Application root directory. | Promise of sorted task names immediately under `matchbox/`, recognizing both parser entry forms. |
38
+ | `loadConfig` | Task directory or config path. | Promise of `{ config, root, pipelinePath }` with defaults and overrides resolved. |
39
+ | `loadArtifact` | Task directory or config path. | Promise of `{ artifact, task, decode, parser, inspect, output, config, root }`. Requires a previously trained artifact. |
40
+
41
+ `loadArtifact().inspect(input)` returns model diagnostics and the candidate, without representing a final validated answer. These details differ by strategy. Use `parser.parse(input)` for application behavior. Discovery, missing files, invalid config, and incompatible artifacts reject their promises.
42
+
43
+ `loadConfig` resolves task, recipe, and decoder module paths to absolute filenames. An extensionless override such as `task: "./schema"` resolves `schema.ts` or `schema/schema.ts`. An explicit filename bypasses conventional lookup for that module. Both conventional forms existing produces an error.
@@ -0,0 +1,21 @@
1
+ # Evaluation API
2
+
3
+ ```ts
4
+ import { evaluate } from "@matchbox-ai/train";
5
+ const metrics = await evaluate(parser, examples, (value) => task.validateOutput(value).success);
6
+ ```
7
+
8
+ Arguments are a `MatchboxParser<unknown>`, nonempty `readonly DatasetExample<unknown>[]`, and `(value: unknown) => boolean` for output validation. It returns a promise for the metrics below. It does not train, select thresholds, dispose the parser, or enforce an acceptance gate. Caller errors and parser rejections propagate. Pass a nonempty set; empty input currently produces non-finite ratio metrics.
9
+
10
+ | Field | Meaning |
11
+ | -------------------- | -------------------------------------------------------------------------------- |
12
+ | `examples` | Number evaluated. |
13
+ | `exactAccuracy` | Fraction whose complete output matches. |
14
+ | `invalidOutputRate` | Fraction of evaluated inputs producing an accepted output that fails validation. |
15
+ | `accepted` | Count returning `status: "ok"`. |
16
+ | `acceptedAccuracy` | Exact accuracy among accepted results, or `null` if none. |
17
+ | `abstentionRate` | Fraction returning uncertainty. |
18
+ | `correctAbstentions` | Count correctly abstaining on rows with `output: null`. |
19
+ | `failures` | Array of `{ input, expected, actual }`; uncertainty appears as `actual: null`. |
20
+
21
+ Object key order does not affect exact matching; array order does. See [evaluation](../evaluation.md) for separate training, validation, test, and challenge sets.
@@ -0,0 +1,43 @@
1
+ # Pipeline API
2
+
3
+ ```ts
4
+ import { definePipeline, fieldClassifier, tokenClassifier } from "@matchbox-ai/train";
5
+ ```
6
+
7
+ ## definePipeline
8
+
9
+ `definePipeline(pipeline: Pipeline): Pipeline` validates a declaration and returns it. Invalid declarations throw a Zod validation error. It does not train or load Burn.
10
+
11
+ | Property | Type | Required | Behavior |
12
+ | ------------------------ | -------------------------------------- | -------- | ---------------------------------------------- |
13
+ | `prediction` | Field or token classifier declaration. | Yes. | Chooses one of the two implemented strategies. |
14
+ | `acceptance.minAccuracy` | Number from 0 to 1. | No. | Minimum validation exact accuracy for export. |
15
+ | `acceptance.maxBytes` | Positive number. | No. | Maximum serialized model size in bytes. |
16
+
17
+ Unknown properties are rejected. See [configuration](configuration.md) for resolved defaults and overrides.
18
+
19
+ ## fieldClassifier
20
+
21
+ `fieldClassifier(): { kind: "field-classifier" }` declares independent categorical predictions over values observed in training outputs. It uses literal word features fitted from training data only. Word order is discarded; unfamiliar vocabulary can cause uncertainty.
22
+
23
+ ```ts
24
+ export default definePipeline({
25
+ prediction: fieldClassifier(),
26
+ acceptance: { minAccuracy: 0.95 },
27
+ });
28
+ ```
29
+
30
+ Use it for small, finite output domains. A numeric field is still a finite class, so this strategy cannot produce an unseen number. It is not a general JSON generator.
31
+
32
+ ## tokenClassifier
33
+
34
+ `tokenClassifier(options?)` returns a token classifier declaration. It discovers `recipe.ts` or `recipe/recipe.ts`, and `decode.ts` or `decode/decode.ts`. Both modules remain authored and required for training. Optional `recipe` and `decode` string paths override these locations, relative to the task directory even when the pipeline lives in `pipeline/pipeline.ts`. Explicit filenames are used exactly; extensionless paths follow the named file-or-folder convention.
35
+
36
+ ```ts
37
+ export default definePipeline({
38
+ prediction: tokenClassifier(),
39
+ acceptance: { minAccuracy: 0.9 },
40
+ });
41
+ ```
42
+
43
+ The recipe owns tokenization and training supervision. The decoder ships to the browser. See [their contracts](supervision.md). Schemas do not select encodings, dictionaries, or normalization rules.