Repository navigation
feat(seer): Show the credits notice when a chat runs out mid-conversation - #130463
Merged
Merged
Conversation
When the org can't afford another chat message, the Seer chat shows the out-of-credits CTA right above the composer and nothing sends: the send button and Enter, suggested questions, timeout retry, /investigate, the autofix embeds' chat actions, and questions forwarded from elsewhere, which wait in the composer instead. Typing stays enabled so the draft survives a top-up. The check only runs while the composer is on screen, and does nothing for orgs without seer-credit-checks. Fixes CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Billing members of orgs with seer-credit-checks now see how much of the org's Seer credits is used, next to the chat's send button. Hovering shows the balance and the auto reload state, using the billing gates copy. The meter is a getsentry override slot. It renders nothing in open source, or when the wallet doesn't load. The out-of-credits alert above the composer now passes reason="agent-chat" to the reworked CTA. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Credit checks also need token-billed-seer-enabled as of #129545, so the tests and stories that turn on seer-credit-checks turn it on too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
useSeerCreditCheck no longer exports hasSeerCreditChecks as of #129545, so the meter checks seer-credit-checks and token-billed-seer-enabled directly. Only token-billed orgs have a wallet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ates designs The Seer chat composer gets the designs' toolbar row under the editor, and the credit usage meter and send button move into it. The send button is the designs' small up arrow. The editor and toolbar share one border and one focus ring. The meter's bar is the designs' 50x10 pill on a bordered track, and its tooltip is 250px wide with a line's space between paragraphs. With auto reload off, the tooltip only counts the month's credits, as in the designs; the out-of-credits alert is where billing members turn auto reload on. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A question forwarded into the chat waits for the first credit check, but the user's own sends went through in the meantime. One landing first left the session non-empty, so the forwarded question was dropped, sent after it, or replayed into the next new chat. While a forwarded question waits, the panel's other sends wait too: the composer, suggestions, retry, /investigate, and the autofix embeds. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The app's query client turns refetch on window focus off by default, so after a top-up or spend in another tab the meter kept its old numbers while the chat's credit check updated. Its wallet and auto reload queries now refetch on focus too. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When Seer stops a reply for credits, or a send comes back 402, recheck the chat's credit check so the out-of-credits notice and disabled composer show right away. A 402 also shows the out-of-credits CTA instead of the generic send error. Refs CW-2332
Use a test-owned QueryClient with the usual rerender instead of a wrapper component, and drop assertions the CTA check already covers. Refs CW-2332
srest2021
marked this pull request as ready for review
November 9, 2026 18:30
When the org can't afford another chat message, the Seer chat shows the out-of-credits CTA right above the composer and nothing sends: the send button and Enter, suggested questions, timeout retry, /investigate, the autofix embeds' chat actions, and questions forwarded from elsewhere, which wait in the composer instead. Typing stays enabled so the draft survives a top-up. The check only runs while the composer is on screen, and does nothing for orgs without seer-credit-checks. Fixes CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Billing members of orgs with seer-credit-checks now see how much of the org's Seer credits is used, next to the chat's send button. Hovering shows the balance and the auto reload state, using the billing gates copy. The meter is a getsentry override slot. It renders nothing in open source, or when the wallet doesn't load. The out-of-credits alert above the composer now passes reason="agent-chat" to the reworked CTA. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Credit checks also need token-billed-seer-enabled as of #129545, so the tests and stories that turn on seer-credit-checks turn it on too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
useSeerCreditCheck no longer exports hasSeerCreditChecks as of #129545, so the meter checks seer-credit-checks and token-billed-seer-enabled directly. Only token-billed orgs have a wallet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ates designs The Seer chat composer gets the designs' toolbar row under the editor, and the credit usage meter and send button move into it. The send button is the designs' small up arrow. The editor and toolbar share one border and one focus ring. The meter's bar is the designs' 50x10 pill on a bordered track, and its tooltip is 250px wide with a line's space between paragraphs. With auto reload off, the tooltip only counts the month's credits, as in the designs; the out-of-credits alert is where billing members turn auto reload on. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A question forwarded into the chat waits for the first credit check, but the user's own sends went through in the meantime. One landing first left the session non-empty, so the forwarded question was dropped, sent after it, or replayed into the next new chat. While a forwarded question waits, the panel's other sends wait too: the composer, suggestions, retry, /investigate, and the autofix embeds. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The app's query client turns refetch on window focus off by default, so after a top-up or spend in another tab the meter kept its old numbers while the chat's credit check updated. Its wallet and auto reload queries now refetch on focus too. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Sofia Rest <68917129+srest2021@users.noreply.github.com>
InputSection's usageMeter prop renders whatever it gets in the toolbar under the editor, before the send button. toolbarItems says where it shows rather than what the chat happens to put there today. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The out-of-reloads tooltip link now reads "Configure auto-reload.", so the test finds it by that name and the story describes where it goes. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
billyvg
force-pushed
the
billyvong/cw-2332-sentry-ui-gate-agent-chat-before-sending
branch
from
November 9, 2026 18:48
deb6206 to
1eb7886
Compare
…rward Each forwarded question remounts the chat, but React Query keeps the previous panel's credit-check answer. The check isn't pending while that cached answer exists, so a forwarded question acted on it. If it said the org was out of credits but someone had topped up since, the question was parked in the composer and never sent. useSeerCreditCheck now also returns hasCheckedSinceMount, which only turns true once the check answers or fails after the caller mounted. The chat waits on it instead of isPending. Later window-focus refetches don't hold sends again. Refs CW-2332 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A 402 on send no longer shows a CTA in place of the send error. The error is hidden and the recheck brings up the out-of-credits notice above the composer, which is the only out-of-credits UI the designs have. This also stops that CTA from coming back after a top-up. Refs CW-2332
…-agent-chat-before-sending' into srest2021/CW-2332-chat-out-of-credits-errors # Conflicts: # static/app/views/seerExplorer/components/inputSection.spec.tsx # static/app/views/seerExplorer/components/inputSection.tsx # static/app/views/seerExplorer/components/seerExplorerContent.spec.tsx # static/app/views/seerExplorer/components/seerExplorerContent.tsx # static/gsApp/components/ai/seerCreditUsageMeter.spec.tsx # static/gsApp/components/ai/seerCreditUsageMeter.stories.tsx # static/gsApp/components/ai/seerCreditUsageMeter.tsx
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4d42d2f. Configure here.
A new send doesn't clear the last request error, so after the first 402 later refusals never rechecked, including after a recheck that failed open. Recheck on each refused send instead. Also fold the hidden-error test into the recheck test and fix two stale comments. Refs CW-2332
Base automatically changed from
billyvong/cw-2332-sentry-ui-gate-agent-chat-before-sending
to
master
November 9, 2026 19:32
…hat-out-of-credits-errors
billyvg
approved these changes
Nov 9, 2026
billyvg
added a commit
that referenced
this pull request
Nov 10, 2026
#129565 landed `AUTOFIX_CREDIT_OPERATIONS` and `useAutofixCreditCheck`, which map each autofix action to the operation the credit check prices. The retries here kept their own copy of that map. `useOutOfCreditsRetry` now takes the autofix action and checks it through `useAutofixCreditCheck`, so both gates read one map. The retry also waits on `hasCheckedSinceMount` instead of `isPending`, as the #129565 gates do. A cached answer from an earlier mount no longer enables a retry before this mount's recheck answers. SeerExplorerContent reuses `isRunOutOfCredits`, which #130463 added, for the transcript's out-of-credits line. The chat window story for a run that stopped for credits now shows the composer's out-of-credits alert, which that recheck brings up. The chat window stories gave billing members the credit usage meter even without a wallet fixture, so the meter crashed and took every story in the file with it. Without a wallet the story's viewer is now a member. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch was successfully deployed
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.

relates to CW-2332
depends on #129563, #130283, #130284
The chat's credit check only runs when the panel opens or the window regains focus. If credits run out partway through a conversation, the message box stays enabled and the next send fails with a generic error.
This rechecks credits when:
failure_reason: out_of_credits)so the out-of-credits notice and disabled message box show right away. A 402 no longer shows "There was an error sending your message"; the recheck brings up the notice instead.
The recheck invalidates the credit check query, like
useExplorerAutofixdoes. That neededuseSeerCreditCheckto turn off withenabledinstead ofskipToken, so the key is the same either way.Example (it would show any intermediate thinking as well):
