@@ -17,19 +17,19 @@ export const pricingSnapshots = sqliteTable(
1717 provider : text ( 'provider' , { enum : [ 'openai' , 'anthropic' , 'google' , 'cloudflare' ] } ) . notNull ( ) ,
1818 modelId : text ( 'model_id' ) . notNull ( ) , // e.g., 'gpt-4o', 'claude-sonnet-4.5'
1919 modelName : text ( 'model_name' ) . notNull ( ) , // Human-readable name
20-
20+
2121 // Base pricing (standard context)
2222 inputCostPerM : real ( 'input_cost_per_m' ) . notNull ( ) , // Cost per 1M input tokens
2323 outputCostPerM : real ( 'output_cost_per_m' ) . notNull ( ) , // Cost per 1M output tokens
24-
24+
2525 // Long context pricing (>200k tokens)
2626 inputLongCostPerM : real ( 'input_long_cost_per_m' ) , // Nullable
2727 outputLongCostPerM : real ( 'output_long_cost_per_m' ) , // Nullable
28-
28+
2929 // Caching costs
3030 cacheReadCostPerM : real ( 'cache_read_cost_per_m' ) , // Nullable
3131 cacheWriteCostPerM : real ( 'cache_write_cost_per_m' ) , // Nullable
32-
32+
3333 // Metadata
3434 metadata : text ( 'metadata' ) , // JSON string for additional data
3535 sourceUrl : text ( 'source_url' ) . notNull ( ) , // URL where pricing was scraped
@@ -45,3 +45,49 @@ export const pricingSnapshots = sqliteTable(
4545
4646export type PricingSnapshot = typeof pricingSnapshots . $inferSelect ;
4747export type NewPricingSnapshot = typeof pricingSnapshots . $inferInsert ;
48+
49+ /**
50+ * Tracks changes to AI model pricing over time
51+ * Used to maintain a changelog of pricing fluctuations
52+ */
53+ export const pricingChangeLog = sqliteTable (
54+ 'pricing_change_log' ,
55+ {
56+ id : text ( 'id' ) . primaryKey ( ) , // UUID
57+ provider : text ( 'provider' , { enum : [ 'openai' , 'anthropic' , 'google' , 'cloudflare' ] } ) . notNull ( ) ,
58+ modelId : text ( 'model_id' ) . notNull ( ) ,
59+ modelName : text ( 'model_name' ) . notNull ( ) ,
60+
61+ // Change type
62+ changeType : text ( 'change_type' , { enum : [ 'new_model' , 'price_increase' , 'price_decrease' , 'no_change' ] } ) . notNull ( ) ,
63+
64+ // Old pricing (null for new models)
65+ oldInputCostPerM : real ( 'old_input_cost_per_m' ) ,
66+ oldOutputCostPerM : real ( 'old_output_cost_per_m' ) ,
67+ oldInputLongCostPerM : real ( 'old_input_long_cost_per_m' ) ,
68+ oldOutputLongCostPerM : real ( 'old_output_long_cost_per_m' ) ,
69+ oldCacheReadCostPerM : real ( 'old_cache_read_cost_per_m' ) ,
70+ oldCacheWriteCostPerM : real ( 'old_cache_write_cost_per_m' ) ,
71+
72+ // New pricing
73+ newInputCostPerM : real ( 'new_input_cost_per_m' ) . notNull ( ) ,
74+ newOutputCostPerM : real ( 'new_output_cost_per_m' ) . notNull ( ) ,
75+ newInputLongCostPerM : real ( 'new_input_long_cost_per_m' ) ,
76+ newOutputLongCostPerM : real ( 'new_output_long_cost_per_m' ) ,
77+ newCacheReadCostPerM : real ( 'new_cache_read_cost_per_m' ) ,
78+ newCacheWriteCostPerM : real ( 'new_cache_write_cost_per_m' ) ,
79+
80+ // Metadata
81+ sourceUrl : text ( 'source_url' ) . notNull ( ) ,
82+ detectedAt : integer ( 'detected_at' , { mode : 'timestamp' } ) . notNull ( ) ,
83+ } ,
84+ ( table ) => ( {
85+ providerIdx : index ( 'pricing_change_provider_idx' ) . on ( table . provider ) ,
86+ modelIdIdx : index ( 'pricing_change_model_id_idx' ) . on ( table . modelId ) ,
87+ detectedAtIdx : index ( 'pricing_change_detected_at_idx' ) . on ( table . detectedAt ) ,
88+ changeTypeIdx : index ( 'pricing_change_type_idx' ) . on ( table . changeType ) ,
89+ } )
90+ ) ;
91+
92+ export type PricingChangeLog = typeof pricingChangeLog . $inferSelect ;
93+ export type NewPricingChangeLog = typeof pricingChangeLog . $inferInsert ;
0 commit comments