fix(meet): recognize backend capacity gate and surface an actionable message#4221
Conversation
The meet capacity-gate detection compared the backend error text for exact
equality against the frontend SERVER_OVERLOADED_MESSAGE constant. That
constant was changed to friendlier copy and no longer equals the backend's
actual wording ('Mascot streaming capacity is exhausted. Please try again
later.'), and apiClient strips errorCode — so the check never fired and the
raw, generic backend string leaked to users on the Send-to-Google-Meet panel.
Add isCapacityGateMessage() (case-insensitive substring match on the backend
wording), surface the tailored actionable copy when gated, and apply the same
mapping in the meet panel's two error paths. Update the unit test to mock the
REAL backend message (which would have caught the mismatch) plus direct
coverage for the matcher.
Closes tinyhumansai#4151
📝 WalkthroughWalkthroughThe meeting-bots flow now treats backend capacity-gate responses as a special case, shows a localized overload message in the card, and adds the new translation key across locales. Tests cover the helper and updated join error handling. ChangesMeeting bot capacity-gate handling
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 88d5124d77
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const raw = meetError?.trim() || t('skills.meetingBots.failedToStart'); | ||
| // A capacity-gate error carries the backend's terse "…try again later." | ||
| // wording; show the tailored, actionable copy instead (#4151). | ||
| const message = isCapacityGateMessage(raw) ? SERVER_OVERLOADED_MESSAGE : raw; |
There was a problem hiding this comment.
Use i18n for capacity-gate copy
For capacity-gated joins in non-English locales, this new branch surfaces the hard-coded English SERVER_OVERLOADED_MESSAGE in both the inline alert and toast instead of going through useT(). The repo AGENTS.md i18n rule requires all UI text to use translation keys with locale entries, so this bypass will leave localized builds showing English precisely on the new error path.
Useful? React with 👍 / 👎.
The capacity-gate branch surfaced the hard-coded English SERVER_OVERLOADED_MESSAGE in the inline alert and toast, bypassing useT() — localized builds would show English on this error path. Add skills.meetingBots.serverOverloaded (with real translations in all 14 locales) and route both error paths through t(). Addresses @chatgpt-codex-connector on app/src/components/skills/MeetingBotsCard.tsx:268
Wrap the BACKEND_CAPACITY_MESSAGE literal to satisfy format:check (the failing Frontend Checks CI step).
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/src/components/skills/MeetingBotsCard.tsx (1)
264-300: 🎯 Functional Correctness | 🟠 MajorPropagate the overload signal through
joinMeetViaBackendBot()
handleSubmitonly getsCore rejected the agent_meetings_join request., soisCapacityGateMessage()never sees the backend overload text here andskills.meetingBots.serverOverloadedcan’t be shown on this path. Surface the backend’s overload message or a dedicated flag from the core RPC layer instead.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@app/src/components/skills/MeetingBotsCard.tsx` around lines 264 - 300, Propagate the backend overload signal through joinMeetViaBackendBot so handleSubmit can recognize it and show skills.meetingBots.serverOverloaded. Right now the catch path in MeetingBotsCard.tsx only receives a generic Core rejected the agent_meetings_join request message, so isCapacityGateMessage() never matches; update the core RPC result/error handling to preserve the backend’s overload text or return a dedicated flag, and then use that in handleSubmit before calling setError/onToast.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@app/src/components/skills/MeetingBotsCard.tsx`:
- Around line 264-300: Propagate the backend overload signal through
joinMeetViaBackendBot so handleSubmit can recognize it and show
skills.meetingBots.serverOverloaded. Right now the catch path in
MeetingBotsCard.tsx only receives a generic Core rejected the
agent_meetings_join request message, so isCapacityGateMessage() never matches;
update the core RPC result/error handling to preserve the backend’s overload
text or return a dedicated flag, and then use that in handleSubmit before
calling setError/onToast.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 33059cde-2ebf-4911-a6e1-9c1c9f2f6e3b
📒 Files selected for processing (17)
app/src/components/skills/MeetingBotsCard.tsxapp/src/lib/i18n/ar.tsapp/src/lib/i18n/bn.tsapp/src/lib/i18n/de.tsapp/src/lib/i18n/en.tsapp/src/lib/i18n/es.tsapp/src/lib/i18n/fr.tsapp/src/lib/i18n/hi.tsapp/src/lib/i18n/id.tsapp/src/lib/i18n/it.tsapp/src/lib/i18n/ko.tsapp/src/lib/i18n/pl.tsapp/src/lib/i18n/pt.tsapp/src/lib/i18n/ru.tsapp/src/lib/i18n/zh-CN.tsapp/src/services/__tests__/joinMeetingViaMascotBot.test.tsapp/src/services/meetCallService.ts
Summary
The meet capacity-gate detection in
meetCallService.tscompared the backend error text for exact equality against the frontendSERVER_OVERLOADED_MESSAGEconstant. That constant was changed to friendlier copy and no longer equals the backend's actual wording ('Mascot streaming capacity is exhausted. Please try again later.'— backendsrc/utils/paidPlan.ts), and the sharedapiClientstripserrorCode(only forwardserror/message). So the check never fired and the raw, generic backend string ("…try again later.") leaked to users on the Send-to-Google-Meet panel instead of the tailored, actionable copy — the issue's main complaint (#4151).Fix
isCapacityGateMessage()— a case-insensitive substring match on the backend wording (streaming capacity/capacity is exhausted), resilient to minor wording drift on either side.SERVER_OVERLOADED_MESSAGE("…try again in a few minutes") whenever the gate is recognized, in bothjoinMeetingViaMascotBotand the meet panel's two error paths (MeetingBotsCard.tsx).Scope note
The active capacity gate and the trigger ultimately live in the backend (the openhuman desktop meet path — core RPC
agent_meetings_join→ backendbot:join— is currently open-access). This PR fixes the openhuman-side capacity-gate detection + message contract so that whenever the gate is surfaced the user sees an informative, actionable notice rather than the raw generic text. Fully re-scoping the gate so it never trips for fresh/zero-session users is a backend concern (tinyhumansai/backendpaidPlan/routes/mascots) outside this repo.Closes #4151
Summary by CodeRabbit