Skip to content

Fix assistant "out of credit" messaging due to stale credits data in the host app#4234

Open
jurgenwerk wants to merge 3 commits intomainfrom
cursor/CS-10438-assistant-credit-message-timing-c640-2
Open

Fix assistant "out of credit" messaging due to stale credits data in the host app#4234
jurgenwerk wants to merge 3 commits intomainfrom
cursor/CS-10438-assistant-credit-message-timing-c640-2

Conversation

@jurgenwerk
Copy link
Contributor

@jurgenwerk jurgenwerk commented Mar 23, 2026

This PR is fixing the bug where if you run out of credits while talking to the assistant, this message will show up and it
will immediately say "Credits added!", even if no credits were actually added. This is confusing and wrong:

image

This happens because we show "Credits added!" when the user has enough credits to continue, but in this case, the credits data in the billing service is stale - the host app thinks the user has enough credits to continue, even after the ai bot sends the "out of credit" error message.

The solution presented here is to reload the credit usage data when "out of credits" error happens, and this way the messaging will be correct, like this:

image

I don't particularly love this solution, I think we should keep our host app in sync with the credits data at all times without refreshing on demand, possibly via subscription. This already works when user makes actions in Stripe (e.g. buying credits), but we don't have the plumbing ready to make this work when the ai-bot is involved. This subscription works with the session room and the communication channel for this is host app <-> realm server. But in this case, the producer of this error is the ai bot, so probably we'd have to figure out a way where on user credit consumption event (which is handled in the ai bot), the ai bot can message the realm server so that the realm server can send a notification to the host app to reload credits data. Perhaps, this is a bit too much for now to fix this small bug, but later on if we need display up-to-date credit amounts in places other than the user profile popover (which triggers a request to get the latest credit data) then I think subscription for credit consumption subscription events would be the right way to go...

@github-actions
Copy link

Preview deployments

@github-actions
Copy link

github-actions bot commented Mar 23, 2026

Host Test Results

    1 files  ±    0      1 suites  ±0   4h 11m 42s ⏱️ + 2h 13m 5s
2 032 tests +   82  2 016 ✅ +   82  15 💤 ± 0  0 ❌ ±0  1 🔥 ±0 
4 013 runs  +2 049  3 981 ✅ +2 034  30 💤 +15  1 ❌ ±0  1 🔥 ±0 

For more details on these errors, see this check.

Results for commit 2b71337. ± Comparison against base commit fffbaff.

♻️ This comment has been updated with latest results.

@jurgenwerk jurgenwerk force-pushed the cursor/CS-10438-assistant-credit-message-timing-c640-2 branch from 93e77b5 to 30aa309 Compare March 23, 2026 13:21
@jurgenwerk jurgenwerk marked this pull request as ready for review March 23, 2026 14:40
@jurgenwerk jurgenwerk requested a review from Copilot March 23, 2026 14:41
@jurgenwerk jurgenwerk changed the title Fix assistant credit message timing Fix assistant "out of credit" messaging Mar 23, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4d3574dcc4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +371 to +372
if (!this.billingService.loadingSubscriptionData) {
await this.billingService.loadSubscriptionData();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Force a post-load refresh before deciding credit state

This guard skips the reload entirely whenever a subscription fetch is already in progress, but the in-flight request may have started before the out-of-credits event was emitted (for example during initial panel load or a concurrent billing notification). In that case the request can resolve with stale credits, and because no second fetch is triggered, the message can keep showing the wrong action state. The reload path should ensure a fresh fetch happens after any in-flight load completes instead of returning early.

Useful? React with 👍 / 👎.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses confusing “out of credits” UI behavior by having the AI-bot mark out-of-credits errors with a flag that instructs the host app to reload billing/subscription data, ensuring the correct follow-up messaging (retry vs buy credits).

Changes:

  • Add a Matrix event content key (app.boxel.reloadBillingData) and plumb it through error events from runtime-common → ai-bot.
  • Extend host message parsing to capture the flag and trigger a one-time billing data reload when the most recent message indicates it.
  • Add an integration test covering the “reload billing data on flagged out-of-credits message” flow.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/runtime-common/matrix-constants.ts Adds a new Matrix content key constant for reload-billing behavior.
packages/runtime-common/ai/matrix-utils.ts Extends sendErrorEvent to optionally include the reload-billing flag in error message content.
packages/host/tests/integration/components/ai-assistant-panel/general-test.gts Adds an integration test verifying billing reload happens once and updates the UI actions.
packages/host/app/lib/matrix-classes/message.ts Adds reloadBillingData to the host Message model shape.
packages/host/app/lib/matrix-classes/message-builder.ts Parses the new Matrix content flag onto Message.reloadBillingData.
packages/host/app/components/matrix/room.gts Passes “most recent message” info down to message components.
packages/host/app/components/matrix/room-message.gts Threads isMostRecentMessage and reloadBillingData through to the AI assistant message component.
packages/host/app/components/ai-assistant/message/index.gts Adds a modifier + task to reload billing data when the most recent message is flagged.
packages/ai-bot/main.ts Flags the out-of-credits error with reloadBillingData: true.
packages/ai-bot/lib/responder.ts Extends onError to accept and forward options.
packages/ai-bot/lib/matrix/response-publisher.ts Extends sendError to forward options into sendErrorEvent.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +371 to +375
if (!this.billingService.loadingSubscriptionData) {
await this.billingService.loadSubscriptionData();
}
});

Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reloadBillingDataTask skips calling loadSubscriptionData() when loadingSubscriptionData is already true. If the in-flight request started before the AI bot consumed credits (or before the out-of-credits error), its response can still be stale; skipping here means the UI may never refresh to the post-consumption values. Consider making BillingService.loadSubscriptionData() de-dupe/return an in-flight promise (so callers can await it) or, at minimum, queue a follow-up reload after the current load completes when this flag is set.

Suggested change
if (!this.billingService.loadingSubscriptionData) {
await this.billingService.loadSubscriptionData();
}
});
await this.billingService.loadSubscriptionData();
});

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@jurgenwerk jurgenwerk requested review from a team and IanCal March 23, 2026 14:49
@jurgenwerk jurgenwerk changed the title Fix assistant "out of credit" messaging Fix assistant "out of credit" messaging due to stale credits data in the host app Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants