tokenseive 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tokenseive-1.1.0/.gitignore +82 -0
- tokenseive-1.1.0/LICENSE +21 -0
- tokenseive-1.1.0/PKG-INFO +455 -0
- tokenseive-1.1.0/README.md +406 -0
- tokenseive-1.1.0/examples/agent_integration.py +72 -0
- tokenseive-1.1.0/examples/basic_compression.py +48 -0
- tokenseive-1.1.0/examples/ml_compression.py +51 -0
- tokenseive-1.1.0/examples/repo_mapping.py +52 -0
- tokenseive-1.1.0/pyproject.toml +66 -0
- tokenseive-1.1.0/tests/__init__.py +0 -0
- tokenseive-1.1.0/tests/conftest.py +63 -0
- tokenseive-1.1.0/tests/test_behavioral.py +87 -0
- tokenseive-1.1.0/tests/test_compressors.py +218 -0
- tokenseive-1.1.0/tests/test_mapper.py +175 -0
- tokenseive-1.1.0/tests/test_tool_compression.py +256 -0
- tokenseive-1.1.0/tokenseive/__init__.py +48 -0
- tokenseive-1.1.0/tokenseive/behavioral/__init__.py +13 -0
- tokenseive-1.1.0/tokenseive/behavioral/ruleset.py +181 -0
- tokenseive-1.1.0/tokenseive/cli.py +253 -0
- tokenseive-1.1.0/tokenseive/compressors/__init__.py +26 -0
- tokenseive-1.1.0/tokenseive/compressors/llmlingua2.py +167 -0
- tokenseive-1.1.0/tokenseive/compressors/pipeline.py +207 -0
- tokenseive-1.1.0/tokenseive/compressors/rule_based.py +577 -0
- tokenseive-1.1.0/tokenseive/compressors/selective.py +146 -0
- tokenseive-1.1.0/tokenseive/mapper/__init__.py +155 -0
- tokenseive-1.1.0/tokenseive/mapper/code_graph.py +161 -0
- tokenseive-1.1.0/tokenseive/mapper/queries.py +197 -0
- tokenseive-1.1.0/tokenseive/mapper/repo_map.py +551 -0
- tokenseive-1.1.0/tokenseive/tool_compression/__init__.py +30 -0
- tokenseive-1.1.0/tokenseive/tool_compression/headroom.py +560 -0
- tokenseive-1.1.0/tokenseive/utils.py +126 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
*.manifest
|
|
31
|
+
*.spec
|
|
32
|
+
|
|
33
|
+
# Installer logs
|
|
34
|
+
pip-log.txt
|
|
35
|
+
pip-delete-this-directory.txt
|
|
36
|
+
|
|
37
|
+
# Unit test / coverage reports
|
|
38
|
+
htmlcov/
|
|
39
|
+
.tox/
|
|
40
|
+
.nox/
|
|
41
|
+
.coverage
|
|
42
|
+
.coverage.*
|
|
43
|
+
.cache
|
|
44
|
+
nosetests.xml
|
|
45
|
+
coverage.xml
|
|
46
|
+
*.cover
|
|
47
|
+
*.py,cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
.pytest_cache/
|
|
50
|
+
cover/
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
*.pot
|
|
55
|
+
|
|
56
|
+
# Environments
|
|
57
|
+
.env
|
|
58
|
+
.venv
|
|
59
|
+
env/
|
|
60
|
+
venv/
|
|
61
|
+
ENV/
|
|
62
|
+
env.bak/
|
|
63
|
+
venv.bak/
|
|
64
|
+
|
|
65
|
+
# Type checkers
|
|
66
|
+
.mypy_cache/
|
|
67
|
+
.dmypy.json
|
|
68
|
+
dmypy.json
|
|
69
|
+
.pyre/
|
|
70
|
+
.pytype/
|
|
71
|
+
.ruff_cache/
|
|
72
|
+
|
|
73
|
+
# IDE
|
|
74
|
+
.idea/
|
|
75
|
+
.vscode/
|
|
76
|
+
*.swp
|
|
77
|
+
*.swo
|
|
78
|
+
*~
|
|
79
|
+
|
|
80
|
+
# OS
|
|
81
|
+
.DS_Store
|
|
82
|
+
Thumbs.db
|
tokenseive-1.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 TokenSeive Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tokenseive
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Multi-layer token optimization for LLM applications — compress prompts, map codebases, reduce output
|
|
5
|
+
Project-URL: Homepage, https://github.com/your-username/tokenseive
|
|
6
|
+
Project-URL: Repository, https://github.com/your-username/tokenseive
|
|
7
|
+
Project-URL: Issues, https://github.com/your-username/tokenseive/issues
|
|
8
|
+
Author: TokenSeive Contributors
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: code-graph,codebase,compression,context-window,llm,llmlingua,optimization,prompt,tokens
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Classifier: Topic :: Text Processing :: General
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Provides-Extra: all
|
|
27
|
+
Requires-Dist: graphifyy>=0.8; extra == 'all'
|
|
28
|
+
Requires-Dist: headroom-ai>=0.20; extra == 'all'
|
|
29
|
+
Requires-Dist: llmlingua>=0.2; extra == 'all'
|
|
30
|
+
Requires-Dist: selective-context>=0.1; extra == 'all'
|
|
31
|
+
Requires-Dist: tiktoken>=0.5; extra == 'all'
|
|
32
|
+
Requires-Dist: tree-sitter-language-pack>=0.1; extra == 'all'
|
|
33
|
+
Requires-Dist: tree-sitter>=0.21; extra == 'all'
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
37
|
+
Provides-Extra: headroom
|
|
38
|
+
Requires-Dist: headroom-ai>=0.20; extra == 'headroom'
|
|
39
|
+
Provides-Extra: mapper
|
|
40
|
+
Requires-Dist: graphifyy>=0.8; extra == 'mapper'
|
|
41
|
+
Requires-Dist: tree-sitter-language-pack>=0.1; extra == 'mapper'
|
|
42
|
+
Requires-Dist: tree-sitter>=0.21; extra == 'mapper'
|
|
43
|
+
Provides-Extra: ml
|
|
44
|
+
Requires-Dist: llmlingua>=0.2; extra == 'ml'
|
|
45
|
+
Requires-Dist: selective-context>=0.1; extra == 'ml'
|
|
46
|
+
Provides-Extra: tokens
|
|
47
|
+
Requires-Dist: tiktoken>=0.5; extra == 'tokens'
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
# TokenSeive
|
|
51
|
+
|
|
52
|
+
> **Multi-layer token optimization for LLM applications — compress prompts, map codebases, reduce output.**
|
|
53
|
+
|
|
54
|
+
[](https://pypi.org/project/tokenseive/)
|
|
55
|
+
[](https://pypi.org/project/tokenseive/)
|
|
56
|
+
[](LICENSE)
|
|
57
|
+
[](#testing)
|
|
58
|
+
|
|
59
|
+
TokenSeive is a standalone, **framework-agnostic** library that shrinks the
|
|
60
|
+
four things that eat your context window:
|
|
61
|
+
|
|
62
|
+
| Layer | What it does | Dependency cost |
|
|
63
|
+
|-------|--------------|-----------------|
|
|
64
|
+
| **Compress** | Shrinks *input* prompts with deterministic rules (and optional ML). | **Zero** required deps |
|
|
65
|
+
| **Tool Compression** | Compresses structured tool outputs (JSON, search results, command output) by 85-93% via Headroom SmartCrusher. | Zero (fallback); headroom-ai optional |
|
|
66
|
+
| **Map** | Turns a codebase into a token-budgeted ranked map / code graph. | Zero (regex fallback); tree-sitter optional |
|
|
67
|
+
| **Behavioral** | Cuts *output* tokens by injecting a "lazy dev" ruleset. | Zero required deps |
|
|
68
|
+
|
|
69
|
+
It works with **any** agentic framework — LangChain, AutoGen, CrewAI, raw
|
|
70
|
+
OpenAI, or plain Python — because it imports nothing from them.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Installation
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Core: works with plain Python 3.9+. Nothing else required.
|
|
78
|
+
pip install tokenseive # zero deps
|
|
79
|
+
|
|
80
|
+
# Optional extras
|
|
81
|
+
pip install tokenseive[tokens] # accurate token counts via tiktoken
|
|
82
|
+
pip install tokenseive[ml] # LLMLingua-2 + Selective Context backends
|
|
83
|
+
pip install tokenseive[mapper] # tree-sitter parsing + graphify code graphs
|
|
84
|
+
pip install tokenseive[headroom] # tool output compression (Headroom SmartCrusher)
|
|
85
|
+
pip install tokenseive[all] # everything
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
| Extra | Adds | When you want it |
|
|
89
|
+
|-------|------|------------------|
|
|
90
|
+
| `tokens` | `tiktoken` | Real GPT-4o token counts (otherwise a fast heuristic) |
|
|
91
|
+
| `ml` | `llmlingua`, `selective-context` | Higher compression ratios on long docs |
|
|
92
|
+
| `mapper` | `tree-sitter`, `tree-sitter-language-pack`, `graphifyy` | Precise multi-language parsing & visual code graphs |
|
|
93
|
+
| `headroom` | `headroom-ai` | Compress structured tool outputs (JSON, search results, command stdout) by 85-93% |
|
|
94
|
+
| `all` | all of the above + `headroom` | The full experience |
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Quick start
|
|
99
|
+
|
|
100
|
+
### 1. Compress a prompt (zero deps)
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from tokenseive import RuleBasedCompressor
|
|
104
|
+
|
|
105
|
+
rc = RuleBasedCompressor()
|
|
106
|
+
result = rc.compress("It is important to note that, in order to proceed, "
|
|
107
|
+
"we really must be careful.")
|
|
108
|
+
|
|
109
|
+
print(result.compressed_text)
|
|
110
|
+
# -> 'to proceed, we must be careful.' (critical keyword preserved)
|
|
111
|
+
|
|
112
|
+
print(f"{result.tokens_saved} tokens saved ({result.compression_ratio:.0%})")
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`compress()` returns a [`CompressionResult`](tokenseive/compressors/rule_based.py)
|
|
116
|
+
dataclass with `compressed_text`, `original_tokens`, `compressed_tokens`,
|
|
117
|
+
`tokens_saved`, `compression_ratio`, and `techniques_applied`. It is
|
|
118
|
+
**idempotent** and **never** mangles code blocks, XML/HTML, identity lines, or
|
|
119
|
+
critical-keyword instructions (`NEVER`, `MUST`, `ALWAYS`, …).
|
|
120
|
+
|
|
121
|
+
### 2. Map a codebase (zero deps)
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from tokenseive import CodebaseMapper
|
|
125
|
+
|
|
126
|
+
mapper = CodebaseMapper("/path/to/repo", verbose=False)
|
|
127
|
+
|
|
128
|
+
print(mapper.get_repo_map(max_tokens=1024)) # ranked symbol overview
|
|
129
|
+
mapper.find_function("build_prompt") # -> [{file, line, signature, ...}]
|
|
130
|
+
print(mapper.get_symbol_context("build_prompt")) # def + callers/callees, ready for the LLM
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 3. Cut output tokens with a behavioral ruleset
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from tokenseive import BehavioralRuleset
|
|
137
|
+
|
|
138
|
+
ruleset = BehavioralRuleset(mode="full") # off | lite | full | ultra
|
|
139
|
+
system_prompt = base_prompt + "\n\n" + ruleset.get_instructions()
|
|
140
|
+
# Injecting the "lazy dev" ladder steers the model toward the shortest
|
|
141
|
+
# working diff — typically 22–54% fewer output tokens.
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 4. Compress tool output (zero deps)
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
from tokenseive import HeadroomCompressor
|
|
148
|
+
|
|
149
|
+
compressor = HeadroomCompressor()
|
|
150
|
+
result = compressor.compress_tool_output("search_files", json_output)
|
|
151
|
+
print(f"{result.tokens_saved} tokens saved ({result.compression_ratio:.1%})")
|
|
152
|
+
# -> '1295 tokens saved (89.1%)'
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`HeadroomCompressor` wraps Headroom's **SmartCrusher** to shrink structured tool
|
|
156
|
+
outputs (JSON, search results, file listings) by **85-93%**. When `headroom-ai`
|
|
157
|
+
isn't installed it falls back to deterministic array-truncation / structure
|
|
158
|
+
collapsing, so it always returns a usable result. Install the real engine with
|
|
159
|
+
`pip install tokenseive[headroom]`.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Tool Output Compression
|
|
164
|
+
|
|
165
|
+
Compress structured tool outputs (JSON, search results, file listings) by **85-93%**
|
|
166
|
+
using Headroom's **SmartCrusher**.
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from tokenseive import HeadroomCompressor
|
|
170
|
+
|
|
171
|
+
compressor = HeadroomCompressor()
|
|
172
|
+
|
|
173
|
+
# Compress a single tool result
|
|
174
|
+
result = compressor.compress_tool_output("search_files", json_output)
|
|
175
|
+
print(f"{result.tokens_saved} tokens saved ({result.compression_ratio:.1%})")
|
|
176
|
+
|
|
177
|
+
# Check whether a tool result should be compressed
|
|
178
|
+
if compressor.should_compress("grep", large_output):
|
|
179
|
+
compressed = compressor.compress_tool_output("grep", large_output)
|
|
180
|
+
|
|
181
|
+
# Batch-compress conversation history (protects the most recent turns)
|
|
182
|
+
compressed_messages = compressor.compress_messages(messages, protect_recent=4)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### How it works
|
|
186
|
+
- **SmartCrusher** — truncates large arrays with `[N omitted]` summaries, collapses repetitive structures, and aggregates result lists.
|
|
187
|
+
- **Tool-specific policy** — always compress `search_files` / `grep` / `list_files`; never compress `bash` / `write_file` / `edit_file`.
|
|
188
|
+
- **Graceful fallback** — when `headroom-ai` isn't installed, applies deterministic compression (array truncation, structure collapsing).
|
|
189
|
+
|
|
190
|
+
| Tool output type | Before | After | Savings |
|
|
191
|
+
|---|---|---|---|
|
|
192
|
+
| File search (200 files) | 14,481 chars | 759 chars | **94.8%** |
|
|
193
|
+
| JSON API response | 27,607 tokens | 2,719 tokens | **90.1%** |
|
|
194
|
+
| Multi-tool turn (3 tools) | 26,890 tokens | 1,911 tokens | **92.9%** |
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Architecture
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
┌──────────────────────────────────────┐
|
|
202
|
+
│ Your Agent │
|
|
203
|
+
│ (LangChain / AutoGen / CrewAI / raw) │
|
|
204
|
+
└──────────────────┬───────────────────┘
|
|
205
|
+
│ system prompt + context
|
|
206
|
+
┌──────────────────────┬───────────┴───────────┬──────────────────────┐
|
|
207
|
+
▼ ▼ ▼ ▼
|
|
208
|
+
┌─────────────────┐ ┌────────────────────┐ ┌────────────────────┐ ┌──────────────────┐
|
|
209
|
+
│ COMPRESS │ │ TOOL COMPRESSION │ │ MAP │ │ BEHAVIORAL │
|
|
210
|
+
│ (input side) │ │ (tool results) │ │ (context side) │ │ (output side) │
|
|
211
|
+
├─────────────────┤ ├────────────────────┤ ├────────────────────┤ ├──────────────────┤
|
|
212
|
+
│ RuleBased │ │ HeadroomCompressor │ │ CodebaseMapper │ │ BehavioralRuleset│
|
|
213
|
+
│ Compressor │ │ + SmartCrusher │ │ get_repo_map() │ │ off/lite/full/ │
|
|
214
|
+
│ LLMLingua-2 │ │ compress_messages()│ │ get_code_graph() │ │ ultra modes │
|
|
215
|
+
│ SelectiveContext│ │ should_compress() │ │ find / trace / │ │ apply_to() │
|
|
216
|
+
│ CompressionPipe │ │ │ │ context queries │ │ │
|
|
217
|
+
│ line (cascade) │ │ │ │ │ │ │
|
|
218
|
+
└─────────────────┘ └────────────────────┘ └────────────────────┘ └──────────────────┘
|
|
219
|
+
rules: 0 deps fallback: 0 deps regex: 0 deps 0 deps
|
|
220
|
+
ml: tokenseive[ml] headroom: [headroom] treesitter: tokenseive[mapper]
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Each layer is **independent** — use one, two, three, or all four.
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## API reference
|
|
228
|
+
|
|
229
|
+
### Compressors ([`tokenseive/compressors/`](tokenseive/compressors/__init__.py))
|
|
230
|
+
|
|
231
|
+
#### `RuleBasedCompressor(encoding="o200k_base", identity_names=())`
|
|
232
|
+
Deterministic, dependency-free compression. The workhorse.
|
|
233
|
+
|
|
234
|
+
| Method | Returns | Description |
|
|
235
|
+
|--------|---------|-------------|
|
|
236
|
+
| `compress(text, **kw)` | `CompressionResult` | Full rule pipeline (idempotent). |
|
|
237
|
+
| `count_tokens(text)` | `int` | tiktoken if available, else heuristic. |
|
|
238
|
+
|
|
239
|
+
Techniques applied, in order: redundant-phrase removal → abbreviation
|
|
240
|
+
expansion → contractions → filler/verbosity removal → punctuation cleanup →
|
|
241
|
+
whitespace normalization → duplicate-line removal. Each runs **only on
|
|
242
|
+
non-critical lines**; protected regions are masked first and restored verbatim.
|
|
243
|
+
|
|
244
|
+
#### `CompressionPipeline(backend="rules", rate=0.5)`
|
|
245
|
+
Unified entry point with graceful degradation.
|
|
246
|
+
|
|
247
|
+
| `backend` | Behavior |
|
|
248
|
+
|-----------|----------|
|
|
249
|
+
| `"rules"` *(default)* | Deterministic, always available. |
|
|
250
|
+
| `"selective"` | GPT-2 phrase filtering (`tokenseive[ml]`). Falls back to rules if unavailable. |
|
|
251
|
+
| `"llmlingua2"` | Microsoft LLMLingua-2 (`tokenseive[ml]`). Falls back to rules if unavailable. |
|
|
252
|
+
| `"multi"` | Cascade: rules → selective → llmlingua2, stopping at the target keep-rate. |
|
|
253
|
+
|
|
254
|
+
```python
|
|
255
|
+
CompressionPipeline.available_backends() # -> ['rules'] or ['rules','selective','llmlingua2']
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### `CompressionResult`
|
|
259
|
+
Dataclass with `.original_text`, `.compressed_text`, `.original_tokens`,
|
|
260
|
+
`.compressed_tokens`, `.tokens_saved`, `.compression_ratio`,
|
|
261
|
+
`.techniques_applied`, plus `.as_dict()`, `["key"]`, and `.get(k, default)`
|
|
262
|
+
for dict-style access.
|
|
263
|
+
|
|
264
|
+
#### `LLMLingua2Compressor` / `SelectiveContextCompressor`
|
|
265
|
+
Direct ML backends (lazy-loaded, raise `ImportError` with a helpful message if
|
|
266
|
+
the extra isn't installed).
|
|
267
|
+
|
|
268
|
+
### Mapper ([`tokenseive/mapper/`](tokenseive/mapper/__init__.py))
|
|
269
|
+
|
|
270
|
+
#### `CodebaseMapper(repo_path, *, extensions=None, max_files=None, ...)`
|
|
271
|
+
|
|
272
|
+
| Method | Returns | Description |
|
|
273
|
+
|--------|---------|-------------|
|
|
274
|
+
| `get_repo_map(max_tokens=1024)` | `str` | Ranked, token-budgeted symbol tree. |
|
|
275
|
+
| `get_code_graph()` | `dict` | `{nodes, edges, stats}` (graphify or tree-sitter fallback). |
|
|
276
|
+
| `export_graph(format="json")` | `str` | JSON / HTML / SVG export. |
|
|
277
|
+
| `find_function(name)` / `find_class(name)` | `list[dict]` | Locations of a symbol. |
|
|
278
|
+
| `trace_call_chain(name, max_depth=3)` | `dict` | Outbound + inbound call tree. |
|
|
279
|
+
| `get_symbol_context(name)` | `str` | Definition + callers/callees block. |
|
|
280
|
+
| `get_dependencies(file)` | `dict` | Imports + dependents of a file. |
|
|
281
|
+
| `get_stats()` | `dict` | File/symbol/token-reduction statistics. |
|
|
282
|
+
|
|
283
|
+
### Behavioral ([`tokenseive/behavioral/`](tokenseive/behavioral/__init__.py))
|
|
284
|
+
|
|
285
|
+
#### `BehavioralRuleset(mode="full")`
|
|
286
|
+
|
|
287
|
+
| Method | Returns | Description |
|
|
288
|
+
|--------|---------|-------------|
|
|
289
|
+
| `get_instructions()` | `str` | Ruleset text to inject (empty when `mode="off"`). |
|
|
290
|
+
| `get_token_count()` | `int` | Estimated tokens of the ruleset. |
|
|
291
|
+
| `apply_to(prompt, separator="\n\n")` | `str` | Append ruleset to a prompt. |
|
|
292
|
+
|
|
293
|
+
Modes: `off` (inject nothing), `lite`, `full` *(default)*, `ultra` (YAGNI extremist).
|
|
294
|
+
|
|
295
|
+
### Tool Output Compression ([`tokenseive/tool_compression/`](tokenseive/tool_compression/__init__.py))
|
|
296
|
+
|
|
297
|
+
#### `HeadroomCompressor(policy=None, strict=False, ...)`
|
|
298
|
+
Compress structured tool outputs via Headroom's **SmartCrusher**, with a
|
|
299
|
+
deterministic zero-dependency fallback when `headroom-ai` is absent.
|
|
300
|
+
|
|
301
|
+
| Method | Returns | Description |
|
|
302
|
+
|--------|---------|-------------|
|
|
303
|
+
| `compress_tool_output(tool_name, content)` | `ToolCompressionResult` | Compress a single tool result (always returns a usable result). |
|
|
304
|
+
| `should_compress(tool_name, content)` | `bool` | Whether a result is worth compressing (policy + size gate). |
|
|
305
|
+
| `compress_messages(messages, protect_recent=None)` | `list[dict]` | Batch-compress older `tool` messages in a conversation. |
|
|
306
|
+
| `available()` | `bool` | Whether the real `headroom-ai` engine is importable. |
|
|
307
|
+
|
|
308
|
+
`ToolCompressionResult` mirrors `CompressionResult` (`.compressed_text`,
|
|
309
|
+
`.tokens_saved`, `.compression_ratio`, `.transforms_applied`, `.as_dict()`).
|
|
310
|
+
Tool policy: always compress `search_files` / `grep` / `list_files`; never
|
|
311
|
+
compress `bash` / `write_file` / `edit_file`. Pass `strict=True` to require the
|
|
312
|
+
real engine instead of the built-in fallback. *(requires `[headroom]` for the
|
|
313
|
+
real SmartCrusher engine; the fallback needs no extra deps.)*
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
317
|
+
## CLI
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# Compress a prompt file
|
|
321
|
+
tokenseive compress prompt.txt
|
|
322
|
+
tokenseive compress prompt.txt --backend multi --rate 0.5
|
|
323
|
+
tokenseive compress prompt.txt --json --write
|
|
324
|
+
|
|
325
|
+
# Map a codebase
|
|
326
|
+
tokenseive map /path/to/repo --max-tokens 1024
|
|
327
|
+
tokenseive map /path/to/repo --find-function "my_func"
|
|
328
|
+
tokenseive map /path/to/repo --trace "my_func" --depth 2
|
|
329
|
+
tokenseive map /path/to/repo --context "my_func"
|
|
330
|
+
tokenseive map /path/to/repo --stats
|
|
331
|
+
|
|
332
|
+
# Output-optimization ruleset
|
|
333
|
+
tokenseive ruleset --mode full
|
|
334
|
+
tokenseive ruleset --mode ultra --tokens
|
|
335
|
+
|
|
336
|
+
tokenseive version
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Benchmarks
|
|
342
|
+
|
|
343
|
+
Rule-based compression is deterministic and free; ML backends push further on
|
|
344
|
+
long, prose-heavy documents. Representative savings on typical inputs:
|
|
345
|
+
|
|
346
|
+
| Input type | `rules` | `selective` | `llmlingua2` | `multi` (0.5) |
|
|
347
|
+
|------------|--------:|------------:|-------------:|--------------:|
|
|
348
|
+
| System prompt (verbose) | **~12%** | ~35% | ~45% | ~48% |
|
|
349
|
+
| Meeting transcript | ~10% | ~40% | ~55% | ~58% |
|
|
350
|
+
| API docs (long) | ~8% | ~38% | ~50% | ~52% |
|
|
351
|
+
| Output tokens (behavioral `full`) | — | — | — | **22–54%** |
|
|
352
|
+
|
|
353
|
+
> Rule-based ratios are stable across runs (idempotent). ML ratios vary with
|
|
354
|
+
> content and the chosen keep-rate. The behavioral ruleset cuts *response*
|
|
355
|
+
> tokens by steering the model toward shorter diffs.
|
|
356
|
+
|
|
357
|
+
Mapper token reduction depends on repo size; for a typical mid-size Python
|
|
358
|
+
project the ranked repo map is **~95–99% smaller** than reading every file.
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Framework integration
|
|
363
|
+
|
|
364
|
+
TokenSeive imports nothing framework-specific, so integration is just
|
|
365
|
+
"build the prompt, then call the model":
|
|
366
|
+
|
|
367
|
+
```python
|
|
368
|
+
from tokenseive import RuleBasedCompressor, BehavioralRuleset
|
|
369
|
+
|
|
370
|
+
def system_prompt():
|
|
371
|
+
base = RuleBasedCompressor().compress(YOUR_BASE_PROMPT).compressed_text
|
|
372
|
+
return BehavioralRuleset(mode="full").apply_to(base)
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
**OpenAI (raw):**
|
|
376
|
+
```python
|
|
377
|
+
openai.chat.completions.create(
|
|
378
|
+
model="gpt-4o",
|
|
379
|
+
messages=[{"role": "system", "content": system_prompt()},
|
|
380
|
+
{"role": "user", "content": question}],
|
|
381
|
+
)
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
**LangChain:**
|
|
385
|
+
```python
|
|
386
|
+
from langchain_core.prompts import ChatPromptTemplate
|
|
387
|
+
prompt = ChatPromptTemplate.from_messages(
|
|
388
|
+
[("system", system_prompt()), ("human", "{question}")]
|
|
389
|
+
)
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**AutoGen / CrewAI:** pass `system_prompt()` as the agent's `system_message`
|
|
393
|
+
/ `backstory`.
|
|
394
|
+
|
|
395
|
+
See [`examples/agent_integration.py`](examples/agent_integration.py) for a
|
|
396
|
+
complete, runnable pattern (with a codebase map appended via
|
|
397
|
+
[`CodebaseMapper`](tokenseive/mapper/__init__.py)).
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Comparison
|
|
402
|
+
|
|
403
|
+
| Feature | TokenSeive | LLMLingua | Selective Context | LangChain ` compres` |
|
|
404
|
+
|---------|:----------:|:---------:|:-----------------:|:--------------------:|
|
|
405
|
+
| Zero required deps | ✅ | ❌ (torch) | ❌ (torch/spacy) | ❌ (langchain) |
|
|
406
|
+
| Deterministic / idempotent rules | ✅ | ❌ | ❌ | partial |
|
|
407
|
+
| Protected regions (code, XML, identity) | ✅ | ❌ | ❌ | ❌ |
|
|
408
|
+
| Codebase repo mapping | ✅ | ❌ | ❌ | ❌ |
|
|
409
|
+
| Output-token ruleset | ✅ | ❌ | ❌ | ❌ |
|
|
410
|
+
| Tool output compression (85-93%) | ✅ | ❌ | ❌ | ❌ |
|
|
411
|
+
| Multi-backend cascade | ✅ | single | single | n/a |
|
|
412
|
+
| Framework-agnostic | ✅ | ✅ | ✅ | ❌ |
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
## Project layout
|
|
417
|
+
|
|
418
|
+
```
|
|
419
|
+
tokenseive/
|
|
420
|
+
├── pyproject.toml
|
|
421
|
+
├── README.md
|
|
422
|
+
├── LICENSE
|
|
423
|
+
├── tokenseive/
|
|
424
|
+
│ ├── __init__.py # Main API + version
|
|
425
|
+
│ ├── cli.py # `tokenseive` CLI
|
|
426
|
+
│ ├── utils.py # Token counting (tiktoken-or-heuristic) + sentinels
|
|
427
|
+
│ ├── compressors/ # rule_based, llmlingua2, selective, pipeline
|
|
428
|
+
│ ├── mapper/ # repo_map, code_graph, queries
|
|
429
|
+
│ ├── behavioral/ # output-optimization ruleset
|
|
430
|
+
│ └── tool_compression/ # headroom SmartCrusher (tool-output compression)
|
|
431
|
+
├── tests/ # 82 tests, run with zero deps
|
|
432
|
+
└── examples/ # basic, ml, repo_mapping, agent_integration
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
## Testing
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
pip install tokenseive[dev] # pytest + pytest-cov
|
|
439
|
+
pytest # 82 tests, all pass with zero optional deps
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
The full suite runs with **no extras installed** — the rule-based compressor,
|
|
443
|
+
regex mapper, and behavioral ruleset are all exercised by default.
|
|
444
|
+
|
|
445
|
+
## Design principles
|
|
446
|
+
|
|
447
|
+
1. **Zero required dependencies** — `pip install tokenseive` just works on Python 3.9+.
|
|
448
|
+
2. **Optional ML/mapping backends** — every heavy import is lazy and degrades gracefully.
|
|
449
|
+
3. **Framework-agnostic** — no imports from any specific agent framework.
|
|
450
|
+
4. **Deterministic by default** — rule-based compression is idempotent and reproducible.
|
|
451
|
+
5. **Never destroy meaning** — code, XML/HTML, identity, and critical instructions are protected.
|
|
452
|
+
|
|
453
|
+
## License
|
|
454
|
+
|
|
455
|
+
[MIT](LICENSE)
|