tokenfold 0.3.3__tar.gz → 0.3.4__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.3.3 → tokenfold-0.3.4}/Cargo.lock +10 -10
- {tokenfold-0.3.3 → tokenfold-0.3.4}/Cargo.toml +1 -1
- tokenfold-0.3.3/README.md → tokenfold-0.3.4/PKG-INFO +125 -4
- tokenfold-0.3.3/PKG-INFO → tokenfold-0.3.4/README.md +101 -16
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/Cargo.toml +1 -1
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-py/Cargo.toml +1 -1
- {tokenfold-0.3.3 → tokenfold-0.3.4}/pyproject.toml +10 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/LICENSE +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/benches/THRESHOLDS.toml +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/benches/compression_bench.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/examples/quickstart.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/budget.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/errors.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/filters.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/input.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/lib.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/modes.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/pipeline.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/report.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/retrieval_store.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/safety.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/stats.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/status.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/token_estimator.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/transforms/diff.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/transforms/json.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/transforms/json_dict.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/transforms/json_fold.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/transforms/log_fold.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/transforms/logs.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/transforms/mod.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/transforms/redaction.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/src/transforms/schema.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/tests/golden.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/tests/integration.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-core/tests/property_tests.rs +0 -0
- {tokenfold-0.3.3 → tokenfold-0.3.4}/crates/tokenfold-py/src/lib.rs +0 -0
|
@@ -1013,7 +1013,7 @@ dependencies = [
|
|
|
1013
1013
|
|
|
1014
1014
|
[[package]]
|
|
1015
1015
|
name = "tokenfold-adapters"
|
|
1016
|
-
version = "0.3.
|
|
1016
|
+
version = "0.3.4"
|
|
1017
1017
|
dependencies = [
|
|
1018
1018
|
"serde",
|
|
1019
1019
|
"serde_json",
|
|
@@ -1022,7 +1022,7 @@ dependencies = [
|
|
|
1022
1022
|
|
|
1023
1023
|
[[package]]
|
|
1024
1024
|
name = "tokenfold-admin"
|
|
1025
|
-
version = "0.3.
|
|
1025
|
+
version = "0.3.4"
|
|
1026
1026
|
dependencies = [
|
|
1027
1027
|
"ed25519-dalek",
|
|
1028
1028
|
"serde",
|
|
@@ -1032,7 +1032,7 @@ dependencies = [
|
|
|
1032
1032
|
|
|
1033
1033
|
[[package]]
|
|
1034
1034
|
name = "tokenfold-cli"
|
|
1035
|
-
version = "0.3.
|
|
1035
|
+
version = "0.3.4"
|
|
1036
1036
|
dependencies = [
|
|
1037
1037
|
"clap",
|
|
1038
1038
|
"serde",
|
|
@@ -1045,7 +1045,7 @@ dependencies = [
|
|
|
1045
1045
|
|
|
1046
1046
|
[[package]]
|
|
1047
1047
|
name = "tokenfold-core"
|
|
1048
|
-
version = "0.3.
|
|
1048
|
+
version = "0.3.4"
|
|
1049
1049
|
dependencies = [
|
|
1050
1050
|
"proptest",
|
|
1051
1051
|
"regex",
|
|
@@ -1059,25 +1059,25 @@ dependencies = [
|
|
|
1059
1059
|
|
|
1060
1060
|
[[package]]
|
|
1061
1061
|
name = "tokenfold-image"
|
|
1062
|
-
version = "0.3.
|
|
1062
|
+
version = "0.3.4"
|
|
1063
1063
|
|
|
1064
1064
|
[[package]]
|
|
1065
1065
|
name = "tokenfold-learn"
|
|
1066
|
-
version = "0.3.
|
|
1066
|
+
version = "0.3.4"
|
|
1067
1067
|
dependencies = [
|
|
1068
1068
|
"tokenfold-core",
|
|
1069
1069
|
]
|
|
1070
1070
|
|
|
1071
1071
|
[[package]]
|
|
1072
1072
|
name = "tokenfold-output"
|
|
1073
|
-
version = "0.3.
|
|
1073
|
+
version = "0.3.4"
|
|
1074
1074
|
dependencies = [
|
|
1075
1075
|
"tokenfold-core",
|
|
1076
1076
|
]
|
|
1077
1077
|
|
|
1078
1078
|
[[package]]
|
|
1079
1079
|
name = "tokenfold-proxy"
|
|
1080
|
-
version = "0.3.
|
|
1080
|
+
version = "0.3.4"
|
|
1081
1081
|
dependencies = [
|
|
1082
1082
|
"clap",
|
|
1083
1083
|
"serde",
|
|
@@ -1089,7 +1089,7 @@ dependencies = [
|
|
|
1089
1089
|
|
|
1090
1090
|
[[package]]
|
|
1091
1091
|
name = "tokenfold-py"
|
|
1092
|
-
version = "0.3.
|
|
1092
|
+
version = "0.3.4"
|
|
1093
1093
|
dependencies = [
|
|
1094
1094
|
"pyo3",
|
|
1095
1095
|
"serde_json",
|
|
@@ -1098,7 +1098,7 @@ dependencies = [
|
|
|
1098
1098
|
|
|
1099
1099
|
[[package]]
|
|
1100
1100
|
name = "tokenfold-rag"
|
|
1101
|
-
version = "0.3.
|
|
1101
|
+
version = "0.3.4"
|
|
1102
1102
|
|
|
1103
1103
|
[[package]]
|
|
1104
1104
|
name = "toml"
|
|
@@ -1,14 +1,38 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tokenfold
|
|
3
|
+
Version: 0.3.4
|
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Intended Audience :: Developers
|
|
6
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
7
|
+
Classifier: Programming Language :: Rust
|
|
8
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
9
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Classifier: Topic :: Text Processing
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Summary: Token-compression toolkit for LLM payloads (Python binding over the tokenfold-core Rust crate)
|
|
19
|
+
Keywords: llm,tokens,compression,tokenizer,openai,json,prompt-engineering,cli,token-optimization
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
22
|
+
|
|
1
23
|
<div align="center">
|
|
2
24
|
|
|
3
25
|
# TOKENFOLD
|
|
4
26
|
|
|
5
27
|
**Send less noise. Fit more context. Pay for fewer input tokens.**
|
|
6
28
|
|
|
7
|
-
|
|
29
|
+
**46–68% fewer tokens on JSON & schemas · deterministic · reversible · every call audited**
|
|
30
|
+
|
|
31
|
+
CLI · Python · TypeScript · proxy · MCP · local-first · provider-neutral
|
|
8
32
|
|
|
9
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)
|
|
10
34
|
|
|
11
|
-
[Quick start](#quick-start) · [Why tokenfold](#why-tokenfold) · [Integrations](#pick-your-integration) · [Benchmarks](#reproduce-the-numbers)
|
|
35
|
+
[Quick start](#quick-start) · [Why tokenfold](#why-tokenfold) · [Integrations](#pick-your-integration) · [Benchmarks](#reproduce-the-numbers) · [Select model](#tokenfold-select)
|
|
12
36
|
|
|
13
37
|
</div>
|
|
14
38
|
|
|
@@ -26,6 +50,22 @@ JSON-data results are lossless. The schema benchmark preserves required
|
|
|
26
50
|
fields and descriptions while trimming redundant examples. Repetitive,
|
|
27
51
|
structured data benefits most.
|
|
28
52
|
|
|
53
|
+
## What it does
|
|
54
|
+
|
|
55
|
+
- **CLI** — `tokenfold compress` / `inspect` files or stdin, and compare
|
|
56
|
+
payloads with `tokenfold diff`; `tokenfold wrap -- <command>` compresses a
|
|
57
|
+
command's output in place.
|
|
58
|
+
- **Library** — the same Rust engine and receipt shape from `pip install tokenfold`
|
|
59
|
+
or `npm install tokenfold`, so behavior never drifts between languages.
|
|
60
|
+
- **Proxy** — `tokenfold-proxy` sits in front of your provider, compresses
|
|
61
|
+
requests, and streams responses through untouched.
|
|
62
|
+
- **MCP server** — `tokenfold mcp serve` exposes compress/inspect/retrieve/stats
|
|
63
|
+
to any MCP-compatible agent or editor.
|
|
64
|
+
- **Receipts, not guesses** — every call returns exact token counts, the
|
|
65
|
+
transforms it applied, and any warnings, so you can audit what changed.
|
|
66
|
+
- **Local and lightweight** — one static Rust binary runs on your machine or
|
|
67
|
+
infrastructure, with no hosted service or additional data processor.
|
|
68
|
+
|
|
29
69
|
## Quick start
|
|
30
70
|
|
|
31
71
|
Install the interface that fits your stack:
|
|
@@ -41,10 +81,12 @@ Or download the CLI for Linux, macOS, or Windows from
|
|
|
41
81
|
[GitHub Releases](https://github.com/snchimata/tokenfold/releases/latest),
|
|
42
82
|
then verify it with the adjacent `.sha256` file.
|
|
43
83
|
|
|
44
|
-
|
|
84
|
+
Preview the savings without changing the input, then write the compressed
|
|
85
|
+
payload when you are ready:
|
|
45
86
|
|
|
46
87
|
```bash
|
|
47
|
-
|
|
88
|
+
tokenfold inspect payload.json --format json
|
|
89
|
+
tokenfold compress payload.json --format json --output payload.compact.json
|
|
48
90
|
```
|
|
49
91
|
|
|
50
92
|
Compress an OpenAI-style request before sending it to your provider:
|
|
@@ -129,6 +171,25 @@ messages · schemas · JSON · logs · diffs
|
|
|
129
171
|
└───────────▶ compressed payload + receipt
|
|
130
172
|
```
|
|
131
173
|
|
|
174
|
+
## When to use tokenfold · when to look elsewhere
|
|
175
|
+
|
|
176
|
+
**Good fit if you...**
|
|
177
|
+
|
|
178
|
+
- want an exact, auditable receipt for every call instead of an estimate
|
|
179
|
+
- need lossless guarantees on structured data — JSON, schemas, tool
|
|
180
|
+
arguments — before it reaches a billing meter
|
|
181
|
+
- want a portable static binary with deterministic behavior and a small
|
|
182
|
+
operational footprint
|
|
183
|
+
- are shrinking logs, diffs, and repetitive tool output before they hit an
|
|
184
|
+
LLM, a log store, or a queue
|
|
185
|
+
|
|
186
|
+
**Look elsewhere if you...**
|
|
187
|
+
|
|
188
|
+
- need query-aware summarization of unstructured prose — that calls for a
|
|
189
|
+
model, and tokenfold stays deterministic on purpose
|
|
190
|
+
- want a hosted API to call — tokenfold runs entirely on your machine or
|
|
191
|
+
your infrastructure; there is nothing to sign up for
|
|
192
|
+
|
|
132
193
|
## What it improves
|
|
133
194
|
|
|
134
195
|
| Workload | User benefit |
|
|
@@ -232,6 +293,61 @@ cargo run --release --locked -p tokenfold-cli -- \
|
|
|
232
293
|
The sample reports 382 → 206 estimated tokens, a **46.1% reduction**. Ragged
|
|
233
294
|
or compact inputs may save little; Tokenfold reports that result honestly.
|
|
234
295
|
|
|
296
|
+
## Tokenfold Select
|
|
297
|
+
|
|
298
|
+
**When structural compression ends, rank what matters.**
|
|
299
|
+
|
|
300
|
+
Tokenfold Core removes structural waste. [Tokenfold Select][tokenfold-select]
|
|
301
|
+
is its optional, query-aware companion: a LoRA-fine-tuned model that ranks
|
|
302
|
+
text spans by relevance before you assemble a smaller context.
|
|
303
|
+
|
|
304
|
+
| | Tokenfold Core | Tokenfold Select |
|
|
305
|
+
| --- | --- | --- |
|
|
306
|
+
| Best at | JSON, schemas, logs, and diffs | Query-conditioned span ranking |
|
|
307
|
+
| Runtime | Static Rust binary | Granite reranker + LoRA adapter |
|
|
308
|
+
| Contract | Compressed payload + auditable receipt | Ranking logits only |
|
|
309
|
+
|
|
310
|
+
Select is deliberately separate from the CLI and libraries. That separation
|
|
311
|
+
lets each tool do one job well: Core provides deterministic transforms and
|
|
312
|
+
auditable receipts; Select adds query-aware ranking when relevance matters.
|
|
313
|
+
Your allocator still owns required-content retention and the hard token
|
|
314
|
+
budget.
|
|
315
|
+
|
|
316
|
+
<details>
|
|
317
|
+
<summary><strong>Python: load the model and score spans</strong></summary>
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
from pathlib import Path
|
|
321
|
+
|
|
322
|
+
import torch
|
|
323
|
+
from huggingface_hub import snapshot_download
|
|
324
|
+
from peft import PeftModel
|
|
325
|
+
from transformers import AutoModelForSequenceClassification, AutoTokenizer
|
|
326
|
+
|
|
327
|
+
base_id = "ibm-granite/granite-embedding-reranker-english-r2"
|
|
328
|
+
repo_dir = Path(snapshot_download("snchimata/tokenfold-select"))
|
|
329
|
+
adapter_dir = repo_dir / "adapter"
|
|
330
|
+
tok = AutoTokenizer.from_pretrained(adapter_dir)
|
|
331
|
+
base = AutoModelForSequenceClassification.from_pretrained(base_id, dtype=torch.float32)
|
|
332
|
+
model = PeftModel.from_pretrained(base, adapter_dir).eval()
|
|
333
|
+
|
|
334
|
+
def score(query: str, spans: list[str]) -> list[float]:
|
|
335
|
+
if not spans:
|
|
336
|
+
return []
|
|
337
|
+
enc = tok([query] * len(spans), spans, padding=True, truncation=True,
|
|
338
|
+
max_length=8192, return_tensors="pt")
|
|
339
|
+
with torch.no_grad():
|
|
340
|
+
out = model(input_ids=enc["input_ids"], attention_mask=enc["attention_mask"])
|
|
341
|
+
return out.logits.view(-1).float().tolist()
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
</details>
|
|
345
|
+
|
|
346
|
+
See the [Tokenfold Select model card][tokenfold-select] for setup, evaluation,
|
|
347
|
+
training data, and limitations.
|
|
348
|
+
|
|
349
|
+
[tokenfold-select]: https://huggingface.co/snchimata/tokenfold-select
|
|
350
|
+
|
|
235
351
|
## Contributing
|
|
236
352
|
|
|
237
353
|
Issues and pull requests are welcome. Run the core checks before opening a PR:
|
|
@@ -256,3 +372,8 @@ receipt, and see how many tokens your application can stop sending today.
|
|
|
256
372
|
```bash
|
|
257
373
|
pip install tokenfold
|
|
258
374
|
```
|
|
375
|
+
|
|
376
|
+
If tokenfold earns a place in your stack, a ⭐ on
|
|
377
|
+
[GitHub](https://github.com/snchimata/tokenfold) helps the next team
|
|
378
|
+
find it.
|
|
379
|
+
|
|
@@ -1,26 +1,16 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: tokenfold
|
|
3
|
-
Version: 0.3.3
|
|
4
|
-
Classifier: Programming Language :: Rust
|
|
5
|
-
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
7
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Summary: Token-compression toolkit for LLM payloads (Python binding over the tokenfold-core Rust crate)
|
|
10
|
-
Requires-Python: >=3.9
|
|
11
|
-
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
12
|
-
|
|
13
1
|
<div align="center">
|
|
14
2
|
|
|
15
3
|
# TOKENFOLD
|
|
16
4
|
|
|
17
5
|
**Send less noise. Fit more context. Pay for fewer input tokens.**
|
|
18
6
|
|
|
19
|
-
|
|
7
|
+
**46–68% fewer tokens on JSON & schemas · deterministic · reversible · every call audited**
|
|
8
|
+
|
|
9
|
+
CLI · Python · TypeScript · proxy · MCP · local-first · provider-neutral
|
|
20
10
|
|
|
21
11
|
[](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)
|
|
22
12
|
|
|
23
|
-
[Quick start](#quick-start) · [Why tokenfold](#why-tokenfold) · [Integrations](#pick-your-integration) · [Benchmarks](#reproduce-the-numbers)
|
|
13
|
+
[Quick start](#quick-start) · [Why tokenfold](#why-tokenfold) · [Integrations](#pick-your-integration) · [Benchmarks](#reproduce-the-numbers) · [Select model](#tokenfold-select)
|
|
24
14
|
|
|
25
15
|
</div>
|
|
26
16
|
|
|
@@ -38,6 +28,22 @@ JSON-data results are lossless. The schema benchmark preserves required
|
|
|
38
28
|
fields and descriptions while trimming redundant examples. Repetitive,
|
|
39
29
|
structured data benefits most.
|
|
40
30
|
|
|
31
|
+
## What it does
|
|
32
|
+
|
|
33
|
+
- **CLI** — `tokenfold compress` / `inspect` files or stdin, and compare
|
|
34
|
+
payloads with `tokenfold diff`; `tokenfold wrap -- <command>` compresses a
|
|
35
|
+
command's output in place.
|
|
36
|
+
- **Library** — the same Rust engine and receipt shape from `pip install tokenfold`
|
|
37
|
+
or `npm install tokenfold`, so behavior never drifts between languages.
|
|
38
|
+
- **Proxy** — `tokenfold-proxy` sits in front of your provider, compresses
|
|
39
|
+
requests, and streams responses through untouched.
|
|
40
|
+
- **MCP server** — `tokenfold mcp serve` exposes compress/inspect/retrieve/stats
|
|
41
|
+
to any MCP-compatible agent or editor.
|
|
42
|
+
- **Receipts, not guesses** — every call returns exact token counts, the
|
|
43
|
+
transforms it applied, and any warnings, so you can audit what changed.
|
|
44
|
+
- **Local and lightweight** — one static Rust binary runs on your machine or
|
|
45
|
+
infrastructure, with no hosted service or additional data processor.
|
|
46
|
+
|
|
41
47
|
## Quick start
|
|
42
48
|
|
|
43
49
|
Install the interface that fits your stack:
|
|
@@ -53,10 +59,12 @@ Or download the CLI for Linux, macOS, or Windows from
|
|
|
53
59
|
[GitHub Releases](https://github.com/snchimata/tokenfold/releases/latest),
|
|
54
60
|
then verify it with the adjacent `.sha256` file.
|
|
55
61
|
|
|
56
|
-
|
|
62
|
+
Preview the savings without changing the input, then write the compressed
|
|
63
|
+
payload when you are ready:
|
|
57
64
|
|
|
58
65
|
```bash
|
|
59
|
-
|
|
66
|
+
tokenfold inspect payload.json --format json
|
|
67
|
+
tokenfold compress payload.json --format json --output payload.compact.json
|
|
60
68
|
```
|
|
61
69
|
|
|
62
70
|
Compress an OpenAI-style request before sending it to your provider:
|
|
@@ -141,6 +149,25 @@ messages · schemas · JSON · logs · diffs
|
|
|
141
149
|
└───────────▶ compressed payload + receipt
|
|
142
150
|
```
|
|
143
151
|
|
|
152
|
+
## When to use tokenfold · when to look elsewhere
|
|
153
|
+
|
|
154
|
+
**Good fit if you...**
|
|
155
|
+
|
|
156
|
+
- want an exact, auditable receipt for every call instead of an estimate
|
|
157
|
+
- need lossless guarantees on structured data — JSON, schemas, tool
|
|
158
|
+
arguments — before it reaches a billing meter
|
|
159
|
+
- want a portable static binary with deterministic behavior and a small
|
|
160
|
+
operational footprint
|
|
161
|
+
- are shrinking logs, diffs, and repetitive tool output before they hit an
|
|
162
|
+
LLM, a log store, or a queue
|
|
163
|
+
|
|
164
|
+
**Look elsewhere if you...**
|
|
165
|
+
|
|
166
|
+
- need query-aware summarization of unstructured prose — that calls for a
|
|
167
|
+
model, and tokenfold stays deterministic on purpose
|
|
168
|
+
- want a hosted API to call — tokenfold runs entirely on your machine or
|
|
169
|
+
your infrastructure; there is nothing to sign up for
|
|
170
|
+
|
|
144
171
|
## What it improves
|
|
145
172
|
|
|
146
173
|
| Workload | User benefit |
|
|
@@ -244,6 +271,61 @@ cargo run --release --locked -p tokenfold-cli -- \
|
|
|
244
271
|
The sample reports 382 → 206 estimated tokens, a **46.1% reduction**. Ragged
|
|
245
272
|
or compact inputs may save little; Tokenfold reports that result honestly.
|
|
246
273
|
|
|
274
|
+
## Tokenfold Select
|
|
275
|
+
|
|
276
|
+
**When structural compression ends, rank what matters.**
|
|
277
|
+
|
|
278
|
+
Tokenfold Core removes structural waste. [Tokenfold Select][tokenfold-select]
|
|
279
|
+
is its optional, query-aware companion: a LoRA-fine-tuned model that ranks
|
|
280
|
+
text spans by relevance before you assemble a smaller context.
|
|
281
|
+
|
|
282
|
+
| | Tokenfold Core | Tokenfold Select |
|
|
283
|
+
| --- | --- | --- |
|
|
284
|
+
| Best at | JSON, schemas, logs, and diffs | Query-conditioned span ranking |
|
|
285
|
+
| Runtime | Static Rust binary | Granite reranker + LoRA adapter |
|
|
286
|
+
| Contract | Compressed payload + auditable receipt | Ranking logits only |
|
|
287
|
+
|
|
288
|
+
Select is deliberately separate from the CLI and libraries. That separation
|
|
289
|
+
lets each tool do one job well: Core provides deterministic transforms and
|
|
290
|
+
auditable receipts; Select adds query-aware ranking when relevance matters.
|
|
291
|
+
Your allocator still owns required-content retention and the hard token
|
|
292
|
+
budget.
|
|
293
|
+
|
|
294
|
+
<details>
|
|
295
|
+
<summary><strong>Python: load the model and score spans</strong></summary>
|
|
296
|
+
|
|
297
|
+
```python
|
|
298
|
+
from pathlib import Path
|
|
299
|
+
|
|
300
|
+
import torch
|
|
301
|
+
from huggingface_hub import snapshot_download
|
|
302
|
+
from peft import PeftModel
|
|
303
|
+
from transformers import AutoModelForSequenceClassification, AutoTokenizer
|
|
304
|
+
|
|
305
|
+
base_id = "ibm-granite/granite-embedding-reranker-english-r2"
|
|
306
|
+
repo_dir = Path(snapshot_download("snchimata/tokenfold-select"))
|
|
307
|
+
adapter_dir = repo_dir / "adapter"
|
|
308
|
+
tok = AutoTokenizer.from_pretrained(adapter_dir)
|
|
309
|
+
base = AutoModelForSequenceClassification.from_pretrained(base_id, dtype=torch.float32)
|
|
310
|
+
model = PeftModel.from_pretrained(base, adapter_dir).eval()
|
|
311
|
+
|
|
312
|
+
def score(query: str, spans: list[str]) -> list[float]:
|
|
313
|
+
if not spans:
|
|
314
|
+
return []
|
|
315
|
+
enc = tok([query] * len(spans), spans, padding=True, truncation=True,
|
|
316
|
+
max_length=8192, return_tensors="pt")
|
|
317
|
+
with torch.no_grad():
|
|
318
|
+
out = model(input_ids=enc["input_ids"], attention_mask=enc["attention_mask"])
|
|
319
|
+
return out.logits.view(-1).float().tolist()
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
</details>
|
|
323
|
+
|
|
324
|
+
See the [Tokenfold Select model card][tokenfold-select] for setup, evaluation,
|
|
325
|
+
training data, and limitations.
|
|
326
|
+
|
|
327
|
+
[tokenfold-select]: https://huggingface.co/snchimata/tokenfold-select
|
|
328
|
+
|
|
247
329
|
## Contributing
|
|
248
330
|
|
|
249
331
|
Issues and pull requests are welcome. Run the core checks before opening a PR:
|
|
@@ -269,3 +351,6 @@ receipt, and see how many tokens your application can stop sending today.
|
|
|
269
351
|
pip install tokenfold
|
|
270
352
|
```
|
|
271
353
|
|
|
354
|
+
If tokenfold earns a place in your stack, a ⭐ on
|
|
355
|
+
[GitHub](https://github.com/snchimata/tokenfold) helps the next team
|
|
356
|
+
find it.
|
|
@@ -6,7 +6,7 @@ rust-version.workspace = true
|
|
|
6
6
|
license.workspace = true
|
|
7
7
|
repository.workspace = true
|
|
8
8
|
description = "Token-aware compression for LLM payloads: shrink JSON tool-call bodies, command output, and diffs with exact tiktoken accounting and a typed safety report."
|
|
9
|
-
keywords = ["llm", "tokenizer", "compression", "tiktoken", "
|
|
9
|
+
keywords = ["llm", "tokenizer", "compression", "tiktoken", "token-optimization"]
|
|
10
10
|
categories = ["compression", "text-processing"]
|
|
11
11
|
|
|
12
12
|
[dependencies]
|
|
@@ -16,7 +16,7 @@ name = "tokenfold_py"
|
|
|
16
16
|
crate-type = ["cdylib", "rlib"]
|
|
17
17
|
|
|
18
18
|
[dependencies]
|
|
19
|
-
tokenfold-core = { version = "0.3.
|
|
19
|
+
tokenfold-core = { version = "0.3.4", path = "../tokenfold-core" }
|
|
20
20
|
serde_json = { workspace = true }
|
|
21
21
|
pyo3 = { version = "0.29.0", features = ["abi3-py39"] }
|
|
22
22
|
|
|
@@ -8,11 +8,21 @@ description = "Token-compression toolkit for LLM payloads (Python binding over t
|
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
requires-python = ">=3.9"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
11
|
+
keywords = ["llm", "tokens", "compression", "tokenizer", "openai", "json", "prompt-engineering", "cli", "token-optimization"]
|
|
11
12
|
classifiers = [
|
|
13
|
+
"Development Status :: 4 - Beta",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"License :: OSI Approved :: Apache Software License",
|
|
12
16
|
"Programming Language :: Rust",
|
|
13
17
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
14
18
|
"Programming Language :: Python :: 3 :: Only",
|
|
15
19
|
"Programming Language :: Python :: 3.9",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
|
+
"Topic :: Text Processing",
|
|
16
26
|
]
|
|
17
27
|
dynamic = ["version"]
|
|
18
28
|
|
|
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
|