Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Costs: Cloudflare's subscriptions read from Cloudflare each day, the estimate only until then; sudo's costs split into Costs & margin and Bill & pricing | 1 | /** |
| 2 | * Costs & margin and Bill & pricing: one report from billing, read by both | |
| 3 | * pages, and the changes staff make on either. | |
| 4 | */ | |
| 5 | import { data, redirect } from "react-router"; | |
| 6 | ||
| Merge platform pause and the hourly usage watcher: staff can pause compute, schedules, indexing or renders for everyone, the watcher emails on a breach and is never blind quietly, and the models proxy holds each run to its cap (billing 0051, integrations 0006) | 7 | import { parseCostSettings, parseMapping, parsePauseLevel, parseRange } from "./costs"; |
| Costs: Cloudflare's subscriptions read from Cloudflare each day, the estimate only until then; sudo's costs split into Costs & margin and Bill & pricing | 8 | import { admin } from "./services.server"; |
| 9 | import { settle } from "./settle"; | |
| 10 | import { requireStaff } from "./staff"; | |
| 11 | ||
| 12 | export const DONE: Record<string, string> = { | |
| 13 | run: "Ran the analysis: read Cloudflare's bill, reconciled the last 31 days and checked the alerts. The figures below are fresh.", | |
| 14 | approved: "Approved. A fall applies now; a rise after the notice period, and owners on the plan are emailed.", | |
| 15 | rejected: "Rejected, with the note kept for whoever measures it next.", | |
| 16 | settings: "Guardrails saved. They apply from the next run.", | |
| 17 | mapping: "Mapping saved. It applies from the next run; read the bill now to see it.", | |
| 18 | removed: "Mapping removed.", | |
| The site no longer has g1t's own agents. g1t is where the coding agents you already use do their work, so the Agents mode is gone from the rail, with every page under /<workspace>/-/agents: personas, faces, skills, abilities, routines, computers, sessions and agent spend. Customize (skills, connectors, plugins, marketplaces), the context hub, model providers, the AI Gateway page, the Spend page and pill, Ask g1t, and the repository's Agents, Plans and agent settings pages go too, and their addresses now answer 404. | 19 | lifted: "Breaker lifted for the rest of today (UTC). Paused work starts again; it is recorded in the audit log.", |
| Merge platform pause and the hourly usage watcher: staff can pause compute, schedules, indexing or renders for everyone, the watcher emails on a breach and is never blind quietly, and the models proxy holds each run to its cap (billing 0051, integrations 0006) | 20 | paused: "Paused across g1t. Every service sees it within 30 seconds; it is recorded in the audit log.", |
| 21 | resumed: "Resumed across g1t. Every service sees it within 30 seconds; it is recorded in the audit log.", | |
| Costs: Cloudflare's subscriptions read from Cloudflare each day, the estimate only until then; sudo's costs split into Costs & margin and Bill & pricing | 22 | }; |
| 23 | ||
| 24 | export type CostsActionResult = { error: string; section: string; values?: Record<string, string> }; | |
| 25 | ||
| 26 | export async function costsLoader(request: Request, context: unknown) { | |
| 27 | requireStaff(context as Parameters<typeof requireStaff>[0]); | |
| 28 | const url = new URL(request.url); | |
| 29 | const range = parseRange(url.searchParams.get("days")); | |
| Merge platform pause and the hourly usage watcher: staff can pause compute, schedules, indexing or renders for everyone, the watcher emails on a breach and is never blind quietly, and the models proxy holds each run to its cap (billing 0051, integrations 0006) | 30 | const [report, guard] = await Promise.all([settle(admin.costs(range)), settle(admin.platformGuard())]); |
| Costs: Cloudflare's subscriptions read from Cloudflare each day, the estimate only until then; sudo's costs split into Costs & margin and Bill & pricing | 31 | const done = url.searchParams.get("done"); |
| 32 | return { | |
| 33 | range, | |
| 34 | bucket: url.searchParams.get("product"), | |
| 35 | report: report.ok ? report.value : null, | |
| 36 | error: report.ok ? null : report.error, | |
| Merge platform pause and the hourly usage watcher: staff can pause compute, schedules, indexing or renders for everyone, the watcher emails on a breach and is never blind quietly, and the models proxy holds each run to its cap (billing 0051, integrations 0006) | 37 | // The platform pause and usage watch (billing's platform.rs). |
| 38 | guard: guard.ok ? guard.value : null, | |
| 39 | guardError: guard.ok ? null : guard.error, | |
| Costs: Cloudflare's subscriptions read from Cloudflare each day, the estimate only until then; sudo's costs split into Costs & margin and Bill & pricing | 40 | done: done ? (DONE[done] ?? null) : null, |
| 41 | }; | |
| 42 | } | |
| 43 | ||
| 44 | export async function costsAction(request: Request, context: unknown) { | |
| 45 | const staff = requireStaff(context as Parameters<typeof requireStaff>[0]); | |
| 46 | const form = await request.formData(); | |
| 47 | const intent = String(form.get("intent") ?? ""); | |
| 48 | const fail = (section: string, error: string) => | |
| 49 | data<CostsActionResult>({ error, section, values: Object.fromEntries([...form.entries()].map(([k, v]) => [k, String(v)])) }, { status: 422 }); | |
| 50 | const back = (done: string, hash = "") => { | |
| 51 | const url = new URL(request.url); | |
| 52 | url.searchParams.set("done", done); | |
| 53 | return redirect(`${url.pathname}${url.search}${hash}`); | |
| 54 | }; | |
| 55 | if (intent === "run") { | |
| 56 | const run = await settle(admin.runCosts(staff.email)); | |
| 57 | if (!run.ok) return fail("run", `Billing did not answer: ${run.error}`); | |
| 58 | if (!run.value.ok) return fail("run", run.value.error.message); | |
| 59 | if (run.value.value.problems.length > 0) return fail("run", run.value.value.problems.join(" ")); | |
| 60 | throw back("run"); | |
| 61 | } | |
| 62 | if (intent === "lift") { | |
| 63 | const note = String(form.get("note") ?? "").trim().slice(0, 500); | |
| 64 | if (note.length < 5) return fail("lift", "Say why it is lifted, for whoever looks next."); | |
| 65 | const result = await settle(admin.liftBreaker(note, staff.email)); | |
| 66 | if (!result.ok) return fail("lift", `Billing did not answer: ${result.error}`); | |
| 67 | if (!result.value.ok) return fail("lift", result.value.error.message); | |
| 68 | throw back("lifted", "#spend"); | |
| 69 | } | |
| Merge platform pause and the hourly usage watcher: staff can pause compute, schedules, indexing or renders for everyone, the watcher emails on a breach and is never blind quietly, and the models proxy holds each run to its cap (billing 0051, integrations 0006) | 70 | if (intent === "pause" || intent === "resume") { |
| 71 | const level = parsePauseLevel(form.get("level")); | |
| 72 | if (!level) return fail("platform", "Pick compute, schedules, indexing or renders."); | |
| 73 | const note = String(form.get("note") ?? "").trim().slice(0, 500); | |
| 74 | if (note.length < 5) return fail(`pause-${level}`, "Say why, for whoever looks next."); | |
| 75 | const result = await settle(admin.setPause(level, intent === "pause", note, staff.email)); | |
| 76 | if (!result.ok) return fail(`pause-${level}`, `Billing did not answer: ${result.error}`); | |
| 77 | if (!result.value.ok) return fail(`pause-${level}`, result.value.error.message); | |
| 78 | throw back(intent === "pause" ? "paused" : "resumed", "#platform"); | |
| 79 | } | |
| Costs: Cloudflare's subscriptions read from Cloudflare each day, the estimate only until then; sudo's costs split into Costs & margin and Bill & pricing | 80 | if (intent === "decide") { |
| 81 | const id = String(form.get("id") ?? ""); | |
| 82 | const decision = form.get("decision") === "approve" ? "approve" : "reject"; | |
| 83 | const note = String(form.get("note") ?? "").trim().slice(0, 500); | |
| 84 | if (decision === "reject" && note.length < 5) return fail(`proposal-${id}`, "Say why it is rejected, for whoever measures it next."); | |
| 85 | const result = await admin.decideProposal(id, decision, note, staff.email); | |
| 86 | if (!result.ok) return fail(`proposal-${id}`, result.error.message); | |
| 87 | throw back(decision === "approve" ? "approved" : "rejected", "#proposals"); | |
| 88 | } | |
| 89 | if (intent === "settings") { | |
| 90 | const parsed = parseCostSettings(form); | |
| 91 | if (!parsed.ok) return fail("settings", parsed.error); | |
| 92 | const result = await admin.setCostSettings(parsed.value, staff.email); | |
| 93 | if (!result.ok) return fail("settings", result.error.message); | |
| 94 | throw back("settings", "#guardrails"); | |
| 95 | } | |
| 96 | if (intent === "mapping") { | |
| 97 | const parsed = parseMapping(form); | |
| 98 | if (!parsed.ok) return fail("mapping", parsed.error); | |
| 99 | const result = await admin.setCostMapping(parsed.value, staff.email); | |
| 100 | if (!result.ok) return fail("mapping", result.error.message); | |
| 101 | throw back(parsed.value.remove ? "removed" : "mapping", "#mappings"); | |
| 102 | } | |
| 103 | return fail("run", "Unknown change."); | |
| 104 | } |
This file's history is long; its oldest lines are credited to the oldest commit read.