Commit Graph
91 Commits
Author SHA1 Message Date
Jeroen UbbinkandClaude Fable 5 7f5a0cf1ae refactor: drop the dead model-instance alias map
get_model_instance now derives from the candidate map, leaving the
module-level alias map write-only; remove it so there is a single
authoritative alias source.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:12:21 +02:00
Jeroen UbbinkandClaude Fable 5 3f850c54f4 fix: re-reserve the serving candidate's max cost on failover
Admission and reservation were sized once to the best-ranked candidate's
max cost while settlement bills the candidate that actually serves, so a
failover to a pricier candidate could settle far beyond the admitted
envelope and consume balance reserved by other in-flight requests. Before
trying a fallback candidate, raise the reservation to its own envelope;
reject candidates the key cannot cover, exactly as admission would have
had they been ranked first.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:12:21 +02:00
Jeroen UbbinkandClaude Fable 5 df4d4c44e6 fix: fail over with each candidate provider's own model
The failover loop resolved a single Model for the request and reused it
for every provider: a fallback provider was asked to serve the routing
winner's model id and billed at the winner's pricing and fee. The alias
map now keeps (model, provider) candidate pairs, the proxy rebinds both
per attempt, and forwarding, max-cost echo, and settlement all use the
candidate actually being tried. On a failover serve the response's
model field now names the serving candidate's id.

The unified candidate lookup also applies the version-suffix strip
(-YYYYMMDD) that model resolution already had, so version-suffixed
requests no longer resolve a model yet 400 with "no provider found".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 15:12:21 +02:00
redshift 892aed61cc Fix mypy: move type: ignore onto ASGITransport line 2026-07-16 16:43:52 +08:00
redshift 57fef44ce7 Merge branch 'main' of https://github.com/Routstr/routstr-core into ehbp-proxy-refactor 2026-07-13 11:14:15 +08:00
9qeklajc edfb0f127c fix provider-scoped model overrides 2026-07-07 13:59:23 +02:00
redshift ab5596ed70 remove .well-known/ from Tinfoil attestation routing
Tinfoil's proxy server guide only requires /attestation (GET) and
/v1/chat/completions + /v1/responses (POST). The .well-known/ path was
never requested by Tinfoil and was incorrectly added to:
- _API_PATH_PREFIXES (prefix gate)
- the unauthenticated GET bypass branch
- the Tinfoil integration docs

Remove it from all three.
2026-07-02 20:09:58 +05:30
9qeklajc 07d39c2a7b simplify 2026-06-30 23:50:25 +02:00
redshift 1c0570cc0e Merge branch 'main' of github.com-red:Routstr/routstr-core into ehbp-proxy-refactor 2026-06-29 13:33:56 +08:00
redshift 5dd3cbbc22 fix: route Tinfoil attestation directly 2026-06-22 13:40:32 +08:00
redshift 2e350e082b feat: add Tinfoil direct blind-upstream integration
Add TinfoilUpstreamProvider that uses inference.tinfoil.sh as a direct
EHBP upstream. Routstr acts as a blind relay: it forwards the opaque
encrypted body to the Tinfoil enclave without ever seeing plaintext,
and bills from the X-Tinfoil-Usage-Metrics response header.

- New routstr/upstream/tinfoil.py: fetches models from public
  GET /v1/models, parses Tinfoil pricing into standard Model/Pricing
  schema, supports_ehbp=True, proxies /attestation to atc.tinfoil.sh
- Updated routstr/upstream/ehbp.py:
  - parse_tinfoil_usage_metrics() parses prompt=N,completion=N header
  - _resolve_ehbp_target_url() honors X-Tinfoil-Enclave-Url from SDK
  - _strip_proxy_headers() removes proxy-only headers before forwarding
  - _compute_ehbp_actual_cost() converts usage to msats via calculate_cost
  - forward_ehbp_request() finalizes with exact token cost when usage
    header is present (non-streaming), falls back to max-cost otherwise
  - forward_ehbp_x_cashu_request() computes refund from actual cost
    when usage is available
- Updated routstr/proxy.py: forward /attestation and /.well-known/ paths
  without model/cost/auth lookups
- Updated routstr/upstream/__init__.py and helpers.py: register and
  auto-seed Tinfoil provider from TINFOIL_API_KEY env var
- Updated .env.example with TINFOIL_API_KEY
- 22 new unit tests in tests/unit/test_tinfoil_integration.py
- Updated docs/tinfoil-direct-integration.md and docs/ehbp-proxy-support.md
  with implementation status and billing behavior table
2026-06-21 13:16:01 +08:00
9qeklajc f408785409 better rate limit forwarding 2026-06-20 20:03:40 +02:00
redshift 24b90af6e6 refactor: move EHBP logic to dedicated module with explicit opt-in
- Add supports_ehbp + get_ehbp_forwarding_target hooks to BaseUpstreamProvider,
  keeping base.py minimal (no large forwarding methods)
- Create routstr/upstream/ehbp.py with forward_ehbp_request and
  forward_ehbp_x_cashu_request helpers, plus max-cost finalization
- PPQAIUpstreamProvider: set supports_ehbp = True, implement target to
  /private/v1/... with X-Private-Model header
- proxy.py: filter to EHBP-capable providers, route to ehbp helpers
- Fix bearer EHBP payment: reserve upfront, finalize max cost on success
- Fix X-Cashu EHBP: refund full token on failure, refund excess on success
- Update docs/ehbp-proxy-support.md to reflect new architecture
2026-06-20 17:18:53 +08:00
9qeklajc ed6e0c0189 Merge main into fix-reset-reserve-balance
Resolve pay_for_request conflict: keep main's atomic child-key
balance_limit guard and post-rowcount-check ordering, and stamp
reserved_at on both billing and child reservations.
2026-06-12 21:08:53 +02:00
9qeklajc 919dcf5535 make key reservation reset predictable 2026-06-12 19:45:39 +02:00
9qeklajc 06c8a071a5 feat: reactive request-correction retry for recoverable upstream 400s 2026-06-07 13:00:19 +02:00
redshift e4165f1dab passing through tee get requests 2026-05-19 10:53:59 +08:00
9qeklajc 547f45c185 less verbose logs and more precise 2026-05-16 15:29:41 +02:00
9qeklajc e2143aa173 Revert "fix home nav"
This reverts commit 2eb257c2a6.
2026-05-14 15:51:20 +02:00
9qeklajc 2eb257c2a6 fix home nav 2026-05-14 15:47:59 +02:00
9qeklajc 966613847e update not found proxy 2026-05-14 15:40:49 +02:00
9qeklajc 9d905758ec added page not found redirection 2026-05-09 14:07:45 +02:00
9qeklajc a1ae6e94e9 match model when versioned 2026-04-15 20:05:36 +02:00
9qeklajc 30db582321 add model id to validation log 2026-04-08 00:36:05 +02:00
9qeklajc 4723b9db4d fix storing in/out trans. 2026-03-14 16:56:44 +01:00
9qeklajc 66975ee271 Merge branch 'v0.4.0' into add-routstr-provider 2026-03-06 23:08:30 +01:00
9qeklajc 847f4b07a5 Merge branch 'v0.4.0' into add-routstr-provider 2026-03-03 23:58:19 +01:00
9qeklajc 9fb6f54d12 fix negative reserve balance 2026-03-03 15:29:07 +01:00
9qeklajc 8c9ede2272 split all spaces 2026-02-25 17:57:17 +01:00
9qeklajc 3ea0a267dd add routstr logic 2026-02-15 16:13:29 +01:00
9qeklajcandGitHub 7c94f60797 Merge pull request #351 from Routstr/child-key-expiration
Child key expiration
2026-02-08 23:20:10 +01:00
9qeklajc f495a10eeb keys with different config and better reset 2026-02-08 22:54:59 +01:00
Shroominic c6e401c3f6 Merge branch 'main' into v0.3.0
# Conflicts:
#	routstr/proxy.py
2026-01-30 10:54:35 +08:00
Shroominic 8d3c064b29 ruff fix 2026-01-23 09:47:48 +08:00
shroominicandGitHub 4ac96ade5f Merge branch 'v0.3.0' into provider-fallback 2026-01-23 09:45:14 +08:00
9qeklajc 701b870d63 make sure to refund 2026-01-22 13:44:04 +01:00
shroominicandGitHub 0d07dd0cdb Merge pull request #303 from Routstr/ignore-disabled-provider
ignore disabled provider
2026-01-15 11:12:16 +08:00
Shroominic 24015ebec1 Revert "Merge remote-tracking branch 'origin/mock-upstream-with-testnut-mint' into v0.2.2"
This reverts commit 5a4ba60072, reversing
changes made to eed5bc5b04.
2026-01-13 06:31:24 +08:00
9qeklajc 3bc38937e8 ignore disabled provider 2026-01-10 18:39:24 +01:00
Shroominic 5255fce7b2 todo comment 2026-01-09 16:55:24 +08:00
Shroominic ee668ee93b handle specific errors eg deactivate ppq on insufficient balance 2026-01-09 16:49:03 +08:00
Shroominic cf8b990fc7 fix specify error codes retry 2026-01-09 16:10:14 +08:00
Shroominic 78dd74845b fix merge 2026-01-07 17:44:28 +01:00
Shroominic e7f4c98475 ranked provider fallback on upstream errors 2026-01-07 17:39:05 +01:00
9qeklajc bdf0e2c192 #282 more filter options 2026-01-03 22:49:35 +01:00
Shroominic 5a4ba60072 Merge remote-tracking branch 'origin/mock-upstream-with-testnut-mint' into v0.2.2 2025-12-28 11:18:08 +01:00
9qeklajc 4418d87664 Merge branch 'v0.2.1' into openai-responses-api 2025-12-26 22:37:07 +01:00
Shroominic ea655b748b optimize startup time 2025-12-26 12:33:42 +01:00
9qeklajc a6d0bd1a19 update aliases 2025-12-23 23:43:16 +01:00
Shroominic ec0fcfb48b mock-upstream-with-testnut-mint 2025-12-20 13:54:14 +01:00