# Changelog

All notable changes to this project will be documented in this file.

## 2.0.0 - 2026-08-23
### Added
- `errors.py`: `GateError` hierarchy (`ConfigurationError`, `MissingCredentialsError`, `UnsupportedFeatureError`, `ProviderError`, `GateDeclined`, `GateNotInteractive`, `PricingUnavailable`). Not raised anywhere yet.
- `records.py`: structured records for one call — `Provider`, `CaptureLevel`, `RecordKind`, `StreamChannel`, `TokenSource`, `CostKind`, `RequestRecord`, `ResponseRecord`, `StreamEvent`, `Usage`, `CostEstimate`, `CallRecord`, plus `redact_headers()` and `SENSITIVE_HEADERS`. Headers are redacted by default.
- `pricing.py`: `ModelPrice`, `PricingTable` (exact model id → family substring → default, flagging every fallback as `estimated`), `estimate_cost()`, `default_pricing()` and `PricingFallbackWarning`. `ANTHROPIC_MODEL_PRICING` is intentionally empty pending a real price list.
- Public surface re-exported from `llm_router_gate`; `cli` is now resolved lazily so `import llm_router_gate` no longer pulls in `rich`, the Anthropic SDK or `load_dotenv()`.
- `tests/test_main.py`: comprehensive pytest test suite covering all four modules (`errors`, `records`, `pricing`, `cli`) with 80+ offline tests.
- `CHANGELOG` (this file): now follows Keep a Changelog conventions.

### Changed
- Library refactored from single-module `llm_router_gate.py` to multi-module package under `src/llm_router_gate/` (`__init__.py`, `cli.py`, `errors.py`, `records.py`, `pricing.py`).
- `resolve_pricing()`, `calculate_cost()`, `heuristic_token_count()` and `FAMILY_PRICING_TIERS` moved from the CLI module to `pricing.py`; the CLI imports them. Behaviour unchanged.
- CLI entry point changed from `llm_router_gate:cli` (single module) to `llm_router_gate.cli:cli` (package).
- Dev dependencies now include `pytest`, `pytest-asyncio`, `respx` and `ruff`.

### Fixed
- `SyntaxError` in `print_final_payload()`: `except KeyError, IndexError, TypeError:` → `except (KeyError, IndexError, TypeError):`. The package did not import before this.
- Anthropic provider path could not start: `AsyncAnthropic(http_client=httpx.AsyncClient(...))` raised `TypeError: Invalid http_client argument; Expected an instance of httpx2.AsyncClient`. Now uses `anthropic.DefaultAsyncHttpxClient`, which is an `httpx2.AsyncClient` subclass and carries the SDK's 600 s streaming timeouts, keeping the request/response event-hook injection intact.
- The injected HTTP client in `run_anthropic()` was never closed; it is now scoped by `async with AsyncAnthropic(...)`.
- A failed Anthropic API call printed an error but exited **0**. It now exits 1.
- `final_message.model_dump()` → `model_dump(mode="json")`, so `print_final_payload()`'s `json.dumps()` cannot fail on non-JSON types.

## 1.0.0 - 2025-08-23
### Added
- Initial release as a CLI.
