Commit graph

2630 commits

Author SHA1 Message Date
Tejas Chopra
31ea3a1cdf
Merge pull request #206 from ShalokShalom/patch-1
Update documentation links to new domain
2026-04-19 12:53:54 -07:00
ShalokShalom
196469852a
Update documentation links to new domain
You forgot to update the URL to your new documentation.
2026-04-19 21:52:18 +02:00
Tejas Chopra
956fe40cce
Merge pull request #203 from tuandinh0801/fix/oauth-bearer-routing
fix: support OAuth Bearer token routing for proxy endpoints
2026-04-18 22:53:33 -07:00
Tuan Dinh
ddb20d9fde
fix: support OAuth Bearer token routing for proxy endpoints
Bearer-only auth (no x-api-key) was misrouted at /v1/models and
catch-all endpoints because routing only checked x-api-key header.
Claude Code users authenticating via ANTHROPIC_AUTH_TOKEN (OAuth)
send Authorization: Bearer instead of x-api-key.

- Add is_anthropic_auth() helper detecting x-api-key, anthropic-version,
  or Bearer sk-ant-* tokens
- Fix /v1/models routing to use consolidated auth detection
- Fix catch-all /{path:path} routing to recognize Bearer tokens
- Use Bearer token prefix for rate-limit key when x-api-key absent
- Add 19 tests covering auth detection, routing, and rate-limit keys

Closes chopratejas/headroom#200
2026-04-19 12:50:09 +07:00
JerrettDavis
8a6579b789 ci: merge latest main and fix workflow validation
Bring the branch onto upstream/main so GitHub validates the same merged
compression code locally, and install act into PATH for the
workflow-validation job.

This keeps the compact-JSON compression regression fixed while making
the shared validation script pass in CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-18 16:17:42 -05:00
JerrettDavis
3ddc7ff33a fix: restore release and compress regressions
Fix workflow validation failures by wiring detect-version outputs into all
release publish jobs, renaming the GitHub Packages skip variable to a
valid Actions variable name, and adjusting the macOS PATH export for
actionlint.

Also make min_tokens_to_compress use token counting instead of whitespace
splits so compact JSON tool outputs still compress after merging the
latest main branch changes, and add a regression test for that path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-18 16:01:57 -05:00
JerrettDavis
d8c2ae88cd ci: validate release workflows with act
Add a workflow-validation CI job that installs actionlint and act,
checks the release and Docker workflows against checked-in event
fixtures, and shares the same validation script developers can run
locally.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-18 15:38:10 -05:00
chopratejas
e4f3cf77c5 docs: fix Kompress-base HuggingFace link 2026-04-18 09:39:43 -07:00
chopratejas
2593ff2c6c docs: rewrite README for clarity and highlight Kompress-base, leaderboard, RTK 2026-04-18 09:36:49 -07:00
JerrettDavis
a36f3e2d3e fix: publish release artifacts and docker together
Call the Docker workflow from the release pipeline so Docker publishes in

the same run, build npm tarballs alongside Python distributions, and

attach those artifacts to the GitHub release page.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 21:33:37 -05:00
Kayzo
9f0a813004 fix: address PR review feedback 2026-04-17 23:09:12 +00:00
chopratejas
3242efe3a5 perf: add compress_system_messages and min_tokens_to_compress config
- compress_system_messages (default True): set False to skip system
  prompt compression entirely
- min_tokens_to_compress (default 250): minimum word count for a
  message to be eligible for compression (was hardcoded at 50)

Both flow through CompressConfig to ContentRouter. Default behavior
unchanged.
2026-04-17 13:18:08 -07:00
chopratejas
1039f66f67 feat: wire kompress_model through compress pipeline
CompressConfig.kompress_model was declared but not passed to transforms.
Now it flows through pipeline.apply() to ContentRouter, enabling:

- Custom Kompress models via HuggingFace model ID
- kompress_model="disabled" to skip ML compression entirely
  (SmartCrusher + CacheAligner still run)
- Default behavior (kompress_model=None) unchanged
2026-04-17 11:59:29 -07:00
Tejas Chopra
80cfcd7e5b
Merge pull request #192 from JerrettDavis/feature/spec-183
feat(specs): #183 scaffold initial application specs.
2026-04-17 11:00:33 -07:00
Tejas Chopra
9469bcb045
Merge pull request #193 from JerrettDavis/fix/release-bump-highest
fix: take highest release bump across unreleased commits
2026-04-17 11:00:21 -07:00
Kayzo
4bdc1482af feat: add Pi/Codex and Cloud Code Assist compatibility routes
- Adds /v1/codex/responses aliases for OpenAI Codex clients configured with /v1 base URLs
- Uses JWT-derived account routing for /v1/responses/* subpaths (compact, cancel, etc)
- Adds /v1internal:streamGenerateContent aliases for Cloud Code Assist / Antigravity
- Preserves upstream HTTP error status/body in StreamingResponse (fixes empty SSE drops)
2026-04-17 17:45:08 +00:00
JerrettDavis
bde7aa9c30 fix: align docker image versions with releases
Derive the exact Docker image version from the release tag or manual
workflow input, sync versioned files in the build workspace before the
image build, and publish an explicit matching image tag.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 12:17:49 -05:00
Garm
5a2c484430 refactor(telemetry): centralize stack slug validation + cardinality cap
Addresses review feedback on PR #194: prior code validated X-Headroom-Stack
slugs differently at each ingress — the Prometheus counter capped length but
the env-var path and beacon didn't. Under a misconfigured or malicious client
sending arbitrary X-Headroom-Stack values, requests_by_stack could grow
unbounded in memory, in the Prometheus scrape, and in the JSONB telemetry
payload.

- New normalize_stack(raw) in headroom/telemetry/context.py: strips, lowercases,
  enforces ^[a-z][a-z0-9_]{0,63}$. Single chokepoint.
- detect_stack now routes HEADROOM_STACK and stats dominant-slug through it;
  invalid env values fall through to the agent-type path or default "proxy".
- PrometheusMetrics.record_stack routes through normalize_stack and rejects
  new slugs once the dict hits MAX_DISTINCT_STACKS (32); existing slugs still
  increment so valid callers aren't starved.
- 10 new unit tests covering normalize_stack charset/length/empty cases, the
  cardinality cap, and invalid-env fallback paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 18:42:41 +02:00
Garm
d81b677f80 docs(telemetry): document headroom_stack and install_mode beacon fields
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 18:42:41 +02:00
Garm
4a8d9812cf fix(ci): resolve mypy no-any-return and ruff formatting
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 18:42:41 +02:00
Garm
d4cd49af95 feat(telemetry): add headroom_stack and install_mode identity fields
Adds two orthogonal identity fields to the anonymous telemetry beacon so we
can segment usage by integration surface and deployment shape:

- headroom_stack: how Headroom is invoked (proxy, wrap_claude, wrap_codex,
  adapter_ts_openai, adapter_ts_anthropic, etc.). Resolved from HEADROOM_STACK
  env, HEADROOM_AGENT_TYPE fallback, or aggregated request-header counts.
- install_mode: how the proxy is deployed (wrapped / persistent / on_demand).
  Detected from HEADROOM_AGENT_TYPE plus DeploymentManifest lookup.

TS SDK adapters now tag every request with X-Headroom-Stack; a FastAPI
middleware buckets the counts and surfaces them via /stats so the beacon can
report requests_by_stack for mixed-integration sessions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 17:12:38 +02:00
JerrettDavis
799e1c3a30 fix: preserve empty-body commits in release bump parsing
Do not strip the raw git-log record before splitting on the field
separator, because commits with empty bodies lose their delimiter and get
dropped entirely. Add a deterministic unit test for empty-body parsing.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 23:46:06 -05:00
JerrettDavis
8872b8be3b fix: take highest release bump across unreleased commits
Determine the release bump from all unreleased commits since the previous
release tag and apply the highest required semantic version increment.
This keeps feat commits at a minor bump unless a breaking change requires
major, even when later patch-level commits are present.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 23:38:29 -05:00
Tejas Chopra
4651f96c92
Merge pull request #190 from JerrettDavis/fix/release-semver-versioning
fix: run release versioning without package imports
2026-04-16 20:49:47 -07:00
Tejas Chopra
cb7bc8c815
Merge pull request #191 from JerrettDavis/feat/filesystem-contract
feat: canonical HEADROOM_CONFIG_DIR and HEADROOM_WORKSPACE_DIR filesystem contract
2026-04-16 20:49:24 -07:00
JerrettDavis
ec305efcd9 docs: move spec from specify/ to docs/spec/
Align with SpecKit's canonical docs/ structure. Update .gitignore
comment to reflect new location.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-16 21:15:04 -05:00
JerrettDavis
31a05dc260 docs: add living specification in specify/ directory
Move specs from docs/superpowers/ to specify/ for git versioning.
Updated specs to match actual codebase:
- Default proxy port: 8787 (not 8765)
- Correct HTTP endpoints: /livez, /readyz (not /live, /ready)
- LearnPlugin interface (not BaseLearnPlugin)
- Correct CLI commands: wrap, memory, evals, install, mcp, perf
- Accurate SQLite schema from storage/sqlite.py
- SmartCrusher/CCR/RollingWindow config details

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-16 20:20:17 -05:00
JerrettDavis
01ce6c710b test(e2e): assert HEADROOM_WORKSPACE_DIR / HEADROOM_CONFIG_DIR reach container at runtime
Fills the deferred TODO in docker-native-install.sh. After 'install
apply' and before 'install stop', we now:

1. 'docker inspect' the running headroom-${PROFILE} container and assert
   both canonical env vars are present in Config.Env with the expected
   /tmp/headroom-home/.headroom and .../config values.
2. 'docker exec env' inside the container and assert the same vars are
   visible to processes running under the proxy entrypoint (proves not
   just Config.Env but actual runtime visibility).

Unit tests in tests/test_install/{test_runtime,test_native_installers}
already lock install-time env forwarding; this completes the runtime
half of the guarantee.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:59:56 -05:00
JerrettDavis
1ef12953d4 test(paths): add adversarial backward-compat stress suite
Three scenarios lock the issue-175 additive guarantee:

1. Legacy-only user (HEADROOM_SAVINGS_PATH set, canonical unset) still
   gets the byte-for-byte legacy value.
2. Canonical-only user (HEADROOM_WORKSPACE_DIR set) sees every workspace
   bucket resource relocate with the correct filenames.
3. Both set: legacy per-resource env var wins over canonical root env
   for its own resource; other unreserved helpers still follow the new
   canonical root (orthogonality).

Plus a regression guard asserting all three legacy vars (savings, toin,
subscription) simultaneously beat the canonical workspace override.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:59:47 -05:00
JerrettDavis
ebc7158de2 test(sdk/ts): add HEADROOM_WORKSPACE_DIR precedence tests for derived helpers
Mirrors the Python coverage gap closure: every derived-only helper
(memoryDbPath, nativeMemoryDir, logDir, rtkPath, beaconLockPath,
pluginConfigDir, etc.) now has both a default test and an override test
that exercises the canonical workspace env var end-to-end.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:59:38 -05:00
JerrettDavis
6410a1bdac test(paths): close coverage gaps for derived-only helpers
Every public helper in headroom/paths.py now has both a default-derived
test and a HEADROOM_WORKSPACE_DIR/CONFIG_DIR precedence test. Adds the
derived_workspace_helpers parametrized matrix plus explicit cases for
proxy_log_path, rtk_path, beacon_lock_path, plugin_*_dir, and both
ensure_* functions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:59:30 -05:00
JerrettDavis
1192f657eb docs: document HEADROOM_CONFIG_DIR / HEADROOM_WORKSPACE_DIR filesystem contract
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:24:17 -05:00
JerrettDavis
4a87753713 feat(docker): forward HEADROOM_WORKSPACE_DIR and HEADROOM_CONFIG_DIR into containers
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:19:25 -05:00
JerrettDavis
edfe22a0c3 fix: run release versioning without package imports
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 19:17:53 -05:00
Tejas Chopra
01fa4aa3a1
Merge pull request #155 from vichu/fix/strip-accept-encoding-forwarded-headers
fix: strip accept-encoding from forwarded proxy headers
2026-04-16 17:17:22 -07:00
JerrettDavis
028e2c0c1b feat(sdk/ts): add paths module with HEADROOM_CONFIG_DIR / HEADROOM_WORKSPACE_DIR parity
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:16:00 -05:00
JerrettDavis
3a1bbbbc14 refactor: migrate Python callsites to canonical paths module
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 19:12:21 -05:00
Tejas Chopra
e2ca3ca829
Merge pull request #187 from JerrettDavis/fix/release-semver-versioning
fix: restore semantic release versioning
2026-04-16 17:11:39 -07:00
JerrettDavis
ebb9149fe9 fix: serialize release versioning
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 19:10:36 -05:00
Tejas Chopra
062dbfda4e
Merge pull request #188 from JerrettDavis/feat/dependabot-grouped-updates
ci: group dependabot minor/patch updates per ecosystem
2026-04-16 16:53:57 -07:00
Tejas Chopra
ff0788a275
Merge pull request #189 from JerrettDavis/fix/ruff-format-server-py
style: apply ruff format to server.py
2026-04-16 16:53:35 -07:00
JerrettDavis
4fb1935405 feat(paths): add canonical HEADROOM_CONFIG_DIR / HEADROOM_WORKSPACE_DIR module
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 18:50:50 -05:00
JerrettDavis
c24b1fa46f fix: harden release notes and semver
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 18:50:36 -05:00
JerrettDavis
ddf4655b66 style: apply ruff format to server.py
Commit 997f364 landed server.py in a state that fails `ruff format
--check .`, blocking all PRs. This runs `ruff format` on the file
and nothing else.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 18:19:38 -05:00
JerrettDavis
bc9deec657 fix: satisfy release version mypy check
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 18:10:07 -05:00
JerrettDavis
ffe3391b2d fix: restore CI compatibility for release versioning
Lazy-load tomllib so Python 3.10 test collection succeeds, and apply the repo formatter change required by the 3.12 lint job.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 17:59:18 -05:00
JerrettDavis
7d03ffeaee ci: group dependabot minor/patch updates per ecosystem
Consolidates routine minor/patch bumps into a single weekly PR per
ecosystem (docker, github-actions, pip), cutting review overhead
roughly in half. Major updates remain ungrouped so breaking changes
still get individual review.

Closes #174

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 17:54:39 -05:00
JerrettDavis
8ac100aa7a chore: satisfy release version lint
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 17:44:36 -05:00
JerrettDavis
0e3e03f319 fix: restore semantic release versioning
Replace the inline release version math with a tested helper that normalizes legacy four-part tags and computes a single semantic version for packages and GitHub releases.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-16 17:44:23 -05:00
Tejas Chopra
1e80ee3f52
Merge pull request #186 from skorokithakis/patch-1
Add support for custom Anthropic API URL
2026-04-16 12:54:31 -07:00