Skip to content

fix(cloud): reject unknown-priced token inference (#11635) - #11649

Merged
lalalune merged 1 commit into
developfrom
nubs/pricing-fail-closed-nonzero-floor
Jul 2, 2026
Merged

lalalune merged 1 commit into
developfrom
nubs/pricing-fail-closed-nonzero-floor

Conversation

@NubsCarson

@NubsCarson NubsCarson commented Jul 2, 2026

Copy link
Copy Markdown
Member

Fixes #11635.

Policy

Do not sell inference we do not know how to price.

The previous last-resort behavior could bill an uncatalogued, non-zero token side at $0. A later floor-based variant still guessed a price. This PR now fails closed instead:

  • exact catalog rows still win
  • unknown models from already priced providers still use provider-max fallback
  • explicitly configured positive AI_PRICING_FALLBACK_INPUT_USD_PER_M / AI_PRICING_FALLBACK_OUTPUT_USD_PER_M still work
  • AI_PRICING_FALLBACK_*=0, negative, and non-numeric values are rejected as invalid
  • if a non-zero token side has no exact row, no provider-max fallback, and no positive env fallback, calculateTextCostFromCatalog throws Pricing unavailable ... refusing to bill unknown-priced inference
  • a zero-token side still costs $0 and does not require pricing

Evidence

  • bun test src/lib/services/ai-pricing/lookup-missing-pricing.test.ts src/lib/services/ai-pricing/lookup-fallback-pricing.test.ts -> 10 pass
  • bun run --cwd packages/cloud/shared typecheck -> pass
  • bunx @biomejs/biome@2.5.2 check packages/cloud/shared/src/lib/services/ai-pricing/lookup.ts packages/cloud/shared/src/lib/services/ai-pricing/lookup-missing-pricing.test.ts packages/cloud/shared/src/lib/services/ai-pricing/lookup-fallback-pricing.test.ts -> clean
  • git diff --check origin/develop...HEAD and git diff --check -> clean

Money lane; not self-merged.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cfaa3599-bd09-4510-b817-4bcc82022ef9

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nubs/pricing-fail-closed-nonzero-floor

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lalalune lalalune left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed the #11635 fix in a sparse checkout at 96aacaad5c.

Local evidence:

  • bun test packages/cloud/shared/src/lib/services/ai-pricing/lookup-fallback-pricing.test.ts packages/cloud/shared/src/lib/services/ai-pricing/lookup-missing-pricing.test.ts -> 10 pass / 0 fail.
  • bunx @biomejs/biome@2.5.2 check packages/cloud/shared/src/lib/services/ai-pricing/lookup.ts packages/cloud/shared/src/lib/services/ai-pricing/lookup-fallback-pricing.test.ts packages/cloud/shared/src/lib/services/ai-pricing/lookup-missing-pricing.test.ts -> clean.
  • git diff --check origin/develop...HEAD -> clean.

The important bit for me is that the missing-price fallback now returns an explicit non-zero last_resort_floor, so the warning logs match the amount actually billed and both reserve/settle go through the same non-zero path. I also like the AI_PRICING_FALLBACK_*=0 regression coverage; that closes the quiet config footgun.

I attempted bun run --cwd packages/cloud/shared typecheck locally, but this sparse checkout is missing unrelated workspace packages/types (@elizaos/core, @elizaos/security/kms, pg typings, etc.), so CI should remain the source of truth for full package typecheck.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@lalalune

lalalune commented Jul 2, 2026

Copy link
Copy Markdown
Member

Rebased and narrowed this after #11647 landed.

What changed from the original #11649 branch:

Fresh verification in /home/shaw/eliza-worktrees/pr-11649-pricing-floor:

bun test packages/cloud/shared/src/lib/services/ai-pricing/lookup-fallback-pricing.test.ts packages/cloud/shared/src/lib/services/ai-pricing/lookup-missing-pricing.test.ts
=> 9 pass, 0 fail, 42 expect() calls

bunx @biomejs/biome check .github/issue-evidence/11635-pricing-fallback-env-zero.md packages/cloud/shared/src/lib/services/ai-pricing/lookup.ts packages/cloud/shared/src/lib/services/ai-pricing/lookup-fallback-pricing.test.ts --files-ignore-unknown=true
=> clean

git diff --check origin/develop...HEAD
=> clean

bun run --cwd packages/cloud/shared typecheck
=> passed after restoring ignored generated i18n files and linking the isolated worktree workspace dependencies

Manual log review from the focused test: both AI_PRICING_FALLBACK_*=0 sides logged ignoring invalid fallback-rate env value, then billed with fallbackSource: "last_resort" and non-zero unit prices (0.000005 input, 0.000025 output).

@lalalune
lalalune force-pushed the nubs/pricing-fail-closed-nonzero-floor branch from bed9901 to 7abdfef Compare July 2, 2026 22:52

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@lalalune lalalune changed the title fix(cloud): fail-closed last-resort pricing floor — stop $0 free inference on uncatalogued models (#11635) fix(cloud): reject unknown-priced token inference (#11635) Jul 2, 2026
Fail closed when a non-zero token side has no exact catalog row, no provider-max fallback, and no positive AI_PRICING_FALLBACK_* env default. This removes the hardcoded floor approach: we should not sell inference we do not know how to price. Zero-token sides still cost zero without requiring a price, provider-max fallback still covers priced providers, and explicit positive env defaults still work. Env fallback values <= 0 are treated as invalid.
@lalalune
lalalune force-pushed the nubs/pricing-fail-closed-nonzero-floor branch from 7abdfef to 8ae3267 Compare July 2, 2026 22:53

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@lalalune lalalune left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Re-reviewed after the policy change: this no longer guesses a hardcoded floor. Unknown non-zero token pricing now fails closed unless there is an exact catalog row, provider-max fallback, or a positive env fallback; zero-token sides still do not require pricing. Verified after rebasing onto current develop: focused pricing suites 10 pass, cloud-shared typecheck pass, Biome touched files clean, git diff --check clean.

@lalalune
lalalune merged commit 41b323a into develop Jul 2, 2026
30 of 46 checks passed
@lalalune
lalalune deleted the nubs/pricing-fail-closed-nonzero-floor branch July 2, 2026 22:53
@NubsCarson

Copy link
Copy Markdown
Member Author

Agreed — this reject-policy is the right one; it should supersede my #11647. [cloud-money]

@lalalune you're right on both counts. "Do not sell inference we don't know how to price" (throw / fail-closed) is a cleaner policy than my #11647's "bill a conservative frontier-max rate," and keeping the decision inside resolveFallbackTokenRate fixes the observability nit my variant left — after #11647 the loud warning still reports fallbackSource: "none" / a $0 unitPrice while billing non-zero, which is inconsistent. This PR does it right.

Reconciliation (my #11647 already merged to develop, so this needs it): #11649 branched before #11647 merged, so it now conflicts on lookup.ts + lookup-missing-pricing.test.ts + lookup-fallback-pricing.test.ts (all three the same files). The clean resolution is to take #11649's side wholesale — drop my lastResortTokenUnitPrice / LAST_RESORT_USD_PER_MILLION and the "bills non-zero last resort" test assertions, replacing them with this PR's throw + its "refuses to bill unknown-priced inference" tests.

I caused the conflict, so I'm happy to rebase #11649 onto develop and resolve it toward this PR's policy — say the word (or if the author is mid-work, I'll stay clear and just leave this as the merge plan). Either way: this supersedes #11647; my merge only bought the interim "never literally $0" guarantee until this lands.

@claude

claude Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Claude encountered an error —— View job


I'll analyze this and get back to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

money: $0 last-resort fallback pricing → free-inference revenue leak when AI_PRICING_FALLBACK_* unset

2 participants