SPB Git

Repository Public

index.ts 2.4 KB 45 lines typescript

1/** Spend: today vs the daily cap, the last 7 days, and the last 7 days by model. Real numbers only. */2import type { FastifyInstance } from 'fastify';3import { SpendSummary, type Provider } from '@aos/shared';4import type { Queryable } from '../../db.js';5import { authOf, type Ctx } from '../../http.js';6import { getSettings } from '../settings/store.js';78/**9 * Spend recorded by the kernel for the current day. `spend_days.day` is assumed to be the10 * database's `CURRENT_DATE` (the kernel writes it in the same database session time zone).11 */12export async function todaySpendUsd(db: Queryable): Promise<number> {13  const row = await db.one<{ usd: number }>('SELECT usd::float8 AS usd FROM spend_days WHERE day = CURRENT_DATE');14  return row?.usd ?? 0;15}1617export default async function spendPlugin(app: FastifyInstance, ctx: Ctx): Promise<void> {18  const { db } = ctx;19  app.get('/spend', { config: { doc: { summary: 'Spend summary (today, 7 days, by model over 7 days)', response: SpendSummary, responseName: 'SpendSummary' } } }, async (req): Promise<SpendSummary> => {20    const a = authOf(req);21    const settings = await getSettings(db, a.userId);22    const days = await db.q<{ day: string; usd: number }>(23      `SELECT to_char(d::date, 'YYYY-MM-DD') AS day, coalesce(s.usd, 0)::float8 AS usd24         FROM generate_series(CURRENT_DATE - 6, CURRENT_DATE, interval '1 day') d25         LEFT JOIN spend_days s ON s.day = d::date ORDER BY d`,26    );27    const byModel = await db.q<{ provider: string; model: string; usd: number; input_tokens: number; output_tokens: number }>(28      `SELECT r.provider, r.model,29              coalesce(sum((s.usage->>'usd')::float8), 0)::float8 AS usd,30              coalesce(sum((s.usage->>'inputTokens')::float8), 0)::float8 AS input_tokens,31              coalesce(sum((s.usage->>'outputTokens')::float8), 0)::float8 AS output_tokens32         FROM steps s JOIN runs r ON r.id = s.run_id JOIN missions m ON m.id = r.mission_id33        WHERE m.owner_id = $1 AND s.kind = 'model_call' AND s.usage IS NOT NULL AND s.started_at >= CURRENT_DATE - 634        GROUP BY r.provider, r.model ORDER BY usd DESC, r.model`,35      [a.userId],36    );37    return {38      todayUsd: days[days.length - 1]?.usd ?? 0,39      dailyBudgetUsd: settings.dailyBudgetUsd,40      last7Days: days,41      byModel: byModel.map((r) => ({ provider: r.provider as Provider, model: r.model, usd: r.usd, inputTokens: r.input_tokens, outputTokens: r.output_tokens })),42    };43  });44}45
Files main
Menu

Theme