Files
routstr-core agent 0ba82f72cc fix(payment): sanitizer-aware cap quote and true context window
Review findings on 84b0246:

HIGH — the quote was computed from the incoming header while the forwarding
sanitizer may strip it: forward_with_trailer removes every header a Connection
field nominates, so `Connection: X-Tinfoil-Max-Output-Tokens` with cap=8 was
quoted at 8 while the enclave received no cap at all, leaving output unbounded
against a smaller hold. enforced_completion_cap now runs the real
_strip_hop_by_hop_headers over the request headers and additionally refuses when
any Connection field nominates the cap (case-insensitive, comma-split); either
signal yields no quote and the full envelope. Provider target headers are merged
after that strip and must never re-add the cap (Tinfoil's adds only usage
metrics), documented at the hook.

MEDIUM — _model_token_window treated top_provider.max_completion_tokens as the
total window. That value is the output share of the window, not the window: a
100k-context model with a 10k completion cap quoted 13_000 msats while a valid
30k prompt + 1k output bills 34_000. The window is now top_provider.context_length
then model.context_length; a completion-only limit is never a context and an
unknown window keeps the full envelope.

Regression coverage runs the real sanitizer rather than only the forwarding mock:
Connection nomination (exact, case-insensitive, unrelated-token preservation),
end-to-end full-envelope reserve under nomination, and the window cases
(completion-only top_provider -> 100k window; context_length fallback -> 50k).

Still disabled: EHBP_OUTPUT_TOKEN_RESERVATION_ENABLED = False and no features
advertised, pending an upstream request-total guarantee.

Tests: 74 dedicated cases, 194 across the touched suites; ruff/mypy clean.
2026-10-27 12:18:02 +00:00
..
2025-08-03 20:35:59 -03:00
2025-08-09 14:55:26 -03:00
2026-09-28 23:59:36 +02:00
2026-06-13 23:40:39 +02:00
2026-09-07 00:30:05 +02:00
2026-08-03 23:32:06 +02:00
2026-08-06 22:58:44 +02:00
2026-09-24 18:27:27 +02:00
2026-08-03 00:05:36 +02:00
2026-09-24 18:27:27 +02:00
2026-09-24 18:27:27 +02:00
2026-09-07 00:30:05 +02:00
2026-07-01 17:08:28 +02:00
2026-05-14 15:40:49 +02:00
2026-09-16 13:15:32 +02:00
2026-09-04 01:35:43 +02:00

FastAPI Async Unit Tests

This directory contains async unit tests for the Routstr proxy FastAPI application.

Installation

First, ensure you have the development dependencies installed:

uv pip install -e ".[dev]"

Running Tests

To run all tests:

pytest

To run tests with coverage:

pytest --cov=routstr --cov-report=html

To run specific test files:

pytest tests/test_main.py
pytest tests/test_models.py
pytest tests/test_proxy.py

To run only async tests:

pytest -m asyncio

Test Structure

  • conftest.py - Pytest fixtures and configuration
  • test_main.py - Tests for main app endpoints
  • test_account.py - Tests for wallet/account management endpoints
  • test_proxy.py - Tests for the proxy functionality with mocked upstream
  • test_models.py - Tests for model pricing and data structures

Key Fixtures

  • async_client - Async HTTP client for testing FastAPI endpoints
  • test_session - In-memory SQLite database session for tests
  • test_api_key - Pre-configured API key with balance
  • api_key_with_balance - API key with sufficient balance for proxy tests

Environment Variables

The tests automatically set up required environment variables in conftest.py. No manual configuration needed.

Writing New Tests

  1. Use @pytest.mark.asyncio for async tests
  2. Use the provided fixtures for database and client access
  3. Mock external dependencies (like upstream API calls)
  4. Test both success and error cases
  5. Verify database state changes when applicable