From fe370b5c00d39bf1f20aa4ca3c158ccfe702498b Mon Sep 17 00:00:00 2001
From: snchimata <38873813+snchimata@users.noreply.github.com>
Date: Wed, 11 Nov 2026 21:25:34 -0500
Subject: [PATCH 1/2] docs: refresh published SDK examples
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
README.md | 736 ++++---
docs/assets/tokenfold-demo.gif | Bin 78086 -> 250039 bytes
docs/sdk-benchmarks-0.6.0.md | 154 ++
docs/sdk-validation-0.6.0.md | 9 +-
docs/tokenfold-demo.tape | 4 +-
eval/research/sdk_quality_corpus.json | 1184 ++++++++++++
eval/research/sdk_quality_results.json | 2135 +++++++++++++++++++++
examples/quickstart.ipynb | 134 +-
python-tests/test_notebook.py | 7 +-
python-tests/test_readme_claims.py | 10 +-
python-tests/test_readme_layout.py | 86 +-
python-tests/test_sdk_quality_evidence.py | 141 ++
scripts/render-demo.py | 246 +++
scripts/test_render_demo.py | 89 +
tests/fixtures/readme_metrics.json | 11 +
15 files changed, 4556 insertions(+), 390 deletions(-)
create mode 100644 docs/sdk-benchmarks-0.6.0.md
create mode 100644 eval/research/sdk_quality_corpus.json
create mode 100644 eval/research/sdk_quality_results.json
create mode 100644 python-tests/test_sdk_quality_evidence.py
create mode 100644 scripts/render-demo.py
create mode 100644 scripts/test_render_demo.py
diff --git a/README.md b/README.md
index 504efdb..93f85d9 100644
--- a/README.md
+++ b/README.md
@@ -7,15 +7,15 @@
# TOKENFOLD
-
More context. Fewer tokens. Exact by default.
+Select what matters. Fit more context.
- Deterministic context compression for LLMs. Cut JSON tokens by up to 68% with exact recovery, or exceed 90% with opt-in, recoverable pruning.
+ Tokenfold Select brings query-aware relevance ranking to your LLM context. Fit complete context groups to a token budget, backed by Core's structural compression and inspectable receipts.
-Tokenfold Core delivers model-free structural compression.
-
-Tokenfold Select ranks the context that matters most when token budgets get tight.
+Python-first SDK. TypeScript alongside it. Rust at the core.
+One fit() workflow for text, JSON, grouped context, and provider requests.
+Select for relevance. Core for structural efficiency. One integrated workflow.
@@ -25,204 +25,246 @@ Tokenfold Select ranks the context that matters most when token budgets get tigh
-[Install](#installation) | [Quick start](#quick-start) | [How it works](#how-it-works) | [MCP & agents](#coding-agents-and-mcp-integration) | [Core](#tokenfold-core) | [Select](#tokenfold-select) | [Benchmarks](#measured-results) | [Safety](#safety-and-auditability)
+
-
-
-## Installation
+
+Demo scope and regeneration
+
+The 13-second FIT -> CORE -> SELECT loop returns directly to the code, with no
+closing slide. It opens on the executed Python SDK `fit()` example and its
+verified result: explicit folding reduces already-compact JSON from 2,366 to
+1,376 tokens (**41.8%**), meeting a 1,500-token budget without dropping any of
+the 30 records. The compact baseline exceeds that same budget.
+
+The following Core frame starts from the formatted API-response fixture:
+3,812 to 1,376 tokens (**63.9%**), with exact JSON-value recovery. These are
+different input representations, not interchangeable SDK and CLI baselines.
+The workflow builds the Core baseline first; Select requires a still-over-budget,
+eligible request, an approved runtime and explicit per-fit opt-in. Select is an
+**illustration, not live inference**, and remains experimental and unqualified.
+Fixture savings are not universal, and reversible data is not model-answer proof.
+
+The [renderer](scripts/render-demo.py) requires Pillow, a locally built CLI and
+the current SDK installed in a Python >=3.12 environment. It checks the fixture
+hash, Core counts, decode equality and SDK receipt before rendering:
```bash
-pip install tokenfold # Python library
-npm install tokenfold # Node.js / TypeScript library
-cargo install tokenfold-cli # Standalone CLI
-cargo add tokenfold-core # Rust library
+python scripts/render-demo.py --sdk-python /path/to/sdk-env/python
```
-These installs provide Core. For optional query-aware model scoring, see
-[Select setup](#tokenfold-select); its models and runtime setup are separate.
-
-
-
-
-
- Up to 96.3% fewer tokens (showcase)
-
- Opt-in, recoverable pruning for heterogeneous array feeds - every dropped row stays fetchable.
-
- |
-
-
- 45.6-67.6% on three fixtures, lossless
-
- Reversible structural folding of repeated keys and columns on three bundled fixtures - verified by exact JSON-value recovery.
-
- |
-
-
- Model-free & deterministic
-
- No GPU, no semantic guesswork, no model in the Core path. A Rust engine with Python, Node.js, CLI and proxy interfaces.
-
- |
-
-
+The [VHS tape](docs/tokenfold-demo.tape) is a separate, Core-only terminal
+recording and writes to `tmp/tokenfold-core-terminal.gif`.
-> [!NOTE]
-> **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.
+
-
+## Table of contents
-## How it works
+[Python quickstart](#quick-start) | [Python fit workflow](#native-sdk-fitting) | [Select](#tokenfold-select) | [Benchmark highlights](#benchmark-highlights) | [Other integrations](#other-integrations) | [How it works](#how-it-works) | [Core](#tokenfold-core) | [Full results](#measured-results) | [Extended tooling](#extended-tooling) | [Safety and auditability](#safety-and-auditability) | [Reproduce the results](#reproduce-the-results) | [Contributing](#contributing) | [License](#license)
-- **Core (default):** folds repeated structure without removing data. The
- compact payload decodes to the original JSON value.
-- **[Recoverable pruning](#recoverable-lossy-pruning) (opt-in):** model-free
- rules rank eligible JSON rows; omissions are stored locally before replacement
- with `$tf_ref` handles. This is the path behind the **96.3% showcase**, not Select.
-- **[Select](#tokenfold-select) (separate):** a model scores groups against your
- query; your allocator keeps selected original text under a token budget.
- Select does not automatically store omissions or create recovery handles.
+> **Built for:** Python application developers and AI teams fitting JSON, tool
+> definitions, and grouped context into LLM requests. TypeScript, coding agents,
+> CLI, proxy, and Rust integrations use the same underlying Core engine.
-### What the model sees
+## Quick start
-```jsonc
-// Input (conceptual illustration - 2 rows shown; small inputs like this
-// pass through unchanged under the never-larger guard)
-[{"id":1,"role":"admin"},{"id":2,"role":"member"}]
+### Published Python SDK
-// Tokenfold output on larger uniform arrays -> still JSON
-{"__tf_cols__":["id","role"],"__tf_rows__":[[1,"admin"],[2,"member"]]}
+Python >=3.12. Install the current SDK release; the base workflow needs no
+repository checkout, model, GPU, or ML framework:
+
+```bash
+python -m pip install "tokenfold==0.6.0"
```
-
+
-
-How this demo was generated (VHS tape)
+### Python fit workflow
-The [VHS tape](docs/tokenfold-demo.tape) runs `inspect`, `compress`, and
-`decode` against the bundled API response, including the **63.9%** receipt.
-Run `vhs docs/tokenfold-demo.tape` to regenerate the GIF; the tape requires
-`tokenfold` on `PATH`.
+The SDK fits text, JSON, or grouped context to an explicit token ceiling.
+Fitting is offline and model-free unless you explicitly configure and consent to
+Select. No automatic sending, model downloads, or recoverable pruning occurs.
-
+Default `Data(records)` renders standard compact JSON; opt into the folded
+representation only for consumers you have validated:
-Send the folded JSON directly to the model: column names label each value's
-position in every row. Decode only when your application needs the original
-object shape again.
+```python
+from tokenfold import Data, fit
+
+records = [
+ {"id": i, "service": "checkout-api", "region": "us-east-1",
+ "status": 200, "latency_ms": 42 + i}
+ for i in range(1, 31)
+]
+result = fit(Data(records, representation="folded"), target_tokens=500)
+print(f"{result.original_tokens} -> {result.final_tokens} tokens")
+payload_text = result.require_met()
+print(result.receipt.to_json())
+```
-#### Why Tokenfold, not LLMLingua / prompt compressors?
+`require_met()` returns the payload only when the exact budget is met; otherwise
+it raises `BudgetUnmetError` or `BudgetIndeterminateError` with the receipt.
+Text/Data/Context return text; full provider requests return JSON objects.
+An exact encoding count is not an exact provider-framing or billing count.
+Explicit best-effort can accept an estimate without calling it exact.
-- **Targets structured JSON, not prose.** Folds repeated keys and columns
- mechanically rather than using semantic guesswork.
-- **Model-free and deterministic.** Zero models running in Core and zero GPU
- overhead.
-- **Verified by exact decode.** Every lossless transform is verified by an
- in-memory round trip before emitting; lossy pruning is strictly opt-in and
- recoverable.
+See the [Python example](examples/sdk_fit.py), [migration guide](docs/sdk-migration.md),
+and [validation status](docs/sdk-validation-0.6.0.md). Advanced compression lives
+under `tokenfold.lowlevel`.
-#### How Tokenfold decides what to fold
+For callers using the lower-level compression API, import it from
+`tokenfold.lowlevel`:
-```mermaid
-%%{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}}}%%
-flowchart LR
- accTitle: Lossless first, pruning only when opted in
- 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.
- Lossless["Build lossless JSON baseline
Verify folds; retain savings"] --> OptIn{"Pruning enabled,
eligible and needed?"}
- OptIn -->|No| Keep("Lossless payload
+ receipt")
- OptIn -->|Yes| Prune["Rank eligible rows
Store before removal"]
- Prune -->|No further savings| Keep
- Prune -->|Fewer tokens than baseline| Emit("Pruned payload
+ markers and receipt")
+```python
+import json
+from tokenfold.lowlevel import InputFormat, compress, decode
+
+records = [
+ {"id": i, "service": "checkout-api", "region": "us-east-1",
+ "status": 200, "latency_ms": 42 + i}
+ for i in range(1, 31)
+]
+raw_bytes = json.dumps(records).encode("utf-8")
+result = compress(raw_bytes, format=InputFormat.JSON)
+print(f"{result.report.original_tokens} -> {result.report.compressed_tokens} tokens")
+assert json.loads(decode(result.payload)) == records
+```
- classDef core fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a
- classDef optional fill:#f8fafc,stroke:#64748b,stroke-dasharray:5 4,color:#334155
- class Lossless,Keep core
- class Prune optional
+
+
+## Tokenfold Select
+
+**When structure ends, rank what matters.**
+
+[Tokenfold Select v3][tokenfold-select] is an Apache-2.0, **149.6M-parameter**
+joint-group Ettin scorer, integrated into the SDK's `fit()` workflow.
+Core remains model-free and neither loads nor invokes Select.
+The SDK uses the lightweight maintained [tokenfold-select-runtime](packages/tokenfold-select-runtime/README.md),
+not the superseded v2 package or an implicit direct-bundle loader. Model files are
+acquired separately at an immutable revision; they do not ship in a clone or base SDK.
+Use explicit CPU/FP32 or CUDA/BF16 setup and per-fit selection consent. Import and
+already-fitting Core requests never load weights. Selection is experimental and
+unqualified: grouping and required flags preserve caller-declared dependencies,
+not independent proof of answer quality. No automatic recoverable pruning occurs.
+See [provisioning, accounting, and lifecycle](docs/sdk-migration.md).
+
+### Python Select workflow
+
+After [explicit runtime provisioning](docs/sdk-migration.md#explicit-select-provisioning-and-consent),
+supply the resulting config and allow selection on each fit. Keep dependent
+content in one group or mark it required:
+
+```python
+from tokenfold import Context, Group, SelectRuntime, Tokenfold
+
+context = Context(
+ query="Which change caused the cache failure?",
+ groups=[
+ Group("constraints", "Use only the supplied release evidence.", required=True),
+ Group("changes", "Commit a41f9c changed the Redis TTL to 0ms."),
+ Group("logs", "After that release, cache evictions spiked on shard-02."),
+ Group("notes", "Weekly planning notes cover unrelated roadmap items. " * 40),
+ ],
+)
+with Tokenfold(select=SelectRuntime("select-runtime.json", experimental=True)) as client:
+ result = client.fit(context, target_tokens=96, allow_selection=True)
+ print(result.receipt.to_json())
+ fitted_context = result.require_met()
+ print("Selection applied:", result.selection_applied)
+ print("Kept:", result.groups_kept, "Dropped:", result.groups_dropped)
```
-
-Text version (screen readers / no-image fallback)
+The full context deliberately exceeds the ceiling. A successful fit requires
+selection; the example does not promise particular kept IDs or answer accuracy.
+If scoring fails or cannot meet the budget, checked access rejects the overflow
+rather than silently returning a successful fit. Already-fitting requests skip
+scoring even when consent is present.
-1. Build the lossless baseline using eligible transforms. Verify structural
- folds with an exact decode round trip and keep only token reductions.
-2. Consider pruning only when explicitly opted in, the payload is eligible,
- and the lossless baseline has not already met a requested token target.
-3. Rank eligible rows and store omissions locally before removing them.
- Rows refused by storage stay inline.
-4. Use the pruned payload only if it has fewer tokens than the lossless
- baseline; otherwise keep the lossless baseline.
-5. Emit the chosen payload and compression receipt. Pruned payloads include
- retrieval markers for stored omissions.
+## Benchmark highlights
-
+Saved fixture results, not universal savings or downstream quality guarantees:
-| Workload | Type | Core mode | Savings |
-| --- | --- | --- | --- |
-| API responses | 30-record JSON payload | Lossless | **63.9% fewer tokens** |
-| Tool schemas | OpenAI tool-schema fixture (Criterion bench) | Lossless | **45.6% fewer tokens** |
-| Repetitive JSON | 50-record payload | Lossless | **67.6% fewer tokens** |
+| Scope | Measured result | Limits and evidence |
+| --- | --- | --- |
+| Core structural compression | **45.6-63.9% on two fixtures, lossless** | Tool schemas and the 30-record API response; exact JSON-value recovery |
+| Core vs. Headroom | **6/6 fixture wins**, 13,071 -> 8,715 tokens (**33.3% saved**) | Default local generic-JSON paths; Tokenfold recovered 6/6 exactly, Headroom matched 4/6 |
+| Tokenfold JSON vs. TOON 4.1.1 | **7/7 fixture wins**, 12,776 vs. 14,841 tokens | 13.9% fewer tokens than TOON in this corpus; both paths round-trip |
+| Opt-in, recoverable pruning | **Up to 96.3% fewer tokens (showcase)** | A 100-row heterogeneous feed; omitted rows stored behind local `$tf_ref` handles, not lossless inline compression |
-These figures use exact `o200k_base` counts in the balanced preset. Versioned
-inputs and provenance live in [`tests/fixtures/readme_metrics.json`](tests/fixtures/readme_metrics.json).
-[Recoverable pruning](#recoverable-lossy-pruning) is separate, opt-in extended tooling.
+These structural counts use exact `o200k_base` accounting. Inputs and provenance
+live in [the metric manifest](tests/fixtures/readme_metrics.json); see
+[full comparisons and methods](#measured-results) and the
+[pruning showcase](#recoverable-lossy-pruning). The historical **67.6%** result
+is a 50-record CHANGELOG measurement without a versioned source fixture; it was
+not reproduced in the SDK rerun and is not used in the headline.
-
+The [saved downstream-answer diagnostic](#sdk-downstream-answer-diagnostic)
+recorded **8/8 correct baseline answers vs. 6/8 with folded JSON**; Select matched
+16/16 baseline answers on eight synthetic tasks with two trials each. These are
+small development diagnostics, not representative quality or Select qualification.
-## Quick start
+## Other integrations
-### Native SDK fitting (0.6.0)
+Python is the primary SDK onboarding path. TypeScript is supported alongside it;
+CLI, MCP, proxy, and Rust are alternative entry points, not Python prerequisites.
-Python >=3.12 (`pip install tokenfold==0.6.0`) and Node >=22
-(`npm install tokenfold@0.6.0`). See the migration guide for breaking import changes.
-Base fitting is offline and model-free, with no auto-send, model download or storage.
+
-```python
-from tokenfold import fit
-result = fit("Keep this text unchanged.", target_tokens=32)
-payload = result.require_met()
-print(result.receipt.to_json())
+### Interfaces
+
+| Interface | Install / setup | Primary use case |
+| --- | --- | --- |
+| Python | `python -m pip install "tokenfold==0.6.0"` | Native fitting SDK; start above |
+| TypeScript / Node.js | `npm install tokenfold@0.6.0` | Native fitting; CLI utilities live under `tokenfold/cli` |
+| MCP | `tokenfold mcp serve` | Coding agents and editors; install the CLI first |
+| CLI | `cargo install tokenfold-cli` | Files, stdin, and shell workflows |
+| Proxy | `cargo install tokenfold-proxy` | Existing OpenAI-compatible clients |
+| Rust | `cargo add tokenfold-core` | Native embedding |
+
+### TypeScript / Node.js
+
+Node >=22. Install the published SDK package. Core fitting runs in-process;
+the base install needs neither Python nor a source build:
+
+```sh
+npm install tokenfold@0.6.0
```
+See the [Node example](examples/sdk_fit.mjs) and
+[migration guide](docs/sdk-migration.md):
+
```js
import { fit } from "tokenfold";
const result = await fit("Keep this text unchanged.", { targetTokens: 32 });
const payload = result.requireMet();
```
-Text/Data/Context return text; full provider requests return JSON objects. Provider
-framing is not an encoding count: exact checked access rejects unavailable/estimated
-budgets. Explicit best-effort can accept an estimate without calling it exact.
-See [SDK migration](docs/sdk-migration.md), [Python example](examples/sdk_fit.py),
-[Node example](examples/sdk_fit.mjs), and [validation status](docs/sdk-validation-0.6.0.md).
-Advanced compression remains under `tokenfold.lowlevel` / `tokenfold/cli`.
-
-### Python: compress JSON directly
+### Coding agents and MCP integration
-After installing Tokenfold, try this self-contained example. Thirty uniform
-records provide enough repeated structure to demonstrate lossless folding:
+Coding agents can exhaust context limits on large shell outputs. Tokenfold runs as a
+stdio MCP server exposing `tokenfold_compress`, `tokenfold_inspect`,
+`tokenfold_retrieve`, and `tokenfold_stats`, with pre-configured filters for Git
+status, diffs, build output, and test logs before they consume agent context.
+`tokenfold init` currently supports Claude Code; Codex uses manual MCP
+registration:
-```python
-import json
-from tokenfold.lowlevel import InputFormat, compress
+```bash
+tokenfold init --agent claude-code
+tokenfold doctor --agent claude-code
-records = [{"id": i, "role": "member", "status": "active"} for i in range(30)]
-result = compress(json.dumps(records), format=InputFormat.JSON)
-print(f"{result.report.original_tokens} -> {result.report.compressed_tokens} tokens "
- f"({result.saved_pct():.1f}% saved)")
+# Or connect manually in Codex:
+codex mcp add tokenfold -- tokenfold mcp serve
```
-Send `result.payload` (bytes) to the model. Use `tokenfold.lowlevel.decode` when your
-application needs the original JSON shape again. Small or irregular inputs may
-pass through unchanged under the never-larger guard.
-
-### CLI: inspect and compress a file
-
-Install the CLI with `cargo install tokenfold-cli` or use a
-[checksummed GitHub Release](https://github.com/snchimata/tokenfold/releases/latest), then:
+`tokenfold init --agent claude-code` merges a project-scoped `.mcp.json` entry without replacing
+other servers; `tokenfold doctor --agent claude-code` verifies it. `tokenfold_inspect`
+is side-effect-free (never returns a modified payload); `tokenfold_retrieve`
+retrieves by hash or marker (report references are reserved but not yet
+resolvable). See
+[`docs/configuration.md`](docs/configuration.md) for tested MCP JSON/TOML and every environment
+override. Trusted filters for Git, build, and test output
+are available through `tokenfold filters list`.
-```bash
-tokenfold inspect payload.json --format json
-tokenfold compress payload.json --format json --output payload.compact.json
-```
+
### Drop-in proxy for OpenAI-compatible clients
@@ -294,212 +336,167 @@ sequenceDiagram
P-->>-C: Response
```
-### Interfaces
+### CLI and low-level Python
-| Interface | 1-line install / command | Primary use case |
-| --- | --- | --- |
-| Proxy | `cargo install tokenfold-proxy` | Existing OpenAI-compatible clients |
-| CLI | `cargo install tokenfold-cli` | Files, stdin, and shell workflows |
-| Python | `pip install tokenfold` | Application pipelines |
-| TypeScript | `npm install tokenfold` | Node.js applications and automation |
-| Rust | `cargo add tokenfold-core` | Native embedding |
-| MCP | `tokenfold mcp serve` | Agents and editors |
+For files and stdin, install the CLI with `cargo install tokenfold-cli` or use a
+[checksummed GitHub Release](https://github.com/snchimata/tokenfold/releases/latest):
-### Presets
+```bash
+tokenfold inspect payload.json --format json
+tokenfold compress payload.json --format json --output payload.compact.json
+```
-| Preset | Behavior |
-| --- | --- |
-| `conservative` | Minification only; no restructuring of what the model sees. |
-| `balanced` (default) | Minification plus reversible columnar folding (`json_field_fold`, `json_value_dict`, `log_field_fold`) on eligible formats. |
-| `aggressive` | Same default transform set as `balanced` today. |
+For provider-shaped JSON, use the low-level Python API. In the published package
+above, import these names directly from `tokenfold`, as in the first quickstart:
-Provider message formats (`openai_json`, `anthropic_json`) use minification
-only; columnar folding applies to generic JSON (`--format json`). The default
-proxy path follows this rule. Explicit `--observations` enables lossless
-compression of eligible JSON tool-result strings on `/v1/chat/completions`
-without folding the provider envelope; see [observation compression](docs/configuration.md#restart-safe-observation-commitments).
+```python
+from tokenfold.lowlevel import InputFormat, compress
-> [!NOTE]
-> `schema_compaction` is not enabled by any preset. Unlike the default
-> transforms, it truncates `examples` arrays and is not reversible.
+# Accepts raw JSON bytes or str (messages, tools, or schemas)
+request_json_bytes = b'{"messages": [{"role": "user", "content": "hello"}]}'
+result = compress(request_json_bytes, format=InputFormat.OPENAI_JSON)
+
+# For standalone JSON records, use: format=InputFormat.JSON
+compressed_payload = result.payload # bytes
+print(f"Saved {result.report.saved_tokens} tokens ({result.saved_pct():.1f}%)")
+```
### Runnable examples (Python >=3.12, Node.js >=22, Rust >=1.98)
-Runnable examples, one per surface, all under [`examples/`](examples):
+After building and installing the SDK, run the examples under [`examples/`](examples):
```bash
-python examples/sdk_fit.py # Python: native fit, checked payload, fit receipt
-node examples/sdk_fit.mjs # Node: native fit, checked payload, fit receipt
-python examples/quickstart.py # Advanced Python lowlevel compression and decoding
-node examples/quickstart.mjs # Advanced Node CLI compression and decoding
+python examples/quickstart.py # Python: compress messages, request bodies, JSON data
+node examples/quickstart.mjs # TypeScript/Node: compress, inspect, read the receipt
cargo run -p tokenfold-core --example quickstart # Rust: the embedded core API
python examples/lossy_pruning.py # CLI: opt-in recoverable pruning, end to end
-python examples/contextdoctor_report.py # source checkout: offline outcome/regression controls
```
[`examples/quickstart.ipynb`](examples/quickstart.ipynb) is the guided tour of the whole
Python surface: everything `quickstart.py` shows, plus previews, budgets and presets,
-provider payloads, recoverable pruning previews, and the offline ContextDoctor controls.
-Its separately provisioned Select v3 CUDA example is explicitly enabled; set
-`RUN_SELECT_V3 = False` for a core-only tour. See the [evaluation guide](eval/README.md)
-for ContextDoctor's source-only interface and evidence limits.
+provider payloads, recoverable pruning with retrieval, and where Tokenfold Select fits.
-### Coding agents and MCP integration
+## How it works
-Coding agents can exhaust context limits on large shell outputs. Tokenfold runs as a
-stdio MCP server exposing `tokenfold_compress`, `tokenfold_inspect`,
-`tokenfold_retrieve`, and `tokenfold_stats`, with pre-configured filters for Git
-status, diffs, build output, and test logs before they consume agent context.
-`tokenfold init` currently supports Claude Code; Codex uses manual MCP
-registration:
+### What the model sees
-```bash
-tokenfold init --agent claude-code
-tokenfold doctor --agent claude-code
+```json
+// Input (conceptual illustration - 2 rows shown; small inputs like this
+// pass through unchanged under the never-larger guard)
+[{"id":1,"role":"admin"},{"id":2,"role":"member"}]
-# Or connect manually in Codex:
-codex mcp add tokenfold -- tokenfold mcp serve
+// Tokenfold output on larger uniform arrays -> still JSON
+{"__tf_cols__":["id","role"],"__tf_rows__":[[1,"admin"],[2,"member"]]}
```
-`tokenfold init --agent claude-code` merges a project-scoped `.mcp.json` entry without replacing
-other servers; `tokenfold doctor --agent claude-code` verifies it. `tokenfold_inspect`
-is side-effect-free (never returns a modified payload); `tokenfold_retrieve`
-retrieves by hash or marker (report references are reserved but not yet
-resolvable). See
-[`docs/configuration.md`](docs/configuration.md) for tested MCP JSON/TOML and every environment
-override. Trusted filters for Git, build, and test output
-are available through `tokenfold filters list`.
-
-
-
-## Tokenfold Core
-
-### Structural, not semantic compression
-
-Semantic prompt compressors such as [LLMLingua](https://github.com/microsoft/LLMLingua) use a smaller language model to identify and remove less-important prompt tokens.
-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.
+Column names label each value's position in every row. Use folded JSON only
+with a consumer you have validated for that representation; decode when your
+application needs the original object shape. The SDK's default `Data`
+representation keeps standard compact JSON.
-[Tokenfold Select](#tokenfold-select) is Tokenfold's complementary query-aware offering: when structure ends, it ranks what matters under a token budget.
+#### Why Tokenfold Core for structured payloads?
-
-
-
-
-## Tokenfold Select
-
-**When structure ends, rank what matters.**
-
-[Tokenfold Select v3][tokenfold-select] is an Apache-2.0, **149.6M-parameter**
-joint-group Ettin scorer. Core remains model-free and neither loads nor invokes Select.
-The 0.6 SDK uses the lightweight maintained [tokenfold-select-runtime](packages/tokenfold-select-runtime/README.md),
-not the superseded v2 package or an implicit direct-bundle loader. Model files are
-acquired separately at an immutable revision; they do not ship in a clone or base SDK.
-Use explicit CPU/FP32 or CUDA/BF16 setup and per-fit selection consent. Import and
-already-fitting Core requests never load weights. Selection is experimental and
-unqualified: grouping and required flags preserve caller-declared dependencies,
-not independent proof of answer quality. No automatic recoverable pruning occurs.
-See [provisioning, accounting, and lifecycle](docs/sdk-migration.md).
-
-### Tokenfold Select v3 benchmarks
+- **Targets structured JSON, not prose.** Folds repeated keys and columns
+ mechanically rather than using semantic guesswork.
+- **Model-free and deterministic.** Zero models running in Core and zero GPU
+ overhead.
+- **Verified by exact decode.** Every lossless transform is verified by an
+ in-memory round trip before emitting; lossy pruning is strictly opt-in and
+ recoverable.
-Saved results from the [published v3 benchmark snapshot](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md),
-pinned to model-card revision `317d3424d3de78c1a708c42a47a7812ab877f1a8`.
-These measurements include the scorer **and whole-group allocator**, not the
-scoring model alone. Core's lossless benchmarks remain separate below.
+#### How Tokenfold decides what to fold
-#### Context-token reduction at a 50% budget
+```mermaid
+%%{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}}}%%
+flowchart LR
+ accTitle: Lossless first, pruning only when opted in
+ 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.
+ Lossless["Build lossless JSON baseline
Verify folds; retain savings"] --> OptIn{"Pruning enabled,
eligible and needed?"}
+ OptIn -->|No| Keep("Lossless payload
+ receipt")
+ OptIn -->|Yes| Prune["Rank eligible rows
Store before removal"]
+ Prune -->|No further savings| Keep
+ Prune -->|Fewer tokens than baseline| Emit("Pruned payload
+ markers and receipt")
-Select v3 removed **50.0-60.0%** of the original context tokens in these five
-saved development examples. Both models had the same exact `o200k_base` output
-cap for each workload; retained V3 groups were copied without rewriting.
+ classDef core fill:#eff6ff,stroke:#2563eb,stroke-width:2px,color:#1e3a8a
+ classDef optional fill:#f8fafc,stroke:#64748b,stroke-dasharray:5 4,color:#334155
+ class Lossless,Keep core
+ class Prune optional
+```
-| Workload | Original tokens | Select v3 output | V3 reduction | Kompress v2 output |
-| --- | ---: | ---: | ---: | ---: |
-| Code | 4,411 | 2,205 | **50.0%** | 2,149 |
-| JSON | 1,303 | 651 | **50.0%** | Refused; 1,303 raw |
-| Logs | 1,103 | 503 | **54.4%** | Refused; 1,103 raw |
-| Multi-turn | 587 | 235 | **60.0%** | 284 |
-| Retrieval | 4,498 | 2,217 | **50.7%** | 2,219 |
+
+Text version (screen readers / no-image fallback)
-One exposed source per workload; JSON and logs share a source population.
-Token reduction does not establish answer accuracy or semantic preservation.
-Six of ten historical Kompress cells refused the budget across the 25%/50%
-screen; refusals and raw fallbacks are **inconclusive, not V3 wins**. The
-[full ten-cell history](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md#benchmark-methodology)
-retains every result.
+1. Build the lossless baseline using eligible transforms. Verify structural
+ folds with an exact decode round trip and keep only token reductions.
+2. Consider pruning only when explicitly opted in, the payload is eligible,
+ and the lossless baseline has not already met a requested token target.
+3. Rank eligible rows and store omissions locally before removing them.
+ Rows refused by storage stay inline.
+4. Use the pruned payload only if it has fewer tokens than the lossless
+ baseline; otherwise keep the lossless baseline.
+5. Emit the chosen payload and compression receipt. Pruned payloads include
+ retrieval markers for stored omissions.
-#### Resident-warm complete-request latency at a 50% budget
+
-| Workload | Select v3 ms | Kompress v2 ms | V3 time difference | Measurement basis |
-| --- | ---: | ---: | ---: | --- |
-| Code | 146.088 | 200.304 | -27.1% | One historical request per model |
-| Retrieval | 139.291 | 201.564 | -30.9% | One historical request per model |
-| Multi-turn | 66.572 | 77.751 | -14.4% | Median of 5 requests per model |
+## Tokenfold Core
-Resident-warm RTX 5080 research pipelines, FP32 parameters/BF16 compute;
-startup excluded. Separate time blocks, not controlled-idle or paired trials.
-These are descriptive development observations, **not representative quality, population p50/p95, or superiority qualification**.
+### Structural, not semantic compression
-
-Benchmark methodology and preserved history
+Core removes structural redundancy, not prose selected by a language model.
+See [what the model sees](#what-the-model-sees) for the columnar JSON format and
+the verified lossless-first pipeline. Unlike semantic prompt compressors such
+as [LLMLingua](https://github.com/microsoft/LLMLingua), Core needs no model or GPU,
+does not inject prompt guidance, and does not fine-tune models.
-RTX 5080, FP32 parameters/BF16 compute, cache off, TF32 off, one Torch thread.
-V3 used the serialized SDPA research runner; Kompress v2 used native EAGER.
-Complete-request clocks include grouping, counting, IPC, scoring, allocation,
-final recount and applicable teardown, but **exclude process/model startup and
-conditioning**. They are not cold-CLI or quickstart-SDK latency measurements.
+[Tokenfold Select](#tokenfold-select) complements Core when query-aware group
+selection is explicitly enabled.
-The models ran in separate time blocks. The five-request multi-turn repeat was
-not controlled-idle: the GPU-busy admission gate was explicitly waived, with
-pre-model busy observations of 25% and 38%. All five samples per model are
-retained. The earlier multi-turn result was **69.362 ms vs 64.411 ms** (V3 time
-7.7% higher), and remains in the history rather than being replaced by the
-repeat's sample medians.
+### Presets
-The shared synthetic publisher-data pilot has incomplete comparator/answer
-evaluation; its literal-substring checks are not answer accuracy. The separate
-[partial answer-lookup evaluation](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/QUALITY-EVAL.json)
-also remains incomplete, with no overall quality score or qualified 90%
-comparability claim.
+| Preset | Behavior |
+| --- | --- |
+| `conservative` | Minification only; no restructuring of what the model sees. |
+| `balanced` (default) | Minification plus reversible columnar folding (`json_field_fold`, `json_value_dict`, `log_field_fold`) on eligible formats. |
+| `aggressive` | Same default transform set as `balanced` today. |
-Sources: [exact counts, timings, all repeat samples and refusals](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/COMPARISON.json),
-[validation](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/VALIDATION.json), and
-[full methodology](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md#benchmark-methodology).
-
+Provider message formats (`openai_json`, `anthropic_json`) use minification
+only; columnar folding applies to generic JSON (`--format json`). The default
+proxy path follows this rule. Explicit `--observations` enables lossless
+compression of eligible JSON tool-result strings on `/v1/chat/completions`
+without folding the provider envelope; see [observation compression](docs/configuration.md#restart-safe-observation-commitments).
-
-Historical Select v1 benchmarks (not v3 results)
+> [!NOTE]
+> `schema_compaction` is not enabled by any preset. Unlike the default
+> transforms, it truncates `examples` arrays and is not reversible.
-The original [Tokenfold Select v1][tokenfold-select-v1] model card reports the
-following literal-answer-retention results against Kompress-v2 and BM25.
-These are source-reported external results, not Core CI or v3 results.
+## Measured results
-| Tokens kept | Tokenfold Select | Kompress-v2 (Headroom) native | Kompress-v2 (Headroom) relevance | BM25 | vs. best baseline |
-| ---: | ---: | ---: | ---: | ---: | ---: |
-| 50% | **86.3%** | 66.5% | 80.5% | 79.4% | **+5.8 pp** |
-| 25% | **70.3%** | 47.2% | 61.5% | 60.7% | **+8.8 pp** |
-| 10% | **39.9%** | 30.4% | 37.7% | 37.7% | **+2.2 pp** |
+### SDK downstream-answer diagnostic
-In this v1 evaluation, Select beat every measured baseline at every budget.
-At a 25% budget, the fine-tuned ranker keeps the answer **70.3% of the time**:
-an **8.8 percentage-point** lead over the strongest baseline (Kompress-v2 relevance, 61.5%), and a
-**15.8% relative lift** over BM25 (60.7% -> 70.3%). Critical-content survival is
-**100% at every measured budget** through allocator force-keep. Results are
-three-seed repeated subsampling over roughly 73,000 training and 24,000
-held-out fixtures per run; the [v1 model card][tokenfold-select-v1] publishes the
-training recipe and full baseline set. Here, task success means the literal
-gold answer survived selection under the stated budget.
-These are source-reported external results, pinned by model revision in the
-[metric manifest](tests/fixtures/readme_metrics.json); Core CI does not reproduce them.
+On 2026-11-10, one free hosted model (`nvidia/nemotron-3.5-super-vl:free`,
+Nvidia provider) answered 12 predeclared tasks twice per arm, with counterbalanced
+order and exact typed-JSON grading. The 48 completed quality calls measured
+answers, not just whether answer text survived compression:
-See the [Select v1 model card][tokenfold-select-v1] for its setup, evaluation,
-training data, and limitations.
+| Path | Distinct tasks x trials | Baseline correct | Candidate correct | Provider prompt tokens |
+| --- | ---: | ---: | ---: | ---: |
+| Explicit folded JSON vs. compact JSON | 4 x 2 | 8/8 | **6/8** | 24,496 -> 16,600 (**32.2% fewer**) |
+| Select at a 50% rendered-text budget vs. full context | 8 x 2 | 16/16 | 16/16 | 5,706 -> 3,416 (**40.1% fewer**) |
-
+**Exact recovery did not guarantee correct model answers:** both folded-JSON
+failures misread the same nested API record's plan tier and seat count. Default
+SDK `Data` uses compact JSON; folding requires explicit opt-in. Select matched
+its baseline on these eight synthetic tasks, not a representative accuracy test.
+Repeated trials are not additional independent tasks; Select remains unqualified.
-
+The first model scope stopped on a rate-limited probe, with all 48 quality cells
+unexecuted; it is retained, not scored as 0% accuracy or silently retried.
+See the [full method, failures and limits](docs/sdk-benchmarks-0.6.0.md),
+[frozen prompts and oracles](eval/research/sdk_quality_corpus.json), and
+[all-attempt results](eval/research/sdk_quality_results.json).
-## Measured results
+### Lossless corpus counts
Exact `o200k_base` token counts, original input versus Tokenfold's lossless
output across the six-fixture Headroom corpus:
@@ -604,6 +601,106 @@ and [reproduction command](eval/research/README.md).
+### Tokenfold Select v3 benchmarks
+
+Saved results from the [published v3 benchmark snapshot](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md),
+pinned to model-card revision `317d3424d3de78c1a708c42a47a7812ab877f1a8`.
+These measurements include the scorer **and whole-group allocator**, not the
+scoring model alone. Core's lossless benchmarks are separate above.
+
+#### Context-token reduction at a 50% budget
+
+Select v3 removed **50.0-60.0%** of the original context tokens in these five
+saved development examples. Both models had the same exact `o200k_base` output
+cap for each workload; retained V3 groups were copied without rewriting.
+
+| Workload | Original tokens | Select v3 output | V3 reduction | Kompress v2 output |
+| --- | ---: | ---: | ---: | ---: |
+| Code | 4,411 | 2,205 | **50.0%** | 2,149 |
+| JSON | 1,303 | 651 | **50.0%** | Refused; 1,303 raw |
+| Logs | 1,103 | 503 | **54.4%** | Refused; 1,103 raw |
+| Multi-turn | 587 | 235 | **60.0%** | 284 |
+| Retrieval | 4,498 | 2,217 | **50.7%** | 2,219 |
+
+One exposed source per workload; JSON and logs share a source population.
+Token reduction does not establish answer accuracy or semantic preservation.
+Six of ten historical Kompress cells refused the budget across the 25%/50%
+screen; refusals and raw fallbacks are **inconclusive, not V3 wins**. The
+[full ten-cell history](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md#benchmark-methodology)
+retains every result.
+
+#### Resident-warm complete-request latency at a 50% budget
+
+| Workload | Select v3 ms | Kompress v2 ms | V3 time difference |
+| --- | ---: | ---: | ---: |
+| Code | 146.088 | 200.304 | -27.1% |
+| Retrieval | 139.291 | 201.564 | -30.9% |
+| Multi-turn | 66.572 | 77.751 | -14.4% |
+
+Resident-warm RTX 5080 research pipelines, FP32 parameters/BF16 compute;
+startup excluded. Code and retrieval each use one historical request per model;
+multi-turn uses the median of five. Separate time blocks, not controlled-idle or paired trials.
+These are descriptive development observations, **not representative quality, population p50/p95, or superiority qualification**.
+
+
+Benchmark methodology and preserved history
+
+RTX 5080, FP32 parameters/BF16 compute, cache off, TF32 off, one Torch thread.
+V3 used the serialized SDPA research runner; Kompress v2 used native EAGER.
+Complete-request clocks include grouping, counting, IPC, scoring, allocation,
+final recount and applicable teardown, but **exclude process/model startup and
+conditioning**. They are not cold-CLI or quickstart-SDK latency measurements.
+
+The models ran in separate time blocks. The five-request multi-turn repeat was
+not controlled-idle: the GPU-busy admission gate was explicitly waived, with
+pre-model busy observations of 25% and 38%. All five samples per model are
+retained. The earlier multi-turn result was **69.362 ms vs 64.411 ms** (V3 time
+7.7% higher), and remains in the history rather than being replaced by the
+repeat's sample medians.
+
+The shared synthetic publisher-data pilot has incomplete comparator/answer
+evaluation; its literal-substring checks are not answer accuracy. The separate
+[partial answer-lookup evaluation](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/QUALITY-EVAL.json)
+also remains incomplete, with no overall quality score or qualified 90%
+comparability claim.
+
+Sources: [exact counts, timings, all repeat samples and refusals](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/COMPARISON.json),
+[validation](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/VALIDATION.json), and
+[full methodology](https://huggingface.co/snchimata/tokenfold-select-v3/blob/317d3424d3de78c1a708c42a47a7812ab877f1a8/README.md#benchmark-methodology).
+
+
+
+Historical Select v1 benchmarks (not v3 results)
+
+The original [Tokenfold Select v1][tokenfold-select-v1] model card reports the
+following literal-answer-retention results against Kompress-v2 and BM25.
+These are source-reported external results, not Core CI or v3 results.
+
+| Tokens kept | Tokenfold Select | Kompress-v2 (Headroom) native | Kompress-v2 (Headroom) relevance | BM25 | vs. best baseline |
+| ---: | ---: | ---: | ---: | ---: | ---: |
+| 50% | **86.3%** | 66.5% | 80.5% | 79.4% | **+5.8 pp** |
+| 25% | **70.3%** | 47.2% | 61.5% | 60.7% | **+8.8 pp** |
+| 10% | **39.9%** | 30.4% | 37.7% | 37.7% | **+2.2 pp** |
+
+In this v1 evaluation, Select beat every measured baseline at every budget.
+At a 25% budget, the fine-tuned ranker keeps the answer **70.3% of the time**:
+an **8.8 percentage-point** lead over the strongest baseline (Kompress-v2 relevance, 61.5%), and a
+**15.8% relative lift** over BM25 (60.7% -> 70.3%). Critical-content survival is
+**100% at every measured budget** through allocator force-keep. Results are
+three-seed repeated subsampling over roughly 73,000 training and 24,000
+held-out fixtures per run; the [v1 model card][tokenfold-select-v1] publishes the
+training recipe and full baseline set. Here, task success means the literal
+gold answer survived selection under the stated budget.
+These are source-reported external results, pinned by model revision in the
+[metric manifest](tests/fixtures/readme_metrics.json); Core CI does not reproduce them.
+
+See the [Select v1 model card][tokenfold-select-v1] for its setup, evaluation,
+training data, and limitations.
+
+
+
+
+
## Extended tooling
These additional capabilities extend Core with recoverable pruning and an
@@ -624,7 +721,7 @@ pruning when strict context budgets apply:
| --- | --- | --- |
| **What it does** | Minifies, folds repeated keys into columns, and stores repeated values once | Adds deterministic ranking and retrieval markers for selected array rows |
| **Best on** | Uniform records, schemas, logs, diffs | Search results, mixed event feeds, agent traces, long arrays |
-| **Measured here** | **45.6-67.6%** fewer tokens on three bundled fixtures | **51.7-96.3%** fewer tokens (40-event feed at 51.7-68.2%; 100-row showcase at 96.3%) |
+| **Measured here** | **45.6-63.9%** fewer tokens on two versioned fixtures | **51.7-96.3%** fewer tokens (40-event feed at 51.7-68.2%; 100-row showcase at 96.3%) |
| **Recovery** | All data remains in the payload | Every emitted marker resolves through the local retrieval store |
@@ -691,8 +788,9 @@ tokenfold inspect examples/incident_feed.json --format json \
--prune --keep-ratio 0.35
```
-The same flags, and the same fail-closed contract, from Python and TypeScript.
-Use a throwaway store directory while experimenting and reuse it for retrieval:
+The same flags and fail-closed contract are available through the low-level
+bindings. Use a throwaway store directory while experimenting and reuse it for
+retrieval:
```python
import json
diff --git a/docs/assets/tokenfold-demo.gif b/docs/assets/tokenfold-demo.gif
index 648a5e969e155705be49a10ae2c46ba8d29b0f72..d34fa0fb6e672d76a282c8eec7d4f16be3e7292d 100644
GIT binary patch
literal 250039
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
H`%l61*fT8Et@rt-k;E*2?-=yuoXxm=lNJE>4l
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