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.
- {tokenfold-0.4.0 → tokenfold-0.5.0}/Cargo.lock +63 -19
- {tokenfold-0.4.0 → tokenfold-0.5.0}/Cargo.toml +3 -2
- {tokenfold-0.4.0 → tokenfold-0.5.0}/PKG-INFO +89 -50
- {tokenfold-0.4.0 → tokenfold-0.5.0}/README.md +88 -49
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/Cargo.toml +2 -0
- tokenfold-0.5.0/crates/tokenfold-core/README.md +29 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/benches/THRESHOLDS.toml +4 -5
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/benches/compression_bench.rs +5 -5
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/budget.rs +71 -44
- tokenfold-0.5.0/crates/tokenfold-core/src/codec.rs +116 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/errors.rs +6 -1
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/filters.rs +8 -8
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/lib.rs +3 -1
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/modes.rs +50 -48
- tokenfold-0.5.0/crates/tokenfold-core/src/pipeline/mod.rs +1130 -0
- tokenfold-0.5.0/crates/tokenfold-core/src/pipeline/tests.rs +1291 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/report.rs +80 -14
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/retrieval_store.rs +347 -43
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/safety.rs +3 -1
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/stats.rs +26 -25
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/status.rs +1 -16
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/diff.rs +5 -7
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_prune.rs +52 -32
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/logs.rs +4 -4
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/tests/golden.rs +3 -1
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/tests/integration.rs +13 -18
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/tests/property_tests.rs +1 -1
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-py/Cargo.toml +1 -1
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-py/src/lib.rs +475 -258
- tokenfold-0.4.0/crates/tokenfold-core/examples/quickstart.rs +0 -83
- tokenfold-0.4.0/crates/tokenfold-core/src/pipeline.rs +0 -2301
- {tokenfold-0.4.0 → tokenfold-0.5.0}/LICENSE +0 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/input.rs +0 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/token_estimator.rs +0 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json.rs +0 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_dict.rs +0 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_fold.rs +0 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/log_fold.rs +0 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/mod.rs +0 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/redaction.rs +0 -0
- {tokenfold-0.4.0 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/schema.rs +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
1094
|
+
version = "0.5.0"
|
|
1063
1095
|
|
|
1064
1096
|
[[package]]
|
|
1065
1097
|
name = "tokenfold-learn"
|
|
1066
|
-
version = "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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
6
|
+
version = "0.5.0"
|
|
7
7
|
edition = "2024"
|
|
8
|
-
rust-version = "1.
|
|
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.
|
|
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
|
|
29
|
+
**Up to 92% fewer input tokens · lossless by default · exact receipts**
|
|
30
30
|
|
|
31
|
-
CLI
|
|
31
|
+
CLI · Python · TypeScript · Rust · proxy · MCP · local-first · provider-neutral
|
|
32
32
|
|
|
33
|
-
[](https://github.com/snchimata/tokenfold/actions/workflows/ci.yml) [](https://github.com/snchimata/tokenfold/actions/workflows/ci.yml) [](https://github.com/snchimata/tokenfold/releases/latest) [](https://pypi.org/project/tokenfold/) [](https://www.npmjs.com/package/tokenfold) [](https://docs.rs/crate/tokenfold-core/latest) [](LICENSE)
|
|
33
|
+
[](https://github.com/snchimata/tokenfold/actions/workflows/ci.yml) [](https://github.com/snchimata/tokenfold/actions/workflows/ci.yml) [](https://github.com/snchimata/tokenfold/releases/latest) [](https://pypi.org/project/tokenfold/) [](https://www.npmjs.com/package/tokenfold) [](https://docs.rs/crate/tokenfold-core/latest) [](https://github.com/snchimata/tokenfold/blob/main/LICENSE)
|
|
34
34
|
|
|
35
|
-
[Measured results](#measured-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** | **
|
|
48
|
-
| 84,032
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
129
|
+
from tokenfold import InputFormat, Preset, compress
|
|
125
130
|
|
|
126
|
-
result =
|
|
127
|
-
Path("request.json").
|
|
128
|
-
|
|
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
|
|
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
|
|
144
|
-
`tokenfold doctor` verifies it.
|
|
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
|
-
|
|
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. `--
|
|
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
|
-
--
|
|
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 |
|
|
171
|
-
| `--
|
|
172
|
-
| `--
|
|
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
|
|
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
|
|
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
|
-
- `--
|
|
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 (`
|
|
192
|
-
|
|
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
|
|
204
|
-
--
|
|
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.
|
|
212
|
-
|
|
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
|
-
|
|
216
|
-
|
|
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.
|
|
229
|
-
|
|
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
|
|
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
|
|
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
|