GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — feat: add organization-scoped AI model prices by SasSwart · Pull Request #30690 · coder/coder

Conversation

@SasSwart

@SasSwart SasSwart commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Adds organization-scoped AI model prices as an overlay on the site-wide price catalog, so the same model can be priced differently per organization, either for every provider of a type or for one configured provider. Pricing one configured provider is the only way to price openai-compat gateways such as LiteLLM routing to Bedrock.

Token usage is priced by the most specific match: the organization's price for the configured provider, then its price for the provider type, then a site-wide custom price, then the price book. The requested model is still preferred over the model the provider reports. Each token usage record now stores which kind of price matched and its keys (price_kind, price_organization_id, price_provider_id, price_provider). These are stored only, not exposed in the API.

New experimental, AI Gateway licensed routes are GET, POST and DELETE on /api/experimental/organizations/{organization}/ai/model-prices, authorized against ResourceAiModelPrice.InOrg(org), so only owners and org admins can use them. The site-wide routes are unchanged.

Interceptions don't carry an organization yet, so the lookup passes none and only site-wide prices apply at runtime for now. Org matching is covered by database tests with explicit org IDs. The migration (000621) only adds tables, an enum and nullable columns, and needs no backfill.

Closes AIGOV-612. Replaces #30396.

Known issue: GetUnpricedAIModelsSince now counts a model as priced when any organization has a provider-ID price for it. Org prices aren't applied at runtime yet, so such a model can drop out of the unpriced-models report while its usage still records a NULL cost.

Design and decisions (from AIGOV-612)

Kinds of price, in lookup order, most specific first:

  1. One org, one configured provider (provider ID). New table ai_org_provider_model_prices, primary key (organization_id, provider_id, model). The provider type comes from ai_providers.
  2. One org, every provider of a type. New table ai_org_model_prices, primary key (organization_id, provider, model), with CHECK (provider <> 'openai-compat').
  3. Site-wide custom price for a provider type. Existing ai_model_prices, unchanged.
  4. Site-wide default from the built-in price book. Existing ai_model_prices, unchanged.

Decisions

  • Org prices always win over site-wide prices. There are no site-wide provider-ID prices.
  • Blanket openai-compat prices stay rejected, because each gateway can route to a different upstream. Allowing them later would be additive.
  • Foreign keys to organizations and ai_providers use ON DELETE CASCADE. Prices for soft-deleted providers are never matched and are hidden by the API.
  • The lookup is one UNION ALL query of primary-key lookups, ordered first by whether the row is for the requested model, then by kind. The ai_model_price_kind enum is declared most specific first.
  • No feature flag: the endpoints are experimental and licensed, and org prices take effect only once set.
  • Site-wide routes are unchanged, including POST returning 204, which the coderd_ai_model_price Terraform resource depends on.
  • The org comes from the route. Upserts take provider or provider_id; a provider_id must be a live provider, and a provider given alongside it must match its type. Invalid entries, duplicate keys and blanket openai-compat prices return 400, and nothing is written.
  • GET on the org route returns every price that applies to the org. By default it lists effective prices, so an org type price hides the matching site-wide prices. source=all lists every row. Each row shows its scope.
  • Org prices are identified by their natural key. DELETE takes provider_id or provider, plus model, in the query string, because model names can contain slashes. There is no surrogate ID for now.
  • All three tables are kept, and the matched kind is recorded per token usage record but not exposed yet (Sas Swart, 13 Oct).

Out of scope: the UI (AIGOV-699), Terraform support for org prices (AIGOV-710), and passing the organization from interceptions into the lookup, which depends on org context work.


This PR was generated by Coder Agents on behalf of @SasSwart.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@SasSwart
Address problems in: Add org-scoped AI model price overlays
4299b9a
@linear-code

linear-code Bot commented Oct 13, 2026

Copy link
Copy Markdown

AIGOV-612

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot assigned SasSwart Oct 13, 2026
This was referenced Oct 13, 2026
refactor(enterprise/coderd): extract AI model price body decoding and validation #30716
Merged
feat(coderd/database): add organization AI model config table #30717
Merged
feat(coderd): add queries for organization AI model prices #30718
Merged
feat(coderd): price token usage with organization prices #30719
Merged
feat: add organization AI model price API #30720
Closed
@SasSwart

SasSwart commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

This PR is split into a stack for easier review: #30716 → #30717 → #30718 → #30719 → #30720. The top of the stack (#30720) has the same git tree as this PR (82ddb955dc). This PR can be closed in favor of the stack.


This comment was generated by Coder Agents on behalf of @SasSwart.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@SasSwart

SasSwart commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

Closing: superseded by the stack #30716 → #30719, which has merged.


This comment was generated by Coder Agents.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@SasSwart SasSwart closed this Oct 26, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 26, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

@ibetitsmike ibetitsmike Awaiting requested review from ibetitsmike ibetitsmike will be requested when the pull request is marked ready for review ibetitsmike is a code owner
@johnstcn johnstcn Awaiting requested review from johnstcn johnstcn will be requested when the pull request is marked ready for review johnstcn is a code owner
@ssncferreira ssncferreira Awaiting requested review from ssncferreira ssncferreira will be requested when the pull request is marked ready for review ssncferreira is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@SasSwart SasSwart

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@SasSwart
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.