tokenfold 0.4.1__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.1 → tokenfold-0.5.0}/Cargo.lock +63 -19
- {tokenfold-0.4.1 → tokenfold-0.5.0}/Cargo.toml +3 -2
- {tokenfold-0.4.1 → tokenfold-0.5.0}/PKG-INFO +63 -49
- {tokenfold-0.4.1 → tokenfold-0.5.0}/README.md +62 -48
- {tokenfold-0.4.1 → 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.1 → tokenfold-0.5.0}/crates/tokenfold-core/benches/THRESHOLDS.toml +3 -4
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/benches/compression_bench.rs +3 -3
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/budget.rs +56 -29
- tokenfold-0.5.0/crates/tokenfold-core/src/codec.rs +116 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/lib.rs +3 -1
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/modes.rs +34 -34
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/pipeline/mod.rs +236 -116
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/pipeline/tests.rs +15 -11
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/report.rs +75 -9
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/retrieval_store.rs +344 -40
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/stats.rs +10 -10
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/status.rs +1 -16
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/diff.rs +1 -1
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_prune.rs +51 -30
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/tests/integration.rs +12 -17
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-py/Cargo.toml +1 -1
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-py/src/lib.rs +293 -300
- {tokenfold-0.4.1 → tokenfold-0.5.0}/LICENSE +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/errors.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/filters.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/input.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/safety.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/token_estimator.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_dict.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/json_fold.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/log_fold.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/logs.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/mod.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/redaction.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/src/transforms/schema.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/tests/golden.rs +0 -0
- {tokenfold-0.4.1 → tokenfold-0.5.0}/crates/tokenfold-core/tests/property_tests.rs +0 -0
- {tokenfold-0.4.1 → 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
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,15 +139,18 @@ 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
156
|
Runnable examples, one per surface, all under [`examples/`](examples):
|
|
@@ -153,49 +162,50 @@ cargo run -p tokenfold-core --example quickstart # Rust: the embedded core API
|
|
|
153
162
|
python examples/lossy_pruning.py # CLI: opt-in recoverable pruning, end to end
|
|
154
163
|
```
|
|
155
164
|
|
|
156
|
-
[`examples/quickstart.ipynb`](examples/quickstart.ipynb) is the
|
|
157
|
-
Python quickstart,
|
|
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.
|
|
158
168
|
|
|
159
169
|
## Recoverable lossy pruning
|
|
160
170
|
|
|
161
|
-
Lossless folding has a ceiling on heterogeneous arrays. `--
|
|
171
|
+
Lossless folding has a ceiling on heterogeneous arrays. `--prune` ranks rows,
|
|
162
172
|
keeps the strongest signals, and replaces selected rows with compact
|
|
163
173
|
`{"$tf_ref": {...}}` handles. A row leaves the payload only after the local
|
|
164
174
|
store accepts it.
|
|
165
175
|
|
|
166
176
|
```bash
|
|
167
177
|
tokenfold compress examples/incident_feed.json --format json \
|
|
168
|
-
--
|
|
178
|
+
--prune --keep-ratio 0.35 --output feed.compact.json
|
|
169
179
|
```
|
|
170
180
|
|
|
171
181
|
On the bundled 40-event feed:
|
|
172
182
|
|
|
173
183
|
| Mode | Exact tokens | Reduction | Events kept | Incident kept |
|
|
174
184
|
| --- | ---: | ---: | ---: | :---: |
|
|
175
|
-
| Lossless |
|
|
176
|
-
| `--
|
|
177
|
-
| `--
|
|
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 | ✅ |
|
|
178
188
|
|
|
179
189
|
The planted `503` with `success: false` and `retries: 7` survives every shown
|
|
180
|
-
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
|
|
181
192
|
amortize marker overhead further: the 100-result showcase reaches **91.7%**.
|
|
182
193
|
|
|
183
194
|
Fetch a dropped row:
|
|
184
195
|
|
|
185
196
|
```bash
|
|
186
|
-
tokenfold retrieve
|
|
197
|
+
tokenfold retrieve cb13cc59cca0c218c579cd1d4b3cbab58d6dea265eb995cc9c00faf0cd0a6856
|
|
187
198
|
# {"seq":1,"ts":"2026-08-15T00:01:11Z","subsystem":"index-writer",...}
|
|
188
199
|
```
|
|
189
200
|
|
|
190
201
|
What the flags mean:
|
|
191
202
|
|
|
192
|
-
- `--
|
|
203
|
+
- `--keep-ratio` is an aggression hint over eligible array items. Lower keeps
|
|
193
204
|
fewer rows; it is not a whole-document guarantee.
|
|
194
205
|
- `--target-tokens` is the whole-document goal. Tokenfold stops when it reaches
|
|
195
206
|
the target losslessly and reports `best_effort` when the safe transform set
|
|
196
|
-
cannot reach it (`
|
|
197
|
-
|
|
198
|
-
- `--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
|
|
199
209
|
protect their nearest eligible ancestor.
|
|
200
210
|
- Generic JSON only: lossy pruning does not run on OpenAI or Anthropic message
|
|
201
211
|
payloads.
|
|
@@ -205,18 +215,18 @@ What the flags mean:
|
|
|
205
215
|
Preview the projected savings with no store writes:
|
|
206
216
|
|
|
207
217
|
```bash
|
|
208
|
-
tokenfold
|
|
209
|
-
--
|
|
218
|
+
tokenfold inspect examples/incident_feed.json --format json \
|
|
219
|
+
--prune --keep-ratio 0.35
|
|
210
220
|
```
|
|
211
221
|
|
|
212
222
|
The same flags, and the same fail-closed contract, from Python and TypeScript:
|
|
213
223
|
|
|
214
224
|
```python
|
|
215
|
-
from tokenfold import
|
|
225
|
+
from tokenfold import InputFormat, PruningPolicy, compress, retrieve
|
|
216
226
|
|
|
217
|
-
|
|
218
|
-
result = compress(feed_bytes, format=InputFormat.JSON,
|
|
219
|
-
original = retrieve(marker["$tf_ref"]
|
|
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
|
|
220
230
|
```
|
|
221
231
|
|
|
222
232
|
```ts
|
|
@@ -224,8 +234,7 @@ import { compress, retrieve } from "tokenfold";
|
|
|
224
234
|
|
|
225
235
|
const { payload, report } = await compress(feed, {
|
|
226
236
|
format: "json",
|
|
227
|
-
|
|
228
|
-
lossyRatio: 0.35,
|
|
237
|
+
pruning: { keepRatio: 0.35 },
|
|
229
238
|
});
|
|
230
239
|
const original = await retrieve(hash); // any dropped row, verbatim
|
|
231
240
|
```
|
|
@@ -234,9 +243,8 @@ const original = await retrieve(hash); // any dropped row, verbatim
|
|
|
234
243
|
<summary><strong>Current Phase 1 constraints</strong></summary>
|
|
235
244
|
|
|
236
245
|
Treat `$tf_ref` as reserved and do not enable lossy pruning on documents that
|
|
237
|
-
already contain retrieval markers.
|
|
238
|
-
|
|
239
|
-
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.
|
|
240
248
|
|
|
241
249
|
Preview is a projection rather than a filesystem transaction, so a real run may
|
|
242
250
|
keep more rows if storage becomes unavailable.
|
|
@@ -250,8 +258,8 @@ keep more rows if storage becomes unavailable.
|
|
|
250
258
|
Tokenfold Select is an Apache-2.0 LoRA adapter on
|
|
251
259
|
`ibm-granite/granite-embedding-reranker-english-r2`. It scores candidate spans
|
|
252
260
|
against a query; your allocator applies the token budget and force-keeps
|
|
253
|
-
required content.
|
|
254
|
-
|
|
261
|
+
required content. It is a separately distributed companion: Core remains
|
|
262
|
+
model-free and deterministic and neither loads nor invokes Select.
|
|
255
263
|
|
|
256
264
|
| | Tokenfold Core | Tokenfold Select |
|
|
257
265
|
| --- | --- | --- |
|
|
@@ -318,6 +326,12 @@ training data, and limitations.
|
|
|
318
326
|
- **Local control:** detected secrets are redacted before reports or storage;
|
|
319
327
|
policy learning changes configuration only with `--apply`.
|
|
320
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
|
+
|
|
321
335
|
## Reproduce the results
|
|
322
336
|
|
|
323
337
|
```bash
|
|
@@ -332,8 +346,8 @@ cargo run --release --locked -p tokenfold-cli -- \
|
|
|
332
346
|
inspect examples/api_response.json --format json
|
|
333
347
|
```
|
|
334
348
|
|
|
335
|
-
The
|
|
336
|
-
reduction**. Benchmark sources and thresholds live in [CHANGELOG.md](https://github.com/snchimata/tokenfold/blob/main/CHANGELOG.md)
|
|
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)
|
|
337
351
|
and [`crates/tokenfold-core/benches/THRESHOLDS.toml`](https://github.com/snchimata/tokenfold/blob/main/crates/tokenfold-core/benches/THRESHOLDS.toml).
|
|
338
352
|
|
|
339
353
|
## Contributing
|
|
@@ -362,7 +376,7 @@ tokens your application can stop sending today.
|
|
|
362
376
|
pip install tokenfold
|
|
363
377
|
```
|
|
364
378
|
|
|
365
|
-
If Tokenfold earns a place in your stack, a
|
|
379
|
+
If Tokenfold earns a place in your stack, a â on
|
|
366
380
|
[GitHub](https://github.com/snchimata/tokenfold) helps the next team find it.
|
|
367
381
|
|
|
368
382
|
[tokenfold-select]: https://huggingface.co/snchimata/tokenfold-select
|