tokenfold 0.4.0__tar.gz → 0.5.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 (42) hide show
  1. {tokenfold-0.4.0 → tokenfold-0.5.0}/Cargo.lock +63 -19
  2. {tokenfold-0.4.0 → tokenfold-0.5.0}/Cargo.toml +3 -2
  3. {tokenfold-0.4.0 → tokenfold-0.5.0}/PKG-INFO +89 -50
  4. {tokenfold-0.4.0 → tokenfold-0.5.0}/README.md +88 -49
  5. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/Cargo.toml +2 -0
  6. tokenfold-0.5.0/crates/tokenfold-core/README.md +29 -0
  7. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/benches/THRESHOLDS.toml +4 -5
  8. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/benches/compression_bench.rs +5 -5
  9. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/budget.rs +71 -44
  10. tokenfold-0.5.0/crates/tokenfold-core/src/codec.rs +116 -0
  11. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/errors.rs +6 -1
  12. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/filters.rs +8 -8
  13. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/lib.rs +3 -1
  14. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/modes.rs +50 -48
  15. tokenfold-0.5.0/crates/tokenfold-core/src/pipeline/mod.rs +1130 -0
  16. tokenfold-0.5.0/crates/tokenfold-core/src/pipeline/tests.rs +1291 -0
  17. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/report.rs +80 -14
  18. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/retrieval_store.rs +347 -43
  19. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/safety.rs +3 -1
  20. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/stats.rs +26 -25
  21. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/status.rs +1 -16
  22. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/diff.rs +5 -7
  23. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_prune.rs +52 -32
  24. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/logs.rs +4 -4
  25. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/tests/golden.rs +3 -1
  26. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/tests/integration.rs +13 -18
  27. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/tests/property_tests.rs +1 -1
  28. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-py/Cargo.toml +1 -1
  29. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-py/src/lib.rs +475 -258
  30. tokenfold-0.4.0/crates/tokenfold-core/examples/quickstart.rs +0 -83
  31. tokenfold-0.4.0/crates/tokenfold-core/src/pipeline.rs +0 -2301
  32. {tokenfold-0.4.0 → tokenfold-0.5.0}/LICENSE +0 -0
  33. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/input.rs +0 -0
  34. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/token_estimator.rs +0 -0
  35. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json.rs +0 -0
  36. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_dict.rs +0 -0
  37. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_fold.rs +0 -0
  38. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/log_fold.rs +0 -0
  39. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/mod.rs +0 -0
  40. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/redaction.rs +0 -0
  41. {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/schema.rs +0 -0
  42. {tokenfold-0.4.0 → tokenfold-0.5.0}/pyproject.toml +0 -0
@@ -206,7 +206,7 @@ dependencies = [
206
206
  "heck",
207
207
  "proc-macro2",
208
208
  "quote",
209
- "syn",
209
+ "syn 2.0.118",
210
210
  ]
211
211
 
212
212
  [[package]]
@@ -270,7 +270,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
270
270
  dependencies = [
271
271
  "proc-macro2",
272
272
  "quote",
273
- "syn",
273
+ "syn 2.0.118",
274
274
  ]
275
275
 
276
276
  [[package]]
@@ -620,7 +620,7 @@ dependencies = [
620
620
  "proc-macro2",
621
621
  "pyo3-macros-backend",
622
622
  "quote",
623
- "syn",
623
+ "syn 2.0.118",
624
624
  ]
625
625
 
626
626
  [[package]]
@@ -632,7 +632,7 @@ dependencies = [
632
632
  "heck",
633
633
  "proc-macro2",
634
634
  "quote",
635
- "syn",
635
+ "syn 2.0.118",
636
636
  ]
637
637
 
638
638
  [[package]]
@@ -860,7 +860,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
860
860
  dependencies = [
861
861
  "proc-macro2",
862
862
  "quote",
863
- "syn",
863
+ "syn 2.0.118",
864
864
  ]
865
865
 
866
866
  [[package]]
@@ -945,6 +945,17 @@ dependencies = [
945
945
  "unicode-ident",
946
946
  ]
947
947
 
948
+ [[package]]
949
+ name = "syn"
950
+ version = "3.0.4"
951
+ source = "registry+https://github.com/rust-lang/crates.io-index"
952
+ checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f"
953
+ dependencies = [
954
+ "proc-macro2",
955
+ "quote",
956
+ "unicode-ident",
957
+ ]
958
+
948
959
  [[package]]
949
960
  name = "target-lexicon"
950
961
  version = "0.13.5"
@@ -970,7 +981,16 @@ version = "1.0.69"
970
981
  source = "registry+https://github.com/rust-lang/crates.io-index"
971
982
  checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
972
983
  dependencies = [
973
- "thiserror-impl",
984
+ "thiserror-impl 1.0.69",
985
+ ]
986
+
987
+ [[package]]
988
+ name = "thiserror"
989
+ version = "2.0.20"
990
+ source = "registry+https://github.com/rust-lang/crates.io-index"
991
+ checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
992
+ dependencies = [
993
+ "thiserror-impl 2.0.20",
974
994
  ]
975
995
 
976
996
  [[package]]
@@ -981,7 +1001,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
981
1001
  dependencies = [
982
1002
  "proc-macro2",
983
1003
  "quote",
984
- "syn",
1004
+ "syn 2.0.118",
1005
+ ]
1006
+
1007
+ [[package]]
1008
+ name = "thiserror-impl"
1009
+ version = "2.0.20"
1010
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1011
+ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
1012
+ dependencies = [
1013
+ "proc-macro2",
1014
+ "quote",
1015
+ "syn 3.0.4",
985
1016
  ]
986
1017
 
987
1018
  [[package]]
@@ -1013,7 +1044,7 @@ dependencies = [
1013
1044
 
1014
1045
  [[package]]
1015
1046
  name = "tokenfold-adapters"
1016
- version = "0.4.0"
1047
+ version = "0.5.0"
1017
1048
  dependencies = [
1018
1049
  "serde",
1019
1050
  "serde_json",
@@ -1022,7 +1053,7 @@ dependencies = [
1022
1053
 
1023
1054
  [[package]]
1024
1055
  name = "tokenfold-admin"
1025
- version = "0.4.0"
1056
+ version = "0.5.0"
1026
1057
  dependencies = [
1027
1058
  "ed25519-dalek",
1028
1059
  "serde",
@@ -1032,7 +1063,7 @@ dependencies = [
1032
1063
 
1033
1064
  [[package]]
1034
1065
  name = "tokenfold-cli"
1035
- version = "0.4.0"
1066
+ version = "0.5.0"
1036
1067
  dependencies = [
1037
1068
  "clap",
1038
1069
  "serde",
@@ -1045,39 +1076,40 @@ dependencies = [
1045
1076
 
1046
1077
  [[package]]
1047
1078
  name = "tokenfold-core"
1048
- version = "0.4.0"
1079
+ version = "0.5.0"
1049
1080
  dependencies = [
1050
1081
  "proptest",
1051
1082
  "regex",
1052
1083
  "serde",
1053
1084
  "serde_json",
1054
1085
  "sha2",
1055
- "thiserror",
1086
+ "thiserror 1.0.69",
1056
1087
  "tiktoken-rs",
1057
1088
  "toml",
1089
+ "toon-format",
1058
1090
  ]
1059
1091
 
1060
1092
  [[package]]
1061
1093
  name = "tokenfold-image"
1062
- version = "0.4.0"
1094
+ version = "0.5.0"
1063
1095
 
1064
1096
  [[package]]
1065
1097
  name = "tokenfold-learn"
1066
- version = "0.4.0"
1098
+ version = "0.5.0"
1067
1099
  dependencies = [
1068
1100
  "tokenfold-core",
1069
1101
  ]
1070
1102
 
1071
1103
  [[package]]
1072
1104
  name = "tokenfold-output"
1073
- version = "0.4.0"
1105
+ version = "0.5.0"
1074
1106
  dependencies = [
1075
1107
  "tokenfold-core",
1076
1108
  ]
1077
1109
 
1078
1110
  [[package]]
1079
1111
  name = "tokenfold-proxy"
1080
- version = "0.4.0"
1112
+ version = "0.5.0"
1081
1113
  dependencies = [
1082
1114
  "clap",
1083
1115
  "serde",
@@ -1089,7 +1121,7 @@ dependencies = [
1089
1121
 
1090
1122
  [[package]]
1091
1123
  name = "tokenfold-py"
1092
- version = "0.4.0"
1124
+ version = "0.5.0"
1093
1125
  dependencies = [
1094
1126
  "pyo3",
1095
1127
  "serde_json",
@@ -1098,7 +1130,7 @@ dependencies = [
1098
1130
 
1099
1131
  [[package]]
1100
1132
  name = "tokenfold-rag"
1101
- version = "0.4.0"
1133
+ version = "0.5.0"
1102
1134
 
1103
1135
  [[package]]
1104
1136
  name = "toml"
@@ -1141,6 +1173,18 @@ version = "0.1.2"
1141
1173
  source = "registry+https://github.com/rust-lang/crates.io-index"
1142
1174
  checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
1143
1175
 
1176
+ [[package]]
1177
+ name = "toon-format"
1178
+ version = "0.5.0"
1179
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1180
+ checksum = "8f89570c1a68d73941f728cca32a4345b2ffca36667ad921af336c60309a3e7e"
1181
+ dependencies = [
1182
+ "indexmap",
1183
+ "serde",
1184
+ "serde_json",
1185
+ "thiserror 2.0.20",
1186
+ ]
1187
+
1144
1188
  [[package]]
1145
1189
  name = "typenum"
1146
1190
  version = "1.20.1"
@@ -1364,7 +1408,7 @@ checksum = "e2e817b7b52d0c7358d3246da9d69935ebb18116b2b102b4230dac079b4862f5"
1364
1408
  dependencies = [
1365
1409
  "proc-macro2",
1366
1410
  "quote",
1367
- "syn",
1411
+ "syn 2.0.118",
1368
1412
  ]
1369
1413
 
1370
1414
  [[package]]
@@ -3,9 +3,9 @@ resolver = "2"
3
3
  members = ["crates/tokenfold-core", "crates/tokenfold-py"]
4
4
 
5
5
  [workspace.package]
6
- version = "0.4.0"
6
+ version = "0.5.0"
7
7
  edition = "2024"
8
- rust-version = "1.97"
8
+ rust-version = "1.98"
9
9
  license = "Apache-2.0"
10
10
  repository = "https://github.com/snchimata/tokenfold"
11
11
 
@@ -18,6 +18,7 @@ clap = { version = "4", features = ["derive"] }
18
18
 
19
19
  tiktoken-rs = "0.7"
20
20
  sha2 = "0.10"
21
+ toon-format = { version = "0.5", default-features = false }
21
22
 
22
23
  proptest = "1"
23
24
  toml = "0.8"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tokenfold
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: Apache Software License
@@ -20,19 +20,19 @@ Keywords: llm,tokens,compression,tokenizer,openai,json,prompt-engineering,cli,to
20
20
  Requires-Python: >=3.9
21
21
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
22
22
 
23
- <div align="center">
23
+ <div align="center">
24
24
 
25
25
  # TOKENFOLD
26
26
 
27
27
  **Send less noise. Fit more context. Pay for fewer input tokens.**
28
28
 
29
- **Up to 92% fewer input tokens · lossless by default · exact receipts**
29
+ **Up to 92% fewer input tokens · lossless by default · exact receipts**
30
30
 
31
- CLI · Python · TypeScript · Rust · proxy · MCP · local-first · provider-neutral
31
+ CLI · Python · TypeScript · Rust · proxy · MCP · local-first · provider-neutral
32
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)
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)](https://github.com/snchimata/tokenfold/blob/main/LICENSE)
34
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)
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
36
 
37
37
  </div>
38
38
 
@@ -44,18 +44,21 @@ CLI · Python · TypeScript · Rust · proxy · MCP · local-first · provider-n
44
44
 
45
45
  | Search / RAG results | Repetitive JSON | API responses | Tool schemas |
46
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 |
47
+ | **91.7% fewer tokens** | **67.6% fewer tokens** | **63.9% fewer tokens** | **45.6% fewer tokens** |
48
+ | 84,032 → 6,951 | 50-record payload | 30-record payload | 1.8 MB OpenAI fixture |
49
49
  | opt-in, recoverable | lossless | lossless | lossless |
50
50
 
51
- All four use exact `o200k_base` counts in balanced mode. The 91.7% showcase
51
+ All four use exact `o200k_base` counts in balanced preset. The 91.7% showcase
52
52
  keeps the planted `503` result inline and makes the other 98 long rows
53
53
  retrievable by hash. Run it with `python examples/lossy_pruning.py`.
54
+ The versioned inputs and source provenance for these headline figures live in
55
+ [`tests/fixtures/readme_metrics.json`](tests/fixtures/readme_metrics.json).
54
56
 
55
57
  ### Fine-tuned relevance ranking
56
58
 
57
- [Tokenfold Select][tokenfold-select] is the optional query-aware model for
59
+ [Tokenfold Select][tokenfold-select] is an optional external query-aware model for
58
60
  choosing what fills a tight context window after structural compression ends.
61
+ It is distributed and evaluated separately; Tokenfold Core does not invoke it.
59
62
 
60
63
  | Token budget kept | Tokenfold Select task success | BM25 reference | Lift |
61
64
  | ---: | ---: | ---: | ---: |
@@ -70,6 +73,8 @@ three-seed repeated subsampling over roughly 73,000 training and 24,000
70
73
  held-out fixtures per run; the [model card][tokenfold-select] publishes the
71
74
  training recipe and full baseline set. Here, task success means the literal
72
75
  gold answer survived selection under the stated budget.
76
+ These are source-reported external results, pinned by model revision in the
77
+ [metric manifest](tests/fixtures/readme_metrics.json); Core CI does not reproduce them.
73
78
 
74
79
  ## One platform, two engines
75
80
 
@@ -78,7 +83,7 @@ gold answer survived selection under the stated budget.
78
83
  | **Tokenfold Core** | Fast deterministic compression for JSON, schemas, provider requests, logs, diffs, and command output |
79
84
  | **Recoverable pruning** | Drop low-signal JSON rows only after storing them locally; fetch any omission with `tokenfold retrieve` |
80
85
  | **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 |
86
+ | **Budget control** | Conservative, balanced, and aggressive presets; nine task scopes; `--target-tokens` with honest best-effort reporting |
82
87
  | **Exact receipts** | Before/after token counts, applied transforms, warnings, provenance, and final status on every call |
83
88
  | **Realized savings** | `gain`, `stats`, and `session` report measured savings; `learn` proposes policy improvements without silently applying them |
84
89
  | **Every integration** | CLI, Python, TypeScript, Rust, HTTP proxy, and MCP share the same Core engine and report shape |
@@ -86,11 +91,11 @@ gold answer survived selection under the stated budget.
86
91
 
87
92
  ### Lossless or recoverable lossy
88
93
 
89
- | | Lossless — default | Recoverable lossy — opt-in |
94
+ | | Lossless — default | Recoverable lossy — opt-in |
90
95
  | --- | --- | --- |
91
96
  | **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
97
  | **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 |
98
+ | **Measured here** | **45.6–67.6%** fewer tokens | **51.7–91.7%** fewer tokens |
94
99
  | **Recovery** | All data remains in the payload | Every emitted marker resolves through the local retrieval store |
95
100
 
96
101
  ## Quick start
@@ -104,7 +109,7 @@ cargo add tokenfold-core # Rust library
104
109
  cargo install tokenfold-cli # Rust CLI
105
110
  ```
106
111
 
107
- Or download a signed CLI build for Linux, macOS, or Windows from
112
+ Or download a checksummed CLI build for Linux, macOS, or Windows from
108
113
  [GitHub Releases](https://github.com/snchimata/tokenfold/releases/latest) and
109
114
  verify it with the adjacent `.sha256` file.
110
115
 
@@ -121,11 +126,12 @@ Python uses the same Core engine and typed receipt:
121
126
  import json
122
127
  from pathlib import Path
123
128
 
124
- from tokenfold import CompressionMode, compress_openai_payload
129
+ from tokenfold import InputFormat, Preset, compress
125
130
 
126
- result = compress_openai_payload(
127
- Path("request.json").read_text(),
128
- mode=CompressionMode.BALANCED,
131
+ result = compress(
132
+ Path("request.json").read_bytes(),
133
+ format=InputFormat.OPENAI_JSON,
134
+ preset=Preset.BALANCED,
129
135
  )
130
136
  compressed_request = json.loads(result.payload)
131
137
  print(f"saved {result.report.saved_tokens} tokens ({result.saved_pct():.1f}%)")
@@ -133,64 +139,73 @@ print(f"saved {result.report.saved_tokens} tokens ({result.saved_pct():.1f}%)")
133
139
 
134
140
  | Surface | Best for | Start here |
135
141
  | --- | --- | --- |
136
- | CLI | Files, stdin, diffs, and command output | `tokenfold compress`, `inspect`, `diff`, `wrap` |
142
+ | CLI | Files and stdin | `tokenfold compress`, `inspect`, `decode`, `retrieve` |
137
143
  | Python | Applications and evaluation pipelines | `pip install tokenfold` |
138
144
  | TypeScript | Node.js applications and automation | `npm install tokenfold` |
139
145
  | Rust | Native embedding | `cargo add tokenfold-core` |
140
146
  | HTTP proxy | Transparent provider-shaped traffic | Build `tokenfold-proxy` |
141
147
  | MCP | Agents and editors | `tokenfold mcp serve` |
142
148
 
143
- `tokenfold init --agent <agent>` installs a durable host integration;
144
- `tokenfold doctor` verifies it. Trusted filters for Git, build, and test output
149
+ `tokenfold init --agent claude-code` merges a project-scoped `.mcp.json` entry without replacing
150
+ other servers; `tokenfold doctor --agent claude-code` verifies it. Codex can use the same stdio
151
+ server with `codex mcp add tokenfold -- tokenfold mcp serve`. See
152
+ [`docs/configuration.md`](docs/configuration.md) for tested MCP JSON/TOML and every environment
153
+ override. Trusted filters for Git, build, and test output
145
154
  are available through `tokenfold filters list`.
146
155
 
147
- Runnable examples:
156
+ Runnable examples, one per surface, all under [`examples/`](examples):
148
157
 
149
158
  ```bash
150
- python examples/quickstart.py
151
- python examples/lossy_pruning.py
159
+ python examples/quickstart.py # Python: compress messages, request bodies, JSON data
160
+ node examples/quickstart.mjs # TypeScript/Node: compress, inspect, read the receipt
161
+ cargo run -p tokenfold-core --example quickstart # Rust: the embedded core API
162
+ python examples/lossy_pruning.py # CLI: opt-in recoverable pruning, end to end
152
163
  ```
153
164
 
165
+ [`examples/quickstart.ipynb`](examples/quickstart.ipynb) is the guided tour of the whole
166
+ Python surface: everything `quickstart.py` shows, plus previews, budgets and presets,
167
+ provider payloads, recoverable pruning with retrieval, and where Tokenfold Select fits.
168
+
154
169
  ## Recoverable lossy pruning
155
170
 
156
- Lossless folding has a ceiling on heterogeneous arrays. `--lossy` ranks rows,
171
+ Lossless folding has a ceiling on heterogeneous arrays. `--prune` ranks rows,
157
172
  keeps the strongest signals, and replaces selected rows with compact
158
173
  `{"$tf_ref": {...}}` handles. A row leaves the payload only after the local
159
174
  store accepts it.
160
175
 
161
176
  ```bash
162
177
  tokenfold compress examples/incident_feed.json --format json \
163
- --lossy heuristic --lossy-ratio 0.35 --output feed.compact.json
178
+ --prune --keep-ratio 0.35 --output feed.compact.json
164
179
  ```
165
180
 
166
181
  On the bundled 40-event feed:
167
182
 
168
183
  | Mode | Exact tokens | Reduction | Events kept | Incident kept |
169
184
  | --- | ---: | ---: | ---: | :---: |
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 | ✅ |
185
+ | Lossless | 6,144 | 14.9% | 40 | ✅ |
186
+ | `--keep-ratio 0.35` | 3,485 | **51.7%** | 13 | ✅ |
187
+ | `--keep-ratio 0.05` | 2,294 | **68.2%** | 1 | ✅ |
173
188
 
174
189
  The planted `503` with `success: false` and `retries: 7` survives every shown
175
- setting because typed failure signals outrank position and length. Long rows
190
+ setting because typed failure signals outrank position and length — at
191
+ `--keep-ratio 0.05` it is the only row kept. Long rows
176
192
  amortize marker overhead further: the 100-result showcase reaches **91.7%**.
177
193
 
178
194
  Fetch a dropped row:
179
195
 
180
196
  ```bash
181
- tokenfold retrieve 978339a8898fedde3c5b0662a213f12ae4ad1b7fe6771f62b3c3d74d87389a4c
197
+ tokenfold retrieve cb13cc59cca0c218c579cd1d4b3cbab58d6dea265eb995cc9c00faf0cd0a6856
182
198
  # {"seq":1,"ts":"2026-08-15T00:01:11Z","subsystem":"index-writer",...}
183
199
  ```
184
200
 
185
201
  What the flags mean:
186
202
 
187
- - `--lossy-ratio` is an aggression hint over eligible array items. Lower keeps
203
+ - `--keep-ratio` is an aggression hint over eligible array items. Lower keeps
188
204
  fewer rows; it is not a whole-document guarantee.
189
205
  - `--target-tokens` is the whole-document goal. Tokenfold stops when it reaches
190
206
  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
207
+ cannot reach it (`unreachable` when protected content alone exceeds the target).
208
+ - `--preserve <path>` protects a named array; nested paths conservatively
194
209
  protect their nearest eligible ancestor.
195
210
  - Generic JSON only: lossy pruning does not run on OpenAI or Anthropic message
196
211
  payloads.
@@ -200,21 +215,39 @@ What the flags mean:
200
215
  Preview the projected savings with no store writes:
201
216
 
202
217
  ```bash
203
- tokenfold compress examples/incident_feed.json --format json \
204
- --lossy heuristic --lossy-ratio 0.35 --dry-run
218
+ tokenfold inspect examples/incident_feed.json --format json \
219
+ --prune --keep-ratio 0.35
220
+ ```
221
+
222
+ The same flags, and the same fail-closed contract, from Python and TypeScript:
223
+
224
+ ```python
225
+ from tokenfold import InputFormat, PruningPolicy, compress, retrieve
226
+
227
+ pruning = PruningPolicy(keep_ratio=0.35)
228
+ result = compress(feed_bytes, format=InputFormat.JSON, pruning=pruning)
229
+ original = retrieve(marker["$tf_ref"]) # any dropped row, verbatim
230
+ ```
231
+
232
+ ```ts
233
+ import { compress, retrieve } from "tokenfold";
234
+
235
+ const { payload, report } = await compress(feed, {
236
+ format: "json",
237
+ pruning: { keepRatio: 0.35 },
238
+ });
239
+ const original = await retrieve(hash); // any dropped row, verbatim
205
240
  ```
206
241
 
207
242
  <details>
208
243
  <summary><strong>Current Phase 1 constraints</strong></summary>
209
244
 
210
245
  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.
246
+ already contain retrieval markers. Filesystem entries are published under a
247
+ cross-process lock, and a refused batch leaves every candidate inline.
214
248
 
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.
249
+ Preview is a projection rather than a filesystem transaction, so a real run may
250
+ keep more rows if storage becomes unavailable.
218
251
 
219
252
  </details>
220
253
 
@@ -225,8 +258,8 @@ more rows if storage becomes unavailable.
225
258
  Tokenfold Select is an Apache-2.0 LoRA adapter on
226
259
  `ibm-granite/granite-embedding-reranker-english-r2`. It scores candidate spans
227
260
  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.
261
+ required content. It is a separately distributed companion: Core remains
262
+ model-free and deterministic and neither loads nor invokes Select.
230
263
 
231
264
  | | Tokenfold Core | Tokenfold Select |
232
265
  | --- | --- | --- |
@@ -293,6 +326,12 @@ training data, and limitations.
293
326
  - **Local control:** detected secrets are redacted before reports or storage;
294
327
  policy learning changes configuration only with `--apply`.
295
328
 
329
+ The offline fidelity gate uses deterministic lexical-overlap, critical-token,
330
+ and containment proxies. Those checks catch regressions but do not establish
331
+ semantic equivalence or downstream task success. Runtime `quality` fields are
332
+ absent unless a versioned evaluator has supplied data; applications should run
333
+ their own representative task evaluation before enabling lossy pruning.
334
+
296
335
  ## Reproduce the results
297
336
 
298
337
  ```bash
@@ -307,9 +346,9 @@ cargo run --release --locked -p tokenfold-cli -- \
307
346
  inspect examples/api_response.json --format json
308
347
  ```
309
348
 
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).
349
+ The bundled 30-record API response reports 3,812 → 1,376 tokens, a **63.9%
350
+ lossless reduction**. Benchmark sources and thresholds live in [CHANGELOG.md](https://github.com/snchimata/tokenfold/blob/main/CHANGELOG.md)
351
+ and [`crates/tokenfold-core/benches/THRESHOLDS.toml`](https://github.com/snchimata/tokenfold/blob/main/crates/tokenfold-core/benches/THRESHOLDS.toml).
313
352
 
314
353
  ## Contributing
315
354
 
@@ -326,7 +365,7 @@ cd packages/tokenfold && npm ci && npm test
326
365
 
327
366
  ## License
328
367
 
329
- [Apache-2.0](LICENSE)
368
+ [Apache-2.0](https://github.com/snchimata/tokenfold/blob/main/LICENSE)
330
369
 
331
370
  ---
332
371
 
@@ -337,7 +376,7 @@ tokens your application can stop sending today.
337
376
  pip install tokenfold
338
377
  ```
339
378
 
340
- If Tokenfold earns a place in your stack, a ⭐ on
379
+ If Tokenfold earns a place in your stack, a ⭐ on
341
380
  [GitHub](https://github.com/snchimata/tokenfold) helps the next team find it.
342
381
 
343
382
  [tokenfold-select]: https://huggingface.co/snchimata/tokenfold-select