Commit Graph
113 Commits
Author SHA1 Message Date
9qeklajc 861fda21b7 resolve review comments 2026-06-12 20:20:38 +02:00
Jeroen UbbinkandClaude Sonnet 4.6 28c4008892 fix: enforce balance_limit atomically on child key requests
The Python pre-check on balance_limit provided no concurrency guarantee —
two concurrent requests could both pass the check on stale in-memory state
and both proceed to reserve, exceeding the limit.

Add the balance_limit guard to the child key UPDATE's WHERE clause so the
enforcement is atomic. The HTTP 402 is raised without an explicit rollback:
since session.commit() was never called, the uncommitted billing key update
is discarded when the session context manager closes on exception exit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 11:37:39 +02:00
9qeklajcandGitHub a16bc1220c Merge pull request #546 from Routstr/fix-parent-key-leak-to-child-key
do not leak parent key to child key
2026-06-07 15:27:32 +02:00
9qeklajc 68a7cd1dfb do not leak parent key to child key 2026-06-07 15:25:13 +02:00
9qeklajc d96dc20e86 secure endpoint 2026-06-07 15:18:49 +02:00
9qeklajc 9e9c2bde57 fix: buffer-based SSE parser for all supported providers
Replace the fragile `re.split(b"data: ")` streaming parser with a
buffered, event-delimited parser in both the chat-completion and
Responses-API streamers. Events are accumulated until the SSE blank-line
delimiter, so parsing is independent of network chunk boundaries.

Fixes:
- OpenRouter `: OPENROUTER PROCESSING` keepalive comments no longer leak
  to clients as `data: : ...` (the `Unexpected token ':'` client crash).
- JSON payloads split across TCP reads are reassembled before parsing.
- CRLF framing (Gemini native alt=sse) handled.
- Combined content+usage chunks (Gemini thinking models over the
  OpenAI-compat endpoint) forward content once and still report usage in
  the cost trailer, instead of dropping the assistant message.
- Multi-line non-JSON `data` blocks are re-prefixed per line so they stay
  valid SSE framing for the client.

Adds tests/unit/test_streaming_sse_providers.py driving the real
generator against per-provider on-the-wire framing, and switches the
integration token-mint fallback to secrets.token_hex to kill a
PRNG/clock collision flake.
2026-06-07 12:58:54 +02:00
9qeklajcandGitHub 8f89171db1 Merge pull request #541 from jeroenubbink/fix/lightning-invoice-key-constraints
fix: persist and propagate key constraints from Lightning invoices
2026-06-07 10:51:29 +02:00
Jeroen UbbinkandClaude Sonnet 4.6 feb76bc89d fix: persist and propagate key constraints from Lightning invoices
LightningInvoice had no columns for balance_limit, balance_limit_reset,
or validity_date. SQLModel silently dropped these constructor kwargs, so
create_api_key_from_invoice always produced an unconstrained key.

Add the three columns to LightningInvoice with a migration, and wire them
through to the ApiKey in create_api_key_from_invoice, matching the pattern
already used in the child key creation path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 14:58:40 +02:00
Jeroen UbbinkandClaude Sonnet 4.6 3b7f96560b fix: make child key balance deduction atomic
The previous in-memory deduction (key.balance -= cost) was a read-modify-
write on stale state, allowing two concurrent create_child_key() calls to
both pass the balance check and both succeed, effectively charging the
parent only once for two child keys.

Replace with an atomic UPDATE ... WHERE balance - reserved_balance >= cost
and check rowcount, matching the pattern already used in pay_for_request.
Also adds a concurrent integration test that reproduces the race and
confirms the fix holds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 12:02:12 +02:00
9qeklajcandGitHub d7bf1d6582 Merge pull request #536 from Routstr/add-created-date-to-api-key
add api key creation date
2026-06-02 00:20:57 +02:00
9qeklajc 379c319e0d fix test 2026-06-01 23:30:20 +02:00
9qeklajc aaa80d47bc add api key creation date 2026-06-01 23:27:26 +02:00
9qeklajcandGitHub 29cfeaed9a Merge pull request #523 from Routstr/rip-08-lightning-invoice
add rop-08 lightning invoice support
2026-05-21 00:28:41 +02:00
9qeklajc 632244e54f add rop-08 lightning invoice support 2026-05-20 23:24:24 +02:00
9qeklajc 3251664513 use correct var to report balance info 2026-05-20 23:00:03 +02:00
9qeklajc 3c13be20cb no key creation when refund 2026-05-13 22:34:24 +02:00
9qeklajc a2db3e2d57 fmt 2026-04-26 22:19:30 +02:00
9qeklajc 1f2ff8a99c added admin token 2026-04-25 11:18:58 +02:00
9qeklajc aa682bf8ec fix test 2026-04-22 23:43:11 +02:00
9qeklajc afd81aeca2 reduce retries 2026-04-22 23:14:45 +02:00
9qeklajc fa7d2804bb add test 2026-04-22 23:00:04 +02:00
9qeklajc 05115c3387 add api-key history and fix race condition while topup 2026-04-22 21:50:22 +02:00
9qeklajc a637acd8f4 use db fixture 2026-04-09 23:08:01 +02:00
9qeklajc 58be0c7976 clean u 2026-04-09 20:42:36 +02:00
9qeklajc 74b58e5fa3 add some tests and improve payment handling 2026-04-09 20:25:43 +02:00
9qeklajc a1018776e9 make sure no negative balance can happen 2026-04-08 00:16:55 +02:00
9qeklajc 7267bb87b9 fix tests 2026-03-13 23:04:17 +01:00
9qeklajc 173f5fbcbd make sure the models with lowest prices are forwarded 2026-03-13 22:59:09 +01:00
9qeklajcandGitHub 8b3fdaa545 Merge pull request #403 from Routstr/fix-admin-routstr-balance-timeout
Handle Routstr admin balance timeouts
2026-03-13 21:13:19 +01:00
Shroominic 9560050946 test: type routstr topup async client mock 2026-03-13 19:08:45 +08:00
Shroominic dd88e9b172 test: annotate admin balance integration session 2026-03-13 18:51:30 +08:00
Shroominic 59f8d31719 Handle Routstr admin balance timeouts 2026-03-13 18:45:18 +08:00
Shroominic 0198569a9a fix: retry transient Routstr top-up invoice failures 2026-03-13 18:17:19 +08:00
9qeklajc 66975ee271 Merge branch 'v0.4.0' into add-routstr-provider 2026-03-06 23:08:30 +01:00
9qeklajc 9fb6f54d12 fix negative reserve balance 2026-03-03 15:29:07 +01:00
9qeklajc 350714f23a default child key price to zero 2026-02-18 23:45:37 +01:00
9qeklajc 21f421b212 fmt 2026-02-15 17:09:46 +01:00
9qeklajc 1d95379328 add child keys details to view 2026-02-15 17:06:01 +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 8f81bcd2fc fix do not remove key after refund 2026-02-05 18:48:46 +01:00
9qeklajc b9890e6ad5 fmt 2026-02-05 01:19:11 +01:00
9qeklajc e4b8293d41 lint 2026-02-05 01:03:25 +01:00
9qeklajc ba5f9fc181 improvve key logic 2026-02-04 23:10:50 +01:00
9qeklajcandGitHub c92372dafd Merge pull request #342 from Routstr/refactor/remove-deprecated-admin-html
refactor: remove deprecated admin html
2026-02-01 23:09:06 +01:00
Shroominic 1af39f043f fix tests 2026-01-31 07:37:39 +08:00
Shroominic c75f170ed0 Refactor: Move Discovery and Nostr logic to routstr/nostr package 2026-01-31 06:59:27 +08:00
9qeklajc 1ebb7d71e1 fix test 2026-01-27 08:58:46 +01:00
9qeklajc 04d6903369 lint & fmt 2026-01-25 14:31:55 +01:00
shroominicandGitHub 180a469399 Merge pull request #304 from Routstr/introduce-child-key
Introduce child key
2026-01-23 09:35:53 +08:00
9qeklajc d4339287be chore: add type annotations to example and test files 2026-01-10 21:35:16 +01:00