## Description
Google model capability lookup was still tied to static provider tables
for support checks and context limits. That made plausible future Gemini
model ids fail token counting or context lookup even when they clearly
belonged to the Google provider family.
This change adds a tolerant `ModelRegistry.resolve()` runtime lookup
path and routes the Google provider through it. Exact built-in registry
matches still win first, LiteLLM pricing metadata can supply live limits
when available, and provider-scoped family fallbacks cover future Gemini
ids without letting Google claim unrelated models.
## Type of Change
- [x] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
- [ ] Performance improvement
- [ ] Code refactoring (no functional changes)
## Changes Made
- Added `ModelRegistry.resolve()` as a tolerant runtime capability
resolver.
- Added provider-scoped Google/Gemini family fallbacks for plausible
future model ids.
- Added support for LiteLLM-style `gemini/gemini-...` model ids in
provider inference and family fallback matching.
- Updated `GoogleProvider.supports_model()` and
`GoogleProvider.get_context_limit()` to use the shared model registry
path.
- Added regression tests for future Gemini ids, legacy Gemini context
limits, and unrelated model rejection.
## Testing
- [x] Unit tests pass (`pytest`)
- [x] Linting passes (`ruff check .`)
- [ ] Type checking passes (`mypy headroom`)
- [x] New tests added for new functionality
- [x] Manual testing performed
### Test Output
```text
uv run --no-project --with pytest --with opentelemetry-api --with pydantic --with tiktoken --with litellm --with click --with rich python -B -m pytest tests/test_provider_model_fallback.py tests/test_models.py
65 passed
uv run --no-project --with ruff ruff check headroom/models/registry.py headroom/providers/google.py tests/test_provider_model_fallback.py tests/test_models.py
All checks passed!
uv run --no-project --with ruff ruff format --check headroom/models/registry.py headroom/providers/google.py tests/test_provider_model_fallback.py tests/test_models.py
4 files already formatted
```
## Real Behavior Proof
- Environment: macOS arm64 local checkout, Python 3.13 virtualenv for
editable install; deployed smoke test in a Cloud Run staging service
using an earlier commit from this fork branch before the review
follow-up.
- Exact command / steps: installed `headroom-ai[langchain]` from the
fork branch in the staging service, triggered long-context requests that
activate Headroom's LangChain compression path, then checked Cloud Run
logs after 2026-06-22 12:20 Europe/Paris.
- Observed result: Headroom initialized successfully, compressed
conversation memory (`23255 -> 5618 chars`), and no logs matched the
previous model-resolution failure signatures (`not recognized as a
Google model`, `Unknown context limit`).
- Not tested: staging was not rerun after the `gemini/gemini-...` review
follow-up; that prefix path is covered by local regression tests. Full
repository `uv run pytest` on local macOS is currently blocked by a
native `maturin`/`esaxx-rs` compile failure (`fatal error: 'cstdint'
file not found`). Type checking was not run.
## Review Readiness
- [x] I have performed a self-review
- [x] This PR is ready for human review
## Checklist
- [x] My code follows the project's style guidelines
- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [x] I have updated the CHANGELOG.md if applicable
## Screenshots (if applicable)
N/A
## Additional Notes
- Documentation changes are not included because this is a runtime
compatibility fix with no public API or user-facing configuration
change.
- Full local test execution should be retried in CI or a Linux
environment where the native Rust extension build is healthy.
Co-authored-by: Julien Guarino <julien.guarino@fashiondata.io>
CodeAwareCompressor:
- Tree-sitter based AST parsing for Python, JS, TS, Go, Rust, Java, C, C++
- Preserves imports, signatures, type annotations, error handlers
- Guarantees syntactically valid output
- Uses tree-sitter-language-pack for broad language support
ContentRouter:
- Intelligent compression orchestrator
- Auto-routes content to optimal compressor based on type detection
- Source hint support for high-confidence routing
Custom Model Configuration:
- HEADROOM_MODEL_LIMITS env var and ~/.headroom/models.json support
- Pattern-based inference for unknown models (opus/sonnet/haiku tiers)
- Support for Claude 4.5, Claude 4, o3, o3-mini
- Graceful fallback - never crashes on unknown models