Open
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.

sandbox size fixes
sandboxes are not burning cash
Greptile Summary
This PR introduces a per-project model picker (MiniMax M2.5, Claude Haiku 4.5, GPT-5.4) and a significant sandbox cost-control overhaul: the three separate Autumn meters (tokens-in, tokens-out, sandbox-hours) are collapsed into a single
ai_budgetUSD-micros meter with per-model pricing, sandbox auto-stop is enforced at 2 idle minutes, and disk-full errors now surface a clear user-facing message and reset flow. It also adds snapshot migration, GitHub App installation token auth, and per-message stats.Key changes:
ai_budgetbilling meter replacestokens_in/tokens_out/sandbox_hoursacrossusage.ts,billing/, and all UI componentsresetProAiBudgetBalancesinternal action resets pro subscribers' monthly budget — but it is not scheduled incrons.ts, so budgets will never automatically resetisOriginAllowed(http.ts): the secondif (allowedOrigins.size === 0)block is unreachable after the first local-dev checksnapshotName+errorKindon instances,statson messages, and a newgithubInstallationstableConfidence Score: 2/5
resetProAiBudgetBalancesis implemented but never scheduled in crons.ts, preventing pro users' monthly budget reset. This is a breaking issue for the pro plan. A secondary issue: unreachable dead-code block inhttp.tsshould be removed for code clarity. Both issues must be fixed before merging.Comments Outside Diff (13)
apps/web/src/convex/instances/actions.ts, line 147-151 (link)Project model field is never used
generateBtcaConfigalways writesDEFAULT_MODEL/DEFAULT_PROVIDERto the btca config file, even when a project has a custom model stored in the DB (set via thesyncMCP action which callsupdateProjectModelInternal). This means the model picker has no effect on what model btca actually uses, because the config file is overwritten with the hardcoded values every time the sandbox wakes.To wire it up,
getResourceConfigs(or a sibling helper) would need to also return the project'smodelfield, and that value would then be passed intogenerateBtcaConfigin place ofDEFAULT_MODEL.apps/web/src/convex/instances/actions.ts, line 525-531 (link)opencodeVersionnever populatedgetInstalledVersionsonly readsbtca --versionand theInstalledVersionstype only hasbtcaVersion. The schema, store, and UI all now referenceopencodeVersion/latestOpencodeVersion, but there is no code path that sets these fields — neither here during provisioning/waking, nor incheckVersionswhich only fetches the latest btca package.As a result,
opencodeVersionwill always benullin the store and the UI will always display "Unknown" for the opencode version row added inInstanceCard.svelte.apps/web/autumn.config.ts, line 490-495 (link)included_usage: 5should be5_000_000microsThe
ai_budgetfeature tracks usage in micros (1 USD = 1_000_000 micros), but the Autumn product is configured withincluded_usage: 5. This means pro users get only 5 micros per month (~$0.000005), which is far below the intended $5/month budget defined inPRO_AI_BUDGET_MICROS = 5_000_000.Because
ensureUsageAvailablecomparesproUsage.aiBudget.balance >= requiredBudgetMicrosand a trivial 100-token request already requires hundreds of micros, this will cause every pro request to fail the usage check the moment the balance (only 5) is depleted after the very first interaction.apps/web/src/convex/http.ts, line 1140-1142 (link)Dead code — second
allowedOrigins.size === 0check is unreachableThe first
if (allowedOrigins.size === 0)block above this line always returns, so this second identical check can never be reached. The original fallbackreturn falsefor an empty allowed-origins set is now silently dropped, but the logic is already covered above.Simply remove this block.
apps/web/autumn.config.ts, line 591-594 (link)included_usageshould be5_000_000, not5The billing code (
aiBudget.ts) tracks usage in micros (PRO_AI_BUDGET_MICROS = 5_000_000), andtrackUsageis called withchargedBudgetMicros. The Autumn feature balance is also compared against micros inusage.ts:With
included_usage: 5, a Pro user would exhaust their entire monthly budget after roughly 5 micros of spend — effectively after the very first message. The PLAN.md also explicitly specifiesincluded_usage: 5_000_000.apps/web/autumn.config.ts, line 56-60 (link)ai_budgetincluded_usageis wrong — should be5_000_000, not5The code tracks AI budget in micros. The budget calculation functions in
aiBudget.tsreturn values in micros (totalAiBudgetMicros,getPreflightAiBudgetMicros), and the usage check at line 842 ofusage.tscomparesproUsage.aiBudget.balance >= requiredBudgetMicros.With
included_usage: 5, a pro user's balance will only be 5 micros. A typical short message toclaude-haiku-4-5with ~100 input + 100 output tokens already costs ~600 micros. This will cause every preflight check to fail and lock out all pro users after their first message.PLAN.md(Phase 2) andaiBudget.ts(PRO_AI_BUDGET_MICROS = 5 * 1_000_000 = 5_000_000) confirm the intended value.apps/web/src/convex/http.ts, line 241-243 (link)Dead code: duplicate
allowedOrigins.size === 0checkThe second
if (allowedOrigins.size === 0)block (lines 241–243) is unreachable. IfallowedOrigins.sizewere0, execution would have already returned inside the first block (lines 232–239). Thereturn falsehere is never hit; execution always falls through toreturn allowedOrigins.has(origin).apps/web/src/convex/http.ts, line 241-243 (link)Dead code: unreachable second
allowedOrigins.size === 0checkThe first
if (allowedOrigins.size === 0)block at lines 232–239 always returns (eithertrue/falsefrom the localhost check, orfalsefrom the catch). The second identical check at this location is unreachable and should be removed to avoid confusion.apps/web/src/convex/usage.ts, line 546 (link)Silent fallback to success URL when
checkout_urlis missingThe code silently redirects to the checkout success page if Autumn's
attachcall returns nocheckout_url:If Autumn returns success but no
checkout_url(e.g., due to an API contract change or unexpected response shape), users will silently skip the checkout flow without paying. This differs fromcreateBillingPortalSessionUrl(line 571–578), which properly validates and returns an error when the URL is missing.Consider at minimum logging a warning, or returning an error if
checkout_urlis absent — especially since billing is at stake.apps/web/src/convex/instances/actions.ts, line 1254 (link)updateInstanceInternalcallsuploadBtcaConfig(sandbox, resources)without passing a model, so it always defaults toclaude-haiku-4-5. This overwrites the user's selected model in the config. If the sandbox is running, it immediately restarts with the wrong model (line 1282).Compare to
wakeInstanceInternal(line 1125), which correctly retrieves the project's model viagetSandboxModelConfig(ctx, instanceId, projectId)before uploading. The fix requires either:projectIdtoupdateInstanceInternal's signature and passing it touploadBtcaConfig, orapps/web/src/convex/http.ts, line 287-289 (link)The second
if (allowedOrigins.size === 0)check (lines 287-289) is unreachable. The first check at line 278 already handles all branches whereallowedOrigins.size === 0and returns in all cases. This block can be safely removed.apps/web/src/convex/http.ts, line 288-290 (link)The second
if (allowedOrigins.size === 0)check is unreachable dead code. The first check at line 279 always returns (eitherlocalDevHosts.has(...)orfalsein the catch block), so execution never reaches this second check. Remove this dead block and keep onlyreturn allowedOrigins.has(origin);apps/web/src/convex/usage.ts, line 969-1024 (link)resetProAiBudgetBalancesis defined as an internal action but is never scheduled as a cron job. Pro users' AI budgets will never reset, effectively breaking the pro tier. Add this entry toapps/web/src/convex/crons.ts:Last reviewed commit: b8cb2eb