tokenfold 0.5.2__tar.gz → 0.5.3__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.5.2 → tokenfold-0.5.3}/Cargo.lock +14 -14
- {tokenfold-0.5.2 → tokenfold-0.5.3}/Cargo.toml +1 -1
- {tokenfold-0.5.2 → tokenfold-0.5.3}/PKG-INFO +195 -97
- {tokenfold-0.5.2 → tokenfold-0.5.3}/README.md +194 -96
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-py/Cargo.toml +1 -1
- {tokenfold-0.5.2 → tokenfold-0.5.3}/LICENSE +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/Cargo.toml +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/README.md +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/benches/THRESHOLDS.toml +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/benches/compression_bench.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/allocation.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/budget.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/codec.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/errors.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/filters.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/holdout.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/input.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/lib.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/measurement.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/modes.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/pipeline/mod.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/pipeline/tests.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/profiles.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/report.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/retrieval_store.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/safety.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/stats.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/status.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/token_estimator.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/transforms/diff.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/transforms/json.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/transforms/json_dict.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/transforms/json_fold.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/transforms/json_prune.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/transforms/log_fold.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/transforms/logs.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/transforms/mod.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/transforms/redaction.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/src/transforms/schema.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/tests/golden.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/tests/integration.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-core/tests/property_tests.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/crates/tokenfold-py/src/lib.rs +0 -0
- {tokenfold-0.5.2 → tokenfold-0.5.3}/pyproject.toml +0 -0
|
@@ -871,9 +871,9 @@ dependencies = [
|
|
|
871
871
|
|
|
872
872
|
[[package]]
|
|
873
873
|
name = "rustls-webpki"
|
|
874
|
-
version = "0.103.
|
|
874
|
+
version = "0.103.16"
|
|
875
875
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
876
|
-
checksum = "
|
|
876
|
+
checksum = "4443b1b6d39d7c663139942cc4558262562d2c84123bb6282ef177009ca8b281"
|
|
877
877
|
dependencies = [
|
|
878
878
|
"ring",
|
|
879
879
|
"rustls-pki-types",
|
|
@@ -1109,7 +1109,7 @@ dependencies = [
|
|
|
1109
1109
|
|
|
1110
1110
|
[[package]]
|
|
1111
1111
|
name = "tokenfold-adapters"
|
|
1112
|
-
version = "0.5.
|
|
1112
|
+
version = "0.5.3"
|
|
1113
1113
|
dependencies = [
|
|
1114
1114
|
"serde",
|
|
1115
1115
|
"serde_json",
|
|
@@ -1118,7 +1118,7 @@ dependencies = [
|
|
|
1118
1118
|
|
|
1119
1119
|
[[package]]
|
|
1120
1120
|
name = "tokenfold-admin"
|
|
1121
|
-
version = "0.5.
|
|
1121
|
+
version = "0.5.3"
|
|
1122
1122
|
dependencies = [
|
|
1123
1123
|
"ed25519-dalek",
|
|
1124
1124
|
"serde",
|
|
@@ -1128,7 +1128,7 @@ dependencies = [
|
|
|
1128
1128
|
|
|
1129
1129
|
[[package]]
|
|
1130
1130
|
name = "tokenfold-cli"
|
|
1131
|
-
version = "0.5.
|
|
1131
|
+
version = "0.5.3"
|
|
1132
1132
|
dependencies = [
|
|
1133
1133
|
"clap",
|
|
1134
1134
|
"serde",
|
|
@@ -1143,7 +1143,7 @@ dependencies = [
|
|
|
1143
1143
|
|
|
1144
1144
|
[[package]]
|
|
1145
1145
|
name = "tokenfold-core"
|
|
1146
|
-
version = "0.5.
|
|
1146
|
+
version = "0.5.3"
|
|
1147
1147
|
dependencies = [
|
|
1148
1148
|
"proptest",
|
|
1149
1149
|
"regex",
|
|
@@ -1158,25 +1158,25 @@ dependencies = [
|
|
|
1158
1158
|
|
|
1159
1159
|
[[package]]
|
|
1160
1160
|
name = "tokenfold-image"
|
|
1161
|
-
version = "0.5.
|
|
1161
|
+
version = "0.5.3"
|
|
1162
1162
|
|
|
1163
1163
|
[[package]]
|
|
1164
1164
|
name = "tokenfold-learn"
|
|
1165
|
-
version = "0.5.
|
|
1165
|
+
version = "0.5.3"
|
|
1166
1166
|
dependencies = [
|
|
1167
1167
|
"tokenfold-core",
|
|
1168
1168
|
]
|
|
1169
1169
|
|
|
1170
1170
|
[[package]]
|
|
1171
1171
|
name = "tokenfold-output"
|
|
1172
|
-
version = "0.5.
|
|
1172
|
+
version = "0.5.3"
|
|
1173
1173
|
dependencies = [
|
|
1174
1174
|
"tokenfold-core",
|
|
1175
1175
|
]
|
|
1176
1176
|
|
|
1177
1177
|
[[package]]
|
|
1178
1178
|
name = "tokenfold-proxy"
|
|
1179
|
-
version = "0.5.
|
|
1179
|
+
version = "0.5.3"
|
|
1180
1180
|
dependencies = [
|
|
1181
1181
|
"clap",
|
|
1182
1182
|
"ctrlc",
|
|
@@ -1190,7 +1190,7 @@ dependencies = [
|
|
|
1190
1190
|
|
|
1191
1191
|
[[package]]
|
|
1192
1192
|
name = "tokenfold-py"
|
|
1193
|
-
version = "0.5.
|
|
1193
|
+
version = "0.5.3"
|
|
1194
1194
|
dependencies = [
|
|
1195
1195
|
"pyo3",
|
|
1196
1196
|
"serde_json",
|
|
@@ -1199,7 +1199,7 @@ dependencies = [
|
|
|
1199
1199
|
|
|
1200
1200
|
[[package]]
|
|
1201
1201
|
name = "tokenfold-rag"
|
|
1202
|
-
version = "0.5.
|
|
1202
|
+
version = "0.5.3"
|
|
1203
1203
|
dependencies = [
|
|
1204
1204
|
"tokenfold-core",
|
|
1205
1205
|
]
|
|
@@ -1353,9 +1353,9 @@ dependencies = [
|
|
|
1353
1353
|
|
|
1354
1354
|
[[package]]
|
|
1355
1355
|
name = "webpki-roots"
|
|
1356
|
-
version = "1.0.
|
|
1356
|
+
version = "1.0.10"
|
|
1357
1357
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1358
|
-
checksum = "
|
|
1358
|
+
checksum = "1c1c8e20c8a38fc7d65abfe74eb7280e4aa667e8eec8bc84996d2874810748d9"
|
|
1359
1359
|
dependencies = [
|
|
1360
1360
|
"rustls-pki-types",
|
|
1361
1361
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tokenfold
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.3
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
@@ -93,14 +93,14 @@ cargo add tokenfold-core # Rust library
|
|
|
93
93
|
<br />
|
|
94
94
|
<strong>Model-free & deterministic</strong>
|
|
95
95
|
<br /><br />
|
|
96
|
-
No GPU, no semantic guesswork, no model in the Core path.
|
|
96
|
+
No GPU, no semantic guesswork, no model in the Core path. A Rust engine with Python, Node.js, CLI and proxy interfaces.
|
|
97
97
|
<br /><br />
|
|
98
98
|
</td>
|
|
99
99
|
</tr>
|
|
100
100
|
</table>
|
|
101
101
|
|
|
102
102
|
> [!NOTE]
|
|
103
|
-
> **Built for:** Developers and AI teams
|
|
103
|
+
> **Built for:** Developers and AI teams sending structured JSON, tool definitions, and RAG feeds to LLMs. Start with a representative payload, inspect the receipt, and validate the result in your application.
|
|
104
104
|
|
|
105
105
|
<br />
|
|
106
106
|
|
|
@@ -117,12 +117,17 @@ cargo add tokenfold-core # Rust library
|
|
|
117
117
|
{"__tf_cols__":["id","role"],"__tf_rows__":[[1,"admin"],[2,"member"]]}
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
120
|
+

|
|
121
|
+
|
|
122
|
+
<details>
|
|
123
|
+
<summary><strong>How this demo was generated (VHS tape)</strong></summary>
|
|
124
|
+
|
|
125
|
+
The [VHS tape](docs/tokenfold-demo.tape) runs `inspect`, `compress`, and
|
|
126
|
+
`decode` against the bundled API response, including the **63.9%** receipt.
|
|
127
|
+
Run `vhs docs/tokenfold-demo.tape` to regenerate the GIF; the tape requires
|
|
128
|
+
`tokenfold` on `PATH`.
|
|
129
|
+
|
|
130
|
+
</details>
|
|
126
131
|
|
|
127
132
|
Send the folded JSON directly to the model: column names label each value's
|
|
128
133
|
position in every row. Decode only when your application needs the original
|
|
@@ -133,7 +138,7 @@ object shape again.
|
|
|
133
138
|
- **Targets structured JSON, not prose.** Folds repeated keys and columns
|
|
134
139
|
mechanically rather than using semantic guesswork.
|
|
135
140
|
- **Model-free and deterministic.** Zero models running in Core and zero GPU
|
|
136
|
-
overhead.
|
|
141
|
+
overhead.
|
|
137
142
|
- **Verified by exact decode.** Every lossless transform is verified by an
|
|
138
143
|
in-memory round trip before emitting; lossy pruning is strictly opt-in and
|
|
139
144
|
recoverable.
|
|
@@ -142,60 +147,38 @@ For tabular arrays, Tokenfold folds repeated keys into
|
|
|
142
147
|
header columns (`__tf_cols__`). No model runs in the Core engine, and every
|
|
143
148
|
lossless transform is verified by exact decode.
|
|
144
149
|
|
|
145
|
-
|
|
146
|
-
> `schema_compaction` is not enabled by any preset. Unlike the default
|
|
147
|
-
> transforms, it truncates `examples` arrays and is not reversible.
|
|
150
|
+
#### How Tokenfold decides what to fold
|
|
148
151
|
|
|
149
152
|
```mermaid
|
|
150
|
-
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#
|
|
153
|
+
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#f8fafc", "primaryTextColor": "#0f172a", "primaryBorderColor": "#94a3b8", "lineColor": "#64748b", "edgeLabelBackground": "#f8fafc", "fontFamily": "Arial", "fontSize": "15px"}, "flowchart": {"curve": "linear", "padding": 16, "nodeSpacing": 40, "rankSpacing": 32}}}%%
|
|
151
154
|
flowchart LR
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
155
|
+
accTitle: Lossless first, pruning only when opted in
|
|
156
|
+
accDescr: Build a verified lossless baseline. Consider pruning only when opted in, eligible, and still needed. Store omissions before removal and use pruning only if it beats the lossless baseline; otherwise keep that baseline.
|
|
157
|
+
Lossless["Build lossless JSON baseline<br/>Verify folds; retain savings"] --> OptIn{"Pruning enabled,<br/>eligible and needed?"}
|
|
158
|
+
OptIn -->|No| Keep("Lossless payload<br/>+ receipt")
|
|
159
|
+
OptIn -->|Yes| Prune["Rank eligible rows<br/>Store before removal"]
|
|
160
|
+
Prune -->|No further savings| Keep
|
|
161
|
+
Prune -->|Fewer tokens than baseline| Emit("Pruned payload<br/>+ markers and receipt")
|
|
162
|
+
|
|
163
|
+
classDef core fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a
|
|
164
|
+
classDef optional fill:#f8fafc,stroke:#64748b,stroke-dasharray:5 4,color:#334155
|
|
165
|
+
class Lossless,Keep core
|
|
166
|
+
class Prune optional
|
|
156
167
|
```
|
|
157
168
|
|
|
158
|
-
#### How Tokenfold decides what to fold
|
|
159
|
-
|
|
160
|
-

|
|
161
|
-
|
|
162
169
|
<details>
|
|
163
170
|
<summary><strong>Text version (screen readers / no-image fallback)</strong></summary>
|
|
164
171
|
|
|
165
|
-
1.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
3.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
#### Proxy / agent round trip
|
|
176
|
-
|
|
177
|
-
```mermaid
|
|
178
|
-
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#22D3EE", "primaryTextColor": "#0b1020", "primaryBorderColor": "#A855F7", "lineColor": "#A855F7", "actorBkg": "#22D3EE", "actorTextColor": "#0b1020", "actorBorder": "#A855F7", "signalColor": "#A855F7", "signalTextColor": "#334155", "fontFamily": "ui-sans-serif, system-ui, sans-serif"}}}%%
|
|
179
|
-
sequenceDiagram
|
|
180
|
-
participant C as Client / Agent
|
|
181
|
-
participant P as Tokenfold Proxy
|
|
182
|
-
participant U as Upstream LLM
|
|
183
|
-
C->>P: Provider-shaped request (large JSON)
|
|
184
|
-
P->>P: Apply lossless transforms
|
|
185
|
-
P->>U: Forwarded compact request
|
|
186
|
-
U-->>P: Completion / action
|
|
187
|
-
P-->>C: Response (Authorization forwarded unchanged)
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-

|
|
191
|
-
|
|
192
|
-
<details>
|
|
193
|
-
<summary><strong>How this demo was generated (VHS tape)</strong></summary>
|
|
194
|
-
|
|
195
|
-
The [VHS tape](docs/tokenfold-demo.tape) runs `inspect`, `compress`, and
|
|
196
|
-
`decode` against the bundled API response, including the **63.9%** receipt.
|
|
197
|
-
Run `vhs docs/tokenfold-demo.tape` to regenerate the GIF; the tape requires
|
|
198
|
-
`tokenfold` on `PATH`.
|
|
172
|
+
1. Build the lossless baseline using eligible transforms. Verify structural
|
|
173
|
+
folds with an exact decode round trip and keep only token reductions.
|
|
174
|
+
2. Consider pruning only when explicitly opted in, the payload is eligible,
|
|
175
|
+
and the lossless baseline has not already met a requested token target.
|
|
176
|
+
3. Rank eligible rows and store omissions locally before removing them.
|
|
177
|
+
Rows refused by storage stay inline.
|
|
178
|
+
4. Use the pruned payload only if it has fewer tokens than the lossless
|
|
179
|
+
baseline; otherwise keep the lossless baseline.
|
|
180
|
+
5. Emit the chosen payload and compression receipt. Pruned payloads include
|
|
181
|
+
retrieval markers for stored omissions.
|
|
199
182
|
|
|
200
183
|
</details>
|
|
201
184
|
|
|
@@ -224,6 +207,24 @@ cargo install tokenfold-proxy
|
|
|
224
207
|
tokenfold-proxy --upstream https://api.openai.com
|
|
225
208
|
```
|
|
226
209
|
|
|
210
|
+
```python
|
|
211
|
+
from openai import OpenAI
|
|
212
|
+
|
|
213
|
+
# Your client's Authorization header is forwarded to upstream unchanged -
|
|
214
|
+
# no credential reconfiguration needed.
|
|
215
|
+
client = OpenAI(base_url="http://127.0.0.1:8787/v1")
|
|
216
|
+
# Existing calls work unchanged: client.chat.completions.create(...)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The proxy listens on loopback (`127.0.0.1:8787`) by default.
|
|
220
|
+
Provider envelopes are minified, not columnar-folded.
|
|
221
|
+
|
|
222
|
+
Works out-of-the-box with any client or framework that accepts a custom base URL
|
|
223
|
+
(LangChain, LlamaIndex, LiteLLM, Instructor, or direct HTTP clients).
|
|
224
|
+
|
|
225
|
+
<details>
|
|
226
|
+
<summary><strong>Proxy routing, streaming, and stderr telemetry details</strong></summary>
|
|
227
|
+
|
|
227
228
|
The proxy installs from source via Cargo and listens on `127.0.0.1:8787` by
|
|
228
229
|
default (`--bind`; use `--allow-non-loopback-bind` to change that). Only
|
|
229
230
|
chat-shaped JSON bodies (a non-empty `messages` array) are compressed on the
|
|
@@ -245,17 +246,25 @@ attempt ended. A provider that reports no usage, or a body whose usage cannot
|
|
|
245
246
|
be read cleanly, records `usage_disposition: absent|malformed|oversized` with a
|
|
246
247
|
`null` count rather than a zero -- and never changes what is forwarded.
|
|
247
248
|
|
|
248
|
-
|
|
249
|
-
from openai import OpenAI
|
|
249
|
+
</details>
|
|
250
250
|
|
|
251
|
-
|
|
252
|
-
# no credential reconfiguration needed.
|
|
253
|
-
client = OpenAI(base_url="http://127.0.0.1:8787/v1")
|
|
254
|
-
# Existing calls work unchanged: client.chat.completions.create(...)
|
|
255
|
-
```
|
|
251
|
+
#### Proxy / agent round trip
|
|
256
252
|
|
|
257
|
-
|
|
258
|
-
|
|
253
|
+
```mermaid
|
|
254
|
+
%%{init: {"theme": "base", "themeVariables": {"fontFamily": "Arial", "fontSize": "15px", "actorBkg": "#f8fafc", "actorTextColor": "#0f172a", "actorBorder": "#94a3b8", "actorLineColor": "#94a3b8", "signalColor": "#64748b", "signalTextColor": "#334155", "activationBkgColor": "#eff6ff", "activationBorderColor": "#2563eb", "sequenceNumberColor": "#ffffff"}, "sequence": {"mirrorActors": false, "actorMargin": 56, "messageMargin": 36}}}%%
|
|
255
|
+
sequenceDiagram
|
|
256
|
+
accTitle: Proxy request and response lifecycle
|
|
257
|
+
accDescr: The client sends a provider-shaped request to Tokenfold Proxy, which applies lossless transforms and forwards the compact request with Authorization unchanged. The upstream response returns through the proxy.
|
|
258
|
+
autonumber
|
|
259
|
+
participant C as Client / Agent
|
|
260
|
+
participant P as Tokenfold Proxy
|
|
261
|
+
participant U as Upstream LLM
|
|
262
|
+
C->>+P: Provider-shaped request
|
|
263
|
+
P->>P: Apply lossless transforms
|
|
264
|
+
P->>+U: Compact request + unchanged Authorization
|
|
265
|
+
U-->>-P: Completion / action
|
|
266
|
+
P-->>-C: Response
|
|
267
|
+
```
|
|
259
268
|
|
|
260
269
|
### Interfaces
|
|
261
270
|
|
|
@@ -298,8 +307,15 @@ print(f"Saved {result.report.saved_tokens} tokens ({result.saved_pct():.1f}%)")
|
|
|
298
307
|
| `balanced` (default) | Minification plus reversible columnar folding (`json_field_fold`, `json_value_dict`, `log_field_fold`) on eligible formats. |
|
|
299
308
|
| `aggressive` | Same default transform set as `balanced` today. |
|
|
300
309
|
|
|
301
|
-
Provider message formats (`openai_json`, `anthropic_json`)
|
|
302
|
-
columnar folding
|
|
310
|
+
Provider message formats (`openai_json`, `anthropic_json`) use minification
|
|
311
|
+
only; columnar folding applies to generic JSON (`--format json`). The default
|
|
312
|
+
proxy path follows this rule. Explicit `--observations` enables lossless
|
|
313
|
+
compression of eligible JSON tool-result strings on `/v1/chat/completions`
|
|
314
|
+
without folding the provider envelope; see [observation compression](docs/configuration.md#restart-safe-observation-commitments).
|
|
315
|
+
|
|
316
|
+
> [!NOTE]
|
|
317
|
+
> `schema_compaction` is not enabled by any preset. Unlike the default
|
|
318
|
+
> transforms, it truncates `examples` arrays and is not reversible.
|
|
303
319
|
|
|
304
320
|
### Runnable examples (Python >=3.9, Node.js >=22, Rust >=1.98)
|
|
305
321
|
|
|
@@ -349,7 +365,7 @@ are available through `tokenfold filters list`.
|
|
|
349
365
|
### Structural, not semantic compression
|
|
350
366
|
|
|
351
367
|
Semantic prompt compressors such as [LLMLingua](https://github.com/microsoft/LLMLingua) use a smaller language model to identify and remove less-important prompt tokens.
|
|
352
|
-
Tokenfold solves a different problem first: repeated keys, values, schemas, rows, and other structural redundancy. Core needs no model, is deterministic, and verifies an exact decode before accepting a lossless transform.
|
|
368
|
+
Tokenfold solves a different problem first: repeated keys, values, schemas, rows, and other structural redundancy. Core needs no model, is deterministic, and verifies an exact decode before accepting a lossless transform. Core does not inject prompt guidance or fine-tune models.
|
|
353
369
|
|
|
354
370
|
[Tokenfold Select](#tokenfold-select) is Tokenfold's complementary query-aware offering: when structure ends, it ranks what matters under a token budget.
|
|
355
371
|
|
|
@@ -361,8 +377,31 @@ Tokenfold solves a different problem first: repeated keys, values, schemas, rows
|
|
|
361
377
|
|
|
362
378
|
**When structure ends, rank what matters.**
|
|
363
379
|
|
|
380
|
+
[Tokenfold Select v3][tokenfold-select] is an Apache-2.0, **149.6M-parameter**
|
|
381
|
+
joint-group scorer built on the full 22-layer Ettin encoder. It scores groups
|
|
382
|
+
against the query and their neighbors within each window; your allocator keeps
|
|
383
|
+
selected source text unchanged, protects required content, and enforces the exact
|
|
384
|
+
token budget. The model returns scores, not a compressed string or calibrated
|
|
385
|
+
probabilities. Core remains model-free and neither loads nor invokes Select.
|
|
386
|
+
|
|
387
|
+
Use the [v3 model card][tokenfold-select] for the included custom loader and
|
|
388
|
+
explicit CPU/FP32 or CUDA/BF16 setup. The older Granite/LoRA model is Select v1,
|
|
389
|
+
not the v3 architecture or loader.
|
|
390
|
+
|
|
391
|
+
| | Tokenfold Core | Tokenfold Select |
|
|
392
|
+
| --- | --- | --- |
|
|
393
|
+
| Best at | Structural compression | Query-conditioned group ranking |
|
|
394
|
+
| Runtime | Static Rust binary | Ettin 150M encoder (v3), CPU or CUDA |
|
|
395
|
+
| Output | Compressed payload + exact receipt | Group relevance scores; caller-owned allocation |
|
|
396
|
+
|
|
397
|
+
<details>
|
|
398
|
+
<summary><strong>Released tokenfold-select 0.5.3 package: Select v2 setup</strong></summary>
|
|
399
|
+
|
|
400
|
+
V3 is provisioned separately through its model card. The released 0.5.3 package
|
|
401
|
+
continues to use the v2 backend below; this README update does not change it.
|
|
402
|
+
|
|
364
403
|
**Select v2 is the default scorer backend in the optional `tokenfold-select`
|
|
365
|
-
0.5.
|
|
404
|
+
0.5.3 package: local FP32 ONNX inference, original text, whole-group ranking.**
|
|
366
405
|
Provision the separate pinned model artifact, generate explicit runtime approval,
|
|
367
406
|
and invoke `tokenfold --experimental select`. Core remains model-free and
|
|
368
407
|
deterministic; installing or upgrading Tokenfold does not silently load a model
|
|
@@ -377,7 +416,7 @@ keeps model execution off until you explicitly enable it.
|
|
|
377
416
|
<details>
|
|
378
417
|
<summary><strong>Python: try Tokenfold Select v2 (ONNX)</strong></summary>
|
|
379
418
|
|
|
380
|
-
Install `tokenfold-select[onnx]==0.5.
|
|
419
|
+
Install `tokenfold-select[onnx]==0.5.3` and `huggingface_hub==1.33.0`, then download
|
|
381
420
|
only the ONNX profile at the pinned release commit:
|
|
382
421
|
|
|
383
422
|
```python
|
|
@@ -405,22 +444,10 @@ Transformers classification class. Neither format silently changes Core behavior
|
|
|
405
444
|
|
|
406
445
|
</details>
|
|
407
446
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
The separately published Select v1 is an Apache-2.0 LoRA adapter on
|
|
411
|
-
`ibm-granite/granite-embedding-reranker-english-r2`. It scores candidate spans
|
|
412
|
-
against a query; your allocator applies the token budget and force-keeps
|
|
413
|
-
required content. It is a separately distributed offering. Core remains
|
|
414
|
-
model-free and deterministic and neither loads nor invokes Select.
|
|
415
|
-
|
|
416
|
-
| | Tokenfold Core | Tokenfold Select |
|
|
417
|
-
| --- | --- | --- |
|
|
418
|
-
| Best at | Structural compression | Query-conditioned span ranking |
|
|
419
|
-
| Runtime | Static Rust binary | Granite reranker + LoRA adapter |
|
|
420
|
-
| Output | Compressed payload + exact receipt | Ranking logits |
|
|
447
|
+
</details>
|
|
421
448
|
|
|
422
449
|
<details>
|
|
423
|
-
<summary><strong>
|
|
450
|
+
<summary><strong>Archived Select v1: Granite + LoRA scoring example (not v3)</strong></summary>
|
|
424
451
|
|
|
425
452
|
```python
|
|
426
453
|
from pathlib import Path
|
|
@@ -461,14 +488,79 @@ def score(query: str, spans: list[str]) -> list[float]:
|
|
|
461
488
|
|
|
462
489
|
</details>
|
|
463
490
|
|
|
464
|
-
### Tokenfold Select
|
|
491
|
+
### Tokenfold Select v3 benchmarks
|
|
492
|
+
|
|
493
|
+
Saved results from the [published v3 benchmark snapshot](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md),
|
|
494
|
+
pinned to model-card revision `317d3424d3de78c1a708c42a47a7812ab877f1a8`.
|
|
495
|
+
These measurements include the scorer **and whole-group allocator**, not the
|
|
496
|
+
scoring model alone. Core's lossless benchmarks remain separate below.
|
|
497
|
+
|
|
498
|
+
#### Context-token reduction at a 50% budget
|
|
499
|
+
|
|
500
|
+
Select v3 removed **50.0-60.0%** of the original context tokens in these five
|
|
501
|
+
saved development examples. Both models had the same exact `o200k_base` output
|
|
502
|
+
cap for each workload; retained V3 groups were copied without rewriting.
|
|
503
|
+
|
|
504
|
+
| Workload | Original tokens | Select v3 output | V3 reduction | Kompress v2 output |
|
|
505
|
+
| --- | ---: | ---: | ---: | ---: |
|
|
506
|
+
| Code | 4,411 | 2,205 | **50.0%** | 2,149 |
|
|
507
|
+
| JSON | 1,303 | 651 | **50.0%** | Refused; 1,303 raw |
|
|
508
|
+
| Logs | 1,103 | 503 | **54.4%** | Refused; 1,103 raw |
|
|
509
|
+
| Multi-turn | 587 | 235 | **60.0%** | 284 |
|
|
510
|
+
| Retrieval | 4,498 | 2,217 | **50.7%** | 2,219 |
|
|
465
511
|
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
512
|
+
One exposed source per workload; JSON and logs share a source population.
|
|
513
|
+
Token reduction does not establish answer accuracy or semantic preservation.
|
|
514
|
+
Six of ten historical Kompress cells refused the budget across the 25%/50%
|
|
515
|
+
screen; refusals and raw fallbacks are **inconclusive, not V3 wins**. The
|
|
516
|
+
[full ten-cell history](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md#benchmark-methodology)
|
|
517
|
+
retains every result.
|
|
518
|
+
|
|
519
|
+
#### Resident-warm complete-request latency at a 50% budget
|
|
520
|
+
|
|
521
|
+
| Workload | Select v3 ms | Kompress v2 ms | V3 time difference | Measurement basis |
|
|
522
|
+
| --- | ---: | ---: | ---: | --- |
|
|
523
|
+
| Code | 146.088 | 200.304 | -27.1% | One historical request per model |
|
|
524
|
+
| Retrieval | 139.291 | 201.564 | -30.9% | One historical request per model |
|
|
525
|
+
| Multi-turn | 66.572 | 77.751 | -14.4% | Median of 5 requests per model |
|
|
526
|
+
|
|
527
|
+
Resident-warm RTX 5080 research pipelines, FP32 parameters/BF16 compute;
|
|
528
|
+
startup excluded. Separate time blocks, not controlled-idle or paired trials.
|
|
529
|
+
These are descriptive development observations, **not representative quality, population p50/p95, or superiority qualification**.
|
|
530
|
+
|
|
531
|
+
<details>
|
|
532
|
+
<summary><strong>Benchmark methodology and preserved history</strong></summary>
|
|
533
|
+
|
|
534
|
+
RTX 5080, FP32 parameters/BF16 compute, cache off, TF32 off, one Torch thread.
|
|
535
|
+
V3 used the serialized SDPA research runner; Kompress v2 used native EAGER.
|
|
536
|
+
Complete-request clocks include grouping, counting, IPC, scoring, allocation,
|
|
537
|
+
final recount and applicable teardown, but **exclude process/model startup and
|
|
538
|
+
conditioning**. They are not cold-CLI or quickstart-SDK latency measurements.
|
|
539
|
+
|
|
540
|
+
The models ran in separate time blocks. The five-request multi-turn repeat was
|
|
541
|
+
not controlled-idle: the GPU-busy admission gate was explicitly waived, with
|
|
542
|
+
pre-model busy observations of 25% and 38%. All five samples per model are
|
|
543
|
+
retained. The earlier multi-turn result was **69.362 ms vs 64.411 ms** (V3 time
|
|
544
|
+
7.7% higher), and remains in the history rather than being replaced by the
|
|
545
|
+
repeat's sample medians.
|
|
546
|
+
|
|
547
|
+
The shared synthetic publisher-data pilot has incomplete comparator/answer
|
|
548
|
+
evaluation; its literal-substring checks are not answer accuracy. The separate
|
|
549
|
+
[partial answer-lookup evaluation](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/QUALITY-EVAL.json)
|
|
550
|
+
also remains incomplete, with no overall quality score or qualified 90%
|
|
551
|
+
comparability claim.
|
|
552
|
+
|
|
553
|
+
Sources: [exact counts, timings, all repeat samples and refusals](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/COMPARISON.json),
|
|
554
|
+
[validation](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/VALIDATION.json), and
|
|
555
|
+
[full methodology](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md#benchmark-methodology).
|
|
556
|
+
</details>
|
|
557
|
+
|
|
558
|
+
<details>
|
|
559
|
+
<summary><strong>Historical Select v1 benchmarks (not v3 results)</strong></summary>
|
|
560
|
+
|
|
561
|
+
The original [Tokenfold Select v1][tokenfold-select-v1] model card reports the
|
|
562
|
+
following literal-answer-retention results against Kompress-v2 and BM25.
|
|
563
|
+
These are source-reported external results, not Core CI or v3 results.
|
|
472
564
|
|
|
473
565
|
| Tokens kept | Tokenfold Select | Kompress-v2 (Headroom) native | Kompress-v2 (Headroom) relevance | BM25 | vs. best baseline |
|
|
474
566
|
| ---: | ---: | ---: | ---: | ---: | ---: |
|
|
@@ -476,21 +568,23 @@ source-reported external results, not Core CI results.
|
|
|
476
568
|
| 25% | **70.3%** | 47.2% | 61.5% | 60.7% | **+8.8 pp** |
|
|
477
569
|
| 10% | **39.9%** | 30.4% | 37.7% | 37.7% | **+2.2 pp** |
|
|
478
570
|
|
|
479
|
-
|
|
480
|
-
the fine-tuned ranker keeps the answer **70.3% of the time**:
|
|
481
|
-
point** lead over the strongest baseline (Kompress-v2 relevance, 61.5%), and a
|
|
571
|
+
In this v1 evaluation, Select beat every measured baseline at every budget.
|
|
572
|
+
At a 25% budget, the fine-tuned ranker keeps the answer **70.3% of the time**:
|
|
573
|
+
an **8.8 percentage-point** lead over the strongest baseline (Kompress-v2 relevance, 61.5%), and a
|
|
482
574
|
**15.8% relative lift** over BM25 (60.7% -> 70.3%). Critical-content survival is
|
|
483
575
|
**100% at every measured budget** through allocator force-keep. Results are
|
|
484
576
|
three-seed repeated subsampling over roughly 73,000 training and 24,000
|
|
485
|
-
held-out fixtures per run; the [model card][tokenfold-select] publishes the
|
|
577
|
+
held-out fixtures per run; the [v1 model card][tokenfold-select-v1] publishes the
|
|
486
578
|
training recipe and full baseline set. Here, task success means the literal
|
|
487
579
|
gold answer survived selection under the stated budget.
|
|
488
580
|
These are source-reported external results, pinned by model revision in the
|
|
489
581
|
[metric manifest](tests/fixtures/readme_metrics.json); Core CI does not reproduce them.
|
|
490
582
|
|
|
491
|
-
See the [
|
|
583
|
+
See the [Select v1 model card][tokenfold-select-v1] for its setup, evaluation,
|
|
492
584
|
training data, and limitations.
|
|
493
585
|
|
|
586
|
+
</details>
|
|
587
|
+
|
|
494
588
|
<br />
|
|
495
589
|
|
|
496
590
|
## Measured results
|
|
@@ -754,6 +848,9 @@ already-compressed JSON representation.
|
|
|
754
848
|
- **Local control:** detected secrets are redacted before reports or storage;
|
|
755
849
|
policy learning changes configuration only with `--apply`.
|
|
756
850
|
|
|
851
|
+
Exact decode proves data recovery, not unchanged downstream task accuracy.
|
|
852
|
+
Validate folded payloads with your representative workload.
|
|
853
|
+
|
|
757
854
|
The offline fidelity gate uses deterministic lexical-overlap, critical-token,
|
|
758
855
|
and containment proxies. Those checks catch regressions but do not establish
|
|
759
856
|
semantic equivalence or downstream task success. Runtime `quality` fields are
|
|
@@ -830,5 +927,6 @@ If Tokenfold earns a place in your stack, a star on
|
|
|
830
927
|
|
|
831
928
|
</div>
|
|
832
929
|
|
|
833
|
-
[tokenfold-select]: https://huggingface.co/snchimata/tokenfold-select
|
|
930
|
+
[tokenfold-select]: https://huggingface.co/snchimata/tokenfold-select-v3
|
|
931
|
+
[tokenfold-select-v1]: https://huggingface.co/snchimata/tokenfold-select
|
|
834
932
|
|
|
@@ -71,14 +71,14 @@ cargo add tokenfold-core # Rust library
|
|
|
71
71
|
<br />
|
|
72
72
|
<strong>Model-free & deterministic</strong>
|
|
73
73
|
<br /><br />
|
|
74
|
-
No GPU, no semantic guesswork, no model in the Core path.
|
|
74
|
+
No GPU, no semantic guesswork, no model in the Core path. A Rust engine with Python, Node.js, CLI and proxy interfaces.
|
|
75
75
|
<br /><br />
|
|
76
76
|
</td>
|
|
77
77
|
</tr>
|
|
78
78
|
</table>
|
|
79
79
|
|
|
80
80
|
> [!NOTE]
|
|
81
|
-
> **Built for:** Developers and AI teams
|
|
81
|
+
> **Built for:** Developers and AI teams sending structured JSON, tool definitions, and RAG feeds to LLMs. Start with a representative payload, inspect the receipt, and validate the result in your application.
|
|
82
82
|
|
|
83
83
|
<br />
|
|
84
84
|
|
|
@@ -95,12 +95,17 @@ cargo add tokenfold-core # Rust library
|
|
|
95
95
|
{"__tf_cols__":["id","role"],"__tf_rows__":[[1,"admin"],[2,"member"]]}
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+

|
|
99
|
+
|
|
100
|
+
<details>
|
|
101
|
+
<summary><strong>How this demo was generated (VHS tape)</strong></summary>
|
|
102
|
+
|
|
103
|
+
The [VHS tape](docs/tokenfold-demo.tape) runs `inspect`, `compress`, and
|
|
104
|
+
`decode` against the bundled API response, including the **63.9%** receipt.
|
|
105
|
+
Run `vhs docs/tokenfold-demo.tape` to regenerate the GIF; the tape requires
|
|
106
|
+
`tokenfold` on `PATH`.
|
|
107
|
+
|
|
108
|
+
</details>
|
|
104
109
|
|
|
105
110
|
Send the folded JSON directly to the model: column names label each value's
|
|
106
111
|
position in every row. Decode only when your application needs the original
|
|
@@ -111,7 +116,7 @@ object shape again.
|
|
|
111
116
|
- **Targets structured JSON, not prose.** Folds repeated keys and columns
|
|
112
117
|
mechanically rather than using semantic guesswork.
|
|
113
118
|
- **Model-free and deterministic.** Zero models running in Core and zero GPU
|
|
114
|
-
overhead.
|
|
119
|
+
overhead.
|
|
115
120
|
- **Verified by exact decode.** Every lossless transform is verified by an
|
|
116
121
|
in-memory round trip before emitting; lossy pruning is strictly opt-in and
|
|
117
122
|
recoverable.
|
|
@@ -120,60 +125,38 @@ For tabular arrays, Tokenfold folds repeated keys into
|
|
|
120
125
|
header columns (`__tf_cols__`). No model runs in the Core engine, and every
|
|
121
126
|
lossless transform is verified by exact decode.
|
|
122
127
|
|
|
123
|
-
|
|
124
|
-
> `schema_compaction` is not enabled by any preset. Unlike the default
|
|
125
|
-
> transforms, it truncates `examples` arrays and is not reversible.
|
|
128
|
+
#### How Tokenfold decides what to fold
|
|
126
129
|
|
|
127
130
|
```mermaid
|
|
128
|
-
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#
|
|
131
|
+
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#f8fafc", "primaryTextColor": "#0f172a", "primaryBorderColor": "#94a3b8", "lineColor": "#64748b", "edgeLabelBackground": "#f8fafc", "fontFamily": "Arial", "fontSize": "15px"}, "flowchart": {"curve": "linear", "padding": 16, "nodeSpacing": 40, "rankSpacing": 32}}}%%
|
|
129
132
|
flowchart LR
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
accTitle: Lossless first, pruning only when opted in
|
|
134
|
+
accDescr: Build a verified lossless baseline. Consider pruning only when opted in, eligible, and still needed. Store omissions before removal and use pruning only if it beats the lossless baseline; otherwise keep that baseline.
|
|
135
|
+
Lossless["Build lossless JSON baseline<br/>Verify folds; retain savings"] --> OptIn{"Pruning enabled,<br/>eligible and needed?"}
|
|
136
|
+
OptIn -->|No| Keep("Lossless payload<br/>+ receipt")
|
|
137
|
+
OptIn -->|Yes| Prune["Rank eligible rows<br/>Store before removal"]
|
|
138
|
+
Prune -->|No further savings| Keep
|
|
139
|
+
Prune -->|Fewer tokens than baseline| Emit("Pruned payload<br/>+ markers and receipt")
|
|
140
|
+
|
|
141
|
+
classDef core fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a
|
|
142
|
+
classDef optional fill:#f8fafc,stroke:#64748b,stroke-dasharray:5 4,color:#334155
|
|
143
|
+
class Lossless,Keep core
|
|
144
|
+
class Prune optional
|
|
134
145
|
```
|
|
135
146
|
|
|
136
|
-
#### How Tokenfold decides what to fold
|
|
137
|
-
|
|
138
|
-

|
|
139
|
-
|
|
140
147
|
<details>
|
|
141
148
|
<summary><strong>Text version (screen readers / no-image fallback)</strong></summary>
|
|
142
149
|
|
|
143
|
-
1.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
3.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
#### Proxy / agent round trip
|
|
154
|
-
|
|
155
|
-
```mermaid
|
|
156
|
-
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#22D3EE", "primaryTextColor": "#0b1020", "primaryBorderColor": "#A855F7", "lineColor": "#A855F7", "actorBkg": "#22D3EE", "actorTextColor": "#0b1020", "actorBorder": "#A855F7", "signalColor": "#A855F7", "signalTextColor": "#334155", "fontFamily": "ui-sans-serif, system-ui, sans-serif"}}}%%
|
|
157
|
-
sequenceDiagram
|
|
158
|
-
participant C as Client / Agent
|
|
159
|
-
participant P as Tokenfold Proxy
|
|
160
|
-
participant U as Upstream LLM
|
|
161
|
-
C->>P: Provider-shaped request (large JSON)
|
|
162
|
-
P->>P: Apply lossless transforms
|
|
163
|
-
P->>U: Forwarded compact request
|
|
164
|
-
U-->>P: Completion / action
|
|
165
|
-
P-->>C: Response (Authorization forwarded unchanged)
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-

|
|
169
|
-
|
|
170
|
-
<details>
|
|
171
|
-
<summary><strong>How this demo was generated (VHS tape)</strong></summary>
|
|
172
|
-
|
|
173
|
-
The [VHS tape](docs/tokenfold-demo.tape) runs `inspect`, `compress`, and
|
|
174
|
-
`decode` against the bundled API response, including the **63.9%** receipt.
|
|
175
|
-
Run `vhs docs/tokenfold-demo.tape` to regenerate the GIF; the tape requires
|
|
176
|
-
`tokenfold` on `PATH`.
|
|
150
|
+
1. Build the lossless baseline using eligible transforms. Verify structural
|
|
151
|
+
folds with an exact decode round trip and keep only token reductions.
|
|
152
|
+
2. Consider pruning only when explicitly opted in, the payload is eligible,
|
|
153
|
+
and the lossless baseline has not already met a requested token target.
|
|
154
|
+
3. Rank eligible rows and store omissions locally before removing them.
|
|
155
|
+
Rows refused by storage stay inline.
|
|
156
|
+
4. Use the pruned payload only if it has fewer tokens than the lossless
|
|
157
|
+
baseline; otherwise keep the lossless baseline.
|
|
158
|
+
5. Emit the chosen payload and compression receipt. Pruned payloads include
|
|
159
|
+
retrieval markers for stored omissions.
|
|
177
160
|
|
|
178
161
|
</details>
|
|
179
162
|
|
|
@@ -202,6 +185,24 @@ cargo install tokenfold-proxy
|
|
|
202
185
|
tokenfold-proxy --upstream https://api.openai.com
|
|
203
186
|
```
|
|
204
187
|
|
|
188
|
+
```python
|
|
189
|
+
from openai import OpenAI
|
|
190
|
+
|
|
191
|
+
# Your client's Authorization header is forwarded to upstream unchanged -
|
|
192
|
+
# no credential reconfiguration needed.
|
|
193
|
+
client = OpenAI(base_url="http://127.0.0.1:8787/v1")
|
|
194
|
+
# Existing calls work unchanged: client.chat.completions.create(...)
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The proxy listens on loopback (`127.0.0.1:8787`) by default.
|
|
198
|
+
Provider envelopes are minified, not columnar-folded.
|
|
199
|
+
|
|
200
|
+
Works out-of-the-box with any client or framework that accepts a custom base URL
|
|
201
|
+
(LangChain, LlamaIndex, LiteLLM, Instructor, or direct HTTP clients).
|
|
202
|
+
|
|
203
|
+
<details>
|
|
204
|
+
<summary><strong>Proxy routing, streaming, and stderr telemetry details</strong></summary>
|
|
205
|
+
|
|
205
206
|
The proxy installs from source via Cargo and listens on `127.0.0.1:8787` by
|
|
206
207
|
default (`--bind`; use `--allow-non-loopback-bind` to change that). Only
|
|
207
208
|
chat-shaped JSON bodies (a non-empty `messages` array) are compressed on the
|
|
@@ -223,17 +224,25 @@ attempt ended. A provider that reports no usage, or a body whose usage cannot
|
|
|
223
224
|
be read cleanly, records `usage_disposition: absent|malformed|oversized` with a
|
|
224
225
|
`null` count rather than a zero -- and never changes what is forwarded.
|
|
225
226
|
|
|
226
|
-
|
|
227
|
-
from openai import OpenAI
|
|
227
|
+
</details>
|
|
228
228
|
|
|
229
|
-
|
|
230
|
-
# no credential reconfiguration needed.
|
|
231
|
-
client = OpenAI(base_url="http://127.0.0.1:8787/v1")
|
|
232
|
-
# Existing calls work unchanged: client.chat.completions.create(...)
|
|
233
|
-
```
|
|
229
|
+
#### Proxy / agent round trip
|
|
234
230
|
|
|
235
|
-
|
|
236
|
-
|
|
231
|
+
```mermaid
|
|
232
|
+
%%{init: {"theme": "base", "themeVariables": {"fontFamily": "Arial", "fontSize": "15px", "actorBkg": "#f8fafc", "actorTextColor": "#0f172a", "actorBorder": "#94a3b8", "actorLineColor": "#94a3b8", "signalColor": "#64748b", "signalTextColor": "#334155", "activationBkgColor": "#eff6ff", "activationBorderColor": "#2563eb", "sequenceNumberColor": "#ffffff"}, "sequence": {"mirrorActors": false, "actorMargin": 56, "messageMargin": 36}}}%%
|
|
233
|
+
sequenceDiagram
|
|
234
|
+
accTitle: Proxy request and response lifecycle
|
|
235
|
+
accDescr: The client sends a provider-shaped request to Tokenfold Proxy, which applies lossless transforms and forwards the compact request with Authorization unchanged. The upstream response returns through the proxy.
|
|
236
|
+
autonumber
|
|
237
|
+
participant C as Client / Agent
|
|
238
|
+
participant P as Tokenfold Proxy
|
|
239
|
+
participant U as Upstream LLM
|
|
240
|
+
C->>+P: Provider-shaped request
|
|
241
|
+
P->>P: Apply lossless transforms
|
|
242
|
+
P->>+U: Compact request + unchanged Authorization
|
|
243
|
+
U-->>-P: Completion / action
|
|
244
|
+
P-->>-C: Response
|
|
245
|
+
```
|
|
237
246
|
|
|
238
247
|
### Interfaces
|
|
239
248
|
|
|
@@ -276,8 +285,15 @@ print(f"Saved {result.report.saved_tokens} tokens ({result.saved_pct():.1f}%)")
|
|
|
276
285
|
| `balanced` (default) | Minification plus reversible columnar folding (`json_field_fold`, `json_value_dict`, `log_field_fold`) on eligible formats. |
|
|
277
286
|
| `aggressive` | Same default transform set as `balanced` today. |
|
|
278
287
|
|
|
279
|
-
Provider message formats (`openai_json`, `anthropic_json`)
|
|
280
|
-
columnar folding
|
|
288
|
+
Provider message formats (`openai_json`, `anthropic_json`) use minification
|
|
289
|
+
only; columnar folding applies to generic JSON (`--format json`). The default
|
|
290
|
+
proxy path follows this rule. Explicit `--observations` enables lossless
|
|
291
|
+
compression of eligible JSON tool-result strings on `/v1/chat/completions`
|
|
292
|
+
without folding the provider envelope; see [observation compression](docs/configuration.md#restart-safe-observation-commitments).
|
|
293
|
+
|
|
294
|
+
> [!NOTE]
|
|
295
|
+
> `schema_compaction` is not enabled by any preset. Unlike the default
|
|
296
|
+
> transforms, it truncates `examples` arrays and is not reversible.
|
|
281
297
|
|
|
282
298
|
### Runnable examples (Python >=3.9, Node.js >=22, Rust >=1.98)
|
|
283
299
|
|
|
@@ -327,7 +343,7 @@ are available through `tokenfold filters list`.
|
|
|
327
343
|
### Structural, not semantic compression
|
|
328
344
|
|
|
329
345
|
Semantic prompt compressors such as [LLMLingua](https://github.com/microsoft/LLMLingua) use a smaller language model to identify and remove less-important prompt tokens.
|
|
330
|
-
Tokenfold solves a different problem first: repeated keys, values, schemas, rows, and other structural redundancy. Core needs no model, is deterministic, and verifies an exact decode before accepting a lossless transform.
|
|
346
|
+
Tokenfold solves a different problem first: repeated keys, values, schemas, rows, and other structural redundancy. Core needs no model, is deterministic, and verifies an exact decode before accepting a lossless transform. Core does not inject prompt guidance or fine-tune models.
|
|
331
347
|
|
|
332
348
|
[Tokenfold Select](#tokenfold-select) is Tokenfold's complementary query-aware offering: when structure ends, it ranks what matters under a token budget.
|
|
333
349
|
|
|
@@ -339,8 +355,31 @@ Tokenfold solves a different problem first: repeated keys, values, schemas, rows
|
|
|
339
355
|
|
|
340
356
|
**When structure ends, rank what matters.**
|
|
341
357
|
|
|
358
|
+
[Tokenfold Select v3][tokenfold-select] is an Apache-2.0, **149.6M-parameter**
|
|
359
|
+
joint-group scorer built on the full 22-layer Ettin encoder. It scores groups
|
|
360
|
+
against the query and their neighbors within each window; your allocator keeps
|
|
361
|
+
selected source text unchanged, protects required content, and enforces the exact
|
|
362
|
+
token budget. The model returns scores, not a compressed string or calibrated
|
|
363
|
+
probabilities. Core remains model-free and neither loads nor invokes Select.
|
|
364
|
+
|
|
365
|
+
Use the [v3 model card][tokenfold-select] for the included custom loader and
|
|
366
|
+
explicit CPU/FP32 or CUDA/BF16 setup. The older Granite/LoRA model is Select v1,
|
|
367
|
+
not the v3 architecture or loader.
|
|
368
|
+
|
|
369
|
+
| | Tokenfold Core | Tokenfold Select |
|
|
370
|
+
| --- | --- | --- |
|
|
371
|
+
| Best at | Structural compression | Query-conditioned group ranking |
|
|
372
|
+
| Runtime | Static Rust binary | Ettin 150M encoder (v3), CPU or CUDA |
|
|
373
|
+
| Output | Compressed payload + exact receipt | Group relevance scores; caller-owned allocation |
|
|
374
|
+
|
|
375
|
+
<details>
|
|
376
|
+
<summary><strong>Released tokenfold-select 0.5.3 package: Select v2 setup</strong></summary>
|
|
377
|
+
|
|
378
|
+
V3 is provisioned separately through its model card. The released 0.5.3 package
|
|
379
|
+
continues to use the v2 backend below; this README update does not change it.
|
|
380
|
+
|
|
342
381
|
**Select v2 is the default scorer backend in the optional `tokenfold-select`
|
|
343
|
-
0.5.
|
|
382
|
+
0.5.3 package: local FP32 ONNX inference, original text, whole-group ranking.**
|
|
344
383
|
Provision the separate pinned model artifact, generate explicit runtime approval,
|
|
345
384
|
and invoke `tokenfold --experimental select`. Core remains model-free and
|
|
346
385
|
deterministic; installing or upgrading Tokenfold does not silently load a model
|
|
@@ -355,7 +394,7 @@ keeps model execution off until you explicitly enable it.
|
|
|
355
394
|
<details>
|
|
356
395
|
<summary><strong>Python: try Tokenfold Select v2 (ONNX)</strong></summary>
|
|
357
396
|
|
|
358
|
-
Install `tokenfold-select[onnx]==0.5.
|
|
397
|
+
Install `tokenfold-select[onnx]==0.5.3` and `huggingface_hub==1.33.0`, then download
|
|
359
398
|
only the ONNX profile at the pinned release commit:
|
|
360
399
|
|
|
361
400
|
```python
|
|
@@ -383,22 +422,10 @@ Transformers classification class. Neither format silently changes Core behavior
|
|
|
383
422
|
|
|
384
423
|
</details>
|
|
385
424
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
The separately published Select v1 is an Apache-2.0 LoRA adapter on
|
|
389
|
-
`ibm-granite/granite-embedding-reranker-english-r2`. It scores candidate spans
|
|
390
|
-
against a query; your allocator applies the token budget and force-keeps
|
|
391
|
-
required content. It is a separately distributed offering. Core remains
|
|
392
|
-
model-free and deterministic and neither loads nor invokes Select.
|
|
393
|
-
|
|
394
|
-
| | Tokenfold Core | Tokenfold Select |
|
|
395
|
-
| --- | --- | --- |
|
|
396
|
-
| Best at | Structural compression | Query-conditioned span ranking |
|
|
397
|
-
| Runtime | Static Rust binary | Granite reranker + LoRA adapter |
|
|
398
|
-
| Output | Compressed payload + exact receipt | Ranking logits |
|
|
425
|
+
</details>
|
|
399
426
|
|
|
400
427
|
<details>
|
|
401
|
-
<summary><strong>
|
|
428
|
+
<summary><strong>Archived Select v1: Granite + LoRA scoring example (not v3)</strong></summary>
|
|
402
429
|
|
|
403
430
|
```python
|
|
404
431
|
from pathlib import Path
|
|
@@ -439,14 +466,79 @@ def score(query: str, spans: list[str]) -> list[float]:
|
|
|
439
466
|
|
|
440
467
|
</details>
|
|
441
468
|
|
|
442
|
-
### Tokenfold Select
|
|
469
|
+
### Tokenfold Select v3 benchmarks
|
|
470
|
+
|
|
471
|
+
Saved results from the [published v3 benchmark snapshot](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md),
|
|
472
|
+
pinned to model-card revision `317d3424d3de78c1a708c42a47a7812ab877f1a8`.
|
|
473
|
+
These measurements include the scorer **and whole-group allocator**, not the
|
|
474
|
+
scoring model alone. Core's lossless benchmarks remain separate below.
|
|
475
|
+
|
|
476
|
+
#### Context-token reduction at a 50% budget
|
|
477
|
+
|
|
478
|
+
Select v3 removed **50.0-60.0%** of the original context tokens in these five
|
|
479
|
+
saved development examples. Both models had the same exact `o200k_base` output
|
|
480
|
+
cap for each workload; retained V3 groups were copied without rewriting.
|
|
481
|
+
|
|
482
|
+
| Workload | Original tokens | Select v3 output | V3 reduction | Kompress v2 output |
|
|
483
|
+
| --- | ---: | ---: | ---: | ---: |
|
|
484
|
+
| Code | 4,411 | 2,205 | **50.0%** | 2,149 |
|
|
485
|
+
| JSON | 1,303 | 651 | **50.0%** | Refused; 1,303 raw |
|
|
486
|
+
| Logs | 1,103 | 503 | **54.4%** | Refused; 1,103 raw |
|
|
487
|
+
| Multi-turn | 587 | 235 | **60.0%** | 284 |
|
|
488
|
+
| Retrieval | 4,498 | 2,217 | **50.7%** | 2,219 |
|
|
443
489
|
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
490
|
+
One exposed source per workload; JSON and logs share a source population.
|
|
491
|
+
Token reduction does not establish answer accuracy or semantic preservation.
|
|
492
|
+
Six of ten historical Kompress cells refused the budget across the 25%/50%
|
|
493
|
+
screen; refusals and raw fallbacks are **inconclusive, not V3 wins**. The
|
|
494
|
+
[full ten-cell history](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md#benchmark-methodology)
|
|
495
|
+
retains every result.
|
|
496
|
+
|
|
497
|
+
#### Resident-warm complete-request latency at a 50% budget
|
|
498
|
+
|
|
499
|
+
| Workload | Select v3 ms | Kompress v2 ms | V3 time difference | Measurement basis |
|
|
500
|
+
| --- | ---: | ---: | ---: | --- |
|
|
501
|
+
| Code | 146.088 | 200.304 | -27.1% | One historical request per model |
|
|
502
|
+
| Retrieval | 139.291 | 201.564 | -30.9% | One historical request per model |
|
|
503
|
+
| Multi-turn | 66.572 | 77.751 | -14.4% | Median of 5 requests per model |
|
|
504
|
+
|
|
505
|
+
Resident-warm RTX 5080 research pipelines, FP32 parameters/BF16 compute;
|
|
506
|
+
startup excluded. Separate time blocks, not controlled-idle or paired trials.
|
|
507
|
+
These are descriptive development observations, **not representative quality, population p50/p95, or superiority qualification**.
|
|
508
|
+
|
|
509
|
+
<details>
|
|
510
|
+
<summary><strong>Benchmark methodology and preserved history</strong></summary>
|
|
511
|
+
|
|
512
|
+
RTX 5080, FP32 parameters/BF16 compute, cache off, TF32 off, one Torch thread.
|
|
513
|
+
V3 used the serialized SDPA research runner; Kompress v2 used native EAGER.
|
|
514
|
+
Complete-request clocks include grouping, counting, IPC, scoring, allocation,
|
|
515
|
+
final recount and applicable teardown, but **exclude process/model startup and
|
|
516
|
+
conditioning**. They are not cold-CLI or quickstart-SDK latency measurements.
|
|
517
|
+
|
|
518
|
+
The models ran in separate time blocks. The five-request multi-turn repeat was
|
|
519
|
+
not controlled-idle: the GPU-busy admission gate was explicitly waived, with
|
|
520
|
+
pre-model busy observations of 25% and 38%. All five samples per model are
|
|
521
|
+
retained. The earlier multi-turn result was **69.362 ms vs 64.411 ms** (V3 time
|
|
522
|
+
7.7% higher), and remains in the history rather than being replaced by the
|
|
523
|
+
repeat's sample medians.
|
|
524
|
+
|
|
525
|
+
The shared synthetic publisher-data pilot has incomplete comparator/answer
|
|
526
|
+
evaluation; its literal-substring checks are not answer accuracy. The separate
|
|
527
|
+
[partial answer-lookup evaluation](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/QUALITY-EVAL.json)
|
|
528
|
+
also remains incomplete, with no overall quality score or qualified 90%
|
|
529
|
+
comparability claim.
|
|
530
|
+
|
|
531
|
+
Sources: [exact counts, timings, all repeat samples and refusals](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/COMPARISON.json),
|
|
532
|
+
[validation](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/VALIDATION.json), and
|
|
533
|
+
[full methodology](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md#benchmark-methodology).
|
|
534
|
+
</details>
|
|
535
|
+
|
|
536
|
+
<details>
|
|
537
|
+
<summary><strong>Historical Select v1 benchmarks (not v3 results)</strong></summary>
|
|
538
|
+
|
|
539
|
+
The original [Tokenfold Select v1][tokenfold-select-v1] model card reports the
|
|
540
|
+
following literal-answer-retention results against Kompress-v2 and BM25.
|
|
541
|
+
These are source-reported external results, not Core CI or v3 results.
|
|
450
542
|
|
|
451
543
|
| Tokens kept | Tokenfold Select | Kompress-v2 (Headroom) native | Kompress-v2 (Headroom) relevance | BM25 | vs. best baseline |
|
|
452
544
|
| ---: | ---: | ---: | ---: | ---: | ---: |
|
|
@@ -454,21 +546,23 @@ source-reported external results, not Core CI results.
|
|
|
454
546
|
| 25% | **70.3%** | 47.2% | 61.5% | 60.7% | **+8.8 pp** |
|
|
455
547
|
| 10% | **39.9%** | 30.4% | 37.7% | 37.7% | **+2.2 pp** |
|
|
456
548
|
|
|
457
|
-
|
|
458
|
-
the fine-tuned ranker keeps the answer **70.3% of the time**:
|
|
459
|
-
point** lead over the strongest baseline (Kompress-v2 relevance, 61.5%), and a
|
|
549
|
+
In this v1 evaluation, Select beat every measured baseline at every budget.
|
|
550
|
+
At a 25% budget, the fine-tuned ranker keeps the answer **70.3% of the time**:
|
|
551
|
+
an **8.8 percentage-point** lead over the strongest baseline (Kompress-v2 relevance, 61.5%), and a
|
|
460
552
|
**15.8% relative lift** over BM25 (60.7% -> 70.3%). Critical-content survival is
|
|
461
553
|
**100% at every measured budget** through allocator force-keep. Results are
|
|
462
554
|
three-seed repeated subsampling over roughly 73,000 training and 24,000
|
|
463
|
-
held-out fixtures per run; the [model card][tokenfold-select] publishes the
|
|
555
|
+
held-out fixtures per run; the [v1 model card][tokenfold-select-v1] publishes the
|
|
464
556
|
training recipe and full baseline set. Here, task success means the literal
|
|
465
557
|
gold answer survived selection under the stated budget.
|
|
466
558
|
These are source-reported external results, pinned by model revision in the
|
|
467
559
|
[metric manifest](tests/fixtures/readme_metrics.json); Core CI does not reproduce them.
|
|
468
560
|
|
|
469
|
-
See the [
|
|
561
|
+
See the [Select v1 model card][tokenfold-select-v1] for its setup, evaluation,
|
|
470
562
|
training data, and limitations.
|
|
471
563
|
|
|
564
|
+
</details>
|
|
565
|
+
|
|
472
566
|
<br />
|
|
473
567
|
|
|
474
568
|
## Measured results
|
|
@@ -732,6 +826,9 @@ already-compressed JSON representation.
|
|
|
732
826
|
- **Local control:** detected secrets are redacted before reports or storage;
|
|
733
827
|
policy learning changes configuration only with `--apply`.
|
|
734
828
|
|
|
829
|
+
Exact decode proves data recovery, not unchanged downstream task accuracy.
|
|
830
|
+
Validate folded payloads with your representative workload.
|
|
831
|
+
|
|
735
832
|
The offline fidelity gate uses deterministic lexical-overlap, critical-token,
|
|
736
833
|
and containment proxies. Those checks catch regressions but do not establish
|
|
737
834
|
semantic equivalence or downstream task success. Runtime `quality` fields are
|
|
@@ -808,4 +905,5 @@ If Tokenfold earns a place in your stack, a star on
|
|
|
808
905
|
|
|
809
906
|
</div>
|
|
810
907
|
|
|
811
|
-
[tokenfold-select]: https://huggingface.co/snchimata/tokenfold-select
|
|
908
|
+
[tokenfold-select]: https://huggingface.co/snchimata/tokenfold-select-v3
|
|
909
|
+
[tokenfold-select-v1]: https://huggingface.co/snchimata/tokenfold-select
|
|
@@ -16,7 +16,7 @@ name = "tokenfold_py"
|
|
|
16
16
|
crate-type = ["cdylib", "rlib"]
|
|
17
17
|
|
|
18
18
|
[dependencies]
|
|
19
|
-
tokenfold-core = { version = "0.5.
|
|
19
|
+
tokenfold-core = { version = "0.5.3", path = "../tokenfold-core" }
|
|
20
20
|
serde_json = { workspace = true }
|
|
21
21
|
pyo3 = { version = "0.29.0", features = ["abi3-py39"] }
|
|
22
22
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|