tokenfold 0.3.3__tar.gz → 0.4.0__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.
Files changed (41) hide show
  1. {tokenfold-0.3.3 → tokenfold-0.4.0}/Cargo.lock +10 -10
  2. {tokenfold-0.3.3 → tokenfold-0.4.0}/Cargo.toml +1 -1
  3. tokenfold-0.4.0/PKG-INFO +344 -0
  4. tokenfold-0.4.0/README.md +321 -0
  5. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/Cargo.toml +1 -1
  6. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/budget.rs +240 -10
  7. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/lib.rs +1 -1
  8. tokenfold-0.4.0/crates/tokenfold-core/src/pipeline.rs +2301 -0
  9. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/report.rs +35 -4
  10. tokenfold-0.4.0/crates/tokenfold-core/src/transforms/json_prune.rs +1238 -0
  11. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/transforms/mod.rs +1 -0
  12. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-py/Cargo.toml +1 -1
  13. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-py/src/lib.rs +10 -2
  14. {tokenfold-0.3.3 → tokenfold-0.4.0}/pyproject.toml +10 -0
  15. tokenfold-0.3.3/PKG-INFO +0 -271
  16. tokenfold-0.3.3/README.md +0 -258
  17. tokenfold-0.3.3/crates/tokenfold-core/src/pipeline.rs +0 -839
  18. {tokenfold-0.3.3 → tokenfold-0.4.0}/LICENSE +0 -0
  19. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/benches/THRESHOLDS.toml +0 -0
  20. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/benches/compression_bench.rs +0 -0
  21. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/examples/quickstart.rs +0 -0
  22. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/errors.rs +0 -0
  23. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/filters.rs +0 -0
  24. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/input.rs +0 -0
  25. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/modes.rs +0 -0
  26. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/retrieval_store.rs +0 -0
  27. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/safety.rs +0 -0
  28. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/stats.rs +0 -0
  29. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/status.rs +0 -0
  30. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/token_estimator.rs +0 -0
  31. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/transforms/diff.rs +0 -0
  32. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/transforms/json.rs +0 -0
  33. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/transforms/json_dict.rs +0 -0
  34. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/transforms/json_fold.rs +0 -0
  35. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/transforms/log_fold.rs +0 -0
  36. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/transforms/logs.rs +0 -0
  37. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/transforms/redaction.rs +0 -0
  38. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/src/transforms/schema.rs +0 -0
  39. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/tests/golden.rs +0 -0
  40. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/tests/integration.rs +0 -0
  41. {tokenfold-0.3.3 → tokenfold-0.4.0}/crates/tokenfold-core/tests/property_tests.rs +0 -0
@@ -1013,7 +1013,7 @@ dependencies = [
1013
1013
 
1014
1014
  [[package]]
1015
1015
  name = "tokenfold-adapters"
1016
- version = "0.3.3"
1016
+ version = "0.4.0"
1017
1017
  dependencies = [
1018
1018
  "serde",
1019
1019
  "serde_json",
@@ -1022,7 +1022,7 @@ dependencies = [
1022
1022
 
1023
1023
  [[package]]
1024
1024
  name = "tokenfold-admin"
1025
- version = "0.3.3"
1025
+ version = "0.4.0"
1026
1026
  dependencies = [
1027
1027
  "ed25519-dalek",
1028
1028
  "serde",
@@ -1032,7 +1032,7 @@ dependencies = [
1032
1032
 
1033
1033
  [[package]]
1034
1034
  name = "tokenfold-cli"
1035
- version = "0.3.3"
1035
+ version = "0.4.0"
1036
1036
  dependencies = [
1037
1037
  "clap",
1038
1038
  "serde",
@@ -1045,7 +1045,7 @@ dependencies = [
1045
1045
 
1046
1046
  [[package]]
1047
1047
  name = "tokenfold-core"
1048
- version = "0.3.3"
1048
+ version = "0.4.0"
1049
1049
  dependencies = [
1050
1050
  "proptest",
1051
1051
  "regex",
@@ -1059,25 +1059,25 @@ dependencies = [
1059
1059
 
1060
1060
  [[package]]
1061
1061
  name = "tokenfold-image"
1062
- version = "0.3.3"
1062
+ version = "0.4.0"
1063
1063
 
1064
1064
  [[package]]
1065
1065
  name = "tokenfold-learn"
1066
- version = "0.3.3"
1066
+ version = "0.4.0"
1067
1067
  dependencies = [
1068
1068
  "tokenfold-core",
1069
1069
  ]
1070
1070
 
1071
1071
  [[package]]
1072
1072
  name = "tokenfold-output"
1073
- version = "0.3.3"
1073
+ version = "0.4.0"
1074
1074
  dependencies = [
1075
1075
  "tokenfold-core",
1076
1076
  ]
1077
1077
 
1078
1078
  [[package]]
1079
1079
  name = "tokenfold-proxy"
1080
- version = "0.3.3"
1080
+ version = "0.4.0"
1081
1081
  dependencies = [
1082
1082
  "clap",
1083
1083
  "serde",
@@ -1089,7 +1089,7 @@ dependencies = [
1089
1089
 
1090
1090
  [[package]]
1091
1091
  name = "tokenfold-py"
1092
- version = "0.3.3"
1092
+ version = "0.4.0"
1093
1093
  dependencies = [
1094
1094
  "pyo3",
1095
1095
  "serde_json",
@@ -1098,7 +1098,7 @@ dependencies = [
1098
1098
 
1099
1099
  [[package]]
1100
1100
  name = "tokenfold-rag"
1101
- version = "0.3.3"
1101
+ version = "0.4.0"
1102
1102
 
1103
1103
  [[package]]
1104
1104
  name = "toml"
@@ -3,7 +3,7 @@ resolver = "2"
3
3
  members = ["crates/tokenfold-core", "crates/tokenfold-py"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.3.3"
6
+ version = "0.4.0"
7
7
  edition = "2024"
8
8
  rust-version = "1.97"
9
9
  license = "Apache-2.0"
@@ -0,0 +1,344 @@
1
+ Metadata-Version: 2.4
2
+ Name: tokenfold
3
+ Version: 0.4.0
4
+ Classifier: Development Status :: 4 - Beta
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: Apache Software License
7
+ Classifier: Programming Language :: Rust
8
+ Classifier: Programming Language :: Python :: Implementation :: CPython
9
+ Classifier: Programming Language :: Python :: 3 :: Only
10
+ Classifier: Programming Language :: Python :: 3.9
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Text Processing
17
+ License-File: LICENSE
18
+ Summary: Token-compression toolkit for LLM payloads (Python binding over the tokenfold-core Rust crate)
19
+ Keywords: llm,tokens,compression,tokenizer,openai,json,prompt-engineering,cli,token-optimization
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
22
+
23
+ <div align="center">
24
+
25
+ # TOKENFOLD
26
+
27
+ **Send less noise. Fit more context. Pay for fewer input tokens.**
28
+
29
+ **Up to 92% fewer input tokens · lossless by default · exact receipts**
30
+
31
+ CLI · Python · TypeScript · Rust · proxy · MCP · local-first · provider-neutral
32
+
33
+ [![CI](https://img.shields.io/github/actions/workflow/status/snchimata/tokenfold/ci.yml?branch=main&label=tests&logo=github&style=flat-square)](https://github.com/snchimata/tokenfold/actions/workflows/ci.yml) [![Coverage](https://img.shields.io/github/actions/workflow/status/snchimata/tokenfold/ci.yml?branch=main&label=coverage&logo=github&style=flat-square)](https://github.com/snchimata/tokenfold/actions/workflows/ci.yml) [![GitHub Release](https://img.shields.io/github/v/release/snchimata/tokenfold?logo=github&style=flat-square)](https://github.com/snchimata/tokenfold/releases/latest) [![PyPI](https://img.shields.io/pypi/v/tokenfold?label=PyPI&style=flat-square)](https://pypi.org/project/tokenfold/) [![npm](https://img.shields.io/npm/v/tokenfold?label=npm&logo=npm&style=flat-square)](https://www.npmjs.com/package/tokenfold) [![Rust](https://img.shields.io/crates/v/tokenfold-core?label=Rust&style=flat-square)](https://docs.rs/crate/tokenfold-core/latest) [![License](https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square)](LICENSE)
34
+
35
+ [Measured results](#measured-results) · [Platform](#one-platform-two-engines) · [Quick start](#quick-start) · [Lossy pruning](#recoverable-lossy-pruning) · [Select model](#tokenfold-select) · [Reproduce](#reproduce-the-results)
36
+
37
+ </div>
38
+
39
+ ---
40
+
41
+ ## Measured results
42
+
43
+ ### Compression
44
+
45
+ | Search / RAG results | Repetitive JSON | API responses | Tool schemas |
46
+ | :---: | :---: | :---: | :---: |
47
+ | **91.7% fewer tokens** | **67.6% fewer tokens** | **61.3% fewer tokens** | **45.6% fewer tokens** |
48
+ | 84,032 → 6,951 | 50-record payload | 30-record payload | 1.8 MB OpenAI fixture |
49
+ | opt-in, recoverable | lossless | lossless | lossless |
50
+
51
+ All four use exact `o200k_base` counts in balanced mode. The 91.7% showcase
52
+ keeps the planted `503` result inline and makes the other 98 long rows
53
+ retrievable by hash. Run it with `python examples/lossy_pruning.py`.
54
+
55
+ ### Fine-tuned relevance ranking
56
+
57
+ [Tokenfold Select][tokenfold-select] is the optional query-aware model for
58
+ choosing what fills a tight context window after structural compression ends.
59
+
60
+ | Token budget kept | Tokenfold Select task success | BM25 reference | Lift |
61
+ | ---: | ---: | ---: | ---: |
62
+ | 50% | **86.3%** | 79.4% | **+8.7%** |
63
+ | 25% | **70.3%** | 60.7% | **+15.8%** |
64
+ | 10% | **39.9%** | 37.7% | **+5.8%** |
65
+
66
+ At a 25% budget, the fine-tuned ranker keeps the answer **70% of the time** and
67
+ beats the strongest free heuristic by **15.8%**. Critical-content survival is
68
+ **100% at every measured budget** through allocator force-keep. Results are
69
+ three-seed repeated subsampling over roughly 73,000 training and 24,000
70
+ held-out fixtures per run; the [model card][tokenfold-select] publishes the
71
+ training recipe and full baseline set. Here, task success means the literal
72
+ gold answer survived selection under the stated budget.
73
+
74
+ ## One platform, two engines
75
+
76
+ | Capability | What you get |
77
+ | --- | --- |
78
+ | **Tokenfold Core** | Fast deterministic compression for JSON, schemas, provider requests, logs, diffs, and command output |
79
+ | **Recoverable pruning** | Drop low-signal JSON rows only after storing them locally; fetch any omission with `tokenfold retrieve` |
80
+ | **Tokenfold Select** | LoRA-fine-tuned, query-aware span ranking with up to **15.8% lift** over BM25 at the same budget |
81
+ | **Budget control** | Conservative, balanced, and aggressive modes; nine task scopes; `--target-tokens` with honest best-effort reporting |
82
+ | **Exact receipts** | Before/after token counts, applied transforms, warnings, provenance, and final status on every call |
83
+ | **Realized savings** | `gain`, `stats`, and `session` report measured savings; `learn` proposes policy improvements without silently applying them |
84
+ | **Every integration** | CLI, Python, TypeScript, Rust, HTTP proxy, and MCP share the same Core engine and report shape |
85
+ | **Local-first safety** | Secret redaction, protected-content gates, reversible structural transforms, and no hosted data processor |
86
+
87
+ ### Lossless or recoverable lossy
88
+
89
+ | | Lossless — default | Recoverable lossy — opt-in |
90
+ | --- | --- | --- |
91
+ | **What it does** | Minifies, folds repeated keys into columns, and stores repeated values once | Adds deterministic ranking and retrieval markers for selected array rows |
92
+ | **Best on** | Uniform records, schemas, logs, diffs | Search results, mixed event feeds, agent traces, long arrays |
93
+ | **Measured here** | **45.6–67.6%** fewer tokens | **39.3–91.7%** fewer tokens |
94
+ | **Recovery** | All data remains in the payload | Every emitted marker resolves through the local retrieval store |
95
+
96
+ ## Quick start
97
+
98
+ Install the surface that fits your stack:
99
+
100
+ ```bash
101
+ pip install tokenfold # Python 3.9+
102
+ npm install tokenfold # Node.js 22+
103
+ cargo add tokenfold-core # Rust library
104
+ cargo install tokenfold-cli # Rust CLI
105
+ ```
106
+
107
+ Or download a signed CLI build for Linux, macOS, or Windows from
108
+ [GitHub Releases](https://github.com/snchimata/tokenfold/releases/latest) and
109
+ verify it with the adjacent `.sha256` file.
110
+
111
+ Preview first, then compress:
112
+
113
+ ```bash
114
+ tokenfold inspect payload.json --format json
115
+ tokenfold compress payload.json --format json --output payload.compact.json
116
+ ```
117
+
118
+ Python uses the same Core engine and typed receipt:
119
+
120
+ ```python
121
+ import json
122
+ from pathlib import Path
123
+
124
+ from tokenfold import CompressionMode, compress_openai_payload
125
+
126
+ result = compress_openai_payload(
127
+ Path("request.json").read_text(),
128
+ mode=CompressionMode.BALANCED,
129
+ )
130
+ compressed_request = json.loads(result.payload)
131
+ print(f"saved {result.report.saved_tokens} tokens ({result.saved_pct():.1f}%)")
132
+ ```
133
+
134
+ | Surface | Best for | Start here |
135
+ | --- | --- | --- |
136
+ | CLI | Files, stdin, diffs, and command output | `tokenfold compress`, `inspect`, `diff`, `wrap` |
137
+ | Python | Applications and evaluation pipelines | `pip install tokenfold` |
138
+ | TypeScript | Node.js applications and automation | `npm install tokenfold` |
139
+ | Rust | Native embedding | `cargo add tokenfold-core` |
140
+ | HTTP proxy | Transparent provider-shaped traffic | Build `tokenfold-proxy` |
141
+ | MCP | Agents and editors | `tokenfold mcp serve` |
142
+
143
+ `tokenfold init --agent <agent>` installs a durable host integration;
144
+ `tokenfold doctor` verifies it. Trusted filters for Git, build, and test output
145
+ are available through `tokenfold filters list`.
146
+
147
+ Runnable examples:
148
+
149
+ ```bash
150
+ python examples/quickstart.py
151
+ python examples/lossy_pruning.py
152
+ ```
153
+
154
+ ## Recoverable lossy pruning
155
+
156
+ Lossless folding has a ceiling on heterogeneous arrays. `--lossy` ranks rows,
157
+ keeps the strongest signals, and replaces selected rows with compact
158
+ `{"$tf_ref": {...}}` handles. A row leaves the payload only after the local
159
+ store accepts it.
160
+
161
+ ```bash
162
+ tokenfold compress examples/incident_feed.json --format json \
163
+ --lossy heuristic --lossy-ratio 0.35 --output feed.compact.json
164
+ ```
165
+
166
+ On the bundled 40-event feed:
167
+
168
+ | Mode | Exact tokens | Reduction | Events kept | Incident kept |
169
+ | --- | ---: | ---: | ---: | :---: |
170
+ | Lossless | 2,840 | 28.1% | 40 | ✅ |
171
+ | `--lossy-ratio 0.35` | 2,399 | **39.3%** | 13 | ✅ |
172
+ | `--lossy-ratio 0.05` | 2,192 | **44.5%** | 2 | ✅ |
173
+
174
+ The planted `503` with `success: false` and `retries: 7` survives every shown
175
+ setting because typed failure signals outrank position and length. Long rows
176
+ amortize marker overhead further: the 100-result showcase reaches **91.7%**.
177
+
178
+ Fetch a dropped row:
179
+
180
+ ```bash
181
+ tokenfold retrieve 978339a8898fedde3c5b0662a213f12ae4ad1b7fe6771f62b3c3d74d87389a4c
182
+ # {"seq":1,"ts":"2026-08-15T00:01:11Z","subsystem":"index-writer",...}
183
+ ```
184
+
185
+ What the flags mean:
186
+
187
+ - `--lossy-ratio` is an aggression hint over eligible array items. Lower keeps
188
+ fewer rows; it is not a whole-document guarantee.
189
+ - `--target-tokens` is the whole-document goal. Tokenfold stops when it reaches
190
+ the target losslessly and reports `best_effort` when the safe transform set
191
+ cannot reach it (`unreachable_target` when protected content alone exceeds
192
+ the target).
193
+ - `--lossy-preserve <path>` protects a named array; nested paths conservatively
194
+ protect their nearest eligible ancestor.
195
+ - Generic JSON only: lossy pruning does not run on OpenAI or Anthropic message
196
+ payloads.
197
+ - Storage is fail-closed: refused rows stay inline, and detected secret-shaped
198
+ bytes are never persisted.
199
+
200
+ Preview the projected savings with no store writes:
201
+
202
+ ```bash
203
+ tokenfold compress examples/incident_feed.json --format json \
204
+ --lossy heuristic --lossy-ratio 0.35 --dry-run
205
+ ```
206
+
207
+ <details>
208
+ <summary><strong>Current Phase 1 constraints</strong></summary>
209
+
210
+ Treat `$tf_ref` as reserved and do not enable lossy pruning on documents that
211
+ already contain retrieval markers. A filesystem failure after partial writes
212
+ may also leave unreferenced entries until their configured TTL expires. Both
213
+ require location-based transactional materialization before promotion.
214
+
215
+ Lossy pruning is CLI-only today; Python and TypeScript remain lossless. Preview
216
+ is a projection rather than a filesystem transaction, so a real run may keep
217
+ more rows if storage becomes unavailable.
218
+
219
+ </details>
220
+
221
+ ## Tokenfold Select
222
+
223
+ **When structure ends, rank what matters.**
224
+
225
+ Tokenfold Select is an Apache-2.0 LoRA adapter on
226
+ `ibm-granite/granite-embedding-reranker-english-r2`. It scores candidate spans
227
+ against a query; your allocator applies the token budget and force-keeps
228
+ required content. Core remains model-free and deterministic, while Select adds
229
+ relevance when lexical heuristics stop being enough.
230
+
231
+ | | Tokenfold Core | Tokenfold Select |
232
+ | --- | --- | --- |
233
+ | Best at | Structural compression | Query-conditioned span ranking |
234
+ | Runtime | Static Rust binary | Granite reranker + LoRA adapter |
235
+ | Output | Compressed payload + exact receipt | Ranking logits |
236
+
237
+ <details>
238
+ <summary><strong>Python: load the model and score spans</strong></summary>
239
+
240
+ ```python
241
+ from pathlib import Path
242
+
243
+ import torch
244
+ from huggingface_hub import snapshot_download
245
+ from peft import PeftModel
246
+ from transformers import AutoModelForSequenceClassification, AutoTokenizer
247
+
248
+ base_id = "ibm-granite/granite-embedding-reranker-english-r2"
249
+ repo_dir = Path(snapshot_download("snchimata/tokenfold-select"))
250
+ adapter_dir = repo_dir / "adapter"
251
+ tokenizer = AutoTokenizer.from_pretrained(adapter_dir)
252
+ base = AutoModelForSequenceClassification.from_pretrained(
253
+ base_id,
254
+ dtype=torch.float32,
255
+ )
256
+ model = PeftModel.from_pretrained(base, adapter_dir).eval()
257
+
258
+ def score(query: str, spans: list[str]) -> list[float]:
259
+ if not spans:
260
+ return []
261
+ encoded = tokenizer(
262
+ [query] * len(spans),
263
+ spans,
264
+ padding=True,
265
+ truncation=True,
266
+ max_length=8192,
267
+ return_tensors="pt",
268
+ )
269
+ with torch.no_grad():
270
+ output = model(
271
+ input_ids=encoded["input_ids"],
272
+ attention_mask=encoded["attention_mask"],
273
+ )
274
+ return output.logits.view(-1).float().tolist()
275
+ ```
276
+
277
+ </details>
278
+
279
+ See the [Tokenfold Select model card][tokenfold-select] for setup, evaluation,
280
+ training data, and limitations.
281
+
282
+ ## Safety and auditability
283
+
284
+ - **Never larger:** Core keeps a transform only when exact recounting shows a
285
+ reduction; a lossy branch must also beat the lossless result.
286
+ - **Reversible structure:** JSON folds must pass an exact round trip.
287
+ - **Protected content:** provider system messages and latest-user content are
288
+ held behind format-aware safety gates.
289
+ - **Clear provenance:** exact tokenizer counts, heuristics, and extrapolations
290
+ are labeled separately.
291
+ - **Actionable receipts:** every result lists savings, transforms, warnings,
292
+ retrieval state, and final status.
293
+ - **Local control:** detected secrets are redacted before reports or storage;
294
+ policy learning changes configuration only with `--apply`.
295
+
296
+ ## Reproduce the results
297
+
298
+ ```bash
299
+ # 91.7% maximum-compression showcase, mixed-feed curve, retrieval, and preserve
300
+ python examples/lossy_pruning.py
301
+
302
+ # Lossless transform benchmarks
303
+ cargo bench -p tokenfold-core
304
+
305
+ # Small exact-token CLI example
306
+ cargo run --release --locked -p tokenfold-cli -- \
307
+ inspect examples/api_response.json --format json
308
+ ```
309
+
310
+ The small bundled API response reports 382 → 206 tokens, a **46.1% lossless
311
+ reduction**. Benchmark sources and thresholds live in [CHANGELOG.md](CHANGELOG.md)
312
+ and [`crates/tokenfold-core/benches/THRESHOLDS.toml`](crates/tokenfold-core/benches/THRESHOLDS.toml).
313
+
314
+ ## Contributing
315
+
316
+ Issues and pull requests are welcome. Run the relevant checks before opening a
317
+ PR:
318
+
319
+ ```bash
320
+ cargo fmt --all --check
321
+ cargo clippy --workspace --all-targets -- -D warnings
322
+ cargo test --workspace --locked
323
+ python eval/run_fidelity.py --gate --profile smoke-first-consumer
324
+ cd packages/tokenfold && npm ci && npm test
325
+ ```
326
+
327
+ ## License
328
+
329
+ [Apache-2.0](LICENSE)
330
+
331
+ ---
332
+
333
+ Start with one representative payload, inspect the receipt, and see how many
334
+ tokens your application can stop sending today.
335
+
336
+ ```bash
337
+ pip install tokenfold
338
+ ```
339
+
340
+ If Tokenfold earns a place in your stack, a ⭐ on
341
+ [GitHub](https://github.com/snchimata/tokenfold) helps the next team find it.
342
+
343
+ [tokenfold-select]: https://huggingface.co/snchimata/tokenfold-select
344
+