fix(cloud): gate ensureElizaAppProvisioning on credits (return insufficient_credits, don't 500 onboarding) (#11499) - #11679
Conversation
…icient_credits, don't 500 onboarding) (#11499)
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
Closes #11499.
The gap
ensureElizaAppProvisioning(packages/cloud/shared/src/lib/services/eliza-app/provisioning.ts) was the only provisioning entry point that skipped the otherwise-universalcheckAgentCreditGate— every other create/provision/resume/wake/restart path runs the gate beforecreateAgent. It is reached from the public onboarding chat (runOnboardingChat,onboarding-chat.ts), so a drained returning org (starter grant already consumed, no live sandbox) could still mint a container. And becauserunOnboardingChathas no enclosing try/catch, a throwing gate would have 500'd the whole onboarding turn — hence the return-a-status design below.Fix (as prescribed by @lalalune on #11499)
provisioning.ts— afterensureElizaAppStarterCredits(so fresh orgs get the $5 grant and pass the $0.10MINIMUM_DEPOSITgate) and after the existing-sandbox early return (so an org with a live sandbox still gets it back untouched), callcheckAgentCreditGate(organizationId)beforecreateAgent. On!allowed, log a warn and return{ status: "insufficient_credits", agentId: null, bridgeUrl: null, sandbox: null }instead of throwing. The reuse guard and the enqueue-throw cleanup are unchanged.onboarding-chat.ts— mapped the new status in the reply path:fallbackReply: new branch → "You're out of credits… Add credits at<app>/dashboard/billingand I'll start your private agent." (reusesELIZA_APP_PRICING_SUMMARY+ the existingonboardingAppPathhelper).generateOnboardingReply: early deterministic return forinsufficient_credits(money-state copy stays exact — the model never improvises billing links/amounts).Type note:
ElizaAppProvisioningStatus.statusis typedstring(not a literal union), and every consumer does plain===checks ("running","error","none") — no exhaustive switch anywhere, so the new value is additive-safe.publicElizaAppProvisioningPayloadpasses it through and already omits the nullagentId/bridgeUrl, so the wire payload for a denial is{ status: "insufficient_credits" }— consistent with the canonicalinsufficient_creditscode used by the 402 body and cron agent-billing.Tests (
provisioning.test.ts)!allowed) →createAgent/enqueueAgentProvision/addCreditsNOT called, result is exactly theinsufficient_creditsstatus.allowedand asserts it was called — grant lands before the gate, so fresh orgs still provision.mock.modulepattern (../agent-billing-gate), reset inbeforeEachlike the other mocks.Files
packages/cloud/shared/src/lib/services/eliza-app/provisioning.tspackages/cloud/shared/src/lib/services/eliza-app/onboarding-chat.tspackages/cloud/shared/src/lib/services/eliza-app/provisioning.test.tsCaveat
Local typecheck/tests couldn't run (box at 100% disk, worktree has no node_modules); static-verified by grep (export exists,
CreditGateResult.allowed/.balanceshape matches usage, no exhaustive status switches,onboarding-chat.test.tsfully mocks./provisioningso the new import chain doesn't leak there). CI must confirm typecheck +provisioning.test.ts.@lalalune — this is your prescribed approach from #11499 verbatim; flagging for your review. Not self-merging.
— [cloud-security]