Repository navigation
Conversation
A request is charged when the provider reports its usage, which it does at the end of the answer. When the client hung up earlier, the gateway cut the provider off, no usage arrived, and Metering released the hold without a charge, while the provider still billed us for what it had generated. Anyone could get answers for free by disconnecting just before the end. Once credit is reserved, the provider call no longer follows the client's connection: the answer runs to the end, and its reported usage is charged, for every account. Pressing Stop therefore no longer lowers the bill; the request's max_tokens bounds it, and the provider client's existing idle timeout still ends a stalled stream. A client that hung up gets no fallback answer. The old 5-second post-finish drain is no longer needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Merged into #22. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A request is charged when the provider reports its usage, at the end of the answer. When the client hung up earlier, the gateway cut the provider off, no usage arrived, and Metering released the hold without a charge. The provider still billed us for what it had generated. Anyone could get answers for free by disconnecting just before the end, on any account. Guest chat (#18) would make that anonymous.
Providers have no API to look up what one cancelled request cost, so the only way to charge the exact amount is to let the answer finish.
What changes
Proxy). The relay keeps reading to the end, and the usage the provider reports is charged, for every account.max_tokens(or the model maximum) bounds it, and the hold already covers it.PROVIDER_SILENCE_TIMEOUT_SECONDS, 15 min) applies.Provider faults are unchanged: what the provider reports is charged (see dappnode-nexus#152), otherwise nothing.
Tests
TestStreamingUsageRetention, a real HTTP run through the production OpenAI adapter: the client hangs up after the first chunk, the provider finishes, and usage is charged. It previously asserted the opposite.proxy_hangup_test.go: hang-up mid-stream, hang-up during a non-streaming answer, no fallback after a hang-up. Each fails with its part of the fix removed.go test -race ./...andgo vet ./...pass.🤖 Generated with Claude Code