Skip to content

Commit 02ddd04

Browse files
Claudejmbish04
andcommitted
Add pricing change log and enhanced GitHub issue creation
- Add pricing_change_log table to track price fluctuations - Detect price changes when scraping (new models, increases, decreases) - Enhanced GitHub issues with detailed pricing tables and exact prompts - Issues now show old vs new prices with source URLs - Include actionable fix commands for coding agents Co-authored-by: jmbish04 <26469722+jmbish04@users.noreply.github.com>
1 parent d7c82c1 commit 02ddd04

4 files changed

Lines changed: 325 additions & 44 deletions

File tree

backend/src/db/schemas/agents/pricing.ts

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4646
export type PricingSnapshot = typeof pricingSnapshots.$inferSelect;
4747
export 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

Comments
 (0)