Commit graph

100 commits

Author SHA1 Message Date
chopratejas
e306d6b338 Bump version to 0.5.25 for PyPI release
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 16:32:13 -07:00
chopratejas
b3a73641a0 Bump to 0.5.24 2026-04-12 09:17:49 -07:00
chopratejas
af3cd7f07f Fix #149: memory crash in Docker — missing vector index + pthread error
Three fixes for Docker-native install with --memory:

1. Add sqlite-vec to proxy extras — memory's vector index now installs
   with pip install headroom-ai[proxy]. No separate pip install needed.

2. Fix AUTO vector backend fallback — was: SQLITE_VEC → HNSW → crash.
   Now: SQLITE_VEC → HNSW → clear error message listing install options.

3. Fix ONNX pthread_setaffinity_np error in Docker containers — set
   intra/inter thread count to 1 in SessionOptions. Prevents the
   "Invalid argument" error on containers with limited CPU affinity.
2026-04-12 09:17:27 -07:00
chopratejas
ccc763a7b0 Bump version to 0.5.23 2026-04-11 19:45:08 -07:00
chopratejas
00a6ab2dee Bump version to 0.5.22 2026-04-11 19:32:53 -07:00
chopratejas
3c0c540e1b Auto-download codebase-memory-mcp binary, add watchdog to proxy deps
No manual install needed. headroom wrap claude --code-graph:
1. Checks if binary exists (PATH or ~/.local/bin/)
2. Downloads from GitHub releases if not found (~15MB, one-time)
3. Indexes project + starts file watcher

Same pattern as rtk auto-download. Platform-aware:
darwin-arm64, darwin-amd64, linux-arm64, linux-amd64, windows-amd64.

Also: add watchdog>=4.0.0 to proxy extras.
2026-04-11 19:30:38 -07:00
chopratejas
1fee4ac8fd Revert version to 0.5.21, fix changelog header to 0.5.22 2026-04-11 11:05:10 -07:00
chopratejas
0f7f7b0f69 Release v0.6.0: cross-agent memory, plugin learn, code graph 2026-04-11 10:44:27 -07:00
JerrettDavis
a1beb08d53 feat: add reproducible devcontainers
Add a default devcontainer and a compose-backed memory-stack profile, validate them in CI, and document the contributor workflow.

Also lock the memory-stack dependencies, pin related container tooling, and sync the latest healthcheck shutdown fix for stubbed memory handlers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-10 12:58:35 -05:00
JerrettDavis
ebd482c0a0 feat: add OTEL observability core
Add a shared observability layer for OTEL metrics and Langfuse tracing.
Instrument the shared compression pipeline once so SDK and proxy paths can
reuse the same metrics and spans without scattering telemetry concerns.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-09 21:20:34 -05:00
chopratejas
65e4a35546 Add OCR routing via RapidOCR + measure actual tokens after compression
Transcode technique now runs RapidOCR to extract text from images.
Falls back to full_low if OCR confidence < 70% or no text detected.

Token counting is now done AFTER compression by measuring the actual
output — no hardcoded estimates. OCR text counted by char length,
resized images re-estimated from new dimensions.

RapidOCR added to headroom-ai[image] extra (~15MB ONNX models, ~180ms CPU).
4 new OCR tests (extraction, blank image, confidence threshold, full pipeline).
29 total image compression tests passing.
2026-04-09 16:22:18 -07:00
chopratejas
c52b0f1e57 Add sentencepiece to image extra — required by SigLIP tokenizer (#103)
SiglipTokenizer from transformers hard-requires sentencepiece at runtime.
Without it, the image router silently falls back to PRESERVE (no compression).
Users on pip install headroom-ai[image] or [all] were missing this dependency.
2026-04-08 11:33:28 -07:00
chopratejas
9c51f63c48 Bump to v0.5.21 2026-04-08 10:31:32 -07:00
Tejas Chopra
8bb1b1ea14 chore: bump version to 0.5.20 2026-04-07 17:30:14 -07:00
JerrettDavis
78163199c4 Merge upstream/main into feat/extended-cache-ttl-metrics 2026-04-06 21:59:46 -05:00
chopratejas
9cca08139f Bump to v0.5.19: cache stats fixes, Codex WS fix, compression-vs-cache tracking
v0.5.19 includes:
- Fix Codex WebSocket HTTP 500: ChatGPT auth routing to chatgpt.com,
  correct beta header, HTTP POST streaming fallback
- Token-level cache hit rate (not binary per-request)
- Compression-vs-cache tracking: tokens_saved vs cache_bust_tokens per session
- Pass uncached_input_tokens for OpenAI and Gemini handlers
- Fix async test failures in test_proxy_scalability
2026-04-06 18:17:13 -07:00
JerrettDavis
0a8254d629 Remove obsolete Ruff UP038 ignore to stabilize CI lint output 2026-04-04 15:02:04 -05:00
JerrettDavis
7d02829f02 Harden Anthropic prefix cache stability across proxy and batch paths 2026-04-04 13:45:37 -05:00
chopratejas
e8ab444f09 Refactor: split server.py into handler mixins (Steps 5-9)
server.py: 8778 → 2343 lines (73% reduction)

HeadroomProxy now inherits from 5 handler mixins:
- StreamingMixin (901 lines): SSE parsing, streaming, response relay
- AnthropicHandlerMixin (1435 lines): /v1/messages, batch API
- OpenAIHandlerMixin (1320 lines): /v1/chat/completions, /v1/responses, WebSocket
- GeminiHandlerMixin (649 lines): Gemini native API
- BatchHandlerMixin (995 lines): Google/OpenAI batch processing

All backward-compatible imports preserved via re-exports.
181 tests pass, 0 regressions. Real-world tested with Anthropic,
OpenAI, and GPT-5.4 API calls.
2026-04-03 17:08:39 -07:00
chopratejas
6a8ae297d6 Refactor: extract 7 modules from server.py (Steps 2-4)
server.py: 8778 → 7412 lines (-1366, -15.5%)

Extracted modules:
- cost.py (629 lines): CostTracker, build_prefix_cache_stats, merge_cost_stats
- prometheus_metrics.py (312 lines): PrometheusMetrics
- semantic_cache.py (142 lines): SemanticCache
- rate_limiter.py (101 lines): TokenBucketRateLimiter
- request_logger.py (108 lines): RequestLogger
- helpers.py (195 lines): _read_request_json, constants, lazy loaders
- models.py (199 lines): ProxyConfig, RequestLog, CacheEntry (from Step 1)

All existing imports via headroom.proxy.server continue to work
through re-exports. Updated test patches to target new module paths.

181 tests pass, 0 regressions.
2026-04-03 16:18:08 -07:00
chopratejas
c33f74d39d Bump to 0.5.18
- Fix image token counting (base64 no longer counted as text tokens)
- Disable CacheAligner (was inflating tokens and breaking prefix caching)
- Fix WebSocket SSL on Windows (native websockets SSL handling)
- Add transforms_summary to API responses
- Extract ProxyConfig to proxy/models.py (server.py refactor step 1)
2026-04-02 18:00:49 -07:00
chopratejas
e963c90b2c Fix multi-worker beacon spam, cost dashboard, upsert telemetry; bump 0.5.17
- Fix beacon spam: file lock ensures only one beacon per proxy regardless
  of worker count. Workers > 1 caused N beacons firing N rows per cycle.
- Beacon upsert: on_conflict=session_id prevents duplicate rows.
- Beacon stop() guard: skip final report if uptime < 2 minutes.
- Fix dashboard cost: savings_usd now uses model list price (monotonic),
  not moving average. Separate breakdown for compression/cache/rtk.

Fixes #83
2026-03-31 09:41:38 -07:00
chopratejas
e5d56aff3d Bump to 0.5.16: WebSocket proxy, Kompress ONNX, Discord link update
- WebSocket proxy for /v1/responses (Codex gpt-5.4+ support)
- Kompress ONNX INT8 text compression (no torch needed, ~100MB vs 1.5GB)
- Updated Discord invite link
- Tool_result ordering fix for Bedrock
2026-03-30 22:53:07 -07:00
chopratejas
2d97d8e900 Kompress ONNX INT8: text compression without torch dependency
KompressCompressor now tries ONNX Runtime first (156MB INT8 model),
falls back to PyTorch only if ONNX unavailable. No torch needed for
text compression — just onnxruntime (~50MB) + transformers (tokenizer).

Changes:
- Add onnxruntime + transformers to [proxy] extra in pyproject.toml
- Add _OnnxModel wrapper with get_scores/get_keep_mask interface
- _load_kompress() tries ONNX first, falls back to PyTorch
- is_kompress_available() returns True if EITHER backend available
- compress() handles both numpy (ONNX) and tensor (PyTorch) outputs

Dependency impact:
  Before: pip install headroom-ai[proxy] → no text compression
  After:  pip install headroom-ai[proxy] → Kompress ONNX INT8 (156MB)
  [ml] extra still available for full PyTorch (600MB, GPU support)
2026-03-30 22:50:13 -07:00
chopratejas
7c23a1a93a Add WebSocket proxy for /v1/responses (Codex gpt-5.4+)
Codex v0.117.0+ with newer models uses WebSocket instead of HTTP POST
for the Responses API. Added @app.websocket("/v1/responses") handler that:
- Accepts ws:// connections and forwards to wss://api.openai.com
- Compresses input on first message using existing pipeline
- Relays all response events bidirectionally
- Handles SSL (certifi), graceful disconnect, missing websockets lib

Tested with real OpenAI API: basic text, large tool outputs (200 records),
parallel function calls, instructions preservation.

Addresses #79
2026-03-30 22:00:12 -07:00
chopratejas
606819cb94 Bump to 0.5.15: Responses API compression, tool_result ordering fix 2026-03-30 20:14:14 -07:00
chopratejas
6212644587 Fix zstd streaming decompression, add zstandard dep; bump to 0.5.14
Use stream_reader instead of decompress() for zstd request bodies.
Codex uses streaming zstd (no content size in frame header), which
causes decompress() to fail. stream_reader handles both cases.

Also added zstandard to the [proxy] optional dependencies.
2026-03-30 16:01:51 -07:00
chopratejas
8228f0edfb Fix streaming tool calls, compressed request bodies, beacon field names; bump to 0.5.13
- Fix LiteLLM stream_message: emit tool_use blocks from delta.tool_calls,
  set stop_reason from finish_reason (fixes silent MCP tool call failures)
- Fix _convert_messages_for_litellm: convert Anthropic tool_result/tool_use
  to OpenAI role=tool/tool_calls format (fixes 500 on tool round-trips)
- Fix proxy request body parsing: decompress zstd/gzip/deflate/brotli
  Content-Encoding before JSON decode (fixes Codex UnicodeDecodeError crash)
- Fix telemetry beacon field names to match /stats endpoint
  (tokens.total_before_compression, not tokens.original)
- Add dedupe_telemetry.py script for hourly Supabase row deduplication
2026-03-30 14:48:48 -07:00
chopratejas
c6d6c6a96c Switch telemetry to proxy_telemetry_v2 table, bump to 0.5.12
Telemetry beacon now writes to proxy_telemetry_v2 which has all 25
columns matching the beacon payload. Added SQL schema for the new table.
2026-03-30 10:55:45 -07:00
chopratejas
e25eb0b88a Bump to 0.5.11: fix cost calculation, Windows path decoding, unused imports 2026-03-30 09:45:35 -07:00
chopratejas
5565e07846 Bump to 0.5.10 (0.5.9 had partial PyPI upload) 2026-03-28 23:49:19 -07:00
chopratejas
3953fd1db6 Bump to 0.5.9
- Fix telemetry beacon: use JWT anon key + plain INSERT (was silently failing since 0.5.6)
- Fix cost tracker: use avg effective $/token for savings calculation
- Add tokenBudget support to /v1/compress endpoint and TS SDK
- Add OpenClaw ContextEngine plugin (@headroom-ai/openclaw)
2026-03-28 23:47:49 -07:00
chopratejas
52c40baff7 Revert version bump: table schema fix resolves telemetry for all versions >= 0.5.6 2026-03-27 20:57:31 -07:00
chopratejas
95a0d0331f Bump to 0.5.9: fix telemetry beacon (restore auth header, requires table schema update) 2026-03-27 20:55:30 -07:00
chopratejas
ec1f2c9327 Bump to 0.5.8: fix Windows Unicode crash, fix Bedrock Claude 4.6 model IDs 2026-03-27 10:36:37 -07:00
chopratejas
72eebd4fe6 Fix CI test, bump to 0.5.7
- test_nested_functions: guard syntax_valid assert behind
  is_tree_sitter_available() (CI doesn't have tree-sitter)
- Bump version to 0.5.7
2026-03-26 12:04:30 -07:00
chopratejas
4605fc1971 Reduce proxy latency, enrich telemetry, protect Bash output, bump to 0.5.6
Performance:
- Replace json roundtrip with copy.deepcopy in deep_copy_messages (~20-80ms)
- Eliminate redundant token counting in pipeline (8→2 calls, ~30-100ms)
- Parallel message compression in ContentRouter via ThreadPoolExecutor (~100-200ms)
- Add granular timing metrics: deep_copy, token_count, parallel_compress
- Switch hot-path hashing from SHA256 to MD5 (2-3x faster, non-crypto)

Telemetry:
- Enrich beacon payload with overhead, TTFB, pipeline timing, request
  patterns, compression cache stats, CCR usage, and waste signals
- Each extraction section guarded independently so one bad key never
  blocks the rest; Supabase POST failure never affects proxy

Bug fix:
- Add Bash/bash to DEFAULT_EXCLUDE_TOOLS so tree/ls output is not
  compressed by the text compressor
2026-03-25 11:22:36 -07:00
chopratejas
9ba0450f3c Reduce compression latency: cache serializations, eager-load all compressors, fix Magika, bump to 0.5.5
SmartCrusher: eliminate 5-7x redundant json.dumps by threading cached item_strings
through _crush_array → _create_plan → _plan_* methods, TOIN token counting, and CCR
storage. Move ISO datetime regex to module level. Cache field name hashes in TOIN
semantic detection. Add item_strings param to error detection.

ContentRouter: compile prose detection regex at module level. Extend
eager_load_compressors() to pre-load Magika detector, tree-sitter parsers (8 common
languages), CodeAwareCompressor, and SmartCrusher at startup.

Magika: add as proxy dependency (was never declared in pyproject.toml). Update
detector.py for Magika 1.x API (result.output.label, result.score). Fix batch
detection to use identify_bytes loop (identify_bytes_batch removed in 1.x).

Proxy: simplify startup to use eager_load_compressors() return status dict for
unified component logging.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 01:04:26 -07:00
chopratejas
e2e74a008a Add telemetry beacon, fix Starlette 0.41+ crash, bump to 0.5.4
- Add anonymous telemetry beacon: proxy sends aggregate-only stats
  (tokens saved, compression ratios, cache hit rates) to Supabase
  every 5 minutes. No prompts, no content, no PII. Opt out with
  --no-telemetry or HEADROOM_TELEMETRY=off.

- Fix Starlette 0.41+ TypeError: migrate from deprecated on_event
  decorators to lifespan context manager. Fixes crash with
  "Router.__init__() got an unexpected keyword argument 'on_startup'".

- Bump version to 0.5.4.
2026-03-24 15:49:38 -07:00
chopratejas
cb21589676 Pin litellm to v1.82.3 and bump version to 0.5.3
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 11:58:25 -07:00
Tejas Chopra
b5631cdf7e chore: bump version to 0.5.2 2026-03-20 12:56:12 -07:00
chopratejas
62a5183814 chore: bump version to 0.5.1 2026-03-19 13:15:38 -07:00
chopratejas
b435d4b27d chore: bump version to 0.5.0 2026-03-19 12:59:07 -07:00
chopratejas
87b54fc159 Enhanced MCP server with compress/stats tools, fix proxy torch crash
- Fix proxy crash when torch not installed: make kompress_compressor.py
imports lazy so `is_kompress_available()` works without [ml] extra
- Rewrite MCP server from 1 tool (retrieve-only) to 3 tools:
headroom_compress (on-demand compression, no proxy needed),
headroom_retrieve (local store first, proxy fallback),
headroom_stats (session stats + sub-agent aggregation + proxy cache)
- Add shared stats file (~/.headroom/session_stats.jsonl) so sub-agent
compression stats are visible from the main session
- Add mcp to [proxy] extras so proxy users get MCP tools automatically
- Remove dead TextCompressor from exports and pipeline (was never called)
- Update mcp install messaging to clarify proxy vs MCP roles
- Fix fcntl Windows compat, asyncio deprecation, httpx timeout race

Bump version to 0.4.6.
2026-03-16 22:56:30 -07:00
chopratejas
fb4ab08856 Fix proxy crash when torch not installed (kompress lazy imports)
The proxy startup crashed with `ModuleNotFoundError: No module named
'torch'` when installed with just `[proxy]` extras because
kompress_compressor.py had unconditional top-level torch imports.
Moved torch/transformers imports to be lazy so the module is safely
importable without the [ml] extra. Added tests for import safety.
Bumped version to 0.4.5
2026-03-15 11:51:21 -07:00
chopratejas
1415a325d3 Bump version to 0.4.4 2026-03-14 08:54:46 -07:00
chopratejas
0e09097735 Bump version to 0.4.3 2026-03-13 16:51:23 -07:00
chopratejas
18118af5ce Slim core dependencies: 2.5GB → 195MB install size
Move heavy deps to optional extras: sentence-transformers, torch,
numpy, pillow, datasets, accelerate out of core. Remove unused deps
entirely (semantic-router, protobuf, sentencepiece).

New extras: [ml] for Kompress, [image] for image compression,
[langchain] for LangChain integration. Guard memory/image imports
so core install works without numpy/torch.

Core (tiktoken, pydantic, litellm, click, rich) gives full
compression: SmartCrusher, ContentRouter, CCR, TOIN, CLI.
2026-03-13 15:35:49 -07:00
Tejas Chopra
384ac34d10 fix(wrap): route through proxy, prevent pipe deadlock, bump to 0.4.2
- Fix ANTHROPIC_API_URL → ANTHROPIC_BASE_URL (SDK uses BASE_URL)
- Write proxy logs to ~/.headroom/logs/proxy.log instead of PIPE
  (macOS 64KB pipe buffer fills up, blocking the proxy process)
- Add --auto-patch to rtk init to avoid interactive prompt timeout
- Bump version to 0.4.2

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 13:40:30 -07:00
chopratejas
4bea17ba8a Fix proxy backend bugs: env vars, tool forwarding, and provider support
- CLI now reads OPENAI_TARGET_API_URL, GEMINI_TARGET_API_URL, and
HEADROOM_ANYLLM_PROVIDER environment variables
- Add --openai-api-url and --gemini-api-url CLI flags
- Remove --backend choices restriction so litellm-* backends work
- Forward tools/tool_choice through LiteLLM and any-llm backends
- Parse tool call arguments from JSON string to dict (Anthropic format)
- Forward top_p, stop_sequences, tools in streaming paths
- Update Vertex AI model map with Claude 3 through 4.6 (from official docs)
- Bump version to 0.4.1
2026-03-12 20:55:26 -07:00