headroom-ai 0.2.13__py3-none-any.whl

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.
Files changed (114) hide show
  1. headroom/__init__.py +212 -0
  2. headroom/cache/__init__.py +76 -0
  3. headroom/cache/anthropic.py +517 -0
  4. headroom/cache/base.py +342 -0
  5. headroom/cache/compression_feedback.py +613 -0
  6. headroom/cache/compression_store.py +814 -0
  7. headroom/cache/dynamic_detector.py +1026 -0
  8. headroom/cache/google.py +884 -0
  9. headroom/cache/openai.py +584 -0
  10. headroom/cache/registry.py +175 -0
  11. headroom/cache/semantic.py +451 -0
  12. headroom/ccr/__init__.py +77 -0
  13. headroom/ccr/context_tracker.py +582 -0
  14. headroom/ccr/mcp_server.py +319 -0
  15. headroom/ccr/response_handler.py +772 -0
  16. headroom/ccr/tool_injection.py +415 -0
  17. headroom/cli.py +219 -0
  18. headroom/client.py +977 -0
  19. headroom/compression/__init__.py +42 -0
  20. headroom/compression/detector.py +424 -0
  21. headroom/compression/handlers/__init__.py +22 -0
  22. headroom/compression/handlers/base.py +219 -0
  23. headroom/compression/handlers/code_handler.py +506 -0
  24. headroom/compression/handlers/json_handler.py +418 -0
  25. headroom/compression/masks.py +345 -0
  26. headroom/compression/universal.py +465 -0
  27. headroom/config.py +474 -0
  28. headroom/exceptions.py +192 -0
  29. headroom/integrations/__init__.py +159 -0
  30. headroom/integrations/agno/__init__.py +53 -0
  31. headroom/integrations/agno/hooks.py +345 -0
  32. headroom/integrations/agno/model.py +625 -0
  33. headroom/integrations/agno/providers.py +154 -0
  34. headroom/integrations/langchain/__init__.py +106 -0
  35. headroom/integrations/langchain/agents.py +326 -0
  36. headroom/integrations/langchain/chat_model.py +1002 -0
  37. headroom/integrations/langchain/langsmith.py +324 -0
  38. headroom/integrations/langchain/memory.py +319 -0
  39. headroom/integrations/langchain/providers.py +200 -0
  40. headroom/integrations/langchain/retriever.py +371 -0
  41. headroom/integrations/langchain/streaming.py +341 -0
  42. headroom/integrations/mcp/__init__.py +37 -0
  43. headroom/integrations/mcp/server.py +533 -0
  44. headroom/memory/__init__.py +37 -0
  45. headroom/memory/extractor.py +390 -0
  46. headroom/memory/fast_store.py +621 -0
  47. headroom/memory/fast_wrapper.py +311 -0
  48. headroom/memory/inline_extractor.py +229 -0
  49. headroom/memory/store.py +434 -0
  50. headroom/memory/worker.py +260 -0
  51. headroom/memory/wrapper.py +321 -0
  52. headroom/models/__init__.py +39 -0
  53. headroom/models/registry.py +687 -0
  54. headroom/parser.py +293 -0
  55. headroom/pricing/__init__.py +51 -0
  56. headroom/pricing/anthropic_prices.py +81 -0
  57. headroom/pricing/litellm_pricing.py +113 -0
  58. headroom/pricing/openai_prices.py +91 -0
  59. headroom/pricing/registry.py +188 -0
  60. headroom/providers/__init__.py +61 -0
  61. headroom/providers/anthropic.py +621 -0
  62. headroom/providers/base.py +131 -0
  63. headroom/providers/cohere.py +362 -0
  64. headroom/providers/google.py +427 -0
  65. headroom/providers/litellm.py +297 -0
  66. headroom/providers/openai.py +566 -0
  67. headroom/providers/openai_compatible.py +521 -0
  68. headroom/proxy/__init__.py +19 -0
  69. headroom/proxy/server.py +2683 -0
  70. headroom/py.typed +0 -0
  71. headroom/relevance/__init__.py +124 -0
  72. headroom/relevance/base.py +106 -0
  73. headroom/relevance/bm25.py +255 -0
  74. headroom/relevance/embedding.py +255 -0
  75. headroom/relevance/hybrid.py +259 -0
  76. headroom/reporting/__init__.py +5 -0
  77. headroom/reporting/generator.py +549 -0
  78. headroom/storage/__init__.py +41 -0
  79. headroom/storage/base.py +125 -0
  80. headroom/storage/jsonl.py +220 -0
  81. headroom/storage/sqlite.py +289 -0
  82. headroom/telemetry/__init__.py +91 -0
  83. headroom/telemetry/collector.py +764 -0
  84. headroom/telemetry/models.py +880 -0
  85. headroom/telemetry/toin.py +1579 -0
  86. headroom/tokenizer.py +80 -0
  87. headroom/tokenizers/__init__.py +75 -0
  88. headroom/tokenizers/base.py +210 -0
  89. headroom/tokenizers/estimator.py +198 -0
  90. headroom/tokenizers/huggingface.py +317 -0
  91. headroom/tokenizers/mistral.py +245 -0
  92. headroom/tokenizers/registry.py +398 -0
  93. headroom/tokenizers/tiktoken_counter.py +248 -0
  94. headroom/transforms/__init__.py +106 -0
  95. headroom/transforms/base.py +57 -0
  96. headroom/transforms/cache_aligner.py +357 -0
  97. headroom/transforms/code_compressor.py +1313 -0
  98. headroom/transforms/content_detector.py +335 -0
  99. headroom/transforms/content_router.py +1158 -0
  100. headroom/transforms/llmlingua_compressor.py +638 -0
  101. headroom/transforms/log_compressor.py +529 -0
  102. headroom/transforms/pipeline.py +297 -0
  103. headroom/transforms/rolling_window.py +350 -0
  104. headroom/transforms/search_compressor.py +365 -0
  105. headroom/transforms/smart_crusher.py +2682 -0
  106. headroom/transforms/text_compressor.py +259 -0
  107. headroom/transforms/tool_crusher.py +338 -0
  108. headroom/utils.py +215 -0
  109. headroom_ai-0.2.13.dist-info/METADATA +315 -0
  110. headroom_ai-0.2.13.dist-info/RECORD +114 -0
  111. headroom_ai-0.2.13.dist-info/WHEEL +4 -0
  112. headroom_ai-0.2.13.dist-info/entry_points.txt +2 -0
  113. headroom_ai-0.2.13.dist-info/licenses/LICENSE +190 -0
  114. headroom_ai-0.2.13.dist-info/licenses/NOTICE +43 -0
headroom/utils.py ADDED
@@ -0,0 +1,215 @@
1
+ """Shared utilities for Headroom SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ import re
8
+ import uuid
9
+ from datetime import datetime
10
+ from typing import Any
11
+
12
+ # Marker format for Headroom modifications
13
+ MARKER_PREFIX = "<headroom:"
14
+ MARKER_SUFFIX = ">"
15
+
16
+
17
+ def generate_request_id() -> str:
18
+ """Generate a unique request ID."""
19
+ return str(uuid.uuid4())
20
+
21
+
22
+ def compute_hash(data: str | bytes) -> str:
23
+ """Compute SHA256 hash, returning hex string."""
24
+ if isinstance(data, str):
25
+ data = data.encode("utf-8")
26
+ return hashlib.sha256(data).hexdigest()
27
+
28
+
29
+ def compute_short_hash(data: str | bytes, length: int = 16) -> str:
30
+ """Compute truncated SHA256 hash."""
31
+ return compute_hash(data)[:length]
32
+
33
+
34
+ def compute_messages_hash(messages: list[dict[str, Any]]) -> str:
35
+ """Compute hash of messages list for deduplication."""
36
+ # Serialize deterministically
37
+ serialized = json.dumps(messages, sort_keys=True, separators=(",", ":"))
38
+ return compute_short_hash(serialized)
39
+
40
+
41
+ def compute_prefix_hash(messages: list[dict[str, Any]], prefix_count: int | None = None) -> str:
42
+ """
43
+ Compute hash of message prefix for cache alignment.
44
+
45
+ Args:
46
+ messages: List of messages.
47
+ prefix_count: Number of messages to include (default: all system messages + 1).
48
+
49
+ Returns:
50
+ Hash of the prefix content.
51
+ """
52
+ if not messages:
53
+ return compute_short_hash("")
54
+
55
+ if prefix_count is None:
56
+ # Default: system messages + first non-system
57
+ prefix_count = 1
58
+ for i, msg in enumerate(messages):
59
+ if msg.get("role") == "system":
60
+ prefix_count = i + 2
61
+ else:
62
+ break
63
+
64
+ prefix_messages = messages[:prefix_count]
65
+ serialized = json.dumps(prefix_messages, sort_keys=True, separators=(",", ":"))
66
+ return compute_short_hash(serialized)
67
+
68
+
69
+ def format_timestamp(dt: datetime | None = None) -> str:
70
+ """Format datetime as ISO8601 string."""
71
+ if dt is None:
72
+ dt = datetime.utcnow()
73
+ return dt.isoformat() + "Z"
74
+
75
+
76
+ def parse_timestamp(ts: str) -> datetime:
77
+ """Parse ISO8601 timestamp string."""
78
+ # Handle both with and without Z suffix
79
+ ts = ts.rstrip("Z")
80
+ return datetime.fromisoformat(ts)
81
+
82
+
83
+ def create_marker(marker_type: str, **kwargs: Any) -> str:
84
+ """
85
+ Create a Headroom marker string.
86
+
87
+ Args:
88
+ marker_type: Type of marker (e.g., "tool_digest", "dropped_context").
89
+ **kwargs: Attributes to include in the marker.
90
+
91
+ Returns:
92
+ Formatted marker string.
93
+ """
94
+ attrs = " ".join(f'{k}="{v}"' for k, v in kwargs.items())
95
+ if attrs:
96
+ return f"{MARKER_PREFIX}{marker_type} {attrs}{MARKER_SUFFIX}"
97
+ return f"{MARKER_PREFIX}{marker_type}{MARKER_SUFFIX}"
98
+
99
+
100
+ def create_tool_digest_marker(original_hash: str) -> str:
101
+ """Create marker for crushed tool output."""
102
+ return create_marker("tool_digest", sha256=original_hash)
103
+
104
+
105
+ def create_dropped_context_marker(reason: str, count: int | None = None) -> str:
106
+ """Create marker for dropped context."""
107
+ if count is not None:
108
+ return create_marker("dropped_context", reason=reason, count=str(count))
109
+ return create_marker("dropped_context", reason=reason)
110
+
111
+
112
+ def create_truncated_marker(original_length: int, truncated_to: int) -> str:
113
+ """Create marker for truncated content."""
114
+ return create_marker(
115
+ "truncated",
116
+ original=str(original_length),
117
+ truncated_to=str(truncated_to),
118
+ )
119
+
120
+
121
+ def extract_markers(text: str) -> list[dict[str, Any]]:
122
+ """
123
+ Extract Headroom markers from text.
124
+
125
+ Returns:
126
+ List of dicts with marker_type and attributes.
127
+ """
128
+ pattern = re.compile(r"<headroom:(\w+)([^>]*)>")
129
+ markers = []
130
+
131
+ for match in pattern.finditer(text):
132
+ marker_type = match.group(1)
133
+ attrs_str = match.group(2).strip()
134
+
135
+ # Parse attributes
136
+ attrs: dict[str, str] = {}
137
+ if attrs_str:
138
+ attr_pattern = re.compile(r'(\w+)="([^"]*)"')
139
+ for attr_match in attr_pattern.finditer(attrs_str):
140
+ attrs[attr_match.group(1)] = attr_match.group(2)
141
+
142
+ markers.append({"type": marker_type, "attributes": attrs})
143
+
144
+ return markers
145
+
146
+
147
+ def safe_json_loads(text: str) -> tuple[Any | None, bool]:
148
+ """
149
+ Safely parse JSON, returning (result, success).
150
+
151
+ Args:
152
+ text: JSON string to parse.
153
+
154
+ Returns:
155
+ Tuple of (parsed_result or None, success_bool).
156
+ """
157
+ try:
158
+ return json.loads(text), True
159
+ except (json.JSONDecodeError, ValueError):
160
+ return None, False
161
+
162
+
163
+ def safe_json_dumps(obj: Any, **kwargs: Any) -> str:
164
+ """
165
+ Safely serialize to JSON with defaults.
166
+
167
+ Args:
168
+ obj: Object to serialize.
169
+ **kwargs: Additional json.dumps arguments.
170
+
171
+ Returns:
172
+ JSON string.
173
+ """
174
+ kwargs.setdefault("ensure_ascii", False)
175
+ kwargs.setdefault("separators", (",", ":")) # Compact by default
176
+ return json.dumps(obj, **kwargs)
177
+
178
+
179
+ def estimate_cost(
180
+ input_tokens: int,
181
+ output_tokens: int,
182
+ model: str,
183
+ cached_tokens: int = 0,
184
+ provider: Any = None,
185
+ ) -> float | None:
186
+ """
187
+ Estimate API cost in USD using provider.
188
+
189
+ Args:
190
+ input_tokens: Number of input tokens.
191
+ output_tokens: Number of output tokens.
192
+ model: Model name.
193
+ cached_tokens: Number of cached input tokens.
194
+ provider: Provider instance for cost estimation.
195
+
196
+ Returns:
197
+ Estimated cost in USD, or None if not available.
198
+ """
199
+ if provider is None:
200
+ return None
201
+ result = provider.estimate_cost(input_tokens, output_tokens, model, cached_tokens)
202
+ return float(result) if result is not None else None
203
+
204
+
205
+ def format_cost(cost: float) -> str:
206
+ """Format cost as human-readable string."""
207
+ if cost < 0.01:
208
+ return f"${cost:.4f}"
209
+ return f"${cost:.2f}"
210
+
211
+
212
+ def deep_copy_messages(messages: list[dict[str, Any]]) -> list[dict[str, Any]]:
213
+ """Create a deep copy of messages list."""
214
+ result: list[dict[str, Any]] = json.loads(json.dumps(messages))
215
+ return result
@@ -0,0 +1,315 @@
1
+ Metadata-Version: 2.4
2
+ Name: headroom-ai
3
+ Version: 0.2.13
4
+ Summary: The Context Optimization Layer for LLM Applications - Cut costs by 50-90%
5
+ Project-URL: Homepage, https://github.com/chopratejas/headroom
6
+ Project-URL: Documentation, https://github.com/chopratejas/headroom#readme
7
+ Project-URL: Repository, https://github.com/chopratejas/headroom
8
+ Project-URL: Issues, https://github.com/chopratejas/headroom/issues
9
+ Project-URL: Changelog, https://github.com/chopratejas/headroom/blob/main/CHANGELOG.md
10
+ Author: Headroom Contributors
11
+ Maintainer: Headroom Contributors
12
+ License-Expression: Apache-2.0
13
+ License-File: LICENSE
14
+ License-File: NOTICE
15
+ Keywords: ai,anthropic,caching,claude,compression,context,gpt,llm,machine-learning,openai,optimization,proxy,token
16
+ Classifier: Development Status :: 4 - Beta
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: License :: OSI Approved :: Apache Software License
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
25
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
26
+ Classifier: Typing :: Typed
27
+ Requires-Python: >=3.10
28
+ Requires-Dist: litellm>=1.0.0
29
+ Requires-Dist: openai>=2.14.0
30
+ Requires-Dist: pydantic>=2.0.0
31
+ Requires-Dist: sentence-transformers>=5.2.0
32
+ Requires-Dist: tiktoken>=0.5.0
33
+ Provides-Extra: agno
34
+ Requires-Dist: agno>=1.0.0; extra == 'agno'
35
+ Provides-Extra: all
36
+ Requires-Dist: fastapi>=0.100.0; extra == 'all'
37
+ Requires-Dist: httpx>=0.24.0; extra == 'all'
38
+ Requires-Dist: jinja2>=3.0.0; extra == 'all'
39
+ Requires-Dist: llmlingua>=0.2.0; extra == 'all'
40
+ Requires-Dist: numpy>=1.24.0; extra == 'all'
41
+ Requires-Dist: sentence-transformers>=2.2.0; extra == 'all'
42
+ Requires-Dist: torch>=2.0.0; extra == 'all'
43
+ Requires-Dist: transformers>=4.30.0; extra == 'all'
44
+ Requires-Dist: tree-sitter-language-pack>=0.10.0; extra == 'all'
45
+ Requires-Dist: uvicorn>=0.23.0; extra == 'all'
46
+ Provides-Extra: code
47
+ Requires-Dist: tree-sitter-language-pack>=0.10.0; extra == 'code'
48
+ Provides-Extra: dev
49
+ Requires-Dist: anthropic>=0.18.0; extra == 'dev'
50
+ Requires-Dist: langchain-ollama>=0.2.0; extra == 'dev'
51
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
52
+ Requires-Dist: ollama>=0.4.0; extra == 'dev'
53
+ Requires-Dist: openai>=1.0.0; extra == 'dev'
54
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
55
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
56
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
57
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
58
+ Provides-Extra: llmlingua
59
+ Requires-Dist: llmlingua>=0.2.0; extra == 'llmlingua'
60
+ Requires-Dist: torch>=2.0.0; extra == 'llmlingua'
61
+ Requires-Dist: transformers>=4.30.0; extra == 'llmlingua'
62
+ Provides-Extra: proxy
63
+ Requires-Dist: fastapi>=0.100.0; extra == 'proxy'
64
+ Requires-Dist: httpx>=0.24.0; extra == 'proxy'
65
+ Requires-Dist: uvicorn>=0.23.0; extra == 'proxy'
66
+ Provides-Extra: relevance
67
+ Requires-Dist: numpy>=1.24.0; extra == 'relevance'
68
+ Requires-Dist: sentence-transformers>=2.2.0; extra == 'relevance'
69
+ Provides-Extra: reports
70
+ Requires-Dist: jinja2>=3.0.0; extra == 'reports'
71
+ Description-Content-Type: text/markdown
72
+
73
+ <p align="center">
74
+ <h1 align="center">Headroom</h1>
75
+ <p align="center">
76
+ <strong>The Context Optimization Layer for LLM Applications</strong>
77
+ </p>
78
+ <p align="center">
79
+ Cut your LLM costs by 50-90% without losing accuracy
80
+ </p>
81
+ </p>
82
+
83
+ <p align="center">
84
+ <a href="https://github.com/chopratejas/headroom/actions/workflows/ci.yml">
85
+ <img src="https://github.com/chopratejas/headroom/actions/workflows/ci.yml/badge.svg" alt="CI">
86
+ </a>
87
+ <a href="https://pypi.org/project/headroom-ai/">
88
+ <img src="https://img.shields.io/pypi/v/headroom-ai.svg" alt="PyPI">
89
+ </a>
90
+ <a href="https://pypi.org/project/headroom-ai/">
91
+ <img src="https://img.shields.io/pypi/pyversions/headroom-ai.svg" alt="Python">
92
+ </a>
93
+ <a href="https://github.com/chopratejas/headroom/blob/main/LICENSE">
94
+ <img src="https://img.shields.io/badge/license-Apache%202.0-blue.svg" alt="License">
95
+ </a>
96
+ </p>
97
+
98
+
99
+ ---
100
+
101
+ ## Why Headroom?
102
+
103
+ - **Zero code changes** - works as a transparent proxy
104
+ - **50-90% cost savings** - verified on real workloads
105
+ - **Reversible compression** - LLM retrieves original data via CCR
106
+ - **Content-aware** - code, logs, JSON each handled optimally
107
+ - **Provider caching** - automatic prefix optimization for cache hits
108
+ - **Persistent memory** - remember across conversations with zero-latency extraction
109
+ - **Framework native** - LangChain, Agno, MCP, agents supported
110
+
111
+ ---
112
+
113
+ ## Headroom vs Alternatives
114
+
115
+ | Approach | Token Reduction | Accuracy | Reversible | Latency |
116
+ |----------|-----------------|----------|------------|---------|
117
+ | **Headroom** | 50-90% | No loss | Yes (CCR) | ~1-5ms |
118
+ | Truncation | Variable | Data loss | No | ~0ms |
119
+ | Summarization | 60-80% | Lossy | No | ~500ms+ |
120
+ | No optimization | 0% | Full | N/A | 0ms |
121
+
122
+ **Headroom wins** because it intelligently selects relevant content while keeping a retrieval path to the original data.
123
+
124
+ ---
125
+
126
+ ## 30-Second Quickstart
127
+
128
+ ### Option 1: Proxy (Zero Code Changes)
129
+
130
+ ```bash
131
+ pip install "headroom-ai[proxy]"
132
+ headroom proxy --port 8787
133
+ ```
134
+
135
+ Point your tools at the proxy:
136
+
137
+ ```bash
138
+ # Claude Code
139
+ ANTHROPIC_BASE_URL=http://localhost:8787 claude
140
+
141
+ # Any OpenAI-compatible client
142
+ OPENAI_BASE_URL=http://localhost:8787/v1 cursor
143
+ ```
144
+
145
+ ### Option 2: LangChain Integration
146
+
147
+ ```bash
148
+ pip install "headroom-ai[langchain]"
149
+ ```
150
+
151
+ ```python
152
+ from langchain_openai import ChatOpenAI
153
+ from headroom.integrations import HeadroomChatModel
154
+
155
+ # Wrap your model - that's it!
156
+ llm = HeadroomChatModel(ChatOpenAI(model="gpt-4o"))
157
+
158
+ # Use exactly like before
159
+ response = llm.invoke("Hello!")
160
+ ```
161
+
162
+ See the full [LangChain Integration Guide](docs/langchain.md) for memory, retrievers, agents, and more.
163
+
164
+ ### Option 3: Agno Integration
165
+
166
+ ```bash
167
+ pip install "headroom-ai[agno]"
168
+ ```
169
+
170
+ ```python
171
+ from agno.agent import Agent
172
+ from agno.models.openai import OpenAIChat
173
+ from headroom.integrations.agno import HeadroomAgnoModel
174
+
175
+ # Wrap your model - that's it!
176
+ model = HeadroomAgnoModel(OpenAIChat(id="gpt-4o"))
177
+ agent = Agent(model=model)
178
+
179
+ # Use exactly like before
180
+ response = agent.run("Hello!")
181
+
182
+ # Check savings
183
+ print(f"Tokens saved: {model.total_tokens_saved}")
184
+ ```
185
+
186
+ See the full [Agno Integration Guide](docs/agno.md) for hooks, multi-provider support, and more.
187
+
188
+ ---
189
+
190
+ ## Framework Integrations
191
+
192
+ | Framework | Integration | Docs |
193
+ |-----------|-------------|------|
194
+ | **LangChain** | `HeadroomChatModel`, memory, retrievers, agents | [Guide](docs/langchain.md) |
195
+ | **Agno** | `HeadroomAgnoModel`, hooks, multi-provider | [Guide](docs/agno.md) |
196
+ | **MCP** | Tool output compression for Claude | [Guide](docs/ccr.md) |
197
+ | **Any OpenAI Client** | Proxy server | [Guide](docs/proxy.md) |
198
+
199
+ ---
200
+
201
+ ## Features
202
+
203
+ | Feature | Description | Docs |
204
+ |---------|-------------|------|
205
+ | **Memory** | Persistent memory across conversations (zero-latency inline extraction) | [Memory](docs/memory.md) |
206
+ | **Universal Compression** | ML-based content detection + structure-preserving compression | [Compression](docs/compression.md) |
207
+ | **SmartCrusher** | Compresses JSON tool outputs statistically | [Transforms](docs/transforms.md) |
208
+ | **CacheAligner** | Stabilizes prefixes for provider caching | [Transforms](docs/transforms.md) |
209
+ | **RollingWindow** | Manages context limits without breaking tools | [Transforms](docs/transforms.md) |
210
+ | **CCR** | Reversible compression with automatic retrieval | [CCR Guide](docs/ccr.md) |
211
+ | **LangChain** | Memory, retrievers, agents, streaming | [LangChain](docs/langchain.md) |
212
+ | **Agno** | Agent framework integration with hooks | [Agno](docs/agno.md) |
213
+ | **Text Utilities** | Opt-in compression for search/logs | [Text Compression](docs/text-compression.md) |
214
+ | **LLMLingua-2** | ML-based 20x compression (opt-in) | [LLMLingua](docs/llmlingua.md) |
215
+ | **Code-Aware** | AST-based code compression (tree-sitter) | [Transforms](docs/transforms.md) |
216
+
217
+ ---
218
+
219
+ ## Performance
220
+
221
+ | Scenario | Before | After | Savings |
222
+ |----------|--------|-------|---------|
223
+ | Search results (1000 items) | 45,000 tokens | 4,500 tokens | 90% |
224
+ | Log analysis (500 entries) | 22,000 tokens | 3,300 tokens | 85% |
225
+ | Long conversation (50 turns) | 80,000 tokens | 32,000 tokens | 60% |
226
+ | Agent with tools (10 calls) | 100,000 tokens | 15,000 tokens | 85% |
227
+
228
+ **Overhead**: ~1-5ms per request
229
+
230
+ ---
231
+
232
+ ## Providers
233
+
234
+ | Provider | Token Counting | Cache Optimization |
235
+ |----------|----------------|-------------------|
236
+ | OpenAI | tiktoken (exact) | Automatic prefix caching |
237
+ | Anthropic | Official API | cache_control blocks |
238
+ | Google | Official API | Context caching |
239
+ | Cohere | Official API | - |
240
+ | Mistral | Official tokenizer | - |
241
+
242
+ New models auto-supported via naming pattern detection.
243
+
244
+ ---
245
+
246
+ ## Safety Guarantees
247
+
248
+ - **Never removes human content** - user/assistant messages preserved
249
+ - **Never breaks tool ordering** - tool calls and responses stay paired
250
+ - **Parse failures are no-ops** - malformed content passes through unchanged
251
+ - **Compression is reversible** - LLM retrieves original data via CCR
252
+
253
+ ---
254
+
255
+ ## Installation
256
+
257
+ ```bash
258
+ pip install headroom-ai # SDK only
259
+ pip install "headroom-ai[proxy]" # Proxy server
260
+ pip install "headroom-ai[langchain]" # LangChain integration
261
+ pip install "headroom-ai[agno]" # Agno agent framework
262
+ pip install "headroom-ai[code]" # AST-based code compression
263
+ pip install "headroom-ai[llmlingua]" # ML-based compression
264
+ pip install "headroom-ai[all]" # Everything
265
+ ```
266
+
267
+ **Requirements**: Python 3.10+
268
+
269
+ ---
270
+
271
+ ## Documentation
272
+
273
+ | Guide | Description |
274
+ |-------|-------------|
275
+ | [Memory Guide](docs/memory.md) | Persistent memory for LLMs |
276
+ | [Compression Guide](docs/compression.md) | Universal compression with ML detection |
277
+ | [LangChain Integration](docs/langchain.md) | Full LangChain support |
278
+ | [Agno Integration](docs/agno.md) | Full Agno agent framework support |
279
+ | [SDK Guide](docs/sdk.md) | Fine-grained control |
280
+ | [Proxy Guide](docs/proxy.md) | Production deployment |
281
+ | [Configuration](docs/configuration.md) | All options |
282
+ | [CCR Guide](docs/ccr.md) | Reversible compression |
283
+ | [Metrics](docs/metrics.md) | Monitoring |
284
+ | [Troubleshooting](docs/troubleshooting.md) | Common issues |
285
+
286
+ ---
287
+
288
+ ## Who's Using Headroom?
289
+
290
+ > Add your project here! [Open a PR](https://github.com/chopratejas/headroom/pulls) or [start a discussion](https://github.com/chopratejas/headroom/discussions).
291
+
292
+ ---
293
+
294
+ ## Contributing
295
+
296
+ ```bash
297
+ git clone https://github.com/chopratejas/headroom.git
298
+ cd headroom
299
+ pip install -e ".[dev]"
300
+ pytest
301
+ ```
302
+
303
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
304
+
305
+ ---
306
+
307
+ ## License
308
+
309
+ Apache License 2.0 - see [LICENSE](LICENSE).
310
+
311
+ ---
312
+
313
+ <p align="center">
314
+ <sub>Built for the AI developer community</sub>
315
+ </p>
@@ -0,0 +1,114 @@
1
+ headroom/__init__.py,sha256=xpDRSbZmqivOrMN_dU7YAD4d5-E9_0ybAbwn3HR8Ieo,5091
2
+ headroom/cli.py,sha256=vqy5qd2J4A0DKRsFs4ceWQgfY6ttTR--H9f179XtiVg,6571
3
+ headroom/client.py,sha256=ow8Jg4pZQz25D2YnsMgk79BzvnsyUjFwGhPp_dcgEBk,36058
4
+ headroom/config.py,sha256=OU4DmOaLZnsio9CC8wfJuwwpQpOJjQJ_SSyAhOk3WYM,18099
5
+ headroom/exceptions.py,sha256=5vKZLgra36R4zOPrCl272iAaoNh4hAYr7q85kAhHs0c,4431
6
+ headroom/parser.py,sha256=wMY4_tZYgTrZCuI-XwNiORRlT-LJyie5s7QOa1q17b4,9097
7
+ headroom/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ headroom/tokenizer.py,sha256=CKwqJWt7o7AO8DsCrGvR7zzK3_yb-2YvgA2FUhMPSBE,2149
9
+ headroom/utils.py,sha256=DZLbBaI7E5nE_7nr0SYEwVX0ANo45D-MD9YkAPHT0r4,6087
10
+ headroom/cache/__init__.py,sha256=858lq533p9NrRdnq7ZXNloumXqCpumGOod-YT5tcPAY,2111
11
+ headroom/cache/anthropic.py,sha256=hbn1ijxx8JaSP3k0tQitZ0_gfC7R14hIqMQj4vuHP68,19039
12
+ headroom/cache/base.py,sha256=_pZ5p7FVK_DFa24CtoJ6KnUwQqICNBiCmWGonecq7vA,9581
13
+ headroom/cache/compression_feedback.py,sha256=4NpnGCrfkJoIDwdBNZVFXuZJTo7PLWyBBd-C4Q_I1sY,22519
14
+ headroom/cache/compression_store.py,sha256=-C0x40x2UEJHXVJcW_sfWzF5ekFyJ0LdcjDMmHxwW8M,31372
15
+ headroom/cache/dynamic_detector.py,sha256=7YZc8BFT1q9J-wX6D2ITkFV6pZnICfEe8yxYrDB7lE0,33517
16
+ headroom/cache/google.py,sha256=PyIG6StV_VRQvKdyfwX-CTkTrSCabx6VtEOJ03Bc1Wo,28910
17
+ headroom/cache/openai.py,sha256=bSZ2qZLr5wXVgcCdCX107ao5cOmYRI6hi0kwYVw3cao,21108
18
+ headroom/cache/registry.py,sha256=NrSGyv-WdzUcR24WzPw28nVdF-FFe65fGXXI4JnFW3E,5238
19
+ headroom/cache/semantic.py,sha256=iaSd44SQ-n7ajDgDqNuq_ZuYwgTD11meB6JHTuwlICA,13320
20
+ headroom/ccr/__init__.py,sha256=8Ii9-t0R9KcVKOucYDpWMO0LAe55oPKIVaLdG-mQgik,2182
21
+ headroom/ccr/context_tracker.py,sha256=Obq9gmbRaUYlk5a-I0oaGDUWn9PVySciUGRyrfXiz2A,18318
22
+ headroom/ccr/mcp_server.py,sha256=-ID1nRvEX7jyCdn1-iE2r6vwaNZGvPqJHjjWU0_6tDo,9893
23
+ headroom/ccr/response_handler.py,sha256=KpXC2wAEL8KkuThosjefg1bzuxbIDM1z-3QTU4_5mpc,26917
24
+ headroom/ccr/tool_injection.py,sha256=wSro_HSEwxbQ-Q7gS1pUdiS5LK3jU81HRot_kCFU57I,14527
25
+ headroom/compression/__init__.py,sha256=1_E_SyKnrcsuVqYQjVt10oZRWicv40zH6wSAnpSWCtI,1174
26
+ headroom/compression/detector.py,sha256=33GRUi8PZQrGyCIC-eDXB4YeA1I4sPE1OhylqXycjWA,11426
27
+ headroom/compression/masks.py,sha256=nkWAFhlYnIKw5P1DF76v-CO3MyMfxWmja2X73PVwtnM,10746
28
+ headroom/compression/universal.py,sha256=akYpmNoirw99RDf_RCiJfiZ5hLE8nTmhxmClbWcweKw,15052
29
+ headroom/compression/handlers/__init__.py,sha256=j7JdxabNfC1Ew9exuQaDwp25j95t6cVtu-qbIjnUdww,694
30
+ headroom/compression/handlers/base.py,sha256=pZ8rl4G1P02bm82CWJ0cPKqebIIgp6BnP4N1u1OlkKc,6173
31
+ headroom/compression/handlers/code_handler.py,sha256=CFf9JVzL6fyDZFuSZqdtvfyS-3QYe9nwxjtXyyHdH1k,16401
32
+ headroom/compression/handlers/json_handler.py,sha256=emevNLyBY3PDscsq_Rf5OtRiLr-dpU5-Z6jRwaM5r9Y,14057
33
+ headroom/integrations/__init__.py,sha256=Djgvi9XKkzKNhlVZw9LBH_Mc4fMLozQgFEmY2A3pXH4,4599
34
+ headroom/integrations/agno/__init__.py,sha256=mbVIm6DE28bjr3XeXg2clMIXOu5Tr1Qf52D1XbH_S2w,1372
35
+ headroom/integrations/agno/hooks.py,sha256=LG8TS6PFofI5OCzhqf4bYmEelV1lmexYdFWIwteKhsg,11451
36
+ headroom/integrations/agno/model.py,sha256=4IsXB_Hkm1gscMfr3lJOZLUJafqkO31vzQpj5togNRk,24076
37
+ headroom/integrations/agno/providers.py,sha256=1L9ub4PuHJJlaZObGjPV8AaZtq-Ht_EyKqjhqW2Mp10,5603
38
+ headroom/integrations/langchain/__init__.py,sha256=8jJBq0vx7TFvRppph-sbsupZR4WYyFXM5fsaC6GXpYI,2785
39
+ headroom/integrations/langchain/agents.py,sha256=e09sQKJoa2BRuNukoUeiv6ONT2nlbZ6C3o6GQQwosPI,10353
40
+ headroom/integrations/langchain/chat_model.py,sha256=enFdd-ZxMCOWbwgS2-3Hxk5EMH5S0ekfGLbjPk0MRwM,35822
41
+ headroom/integrations/langchain/langsmith.py,sha256=fbfDQ6bG2psB7D56PXr3kp6sAoNmV5B6jWUq5dsUg8Y,10183
42
+ headroom/integrations/langchain/memory.py,sha256=PwjuFoP6PVJ8w6V1Ige8GmPCzmlD3QDLCYyhC13qZUI,10972
43
+ headroom/integrations/langchain/providers.py,sha256=1XEShnlqnhawJ2_S8kXsEW7bdRnI9uYveVxcTP3Xt-E,6655
44
+ headroom/integrations/langchain/retriever.py,sha256=8nqSVJzoE8qg5fTmEr3rIhfgpgz6QKUF70xru9HWUTw,12545
45
+ headroom/integrations/langchain/streaming.py,sha256=G24xbopZIQo7d_mLJ9U40Q4DIzYCuamYERC1VpGzSsI,10092
46
+ headroom/integrations/mcp/__init__.py,sha256=aVVYXRR5PGo-2xI2sRAVnEuvqX1EchiPavVUTnzaIbE,931
47
+ headroom/integrations/mcp/server.py,sha256=sFiSzy1GhhyRlpzsodLqwogZfIWP-Osrn-jGHF1rO_g,17525
48
+ headroom/memory/__init__.py,sha256=puPyG1afrnUQP2wA9cGx5mCLqcutRrbrDc5RgYbGDXI,1123
49
+ headroom/memory/extractor.py,sha256=T2juKQiUTuYQo14Ag6dlZwmm0k8NCaTmB6UcFY579yU,12281
50
+ headroom/memory/fast_store.py,sha256=WnQvYLTizqYRvuTGPBjVTa75XJxsrmf_0TmwxxPyWrk,20153
51
+ headroom/memory/fast_wrapper.py,sha256=JYp7TPVoWGyJqXuRGoFn_L2Sp4Fu0JEs34PR2KdOofE,10119
52
+ headroom/memory/inline_extractor.py,sha256=GAyrBTKkiqtyEaZlcK0foenMBOsMlC7FYqGOSG226VY,6833
53
+ headroom/memory/store.py,sha256=rAAUBOsJIGvIRwu-hRag01Np5plPlQRtiPa-frc2r2k,13883
54
+ headroom/memory/worker.py,sha256=keHNw0tx3feU29HH0ckBnNeSd8oL2fIfAkRUgAyQD70,8480
55
+ headroom/memory/wrapper.py,sha256=lJFZxytrKR1GX5qmYUET9AmHosR_odHOgJ7041IJ9x0,9817
56
+ headroom/models/__init__.py,sha256=3rVSXirBE6PMW0Al3JkCNF2Wj8pPvIhyWlYd_kySdKs,873
57
+ headroom/models/registry.py,sha256=59f40DlSohYzYfciEgAfMuft2GnMvXurtrbamxB8aD4,20350
58
+ headroom/pricing/__init__.py,sha256=CZO-2VFXArMlQBance_rS6MOWV2zu0PjWmxoxkfIqF8,1359
59
+ headroom/pricing/anthropic_prices.py,sha256=Xu39m-ui4AVNt4IT9tJkEvbbe5ED9xi7NSe5AHGDr7I,2526
60
+ headroom/pricing/litellm_pricing.py,sha256=ldVEYG8FecRir9TFjfnGsgcdAf1YsMrjfmtWhjpTI_Y,3232
61
+ headroom/pricing/openai_prices.py,sha256=bseLDWG-fnad_Kp2LVtizKsThWQ475M6y7ilM6cFtV0,2573
62
+ headroom/pricing/registry.py,sha256=wCLKpzapRNrYKhnzgdm5vH6n7gQb1A16YvqXN4qz6rA,6344
63
+ headroom/providers/__init__.py,sha256=L66dA13RcxjpEoj9-2iautoJHBK6AYpqcES1gw3qK6w,1707
64
+ headroom/providers/anthropic.py,sha256=c4yT86mzZ9_eJq6RzNz2_obIdconV11cW1fRr33L8bE,23820
65
+ headroom/providers/base.py,sha256=R_BmRjeNZcPaY2in7f5fqKXqQz059eLfU5yjHzFrzm8,3195
66
+ headroom/providers/cohere.py,sha256=TIxn7Dnjr8Wmref6V9pjl1D7GqEh8-lrgcxPd37eTu4,11368
67
+ headroom/providers/google.py,sha256=2M8YXswMaUp5E6e07svnwQpbuY83Pkk2eT3XGXzj83E,14643
68
+ headroom/providers/litellm.py,sha256=JIsAcYUpg12QfJhQKkRKmNcjcwOgtU_AjIjwQaB0NFc,9398
69
+ headroom/providers/openai.py,sha256=-scxYB1nNFzhkqnEG2jRAt6zfo1p9zMRknuyYh4GyBg,19807
70
+ headroom/providers/openai_compatible.py,sha256=xki1h6lJU7EvkcJ0tDUoUGwH3JXN_eoFJtzB5UlINQ0,14154
71
+ headroom/proxy/__init__.py,sha256=4YsySyHYWD5UgpJtTnFOHBiNrE-VaKrz32nBlk84FWk,511
72
+ headroom/proxy/server.py,sha256=WIQELkFA8oMV5jGixYiscdjuTWMdIilYMLE5P_wKDOg,105249
73
+ headroom/relevance/__init__.py,sha256=yCTJAgzWHjDCHfj5-lmRMPaskJ5_lPsLZ4JxwH3P6e8,3784
74
+ headroom/relevance/base.py,sha256=ZQNM_Qrjf4H9rt3xiyB4LEyies6FGmUNd6VxJrgflAA,3198
75
+ headroom/relevance/bm25.py,sha256=-C0svaUTPvNZWMicZWh3BWnxyboUS2ueS9IsPHnRhLU,7976
76
+ headroom/relevance/embedding.py,sha256=PNg2CMrzq_A9zuAV-1lHmSatEJ2xGIg0GA5KM_-dDFk,7603
77
+ headroom/relevance/hybrid.py,sha256=PMmWGzqhpqM7cftiwJ1EcV23tT52UJ-u5bmknvbj_kA,9306
78
+ headroom/reporting/__init__.py,sha256=xsv9DswXQeYw7UuX8V8joIHI5dbhHNVTMDYKYtJ_naw,112
79
+ headroom/reporting/generator.py,sha256=d9S1Kcz1zUamdKonLBvzslK7PvNxarWIg72gE-nvs0M,17469
80
+ headroom/storage/__init__.py,sha256=Cp3wbeesr_BTn0d27urJlotySYvv5KsqM70buJZJCpE,1002
81
+ headroom/storage/base.py,sha256=wJZ5Q71XNbYEc9nknkOEdTJZ8riesA0rIuvNONj74pA,3090
82
+ headroom/storage/jsonl.py,sha256=bzrvZ4_ACIn9aagG6whByU9aCEy3HBmpvL5ejE-_mcg,7787
83
+ headroom/storage/sqlite.py,sha256=ilb3x_1zrenPNYRuKzRGdVM_APTDLnlQqsi4DK5Bv5E,10015
84
+ headroom/telemetry/__init__.py,sha256=Bn_BS-q13Tp3S-XXhqXGcE-W11HCOxY9jKZcgWQT_dc,2184
85
+ headroom/telemetry/collector.py,sha256=DEZqRmtQloTmPVSC43LXScS4xiXgTJMT3GD0NPCKFl8,28606
86
+ headroom/telemetry/models.py,sha256=eMyE1QXEXJ9M58EFcWrBMkKERBYDrmDc2LUjd_0-z1A,34651
87
+ headroom/telemetry/toin.py,sha256=xTcJ-k9x7WJ4MnwntfPyFSb78SObkDv0OsHHLj3IkfE,67905
88
+ headroom/tokenizers/__init__.py,sha256=20Enzr5VjhyHho7k4jigCadKxeeRQcqLBRJ282mfvh8,2030
89
+ headroom/tokenizers/base.py,sha256=yKEX5wLGYmY_p8lU80bgfXSOjcQBD1CA97zSHzlcw9Y,6752
90
+ headroom/tokenizers/estimator.py,sha256=7My8MiULg2xNAHiKdg3ZiFUagNIH7tIBIoe4MyaO8K0,6010
91
+ headroom/tokenizers/huggingface.py,sha256=qhJ0sHEfo-tdmFD2Yi9cN4d2RCaCngW4vYxWOxqMIe4,9838
92
+ headroom/tokenizers/mistral.py,sha256=alLAIAhGYm4uT43UaVE3Y1j5Tp2pCn5XtRKRI9L7BEE,7155
93
+ headroom/tokenizers/registry.py,sha256=G5TiaFhkqFehf9G3WLLzu8Z9RKFvwW06j-yGlagY6og,12314
94
+ headroom/tokenizers/tiktoken_counter.py,sha256=GSdRV-KB1ThFz49xOATfNIm7BwrE8sURaj9I_VCnKII,8283
95
+ headroom/transforms/__init__.py,sha256=v6PANKEreOPSUvIJfe1ZRI2tjmwneNfusL2pojDeJxg,2839
96
+ headroom/transforms/base.py,sha256=5QTe-O3Db8NgVWMU9B8L152QE3ImOg1-mZRkeDglmSM,1418
97
+ headroom/transforms/cache_aligner.py,sha256=138I-ikdvOJ4fDGf7nqpy7ZfcBJsgpD0DvvrGqSWaWM,12369
98
+ headroom/transforms/code_compressor.py,sha256=z9RHj6L0nocAiINf2Swu7_gke26bmy0KuclOxCrcbpI,47525
99
+ headroom/transforms/content_detector.py,sha256=H9jtV3nOqcePR_FZt2Bcf-fMWMrADgImQlIRiCNU8lM,10421
100
+ headroom/transforms/content_router.py,sha256=O4HxpnBRg1VRwnV5oswH8dv_OFt0ZtjFdCBnhslQqMc,40733
101
+ headroom/transforms/llmlingua_compressor.py,sha256=kwYpbKjpm3SAQy4fY5y4Nb3r0nyfQpbFor3Y_PKkxHI,22530
102
+ headroom/transforms/log_compressor.py,sha256=I1741IoafdEQ9DPPS5hBpSnQa7n3aQlzi1th2WQgXqU,17152
103
+ headroom/transforms/pipeline.py,sha256=U877fTvcMA8lAKHgJvDn6krd474QU2Qit2vDnBa4l7g,10391
104
+ headroom/transforms/rolling_window.py,sha256=alunXwaUgqT7np-QNvE531qglrvLn9I94zC8naJUZJw,11345
105
+ headroom/transforms/search_compressor.py,sha256=3ZeBZMlpuvCpeZtQpBqSRlQcIiPrG6vwuIJobgENtHY,11679
106
+ headroom/transforms/smart_crusher.py,sha256=BnLXyqO-_gPOw5s8N7S3QqxHltVqLrpnax6ZSHvQX8Q,107390
107
+ headroom/transforms/text_compressor.py,sha256=vJcjv-7hQlR_KPSyU_m0xgpTnyYRfTglCwmhdG50V9c,8438
108
+ headroom/transforms/tool_crusher.py,sha256=yA9wUHy9Zs1RxVJq4ldeIBGW_nG_0tNwR-IKaN-qxcM,11210
109
+ headroom_ai-0.2.13.dist-info/METADATA,sha256=ik1K3AfrCZcW_HWphLs3Noly7Kw75ESTxgdOoMVSC0U,10853
110
+ headroom_ai-0.2.13.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
111
+ headroom_ai-0.2.13.dist-info/entry_points.txt,sha256=aJkYI5-izD3UFi07BK4FgQXmPaMftTTDSsta8LxeA9o,47
112
+ headroom_ai-0.2.13.dist-info/licenses/LICENSE,sha256=8U3UQMjjFStNTTJGFd6CUd2wEdyB9ITarQtpAgk1Ocw,10770
113
+ headroom_ai-0.2.13.dist-info/licenses/NOTICE,sha256=i_mkOhEsx5Z3tI4kbQ6KYOBbYC30-FHxxMeS5b5RhBs,1237
114
+ headroom_ai-0.2.13.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ headroom = headroom.cli:main