import { sdk } from '../sdk' import { configFile } from '../file-models/config.json' const { InputSpec, Value } = sdk // Operator-set per-tier monthly subscription prices, in USD. Used by // the dashboard to compute revenue and operating margin (Gemini cost // already comes out of the audit log). Pure accounting — the relay // itself does no billing. const inputSpec = InputSpec.of({ core_price: Value.number({ name: 'Core (Free) — Monthly Price', description: 'Monthly subscription price for the Core tier in USD. Typically $0 since Core is the free entry tier. Used by the dashboard to compute total revenue; leave at 0 unless you actually charge for Core.', required: true, default: 0, min: 0, max: 10_000, integer: false, step: 0.01, units: 'USD', placeholder: null, }), pro_price: Value.number({ name: 'Pro — Monthly Price', description: 'Monthly subscription price for the Pro tier in USD. Should match what you actually charge Pro customers on the licensing side.', required: true, default: 5, min: 0, max: 10_000, integer: false, step: 0.01, units: 'USD', placeholder: null, }), max_price: Value.number({ name: 'Max — Monthly Price', description: 'Monthly subscription price for the Max tier in USD. Should match what you actually charge Max customers on the licensing side.', required: true, default: 15, min: 0, max: 10_000, integer: false, step: 0.01, units: 'USD', placeholder: null, }), }) export const setTierPrices = sdk.Action.withInput( 'set-tier-prices', async ({ effects }) => ({ name: 'Set Tier Prices (USD)', description: 'Configure the monthly USD price you charge per tier. The dashboard uses these numbers to compute revenue and operating margin against Gemini API cost. Has no effect on actual billing — it is for the operator’s accounting view only.', warning: null, allowedStatuses: 'any', group: 'Tiers', visibility: 'enabled', }), inputSpec, async ({ effects }) => { const config = await configFile.read().once() let parsed: any = {} try { parsed = JSON.parse(config?.relay_tier_prices_usd_json || '{}') } catch { parsed = {} } return { core_price: typeof parsed?.core === 'number' ? parsed.core : 0, pro_price: typeof parsed?.pro === 'number' ? parsed.pro : 5, max_price: typeof parsed?.max === 'number' ? parsed.max : 15, } }, async ({ effects, input }) => { const prices = { core: Number(input.core_price ?? 0), pro: Number(input.pro_price ?? 5), max: Number(input.max_price ?? 15), } await configFile.merge(effects, { relay_tier_prices_usd_json: JSON.stringify(prices), }) return null }, )