g1t/services/billing/migrations/0040_ai_credit.sql
| 1 | -- Prepaid AI credit, the agent's own rate, budgets and quantities. |
| 2 | -- |
| 3 | -- AI is prepaid: a workspace buys AI credit (Stripe Checkout, one-time), |
| 4 | -- optionally reloads it from its saved card, and model usage draws on it |
| 5 | -- first (credit_grants with kind purchased, scope models, source purchase: |
| 6 | -- see grants.rs and ai.rs). g1t never fronts a model's cost for a |
| 7 | -- workspace on the plan: at $0 of AI credit, new runs on g1t's models stop |
| 8 | -- until credit is bought or auto-reload is on. |
| 9 | -- |
| 10 | -- Pricing changes, as dated price versions with a public record: |
| 11 | -- |
| 12 | -- - Agent models (`agent_models`): what the model provider charged, with no |
| 13 | -- markup from 2026-10-08 (was cost plus 20%). A fall: it applies at once. |
| 14 | -- - The g1t agent rate (`agent_tokens`): a flat price per million tokens an |
| 15 | -- agent's run used (input, output and cached), for what g1t adds around |
| 16 | -- the model: context, memory, routing and orchestration. $0.25 a million. |
| 17 | -- New, so a rise from nothing: it takes effect after the 14 days' notice |
| 18 | -- (2026-10-22), and owners on the plan are emailed once. |
| 19 | -- - AI Gateway (`gateway_models`): the provider's price with no markup |
| 20 | -- while it is in beta. A price-book value, so it can change without a |
| 21 | -- deploy, with notice like any other rise. |
| 22 | -- - Card processing fee on AI credit bought by card: Stripe's fee, passed |
| 23 | -- on as its own line (`card_fee_percent` per dollar charged and |
| 24 | -- `card_fee_fixed` per payment). Never on invoiced billing. Switched by |
| 25 | -- the `card_fee` cost setting (`on` or `off`). |
| 26 | |
| 27 | INSERT OR IGNORE INTO prices (meter, title, unit, cost_micros, markup_percent, source, updated_at) VALUES |
| 28 | ('agent_models', 'Agent models', 'provider dollar', 1000000, 20, 'list', '2026-10-08T00:00:00Z'), |
| 29 | ('agent_tokens', 'g1t agent rate', 'million tokens', 0, 0, 'list', '2026-10-08T00:00:00Z'), |
| 30 | ('gateway_models', 'AI Gateway models', 'provider dollar', 1000000, 0, 'list', '2026-10-08T00:00:00Z'), |
| 31 | ('card_fee_percent', 'Card processing fee', 'dollar charged', 29000, 0, 'list', '2026-10-08T00:00:00Z'), |
| 32 | ('card_fee_fixed', 'Card processing fee', 'payment', 300000, 0, 'list', '2026-10-08T00:00:00Z'); |
| 33 | |
| 34 | -- Version 1 is what was charged until now; the next versions wait for |
| 35 | -- their date and are applied by the daily run (pricing.rs), which writes |
| 36 | -- the public record in price_changes. |
| 37 | INSERT OR IGNORE INTO price_versions (id, meter, version, cost_micros, markup_percent, effective_at, reason, created_by, created_at, applied_at) VALUES |
| 38 | ('pv_agent_models_1', 'agent_models', 1, 1000000, 20, '2026-10-01T00:00:00Z', |
| 39 | 'Models at what the provider charged plus 20%', 'migration', '2026-10-08T00:00:00Z', '2026-10-08T00:00:00Z'), |
| 40 | ('pv_agent_models_2', 'agent_models', 2, 1000000, 0, '2026-10-08T00:00:00Z', |
| 41 | 'Models at what the provider charged, with no markup: g1t''s own work around them is the agent rate now', 'migration', '2026-10-08T00:00:00Z', NULL), |
| 42 | ('pv_agent_tokens_1', 'agent_tokens', 1, 0, 0, '2026-10-08T00:00:00Z', |
| 43 | 'The g1t agent rate, not charged yet', 'migration', '2026-10-08T00:00:00Z', '2026-10-08T00:00:00Z'), |
| 44 | ('pv_agent_tokens_2', 'agent_tokens', 2, 250000, 0, '2026-10-22T00:00:00Z', |
| 45 | 'New: $0.25 per million tokens an agent''s run uses (input, output and cached), for context, memory, routing and orchestration; models themselves are no longer marked up', 'migration', '2026-10-08T00:00:00Z', NULL), |
| 46 | ('pv_gateway_models_1', 'gateway_models', 1, 1000000, 0, '2026-10-08T00:00:00Z', |
| 47 | 'AI Gateway at the provider''s price, free of any markup while it is in beta', 'migration', '2026-10-08T00:00:00Z', '2026-10-08T00:00:00Z'), |
| 48 | ('pv_card_fee_percent_1', 'card_fee_percent', 1, 29000, 0, '2026-10-08T00:00:00Z', |
| 49 | 'Stripe''s card fee on AI credit bought by card, passed on as its own line', 'migration', '2026-10-08T00:00:00Z', '2026-10-08T00:00:00Z'), |
| 50 | ('pv_card_fee_fixed_1', 'card_fee_fixed', 1, 300000, 0, '2026-10-08T00:00:00Z', |
| 51 | 'Stripe''s card fee on AI credit bought by card, passed on as its own line', 'migration', '2026-10-08T00:00:00Z', '2026-10-08T00:00:00Z'); |
| 52 | |
| 53 | INSERT OR IGNORE INTO price_changes (id, meter, old_cost_micros, new_cost_micros, markup_percent, reason, created_at) VALUES |
| 54 | ('prc_gateway_models', 'gateway_models', 1000000, 1000000, 0, 'New: AI Gateway at the provider''s price, free of any markup while it is in beta', '2026-10-08T00:00:00Z'), |
| 55 | ('prc_card_fee', 'card_fee_percent', 29000, 29000, 0, 'New: Stripe''s card fee (2.9% + $0.30) on AI credit bought by card, as its own line; none on invoiced billing', '2026-10-08T00:00:00Z'); |
| 56 | |
| 57 | INSERT OR IGNORE INTO cost_settings (key, value, updated_at, updated_by) VALUES |
| 58 | ('card_fee', 'on', '2026-10-08T00:00:00Z', 'migration'); |
| 59 | |
| 60 | -- A payment page for AI credit is a checkout with feature `ai_credit`: |
| 61 | -- `amount_cents` is the credit, and this the card fee on top. |
| 62 | ALTER TABLE checkouts ADD COLUMN fee_cents INTEGER NOT NULL DEFAULT 0; |
| 63 | |
| 64 | -- How much of something a usage line was: sandbox seconds, tokens. Null on |
| 65 | -- lines from before, which are counted as entries. |
| 66 | ALTER TABLE ledger ADD COLUMN quantity REAL; |
| 67 | -- What a sandbox line was for: agent, check, workflow, queue or deploy, so |
| 68 | -- the Usage page shows an agent's sandbox time under Agent. |
| 69 | ALTER TABLE ledger ADD COLUMN compute TEXT; |
| 70 | |
| 71 | -- The tokens a run's agent rate was charged for, so a later count charges |
| 72 | -- only what is new. |
| 73 | ALTER TABLE runs ADD COLUMN agent_tokens INTEGER NOT NULL DEFAULT 0; |
| 74 | |
| 75 | -- Auto-reload: when AI credit falls below the threshold, the saved card is |
| 76 | -- charged (off-session, an idempotency key per attempt) to bring it back |
| 77 | -- to the target, at most `monthly_max_micros` a calendar month. Off by |
| 78 | -- default; a failed charge turns it off and tells the owners. |
| 79 | CREATE TABLE IF NOT EXISTS ai_reload ( |
| 80 | workspace TEXT PRIMARY KEY, |
| 81 | enabled INTEGER NOT NULL DEFAULT 0, |
| 82 | threshold_micros INTEGER NOT NULL, |
| 83 | target_micros INTEGER NOT NULL, |
| 84 | monthly_max_micros INTEGER NOT NULL, |
| 85 | updated_by TEXT NOT NULL, |
| 86 | updated_at TEXT NOT NULL, |
| 87 | failed_at TEXT, |
| 88 | error TEXT |
| 89 | ); |
| 90 | |
| 91 | -- Each reload: its key is the idempotency key Stripe saw, so a retry of |
| 92 | -- the same attempt is the same payment. |
| 93 | CREATE TABLE IF NOT EXISTS ai_reloads ( |
| 94 | id TEXT PRIMARY KEY, |
| 95 | workspace TEXT NOT NULL, |
| 96 | -- YYYY-MM, for the monthly maximum. |
| 97 | month TEXT NOT NULL, |
| 98 | amount_micros INTEGER NOT NULL, |
| 99 | fee_micros INTEGER NOT NULL DEFAULT 0, |
| 100 | payment_intent TEXT, |
| 101 | -- pending, paid or failed. |
| 102 | status TEXT NOT NULL, |
| 103 | error TEXT, |
| 104 | created_at TEXT NOT NULL |
| 105 | ); |
| 106 | CREATE INDEX IF NOT EXISTS ai_reloads_by_month ON ai_reloads (workspace, month); |
| 107 | |
| 108 | -- Budgets: the owners' monthly spend limit, with which alerts to send |
| 109 | -- (comma-separated percents), whether usage pauses at 100%, and an |
| 110 | -- optional webhook told at each alert. |
| 111 | ALTER TABLE limits ADD COLUMN alert_levels TEXT; |
| 112 | ALTER TABLE limits ADD COLUMN pause_at_limit INTEGER NOT NULL DEFAULT 1; |
| 113 | ALTER TABLE limits ADD COLUMN budget_webhook TEXT; |