You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(chatbot): surface AI quota refusals as upgrade/top-up CTA (P1d) (#1777)
Closes the loop opened by the cloud-side pricing rework: when the token guardrail
refuses an AI request with a 429 (free design quota, free data-Q&A trial, or paid
allowance exhausted), the chat UI now shows a friendly upgrade / top-up CTA
instead of a red "Response failed" transport error.
The ai-sdk chat transport throws a plain Error whose `message` is the 429 body
text (no status code preserved), so the only signal is the JSON body.
- tool-display.ts: parseAiQuotaError() — strip retry/format prefixes, locate the
JSON, match the three guardrail codes; null otherwise. + unit tests.
- ChatbotEnhanced.tsx: ErrorBanner renders an amber upgrade card with a CTA
("Upgrade plan" / "Buy a credit pack" for topUp; zh/en by locale) on a quota
refusal; generic errors unchanged. New onUpgrade prop threaded through;
FloatingChatbot forwards it automatically via {...chatbotProps}.
- marketplaceApi.ts: cloudPricingDeepLink() — deep-link to the cloud upgrade
entry (envs list), mirroring cloudInstallDeepLink; centralized for re-pointing.
- AiChatPage.tsx + ConsoleFloatingChatbot.tsx: wire onUpgrade -> open cloud.
Pairs with cloud PR objectstack-ai/cloud#371 (P0+P1a+P1b). Tests: 5
parseAiQuotaError cases pass; changed files typecheck clean. Full browser E2E is
the T8 follow-up.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments