decision-toolkit 0.4.2__tar.gz → 0.4.4__tar.gz
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.
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/CHANGELOG.md +22 -1
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/PKG-INFO +15 -11
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/README.md +14 -10
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/CLI.md +114 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/EXAMPLES.md +13 -3
- decision_toolkit-0.4.4/docs/FAQ.md +159 -0
- decision_toolkit-0.4.4/docs/GLOSSARY.md +36 -0
- decision_toolkit-0.4.4/docs/INSTALLATION.md +175 -0
- decision_toolkit-0.4.4/docs/LIBRARY.md +250 -0
- decision_toolkit-0.4.4/docs/MODELS.md +218 -0
- decision_toolkit-0.4.4/docs/QUICKSTART.md +144 -0
- decision_toolkit-0.4.4/docs/RECIPES.md +140 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/RELEASE.md +12 -8
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/REST.md +6 -3
- decision_toolkit-0.4.4/docs/TROUBLESHOOTING.md +258 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/VARIANTS.md +11 -8
- decision_toolkit-0.4.4/docs/index.md +135 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/models/README.md +2 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/pyproject.toml +1 -1
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/__init__.py +1 -1
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/catalog.py +1 -1
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/cli.py +19 -11
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/contracts/systemone_v1.py +4 -4
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/decision_model.py +1 -3
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_cli.py +8 -2
- decision_toolkit-0.4.4/tests/test_docs.py +46 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_server.py +1 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/uv.lock +1 -1
- decision_toolkit-0.4.2/docs/index.md +0 -56
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/.github/workflows/ci.yml +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/.github/workflows/docs.yml +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/.github/workflows/release.yml +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/.gitignore +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/CONTRIBUTING.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/LICENSE +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/SECURITY.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/THIRD_PARTY_NOTICES.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/bench/README.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/bench/__init__.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/bench/load.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/bench/results/2026-10-20-calibration.json +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/bench/results/2026-10-20-load.json +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/bench/results/2026-10-20-smoke.json +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/bench/run.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/bench/suites/calibration.jsonl +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/bench/suites/smoke.jsonl +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/BENCH.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/CORE.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/OPERATIONS.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/models/gliner2.5-decide.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/models/gliner2.5-multi.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/models/julia-1.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/models/laya-multilingual.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/models/laya.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/models/open-jev-deberta-v3-large.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/models/opendecider-nano.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/docs/models/strands-decider-2b.md +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/__main__.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/adapters/__init__.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/adapters/base.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/adapters/gliner2.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/adapters/gliner2_decide.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/adapters/julia.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/adapters/laya.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/adapters/opendecider.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/adapters/openjev.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/adapters/strands_decider.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/calibration.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/config.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/contracts/__init__.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/contracts/common.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/contracts/mapping.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/contracts/openai_decisions_beta.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/engine/__init__.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/errors.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/limits.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/metrics.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/models.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/observability.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/py.typed +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/registry.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/results.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/schema.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/server.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/src/decision_toolkit/tracing.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/__init__.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/conftest.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_adapters_gliner2.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_adapters_gliner2_decide.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_adapters_julia.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_adapters_laya.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_adapters_opendecider.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_adapters_openjev.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_adapters_strands.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_bench.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_catalog.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_config.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_contracts_conformance.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_core_phase1.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_decision_model.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_fuzz_rest.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_help_examples.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_integration_gliner2.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_models.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_operations.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_results.py +0 -0
- {decision_toolkit-0.4.2 → decision_toolkit-0.4.4}/tests/test_schema.py +0 -0
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
All notable changes to this project are documented here. Version `0.4.
|
|
3
|
+
All notable changes to this project are documented here. Version `0.4.4` is
|
|
4
4
|
published on PyPI.
|
|
5
5
|
|
|
6
|
+
## [0.4.4] — 2026-10-21
|
|
7
|
+
|
|
8
|
+
Documentation correction: removed the remaining wording that described
|
|
9
|
+
`variant` as a request extension. System One and OpenAI request bodies have no
|
|
10
|
+
`variant` field; quantization is selected with the model alias and the chosen
|
|
11
|
+
variant is reported under `x_decision_toolkit` in responses. No runtime changes.
|
|
12
|
+
|
|
13
|
+
## [0.4.3] — 2026-10-21
|
|
14
|
+
|
|
15
|
+
Documentation and help UX improvements. Added a Quickstart, Installation guide,
|
|
16
|
+
Models/cache guide, Library guide, Troubleshooting, FAQ, Glossary and Recipes;
|
|
17
|
+
reorganized the documentation navigation around user tasks; added CLI option
|
|
18
|
+
tables and examples; corrected the README REST alias text; clarified that the
|
|
19
|
+
server extra is installed as `[onnx,server]`. The CLI now suggests the exact
|
|
20
|
+
download/use commands for an empty cache, marks current/cached catalog rows, and
|
|
21
|
+
reports user-facing catalog counts in `dtk doctor`. Public model metadata uses
|
|
22
|
+
`available` instead of an internal status label. No inference, model, or catalog
|
|
23
|
+
content changes.
|
|
24
|
+
|
|
6
25
|
## [0.4.2] — 2026-10-21
|
|
7
26
|
|
|
8
27
|
Documentation cleanup: removed internal project language (`m0`, phase numbers,
|
|
@@ -223,6 +242,8 @@ README correction. No code or model behavior changed.
|
|
|
223
242
|
- Typed `DecisionModel` API with lifecycle, batching, async, usage, warnings,
|
|
224
243
|
normalized confidence, capabilities, structured events and atomic model store.
|
|
225
244
|
|
|
245
|
+
[0.4.4]: https://pypi.org/project/decision-toolkit/0.4.4/
|
|
246
|
+
[0.4.3]: https://pypi.org/project/decision-toolkit/0.4.3/
|
|
226
247
|
[0.4.2]: https://pypi.org/project/decision-toolkit/0.4.2/
|
|
227
248
|
[0.4.1]: https://pypi.org/project/decision-toolkit/0.4.1/
|
|
228
249
|
[0.4.0]: https://pypi.org/project/decision-toolkit/0.4.0/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: decision-toolkit
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
4
4
|
Summary: Local-first toolkit for open-weights decision models: one ONNX engine, one adapter per model contract, typed choice/yes-no/score decisions with probabilities on CPU.
|
|
5
5
|
Project-URL: Homepage, https://github.com/gia-uh/decision-toolkit
|
|
6
6
|
Project-URL: Repository, https://github.com/gia-uh/decision-toolkit
|
|
@@ -50,24 +50,27 @@ One **ONNX engine** (`onnxruntime`), in-process, on CPU. One **adapter per model
|
|
|
50
50
|
contract** (how a model is fed and read). Three thin surfaces over the same API:
|
|
51
51
|
**library**, **CLI** and **REST**.
|
|
52
52
|
|
|
53
|
-
Co-developed by [GIA-UH](https://github.com/gia-uh) and [Syalia S.R.L.](https://github.com/syalia-srl)
|
|
53
|
+
**Co-developed by [GIA-UH](https://github.com/gia-uh) and [Syalia S.R.L.](https://github.com/syalia-srl).**
|
|
54
54
|
|
|
55
55
|
**Documentation:** <https://gia-uh.github.io/decision-toolkit/>. Start with
|
|
56
|
-
[
|
|
56
|
+
[Quickstart](https://gia-uh.github.io/decision-toolkit/QUICKSTART/) for the library, REST
|
|
57
57
|
and CLI. `dtk --help` and every subcommand help also include runnable examples.
|
|
58
|
+
See [Models](https://gia-uh.github.io/decision-toolkit/MODELS/) for the cache and
|
|
59
|
+
variants, and [Troubleshooting](https://gia-uh.github.io/decision-toolkit/TROUBLESHOOTING/)
|
|
60
|
+
when a command fails.
|
|
58
61
|
|
|
59
62
|
## Installation
|
|
60
63
|
|
|
61
64
|
```bash
|
|
62
|
-
uv pip install decision-toolkit # library + CLI
|
|
65
|
+
uv pip install decision-toolkit # library + CLI; add [onnx] to run models
|
|
63
66
|
uv pip install "decision-toolkit[onnx]" # + onnxruntime, tokenizers (the model runtime)
|
|
64
|
-
uv pip install "decision-toolkit[server]"
|
|
67
|
+
uv pip install "decision-toolkit[onnx,server]" # + REST server (FastAPI)
|
|
65
68
|
```
|
|
66
69
|
|
|
67
70
|
The project is managed with [uv](https://docs.astral.sh/uv/) and ships a committed `uv.lock`. Published
|
|
68
71
|
wheels remain compatible with `pip` for environments that do not use uv.
|
|
69
72
|
|
|
70
|
-
PyPI: <https://pypi.org/project/decision-toolkit/0.4.
|
|
73
|
+
PyPI: <https://pypi.org/project/decision-toolkit/0.4.4/>. See
|
|
71
74
|
[docs/RELEASE.md](https://github.com/gia-uh/decision-toolkit/blob/main/docs/RELEASE.md)
|
|
72
75
|
for the Trusted Publishing flow and clean-install checks.
|
|
73
76
|
|
|
@@ -167,7 +170,7 @@ batch, custom `--adapter/--files`, config and completion.
|
|
|
167
170
|
**3. As a REST service (optional extra)**
|
|
168
171
|
|
|
169
172
|
```bash
|
|
170
|
-
uv pip install "decision-toolkit[server]"
|
|
173
|
+
uv pip install "decision-toolkit[onnx,server]"
|
|
171
174
|
dtk serve --model gliner2.5-multi --warmup \
|
|
172
175
|
--api-key "$DECISION_TOOLKIT_API_KEY" \
|
|
173
176
|
--log-format json
|
|
@@ -176,8 +179,9 @@ dtk serve --model gliner2.5-multi --warmup \
|
|
|
176
179
|
Endpoints: `POST /v1/systemone` (TypeSafe System One), `POST /v1/decisions`
|
|
177
180
|
(OpenAI Decisions beta), `GET /v1/models` (OpenAI shape),
|
|
178
181
|
`GET /v1/decision-models` (rich catalog), `GET /v1/info`, `GET /health`,
|
|
179
|
-
`GET /ready`. Requests select `model`;
|
|
180
|
-
|
|
182
|
+
`GET /ready`. Requests select `model`; quantization is selected with the model
|
|
183
|
+
alias `id@variant` (for example `gliner2.5-multi@fp32`). There is no `variant`
|
|
184
|
+
field in either public request body. System One request validation uses the TypeSafe
|
|
181
185
|
`422 {"detail": [...]}` shape; OpenAI Decisions uses its
|
|
182
186
|
`{"error": {...}}` envelope. Every response carries `x-request-id`.
|
|
183
187
|
A standard System One client that sends `model`, `state` and `questions` can
|
|
@@ -217,7 +221,7 @@ own repo files, size and role. A `*` in the table above marks the default.
|
|
|
217
221
|
|
|
218
222
|
```bash
|
|
219
223
|
dtk models list # one row per variant; * = default
|
|
220
|
-
dtk models list --quant #
|
|
224
|
+
dtk models list --quant # accepted for compatibility; quant is always shown
|
|
221
225
|
dtk models variants gliner2.5-multi # full details for one model
|
|
222
226
|
```
|
|
223
227
|
|
|
@@ -312,7 +316,7 @@ register_adapter("my-layout", MyAdapter)
|
|
|
312
316
|
```
|
|
313
317
|
|
|
314
318
|
Custom models do not appear in `dtk models list`; the toolkit never guesses a
|
|
315
|
-
layout. If a model deserves support, it goes through
|
|
319
|
+
layout. If a model deserves support, it goes through catalog review.
|
|
316
320
|
|
|
317
321
|
## Development
|
|
318
322
|
|
|
@@ -12,24 +12,27 @@ One **ONNX engine** (`onnxruntime`), in-process, on CPU. One **adapter per model
|
|
|
12
12
|
contract** (how a model is fed and read). Three thin surfaces over the same API:
|
|
13
13
|
**library**, **CLI** and **REST**.
|
|
14
14
|
|
|
15
|
-
Co-developed by [GIA-UH](https://github.com/gia-uh) and [Syalia S.R.L.](https://github.com/syalia-srl)
|
|
15
|
+
**Co-developed by [GIA-UH](https://github.com/gia-uh) and [Syalia S.R.L.](https://github.com/syalia-srl).**
|
|
16
16
|
|
|
17
17
|
**Documentation:** <https://gia-uh.github.io/decision-toolkit/>. Start with
|
|
18
|
-
[
|
|
18
|
+
[Quickstart](https://gia-uh.github.io/decision-toolkit/QUICKSTART/) for the library, REST
|
|
19
19
|
and CLI. `dtk --help` and every subcommand help also include runnable examples.
|
|
20
|
+
See [Models](https://gia-uh.github.io/decision-toolkit/MODELS/) for the cache and
|
|
21
|
+
variants, and [Troubleshooting](https://gia-uh.github.io/decision-toolkit/TROUBLESHOOTING/)
|
|
22
|
+
when a command fails.
|
|
20
23
|
|
|
21
24
|
## Installation
|
|
22
25
|
|
|
23
26
|
```bash
|
|
24
|
-
uv pip install decision-toolkit # library + CLI
|
|
27
|
+
uv pip install decision-toolkit # library + CLI; add [onnx] to run models
|
|
25
28
|
uv pip install "decision-toolkit[onnx]" # + onnxruntime, tokenizers (the model runtime)
|
|
26
|
-
uv pip install "decision-toolkit[server]"
|
|
29
|
+
uv pip install "decision-toolkit[onnx,server]" # + REST server (FastAPI)
|
|
27
30
|
```
|
|
28
31
|
|
|
29
32
|
The project is managed with [uv](https://docs.astral.sh/uv/) and ships a committed `uv.lock`. Published
|
|
30
33
|
wheels remain compatible with `pip` for environments that do not use uv.
|
|
31
34
|
|
|
32
|
-
PyPI: <https://pypi.org/project/decision-toolkit/0.4.
|
|
35
|
+
PyPI: <https://pypi.org/project/decision-toolkit/0.4.4/>. See
|
|
33
36
|
[docs/RELEASE.md](https://github.com/gia-uh/decision-toolkit/blob/main/docs/RELEASE.md)
|
|
34
37
|
for the Trusted Publishing flow and clean-install checks.
|
|
35
38
|
|
|
@@ -129,7 +132,7 @@ batch, custom `--adapter/--files`, config and completion.
|
|
|
129
132
|
**3. As a REST service (optional extra)**
|
|
130
133
|
|
|
131
134
|
```bash
|
|
132
|
-
uv pip install "decision-toolkit[server]"
|
|
135
|
+
uv pip install "decision-toolkit[onnx,server]"
|
|
133
136
|
dtk serve --model gliner2.5-multi --warmup \
|
|
134
137
|
--api-key "$DECISION_TOOLKIT_API_KEY" \
|
|
135
138
|
--log-format json
|
|
@@ -138,8 +141,9 @@ dtk serve --model gliner2.5-multi --warmup \
|
|
|
138
141
|
Endpoints: `POST /v1/systemone` (TypeSafe System One), `POST /v1/decisions`
|
|
139
142
|
(OpenAI Decisions beta), `GET /v1/models` (OpenAI shape),
|
|
140
143
|
`GET /v1/decision-models` (rich catalog), `GET /v1/info`, `GET /health`,
|
|
141
|
-
`GET /ready`. Requests select `model`;
|
|
142
|
-
|
|
144
|
+
`GET /ready`. Requests select `model`; quantization is selected with the model
|
|
145
|
+
alias `id@variant` (for example `gliner2.5-multi@fp32`). There is no `variant`
|
|
146
|
+
field in either public request body. System One request validation uses the TypeSafe
|
|
143
147
|
`422 {"detail": [...]}` shape; OpenAI Decisions uses its
|
|
144
148
|
`{"error": {...}}` envelope. Every response carries `x-request-id`.
|
|
145
149
|
A standard System One client that sends `model`, `state` and `questions` can
|
|
@@ -179,7 +183,7 @@ own repo files, size and role. A `*` in the table above marks the default.
|
|
|
179
183
|
|
|
180
184
|
```bash
|
|
181
185
|
dtk models list # one row per variant; * = default
|
|
182
|
-
dtk models list --quant #
|
|
186
|
+
dtk models list --quant # accepted for compatibility; quant is always shown
|
|
183
187
|
dtk models variants gliner2.5-multi # full details for one model
|
|
184
188
|
```
|
|
185
189
|
|
|
@@ -274,7 +278,7 @@ register_adapter("my-layout", MyAdapter)
|
|
|
274
278
|
```
|
|
275
279
|
|
|
276
280
|
Custom models do not appear in `dtk models list`; the toolkit never guesses a
|
|
277
|
-
layout. If a model deserves support, it goes through
|
|
281
|
+
layout. If a model deserves support, it goes through catalog review.
|
|
278
282
|
|
|
279
283
|
## Development
|
|
280
284
|
|
|
@@ -5,6 +5,31 @@ standard** to comply with: it is consistent with itself, script-friendly, and a
|
|
|
5
5
|
thin adapter over the programmatic core. Inference logic never lives in the
|
|
6
6
|
CLI.
|
|
7
7
|
|
|
8
|
+
## Invocation
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
dtk [global options] <command> [command options]
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Global options must come **before** the command. This matters for `--home`:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
dtk --home /data/dtk-home models list
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
| Global option | Meaning |
|
|
21
|
+
| --- | --- |
|
|
22
|
+
| `--home DIR` | Toolkit home (models cache + config). Default: `~/.local/share/decision-toolkit`. |
|
|
23
|
+
| `-q, --quiet` | Suppress informational output. |
|
|
24
|
+
| `-v, --verbose` | Debug logs and tracebacks on stderr. |
|
|
25
|
+
| `--log-level LEVEL` | `DEBUG`, `INFO`, `WARNING` or `ERROR`. |
|
|
26
|
+
| `--log-format FORMAT` | `text` or `json`. |
|
|
27
|
+
| `--no-color` | Disable colors (accepted for scripts). |
|
|
28
|
+
| `--version` | Print the toolkit version. |
|
|
29
|
+
|
|
30
|
+
Only `dtk models download` uses the network. The model must already be cached
|
|
31
|
+
for inference.
|
|
32
|
+
|
|
8
33
|
## Command map
|
|
9
34
|
|
|
10
35
|
| Command | Purpose |
|
|
@@ -26,6 +51,95 @@ CLI.
|
|
|
26
51
|
| `dtk version` | Version information. |
|
|
27
52
|
| `dtk completion` | Bash/zsh/fish completion snippet. |
|
|
28
53
|
|
|
54
|
+
## Command options
|
|
55
|
+
|
|
56
|
+
### Models
|
|
57
|
+
|
|
58
|
+
`dtk models` without a subcommand lists the cached entries. `dtk models list`
|
|
59
|
+
shows the catalog even when the cache is empty.
|
|
60
|
+
|
|
61
|
+
| Command | Important options |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| `dtk models list` | `--quant`, `--adapter`, `--license`, `--json` |
|
|
64
|
+
| `dtk models variants <id>` | `--json` |
|
|
65
|
+
| `dtk models download <id>` | `--variant NAME`, `--revision REV`, `--force`, `--dry-run`, `--json` |
|
|
66
|
+
| `dtk models use <id>` | `--variant NAME`, `--json` |
|
|
67
|
+
| `dtk models current` | `--json` |
|
|
68
|
+
| `dtk models delete <id>` | `--variant NAME`, `--all-variants`, `--yes`, `--json` |
|
|
69
|
+
| `dtk models verify [id]` | `--variant NAME`, `--all`, `--json` |
|
|
70
|
+
| `dtk models import <path>` | `--name NAME`, `--adapter NAME`, `--files ROLE=PATH`, `--json` |
|
|
71
|
+
|
|
72
|
+
`download` does not activate a variant; `use` persists the selection.
|
|
73
|
+
`--variant` on `decide`, `classify` or `serve` overrides it for one command.
|
|
74
|
+
|
|
75
|
+
### Decide
|
|
76
|
+
|
|
77
|
+
| Option | Meaning |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `--model ID` | Catalog id or cached model path (default: current model). |
|
|
80
|
+
| `--variant NAME` | Variant/quantization for this command. |
|
|
81
|
+
| `-s, --state TEXT` | State as text. |
|
|
82
|
+
| `--state-file FILE` | Read the state from a file (`-` for stdin; JSON files are sent as JSON). |
|
|
83
|
+
| `--input-jsonl FILE` | Batch input, one state per line (`-` for stdin). |
|
|
84
|
+
| `--q NAME=SPEC` | Repeatable shorthand question. |
|
|
85
|
+
| `--questions-file FILE` | JSON/YAML question mapping. |
|
|
86
|
+
| `--output-jsonl FILE` | Batch output (`-` for stdout). |
|
|
87
|
+
| `--batch-size N` | JSONL chunk size (default 32). |
|
|
88
|
+
| `--strict` | Fail instead of returning truncated answers. |
|
|
89
|
+
| `--json` | Print JSON (the default output). |
|
|
90
|
+
| `--pretty` | Indent JSON output. |
|
|
91
|
+
|
|
92
|
+
### Classify
|
|
93
|
+
|
|
94
|
+
| Option | Meaning |
|
|
95
|
+
| --- | --- |
|
|
96
|
+
| `--model ID` | Catalog id or cached model path. |
|
|
97
|
+
| `--variant NAME` | Variant for this command. |
|
|
98
|
+
| `-t, --text TEXT` | Text to classify. |
|
|
99
|
+
| `--text-file FILE` | Read text from a file (`-` for stdin). |
|
|
100
|
+
| `--labels L1,L2,...` | Comma-separated labels. |
|
|
101
|
+
| `--labels-file FILE` | YAML `labels: {name: description}` mapping. |
|
|
102
|
+
| `--instructions TEXT` | Custom question text. |
|
|
103
|
+
| `--threshold FLOAT` | Flag results below it (default 0.5). |
|
|
104
|
+
| `--top-k N` | Number of ranked labels to show (default 3). |
|
|
105
|
+
| `--json` | Machine-readable output. |
|
|
106
|
+
|
|
107
|
+
### Serve
|
|
108
|
+
|
|
109
|
+
| Option | Meaning |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| `--model ID`, `--variant NAME` | Default model for the process. |
|
|
112
|
+
| `--host HOST`, `--port PORT` | Bind address and port (default `127.0.0.1:8000`). |
|
|
113
|
+
| `--workers N` | Uvicorn worker processes. |
|
|
114
|
+
| `--reload` | Development reload; cannot combine with `--workers > 1`. |
|
|
115
|
+
| `--api-key KEY` | Require `Authorization: Bearer <key>`. |
|
|
116
|
+
| `--cors-origin ORIGIN` | Allow a browser origin; repeatable. |
|
|
117
|
+
| `--max-body-mb N`, `--timeout SECONDS` | Request limits. |
|
|
118
|
+
| `--max-models N` | Idle models kept loaded (LRU). |
|
|
119
|
+
| `--max-concurrent N` | Bounded inference concurrency. |
|
|
120
|
+
| `--rate-limit N`, `--rate-window SECONDS`, `--rate-burst N` | Per-key rate limit. |
|
|
121
|
+
| `--no-metrics` | Disable `/metrics`. |
|
|
122
|
+
| `--tracing` | Enable optional OpenTelemetry spans. |
|
|
123
|
+
| `--warmup` | Warm the default model at startup. |
|
|
124
|
+
| `--log-level`, `--log-format` | Server logging overrides. |
|
|
125
|
+
|
|
126
|
+
See [Operations](OPERATIONS.md) for the semantics of these limits.
|
|
127
|
+
|
|
128
|
+
### Config, doctor and completion
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
dtk config list --json
|
|
132
|
+
dtk config get device
|
|
133
|
+
dtk config set device cpu
|
|
134
|
+
dtk config set cache_dir /data/dtk-models
|
|
135
|
+
dtk doctor
|
|
136
|
+
dtk doctor --json
|
|
137
|
+
dtk completion bash
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Writable config keys are `cache_dir`, `current`, `current_variant` and `device`.
|
|
141
|
+
`home` is read-only; use `--home`.
|
|
142
|
+
|
|
29
143
|
## Exit codes
|
|
30
144
|
|
|
31
145
|
| Code | Meaning |
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
# Examples
|
|
2
2
|
|
|
3
|
-
Runnable examples for the three surfaces. Models must already be cached
|
|
3
|
+
Runnable examples for the three surfaces. Models must already be cached; none
|
|
4
|
+
of these examples downloads a model. For the shortest path from a fresh
|
|
5
|
+
install, start with [Quickstart](QUICKSTART.md).
|
|
6
|
+
|
|
7
|
+
The repository ships one small script that exercises the library end to end:
|
|
8
|
+
|
|
9
|
+
| Script | What it shows |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| [`examples/quickstart.py`](https://github.com/gia-uh/decision-toolkit/blob/main/examples/quickstart.py) | Load a cached model, ask choice/yes-no/score questions and print probabilities. |
|
|
4
12
|
|
|
5
13
|
```bash
|
|
6
14
|
dtk models download gliner2.5-multi
|
|
7
|
-
|
|
8
|
-
uv run dtk models download gliner2.5-multi
|
|
15
|
+
python examples/quickstart.py gliner2.5-multi
|
|
9
16
|
```
|
|
10
17
|
|
|
18
|
+
The code blocks below cover the same surfaces and are the reference examples
|
|
19
|
+
for the library, CLI and REST APIs.
|
|
20
|
+
|
|
11
21
|
## Library
|
|
12
22
|
|
|
13
23
|
```python
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# FAQ
|
|
2
|
+
|
|
3
|
+
## Is this a generative LLM?
|
|
4
|
+
|
|
5
|
+
No. The models score typed questions and return probabilities. They do not
|
|
6
|
+
generate prose, explanations or chat turns, and there is no text parser between
|
|
7
|
+
the model and the answer.
|
|
8
|
+
|
|
9
|
+
## What does `noul` mean?
|
|
10
|
+
|
|
11
|
+
`noul` is a yes/no question. Its result is the probability of `true`, plus the
|
|
12
|
+
normalized confidence and metadata. The name avoids overloading “boolean” for a
|
|
13
|
+
model score that is not a hard logical value.
|
|
14
|
+
|
|
15
|
+
## What is the difference between `choice`, `noul` and `score`?
|
|
16
|
+
|
|
17
|
+
- `choice`: pick one option from a list. The core has a multi-label flag, but
|
|
18
|
+
no model in the current catalog declares multi-label support.
|
|
19
|
+
- `noul`: estimate the probability of yes versus no.
|
|
20
|
+
- `score`: choose an ordered level such as `calm`, `annoyed`, `furious`; the
|
|
21
|
+
expected level is available separately.
|
|
22
|
+
|
|
23
|
+
All three are validated against the selected model's capabilities.
|
|
24
|
+
|
|
25
|
+
## Why probabilities instead of labels?
|
|
26
|
+
|
|
27
|
+
A threshold can turn a probability into a label, but the probability preserves
|
|
28
|
+
uncertainty and lets each application choose its own operating point. Use
|
|
29
|
+
`classify(..., threshold=...)` when you want a label plus a `below_threshold`
|
|
30
|
+
flag.
|
|
31
|
+
|
|
32
|
+
Are the probabilities calibrated? Calibration evidence is measured per model
|
|
33
|
+
and variant in [Benchmarks](BENCH.md); do not assume that a probability from one
|
|
34
|
+
model is directly comparable with a probability from another.
|
|
35
|
+
|
|
36
|
+
## Does it run offline?
|
|
37
|
+
|
|
38
|
+
Yes, after the model is in the local cache. Only `dtk models download` needs the
|
|
39
|
+
network. The library, CLI and REST server otherwise run locally. See
|
|
40
|
+
[Models](MODELS.md#offline-workflow).
|
|
41
|
+
|
|
42
|
+
## Does it download models implicitly?
|
|
43
|
+
|
|
44
|
+
No. If a model or variant is missing, the call fails instead of downloading it.
|
|
45
|
+
Run `dtk models download <id>` explicitly. This keeps startup deterministic and
|
|
46
|
+
makes offline operation possible.
|
|
47
|
+
|
|
48
|
+
## Do I need a GPU?
|
|
49
|
+
|
|
50
|
+
No. The supported runtime is ONNX Runtime on CPU. GPU acceleration is not part
|
|
51
|
+
of the documented path. Larger models need more RAM and take longer.
|
|
52
|
+
|
|
53
|
+
## Which model should I start with?
|
|
54
|
+
|
|
55
|
+
For general choice, yes/no and score decisions, start with
|
|
56
|
+
`gliner2.5-multi` and its default variant. If your state is not English, start
|
|
57
|
+
with `laya-multilingual`. Read [Models](MODELS.md#choosing-a-model) and the
|
|
58
|
+
[model cards](models/README.md), then measure on a small labelled sample from
|
|
59
|
+
your domain.
|
|
60
|
+
|
|
61
|
+
## Which variant should I choose?
|
|
62
|
+
|
|
63
|
+
Start with the catalog default. Try `fp32` when quality matters more than
|
|
64
|
+
latency, and `q4`/`q4f16`/`q8` when memory or disk is tight. Verify quality on
|
|
65
|
+
your own data before switching. The default is a sensible starting point, not a
|
|
66
|
+
universal recommendation.
|
|
67
|
+
|
|
68
|
+
## Can I download several variants of the same model?
|
|
69
|
+
|
|
70
|
+
Yes. Variants coexist in the cache. Downloading one does not replace another;
|
|
71
|
+
`dtk models use` selects the persistent default, and `--variant` selects one
|
|
72
|
+
for a single command.
|
|
73
|
+
|
|
74
|
+
## Can I load two variants at the same time?
|
|
75
|
+
|
|
76
|
+
Yes, for example over REST with `gliner2.5-multi@fp16` and
|
|
77
|
+
`gliner2.5-multi@fp32`. They occupy separate registry slots. The library can
|
|
78
|
+
also hold separate `DecisionModel` instances. Do not assume their probability
|
|
79
|
+
outputs are interchangeable without evaluation.
|
|
80
|
+
|
|
81
|
+
## Can I mix models in one application?
|
|
82
|
+
|
|
83
|
+
You can load different models in separate instances, but a decision is made by
|
|
84
|
+
one model at a time. Different models have different adapters, calibration and
|
|
85
|
+
behavior; do not average or compare their probabilities without measuring what
|
|
86
|
+
that means for your task.
|
|
87
|
+
|
|
88
|
+
## Does REST use the TypeSafe and OpenAI schemas?
|
|
89
|
+
|
|
90
|
+
Yes. The server exposes System One at `/v1/systemone` and OpenAI Decisions at
|
|
91
|
+
`/v1/decisions`, with the pinned request and response shapes documented in
|
|
92
|
+
[REST](REST.md). Local extensions are namespaced.
|
|
93
|
+
|
|
94
|
+
## How do I select a quantization in REST?
|
|
95
|
+
|
|
96
|
+
Use a model alias in the standard `model` field:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{"model": "gliner2.5-multi@fp32"}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
There is no `variant` field in a System One or OpenAI request body. The base id
|
|
103
|
+
uses the server's `--variant` or the persisted default.
|
|
104
|
+
|
|
105
|
+
## Is the REST server authenticated?
|
|
106
|
+
|
|
107
|
+
It can be. `dtk serve --api-key ...` requires a bearer token, and
|
|
108
|
+
`DECISION_TOOLKIT_API_KEY` is an optional environment fallback. Without either,
|
|
109
|
+
the server is unauthenticated. It is local-first infrastructure: bind it to
|
|
110
|
+
localhost or put your own authenticated proxy/TLS in front of it when exposed.
|
|
111
|
+
|
|
112
|
+
## Does the server store my states or decisions?
|
|
113
|
+
|
|
114
|
+
No, not by default. It evaluates a request and returns a response; it does not
|
|
115
|
+
create a decision database. State and question text are not used as metric
|
|
116
|
+
labels. Application logs and your own proxy may still retain request metadata;
|
|
117
|
+
review [Operations](OPERATIONS.md#pii-and-logging).
|
|
118
|
+
|
|
119
|
+
## Can I use a custom ONNX model?
|
|
120
|
+
|
|
121
|
+
Yes, with an explicit adapter and file map, using `DecisionModel.from_onnx(...)`
|
|
122
|
+
or `dtk models import`. Custom models are not catalogued, do not receive hash
|
|
123
|
+
verification or support, and do not get a guessed layout. See
|
|
124
|
+
[Core API](CORE.md#custom-local-onnx) and [CLI](CLI.md#custom-models).
|
|
125
|
+
|
|
126
|
+
## What licenses do the models have?
|
|
127
|
+
|
|
128
|
+
The toolkit is MIT licensed. Each model has its own license, recorded in its
|
|
129
|
+
model card; check the card and the upstream model page before redistribution.
|
|
130
|
+
See [THIRD_PARTY_NOTICES](https://github.com/gia-uh/decision-toolkit/blob/main/THIRD_PARTY_NOTICES.md).
|
|
131
|
+
|
|
132
|
+
## What Python versions are supported?
|
|
133
|
+
|
|
134
|
+
Python 3.12 and 3.13. The package requires Python 3.12 or newer.
|
|
135
|
+
|
|
136
|
+
## Is this ready for production?
|
|
137
|
+
|
|
138
|
+
The 0.4.x line is usable, but still evolving. Pin the version you deploy, read
|
|
139
|
+
the [changelog](https://github.com/gia-uh/decision-toolkit/blob/main/CHANGELOG.md),
|
|
140
|
+
and use the operational limits and runbook in [Operations](OPERATIONS.md). The
|
|
141
|
+
REST contracts are pinned; the core API can still change between minor releases.
|
|
142
|
+
|
|
143
|
+
## Does it support images or assets?
|
|
144
|
+
|
|
145
|
+
The core has typed support for assets and `box`, but every model currently in
|
|
146
|
+
the catalog is text-only. The REST server rejects image/asset and `box` requests
|
|
147
|
+
for this catalog. See [REST](REST.md#not-implemented-by-this-server).
|
|
148
|
+
|
|
149
|
+
## Is it a vector database or search engine?
|
|
150
|
+
|
|
151
|
+
No. It returns decisions for typed questions. It does not store vectors, index
|
|
152
|
+
documents or provide a search UI.
|
|
153
|
+
|
|
154
|
+
## How do I report a bug?
|
|
155
|
+
|
|
156
|
+
Include the exact command or request, the output of `dtk doctor --json`, the
|
|
157
|
+
toolkit version, the model and variant, and any error code. Redact state text
|
|
158
|
+
that you cannot share. Use the repository issue tracker linked from the
|
|
159
|
+
[home page](index.md).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Glossary
|
|
2
|
+
|
|
3
|
+
| Term | Meaning |
|
|
4
|
+
|---|---|
|
|
5
|
+
| **State** | The text or JSON value the model reasons over. In the library it can be a string, `State(text=...)` or a JSON-compatible object. |
|
|
6
|
+
| **Question** | A typed request for one decision: `choice`, `noul` or `score`. |
|
|
7
|
+
| **`choice`** | A question with a list of options and one selected option. The core has a multi-label flag, but no model in the current catalog declares it. |
|
|
8
|
+
| **`noul`** | A yes/no question. The result is a probability of `true`, not a hard boolean. |
|
|
9
|
+
| **`score`** | A question with ordered levels. The result includes the expected score, the most likely level and the level legend. |
|
|
10
|
+
| **Criteria** | Descriptions or option definitions attached to a question. For `choice`, they tell the model what each option means. |
|
|
11
|
+
| **Adapter** | The code that formats a state and typed questions for a specific model layout and reads its outputs. One adapter per model contract. |
|
|
12
|
+
| **Catalog** | The models and pinned variants shipped with the toolkit. `dtk models list` shows it. |
|
|
13
|
+
| **Variant** | One real, pinned ONNX build of a model. The variant name is passed to `--variant` or `variant=`. |
|
|
14
|
+
| **Quantization** | The numeric format of a build, such as `fp16`, `fp32`, `q8`, `q4` or `q4f16`. It is related to, but not always identical to, the variant name. |
|
|
15
|
+
| **Model alias** | The REST identifier `id@variant` used in the standard `model` field, for example `gliner2.5-multi@fp32`. |
|
|
16
|
+
| **Default variant** | The catalog's preferred variant for a model, marked with `*` in `dtk models list`. Used when no explicit or persisted selection exists. |
|
|
17
|
+
| **Current selection** | The model and variant stored by `dtk models use`; reported by `dtk models current`. |
|
|
18
|
+
| **Model cache** | The local directory holding downloaded or imported model variants. It is independent from the HuggingFace cache. |
|
|
19
|
+
| **Toolkit home** | The parent directory containing `config.json` and the model cache, by default `~/.local/share/decision-toolkit/`. |
|
|
20
|
+
| **`cache_dir`** | The `config.json` value that points at the model cache. It may be absolute or relative to the toolkit home. |
|
|
21
|
+
| **Model store** | The `ModelStore` API that owns download, import, selection, verification and resolution. |
|
|
22
|
+
| **Strict mode** | A mode where truncation raises `TruncationError` instead of returning a truncated answer. |
|
|
23
|
+
| **Truncation** | Shortening an input or output to fit a model context window. Answers expose `truncated` and `warnings`. |
|
|
24
|
+
| **Confidence** | The normalized probability reported for the chosen answer. Its meaning is documented in [Core API](CORE.md#confidence). |
|
|
25
|
+
| **Calibration** | How well predicted probabilities match observed frequencies. Evidence is measured per model and variant; see [Benchmarks](BENCH.md). |
|
|
26
|
+
| **Warmup** | Loading the ONNX session before the first real request. Available in the library and with `dtk serve --warmup`. |
|
|
27
|
+
| **Usage** | Token accounting attached to a decision: input, output, total and whether the count is estimated. |
|
|
28
|
+
| **Request ID** | A correlation identifier attached to a decision and emitted in logs. Set it with `request_context(...)` or the CLI/REST request metadata. |
|
|
29
|
+
| **System One** | The TypeSafe REST schema used by `POST /v1/systemone`. |
|
|
30
|
+
| **OpenAI Decisions beta** | The OpenAI Decisions schema used by `POST /v1/decisions`. |
|
|
31
|
+
| **Local extension** | A field or response extension namespaced by decision-toolkit, outside the public TypeSafe/OpenAI shapes. |
|
|
32
|
+
| **`top_k`** | In one-label classification, the number of best alternatives to return (when the surface exposes it). |
|
|
33
|
+
| **Threshold** | A probability cutoff used by `classify` to decide whether to return a label or mark the result as below threshold. |
|
|
34
|
+
| **Custom model** | A local ONNX directory supplied by the user with an explicit adapter and file map. It is not a catalog entry and has no catalog guarantees. |
|
|
35
|
+
| **REST server** | The optional FastAPI process started by `dtk serve`; it projects a subset of the core over HTTP. |
|
|
36
|
+
| **CLI** | The `dtk` command, a thin operational surface over the core. |
|