mirror of
https://github.com/coder/coder.git
synced 2026-10-31 19:36:41 +08:00
## Description Prices in `ai_model_prices` come from two places: the price book embedded in each Coder release, and prices set through the experimental CLI (https://github.com/coder/coder/pull/27926). Until now, they were indistinguishable, so the startup seeder re-applied the book over every row, and a price someone set would silently revert on the next restart. This adds a `source` column with values `default` and `custom`, and keeps a row for each. Readers resolve a model to its custom price when one exists and fall back to the book, including the cost path that prices an interception. Keeping both rows means the price book stays current underneath an override, so a future delete can restore it. Note: the endpoint still only accepts models the price book does not cover. Overriding a price the book already carries is handled by the follow-up issue https://linear.app/codercom/issue/AIGOV-594. ## Changes - Add a migration for the `ai_model_price_source` enum and a `source` column, backfilled to `default` and then `NOT NULL`. `source` joins the primary key, so a model can hold one row per source. - Take a `source` parameter on `UpsertAIModelPrices`. Each source keeps its own row, so the price book and a custom price never overwrite each other. - Resolve to the custom price in `GetAIModelPriceByProviderModel` and `GetAIModelPrices`, so both the interception cost snapshot and the list endpoint use it. - Seed the price book as `default`, and write prices set through the endpoint as `custom`. Closes https://linear.app/codercom/issue/AIGOV-592 > [!NOTE] > Initially generated by Claude Opus 5, modified and reviewed by @ssncferreira
18 lines
796 B
SQL
18 lines
796 B
SQL
-- source records where a price came from, either the price book embedded in
|
|
-- each Coder release or a price set through the API. Both can exist for the
|
|
-- same model, so source joins the primary key.
|
|
|
|
CREATE TYPE ai_model_price_source AS ENUM ('default', 'custom');
|
|
|
|
ALTER TABLE ai_model_prices ADD COLUMN source ai_model_price_source;
|
|
|
|
UPDATE ai_model_prices SET source = 'default' WHERE source IS NULL;
|
|
|
|
ALTER TABLE ai_model_prices ALTER COLUMN source SET NOT NULL;
|
|
|
|
ALTER TABLE ai_model_prices DROP CONSTRAINT ai_model_prices_pkey;
|
|
|
|
ALTER TABLE ai_model_prices ADD PRIMARY KEY (provider, model, source);
|
|
|
|
COMMENT ON COLUMN ai_model_prices.source IS 'Where the price came from: default for the embedded price book, custom for a price set through the API. Both can exist for the same model.';
|