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.
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 1 | import type { ComputeKind, Reservation } from "./compute"; |
| 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) | 2 | import type { PauseLevel } from "./platform"; |
| Deploy scripts live in the repository | 3 | import type { User, Viewer } from "./identity"; |
| 4 | import type { RepoPath } from "./repos"; | |
| 5 | import type { Result } from "./result"; | |
| 6 | ||
| 7 | /** Millionths of a US dollar in one dollar: the unit money is held in. */ | |
| 8 | export const MICROS_PER_DOLLAR = 1_000_000; | |
| 9 | ||
| 10 | /** Whether workspaces are charged for agents at all, and with real money. */ | |
| 11 | export type BillingStatus = { | |
| 12 | /** | |
| 13 | * False when no card processor is configured: nothing is charged, and who | |
| 14 | * may run agents is decided some other way. | |
| 15 | */ | |
| 16 | enabled: boolean; | |
| 17 | /** False while the card processor is in its test mode, where cards are not real. */ | |
| 18 | live: boolean; | |
| 19 | /** | |
| 20 | * True while g1t is being built out: runs are recorded with what they | |
| 21 | * cost, but nothing is charged and no credit is needed. Not forever. | |
| 22 | */ | |
| 23 | free?: boolean; | |
| 24 | }; | |
| 25 | ||
| 26 | /** A workspace's standing. */ | |
| 27 | export type BillingAccount = { | |
| 28 | workspace: string; | |
| 29 | /** | |
| 30 | * Credit left, in millionths of a dollar. Can dip below zero by the cost | |
| 31 | * of the runs that were under way when it ran out. | |
| 32 | */ | |
| 33 | balanceMicros: number; | |
| 34 | status: BillingStatus; | |
| 35 | /** What is added to a run's cost, in percent. */ | |
| 36 | marginPercent: number; | |
| Billing on Stripe's pages, month-end charges, warnings; sudo by workspace | 37 | /** The card charged near the limit and when a month closes, if one is saved. */ |
| 38 | card?: { brand: string; last4: string; expMonth: number; expYear: number } | null; | |
| Deploy scripts live in the repository | 39 | }; |
| 40 | ||
| 41 | /** One line of a workspace's statement. */ | |
| 42 | export type LedgerEntry = { | |
| 43 | id: string; | |
| 44 | /** Credit bought with a card, or an agent's run. */ | |
| 45 | kind: "top_up" | "usage"; | |
| 46 | /** Positive for credit added, negative for usage. */ | |
| 47 | amountMicros: number; | |
| 48 | description: string; | |
| 49 | /** For usage: the repository and pull request the agent worked on. */ | |
| 50 | repo: string | null; | |
| 51 | number: number | null; | |
| 52 | /** For usage: `implement`, `review` or `update`. */ | |
| 53 | task: string | null; | |
| 54 | /** For usage: the model, by its public name. */ | |
| 55 | model: string | null; | |
| 56 | /** For usage: who paid the model provider. */ | |
| 57 | billedTo: "g1t" | "workspace"; | |
| 58 | /** For a top-up: the username of whoever paid. */ | |
| 59 | createdBy: string | null; | |
| 60 | /** RFC 3339. */ | |
| 61 | createdAt: string; | |
| Billing on Stripe's pages, month-end charges, warnings; sudo by workspace | 62 | /** The workspace the line belongs to, which tells an enterprise's lines apart. */ |
| 63 | workspace?: string | null; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 64 | /** For usage: what the plan's included usage paid of it. `amountMicros` is what is left to pay. */ |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 65 | creditMicros?: number; |
| 66 | /** For usage: what the workspace's trial credit paid of it. */ | |
| 67 | trialMicros?: number; | |
| 68 | /** For usage: what g1t's open-source pool paid of it. */ | |
| 69 | ossMicros?: number; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 70 | /** For usage: what g1t covered itself, such as a trial's last run past its credit. */ |
| 71 | givenMicros?: number; | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 72 | /** For usage: what the account's discount took off its price. */ |
| 73 | discountMicros?: number; | |
| 74 | /** For a credit from g1t, and for what of one expired or was revoked: its kind. */ | |
| 75 | creditKind?: CreditKind; | |
| Deploy scripts live in the repository | 76 | }; |
| 77 | ||
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 78 | /** |
| 79 | * Why g1t gave a workspace credit. Promotional (a welcome, a referral) and | |
| 80 | * goodwill (an apology) are given away when spent; a refund gives back | |
| 81 | * money already paid, and never expires. | |
| 82 | */ | |
| 83 | export type CreditKind = "promotional" | "goodwill" | "refund" | "purchased"; | |
| 84 | ||
| 85 | /** One credit g1t gave, with what of it was used: spent before anything paid in advance, the soonest-expiring first. */ | |
| 86 | export type CreditGrant = { | |
| 87 | /** `crd_…`, the grant's ledger reference. */ | |
| 88 | id: string; | |
| 89 | workspace: string; | |
| 90 | kind: CreditKind; | |
| 91 | amountMicros: number; | |
| 92 | usedMicros: number; | |
| 93 | /** What can still be spent: nothing once it expired or was revoked. */ | |
| 94 | leftMicros: number; | |
| 95 | note: string; | |
| 96 | /** A refund: what it refunds, and the day of it. */ | |
| 97 | refundFor?: string | null; | |
| 98 | refundDay?: string | null; | |
| 99 | /** RFC 3339; null never expires. */ | |
| 100 | expiresAt: string | null; | |
| 101 | createdBy: string; | |
| 102 | createdAt: string; | |
| 103 | state: "open" | "used" | "expired" | "revoked"; | |
| 104 | closedAt?: string | null; | |
| 105 | closedNote?: string | null; | |
| 106 | closedBy?: string | null; | |
| 107 | /** What expiring or revoking took off the balance. */ | |
| 108 | closedMicros?: number; | |
| 109 | /** What it pays for: all usage, or models only (spent first). */ | |
| 110 | scope?: "all" | "models"; | |
| 111 | /** Where it came from. */ | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 112 | source?: "staff" | "purchase" | "promo_code" | "upgrade"; |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 113 | }; |
| 114 | ||
| 115 | /** A workspace's credits from g1t, newest first. */ | |
| 116 | export type Credits = { grants: CreditGrant[]; leftMicros: number }; | |
| 117 | ||
| 118 | /** One month's credits of one kind: given, spent that month, and taken back unused. */ | |
| 119 | export type CreditMonth = { | |
| 120 | month: string; | |
| 121 | kind: CreditKind; | |
| 122 | givenMicros: number; | |
| 123 | grants: number; | |
| 124 | usedMicros: number; | |
| 125 | expiredMicros: number; | |
| 126 | revokedMicros: number; | |
| 127 | }; | |
| 128 | ||
| 129 | /** Every credit g1t gave (at most 200, filtered), the last 12 months by kind, and who gave them. */ | |
| 130 | export type AdminCredits = { grants: CreditGrant[]; months: CreditMonth[]; staff: string[] }; | |
| 131 | ||
| 132 | /** What a credit from sudo is, past its amount and note. */ | |
| 133 | export type CreditOptions = { | |
| 134 | kind: CreditKind; | |
| 135 | /** RFC 3339; never for a refund. */ | |
| 136 | expiresAt?: string | null; | |
| 137 | /** A refund: what it is for, and the day refunded (`YYYY-MM-DD`). */ | |
| 138 | refundFor?: string | null; | |
| 139 | refundDay?: string | null; | |
| 140 | }; | |
| 141 | ||
| Deploy scripts live in the repository | 142 | /** What lets a sandbox, and nothing else, report what its run cost. */ |
| 143 | export type RunTicket = { runId: string; token: string }; | |
| 144 | ||
| 145 | /** | |
| 146 | * What agents cost, charged to the workspace they worked for. A workspace | |
| 147 | * buys credit; each run deducts its cost plus g1t's margin; with no credit, | |
| 148 | * no agent starts. | |
| 149 | */ | |
| 150 | /** | |
| 151 | * The free allowance on g1t's hosted models for a workspace not otherwise | |
| 152 | * open to them: a few dollars of model cost each, out of one pool, until a | |
| 153 | * date. Mirrors `Trial` in `crates/contracts/src/billing.rs`. | |
| 154 | */ | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 155 | /** |
| 156 | * How an account is charged. Standard unless g1t set otherwise in sudo: | |
| 157 | * custom terms are a discount (0 to 100%), a ceiling, or both. A 100% | |
| 158 | * discount charges nothing and shows the usage at its price. `comped` is | |
| 159 | * from before discounts and reads as 100%; billing no longer writes it. | |
| 160 | */ | |
| Billing accounts, terms and enterprises; g1t is no longer free | 161 | export type Terms = { |
| 162 | kind: "standard" | "comped" | "custom"; | |
| 163 | discountPercent: number; | |
| 164 | ceilingMicros: number | null; | |
| 165 | note: string; | |
| 166 | until: string | null; | |
| 167 | setBy: string | null; | |
| 168 | setAt: string | null; | |
| 169 | }; | |
| 170 | ||
| 171 | /** | |
| 172 | * Who pays: a workspace's own account, or an enterprise's, which pays for | |
| 173 | * several workspaces with one bill and one limit. | |
| 174 | */ | |
| 175 | export type PayingAccount = { | |
| 176 | id: string; | |
| 177 | kind: "workspace" | "enterprise"; | |
| 178 | name: string; | |
| 179 | terms: Terms; | |
| 180 | workspaces: string[]; | |
| Stripe webhooks, enterprise invoices, and sudo for both | 181 | /** Where an enterprise's invoices go. */ |
| 182 | billingEmail?: string | null; | |
| 183 | /** An enterprise's invoices, newest first. */ | |
| 184 | invoices?: EnterpriseInvoice[]; | |
| Billing accounts, terms and enterprises; g1t is no longer free | 185 | createdAt: string; |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 186 | /** What g1t staff set for the account beyond its terms. */ |
| 187 | allowances?: Allowances; | |
| 188 | }; | |
| 189 | ||
| 190 | /** Set per account by g1t staff in sudo, on top of its terms. */ | |
| 191 | export type Allowances = { | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 192 | /** The g1t plan without its monthly price; usage is charged as usual. Comped accounts have it anyway. */ |
| 193 | plan: boolean; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 194 | /** Each public repository's monthly cap on g1t's open-source pool; null for the default. */ |
| 195 | ossRepoMicros: number | null; | |
| 196 | /** Each workspace's trial credit, outside the monthly pool; null for the default. */ | |
| 197 | trialMicros: number | null; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 198 | /** Agents at once, in place of the plan's (2 in the first month or on the trial, then 10); null for the default. */ |
| 199 | maxConcurrentAgents?: number | null; | |
| 200 | /** One run's spend cap, in place of the owners' and the default $2; null for none. */ | |
| 201 | runCapMicros?: number | null; | |
| 202 | /** What one issue's agents may spend in all, in place of the owners' and the default $10; null for none. */ | |
| 203 | issueCapMicros?: number | null; | |
| Audit logs are kept by plan: a week on free, 90 days on the plan, and what staff set for an account in sudo | 204 | /** Days of audit log its workspaces keep, in place of the plan's (7 free, 90 on the plan), longer or shorter; null for the plan's. */ |
| 205 | auditRetentionDays?: number | null; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 206 | /** A hold on new compute, with why; null for none. */ |
| 207 | hold?: string | null; | |
| Billing accounts, terms and enterprises; g1t is no longer free | 208 | }; |
| 209 | ||
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 210 | // --- Entitlements, and compute started under a reservation ------------------ |
| 211 | // | |
| 212 | // Every service that starts compute asks billing first: | |
| 213 | // 1. `entitlements(workspace)`: what it may do at all, its caps, and whether compute is paused. | |
| 214 | // 2. `reserve(...)`: holds the estimate against what may pay for it, so starts at the same moment | |
| 215 | // cannot overshoot together. Answers who pays first, or refuses with a stable code | |
| 216 | // (`not_paid`, `trial_used`, `limit`, `paused`, `oss_pool_empty`) and a message for the owner. | |
| 217 | // 3. `settle(reservationId, actualMicros)`: releases the hold. The charge goes on the ledger the usual way. | |
| 218 | // A reservation never settled lapses after `RESERVATION_HOURS`. | |
| 219 | ||
| 220 | /** A reservation that is never settled stops holding after this long. */ | |
| 221 | export const RESERVATION_HOURS = 3; | |
| 222 | /** What a ceiling reads as when there is none (g1t's own workspaces). */ | |
| 223 | export const UNLIMITED_MICROS = 1_000_000_000_000_000; | |
| 224 | ||
| 225 | /** What a workspace pays g1t on, as far as compute is concerned. Mirrors `PlanKind`. */ | |
| 226 | export type PlanKind = "free" | "paid" | "internal" | "enterprise"; | |
| 227 | ||
| 228 | // `ComputeKind` (what compute is for), `PaidBy` (who pays first: credit, trial, oss, on_demand) and | |
| 229 | // `Reservation` are in `./compute`, with the gate that calls `reserve` and `settle`. | |
| 230 | ||
| 231 | /** One level reached: 50, 75, 90 or 100 percent. */ | |
| 232 | export type UsageAlert = { | |
| 233 | /** `included` (the plan's included usage), `spend_limit` or `ceiling`. */ | |
| 234 | meter: "included" | "spend_limit" | "ceiling" | string; | |
| 235 | level: number; | |
| 236 | usedMicros: number; | |
| 237 | limitMicros: number; | |
| 238 | message: string; | |
| 239 | }; | |
| 240 | ||
| 241 | /** An hour's spend well above the workspace's usual: new compute waits for an owner. */ | |
| 242 | export type Spike = { | |
| 243 | id: string; | |
| 244 | /** `open` (waiting), `continued` (keep going) or `stopped`. */ | |
| 245 | status: "open" | "continued" | "stopped" | string; | |
| 246 | hourMicros: number; | |
| 247 | averageMicros: number; | |
| 248 | detectedAt: string; | |
| 249 | decidedBy?: string | null; | |
| 250 | decidedAt?: string | null; | |
| 251 | /** While continued: until when, unless spend doubles again first. */ | |
| 252 | until?: string | null; | |
| 253 | }; | |
| 254 | ||
| 255 | /** What a workspace may do now. Mirrors `Entitlements` in `crates/contracts/src/billing.rs`. */ | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 256 | export type Entitlements = { |
| 257 | workspace: string; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 258 | plan: PlanKind; |
| 259 | /** May start sandboxes, models, deployments and semantic search at all: paid, internal, enterprise, or free with trial credit left. */ | |
| 260 | compute: boolean; | |
| 261 | /** The one-time trial credit left; 0 if none or used. */ | |
| 262 | trialMicrosLeft: number; | |
| 263 | /** A card check has been done; the trial and the open-source pool need it. */ | |
| 264 | trialVerified: boolean; | |
| 265 | /** A paid workspace still in its first billing cycle. */ | |
| 266 | firstMonth: boolean; | |
| 267 | /** 2 in the first month or on the trial, 10 after; staff can override it. */ | |
| 268 | maxConcurrentAgents: number; | |
| 269 | /** 60 in the first month or on the trial; otherwise the guardrails' own caps. */ | |
| 270 | maxRunMinutes: number; | |
| 271 | /** One run's spend cap, $2 by default; staff can override it. */ | |
| 272 | runCapMicros: number; | |
| 273 | /** Agent spend on one issue in all, $10 by default. */ | |
| 274 | issueCapMicros: number; | |
| 275 | /** g1t's ceiling on usage not yet paid for; `UNLIMITED_MICROS` for g1t's own; 0 for free. */ | |
| 276 | ceilingMicros: number; | |
| 277 | /** Usage not yet paid for this month, prepayment taken off. */ | |
| 278 | exposureMicros: number; | |
| 279 | /** Why new compute is paused, for the owner; null when it is not. */ | |
| 280 | paused: string | null; | |
| 281 | /** What open reservations hold now. */ | |
| 282 | heldMicros?: number; | |
| 283 | /** Paid in advance and not used yet. */ | |
| 284 | prepaidMicros?: number; | |
| 285 | /** The plan's included usage each month, and what of it is used. */ | |
| 286 | includedMicros?: number; | |
| 287 | includedUsedMicros?: number; | |
| Audit logs are kept by plan: a week on free, 90 days on the plan, and what staff set for an account in sudo | 288 | /** How far back the audit log can be read and exported, and what is kept: the plan's days, or what g1t staff set for the account. */ |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 289 | auditRetentionDays: number; |
| Audit logs are kept by plan: a week on free, 90 days on the plan, and what staff set for an account in sudo | 290 | /** Whether `auditRetentionDays` is what staff set for the account rather than the plan's. */ |
| 291 | auditRetentionCustom?: boolean; | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 292 | /** Private repository storage free for every workspace: past it, the plan pays and a free workspace's pushes stop. */ |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 293 | freePrivateStorageBytes: number; |
| 294 | /** The last daily measure of the workspace's private repositories (a lower bound). */ | |
| 295 | privateStorageBytes: number; | |
| Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member | 296 | /** On a paid plan: package storage past the free amounts is charged, never refused. */ |
| 297 | hasPlan?: boolean; | |
| 298 | /** Package storage free for every workspace (public, and private): past it a free workspace's pushes are refused. */ | |
| 299 | packagePublicFreeBytes?: number; | |
| 300 | packagePrivateFreeBytes?: number; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 301 | /** What g1t's open-source pool paid for the workspace this month. */ |
| 302 | ossPaidMicros: number; | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 303 | /** Deploy build time this month, every second of it metered. */ |
| 304 | buildSecondsUsed?: number; | |
| 305 | /** Git operations this month, and how many are free for every workspace. */ | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 306 | gitOperations?: number; |
| 307 | gitOperationsIncluded?: number; | |
| 308 | /** The smallest amount a card is charged when a month closes. */ | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 309 | minChargeMicros: number; |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 310 | /** A spend spike waiting for an owner, or decided. */ |
| 311 | spike?: Spike | null; | |
| 312 | /** Where usage stands against what is included and the limits, from 50%. */ | |
| 313 | alerts?: UsageAlert[]; | |
| 314 | }; | |
| 315 | ||
| 316 | /** A hold on a start's estimated cost, as billing answers it (`Reservation` in `./compute`, and more). */ | |
| 317 | export type ReservationHeld = Reservation & { | |
| 318 | /** What is held, at cost; may be less than the estimate for a free workspace's last bit of trial. */ | |
| 319 | heldMicros?: number; | |
| 320 | /** When the hold lapses if never settled. */ | |
| 321 | expiresAt?: string; | |
| 322 | }; | |
| 323 | ||
| 324 | /** A request to g1t: a higher limit, or help with usage past what was meant. */ | |
| 325 | export type LimitRequest = { | |
| 326 | id: string; | |
| 327 | workspace: string; | |
| 328 | kind: "limit" | "overage" | string; | |
| 329 | amountMicros: number; | |
| 330 | reason: string; | |
| 331 | expectedMonthlyMicros: number; | |
| 332 | status: "open" | "approved" | "declined" | string; | |
| 333 | decidedMicros?: number | null; | |
| 334 | decidedBy?: string | null; | |
| 335 | /** The answer, as the owner sees it. */ | |
| 336 | answer?: string | null; | |
| 337 | createdBy: string; | |
| 338 | createdAt: string; | |
| 339 | decidedAt?: string | null; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 340 | }; |
| 341 | ||
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 342 | /** What staff see beside a request. */ |
| 343 | export type WorkspaceHistory = { | |
| 344 | plan: PlanKind | null; | |
| 345 | months: MonthFigures[]; | |
| 346 | paidClearedMicros: number; | |
| 347 | payments: number; | |
| 348 | disputes: number; | |
| 349 | declines: number; | |
| 350 | firstSeen: string | null; | |
| 351 | ceilingMicros: number | null; | |
| 352 | maxCeilingMicros: number | null; | |
| 353 | spendLimitMicros: number | null; | |
| 354 | lastHourMicros: number; | |
| 355 | averageHourMicros: number; | |
| 356 | lastDayMicros: number; | |
| 357 | }; | |
| 358 | ||
| 359 | export type LimitRequestReview = { request: LimitRequest; history: WorkspaceHistory }; | |
| 360 | ||
| 361 | /** What a one-time goodwill credit comes to: the margin on the overage, always, plus its cost up to the cap. */ | |
| 362 | export type Goodwill = { | |
| 363 | overageMicros: number; | |
| 364 | marginMicros: number; | |
| 365 | costMicros: number; | |
| 366 | creditMicros: number; | |
| 367 | absorbedMicros: number; | |
| 368 | }; | |
| 369 | ||
| 370 | /** A workspace whose month went well past its usual, or hit a spike. */ | |
| 371 | export type Overage = { | |
| 372 | workspace: string; | |
| 373 | plan: PlanKind; | |
| 374 | typicalMonthMicros: number; | |
| 375 | thisMonthMicros: number; | |
| 376 | costMicros: number; | |
| 377 | marginMicros: number; | |
| 378 | spike: Spike | null; | |
| 379 | topEntries: LedgerEntry[]; | |
| 380 | goodwill: Goodwill; | |
| 381 | goodwillAvailable: boolean; | |
| 382 | lastGoodwillAt: string | null; | |
| 383 | request: LimitRequest | null; | |
| 384 | }; | |
| 385 | ||
| 386 | /** One workspace's recent pace. */ | |
| 387 | export type Velocity = { | |
| 388 | workspace: string; | |
| 389 | plan: PlanKind; | |
| 390 | lastHourMicros: number; | |
| 391 | averageHourMicros: number; | |
| 392 | lastDayMicros: number; | |
| 393 | thisMonthMicros: number; | |
| 394 | ratio: number; | |
| 395 | spike: Spike | null; | |
| 396 | firstSeen: string | null; | |
| 397 | }; | |
| 398 | ||
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 399 | /** g1t's capped budgets for free usage this month. */ |
| 400 | export type Pools = { | |
| 401 | month: string; | |
| 402 | trialGrantedMicros: number; | |
| 403 | trialPoolMicros: number; | |
| 404 | trialGrants: number; | |
| 405 | ossUsedMicros: number; | |
| 406 | ossPoolMicros: number; | |
| 407 | ossRepoMicros: number; | |
| 408 | }; | |
| 409 | ||
| Billing accounts, terms and enterprises; g1t is no longer free | 410 | export type AccountSummary = { |
| 411 | account: PayingAccount; | |
| 412 | limit: Limit; | |
| 413 | chargedMicros: number; | |
| 414 | costMicros: number; | |
| 415 | paidMicros: number; | |
| Billing on Stripe's pages, month-end charges, warnings; sudo by workspace | 416 | /** The same figures for each of the account's workspaces that has any. */ |
| 417 | byWorkspace: WorkspaceFigures[]; | |
| Two limits, real invoices, trust that grows by itself, sales signals | 418 | /** The last six months, oldest first. */ |
| 419 | months?: MonthFigures[]; | |
| Billing on Stripe's pages, month-end charges, warnings; sudo by workspace | 420 | }; |
| 421 | ||
| 422 | /** One workspace's share of an `AccountSummary`. */ | |
| 423 | export type WorkspaceFigures = { workspace: string; chargedMicros: number; costMicros: number; paidMicros: number }; | |
| 424 | ||
| Stripe webhooks, enterprise invoices, and sudo for both | 425 | export type StripeStatus = { |
| 426 | /** `test` or `live`, from the key; `off` without one. */ | |
| 427 | mode: "test" | "live" | "off" | string; | |
| Stripe's webhook secret is a Worker secret, STRIPE_WEBHOOK_SECRET, from a destination made in Stripe's dashboard | 428 | /** Whether `STRIPE_WEBHOOK_SECRET` is set, so events can be checked. */ |
| 429 | secretSet: boolean; | |
| 430 | /** The destination at billing's address in Stripe, as Stripe has it. */ | |
| 431 | webhook: { url: string; endpointId: string; status: "enabled" | "disabled" | string; events: string[]; createdAt: string } | null; | |
| 432 | /** Events billing handles that the destination does not send. */ | |
| 433 | missingEvents: string[]; | |
| Stripe webhooks, enterprise invoices, and sudo for both | 434 | recentEvents: { id: string; kind: string; outcome: string; receivedAt: string }[]; |
| 435 | error: string | null; | |
| 436 | }; | |
| 437 | ||
| 438 | /** An enterprise's invoice: one line per workspace, paid on Stripe's page. */ | |
| 439 | export type EnterpriseInvoice = { | |
| 440 | invoiceId: string; | |
| 441 | hostedUrl: string | null; | |
| 442 | amountMicros: number; | |
| 443 | status: "open" | "paid" | "overdue" | "void" | string; | |
| 444 | period: string; | |
| 445 | lines: { workspace: string; amountMicros: number }[]; | |
| 446 | createdAt: string; | |
| 447 | }; | |
| 448 | ||
| Two limits, real invoices, trust that grows by itself, sales signals | 449 | /** A workspace's invoice: monthly, or when charged near its limit. Itemised, in Stripe's billing page. */ |
| 450 | export type WorkspaceInvoice = { | |
| 451 | invoiceId: string; | |
| 452 | workspace: string; | |
| 453 | reason: "month" | "threshold" | string; | |
| 454 | period: string; | |
| 455 | amountMicros: number; | |
| 456 | status: "paid" | "open" | "failed" | "void" | string; | |
| 457 | hostedUrl: string | null; | |
| 458 | pdfUrl: string | null; | |
| 459 | lines: { description: string; amountMicros: number }[]; | |
| 460 | createdAt: string; | |
| Merge Stripe Tax, the card fee on card payments, and one free workspace per person | 461 | /** The card processing fee on top of `amountMicros` when charged to a card, and the tax Stripe added once known. */ |
| 462 | feeMicros?: number; | |
| 463 | taxMicros?: number; | |
| Two limits, real invoices, trust that grows by itself, sales signals | 464 | }; |
| 465 | ||
| The statement is a month at a time, a line per kind of charge | 466 | /** A month of the ledger, grouped by day or project, a line per kind of charge. */ |
| 467 | export type Statement = { | |
| 468 | month: string; | |
| 469 | months: string[]; | |
| 470 | groups: { | |
| 471 | key: string; | |
| 472 | label: string; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 473 | /** `coveredMicros`: what the plan's included usage, the trial, the open-source pool or g1t paid, not in `chargedMicros`. */ |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 474 | /** `priceMicros`: usage at its price; `discountMicros`: what the account's discount took off it. */ |
| 475 | lines: { | |
| 476 | kind: string; | |
| 477 | count: number; | |
| 478 | chargedMicros: number; | |
| 479 | costMicros: number; | |
| 480 | coveredMicros?: number; | |
| 481 | priceMicros?: number; | |
| 482 | discountMicros?: number; | |
| Merge Stripe Tax, the card fee on card payments, and one free workspace per person | 483 | /** On `Tax` and `Card processing fees` lines: what was paid with payments on top of what reached the balance. Never charged. */ |
| 484 | passedMicros?: number; | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 485 | }[]; |
| The statement is a month at a time, a line per kind of charge | 486 | chargedMicros: number; |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 487 | priceMicros?: number; |
| 488 | discountMicros?: number; | |
| The statement is a month at a time, a line per kind of charge | 489 | }[]; |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 490 | totals: { |
| 491 | chargedMicros: number; | |
| 492 | paidMicros: number; | |
| 493 | costMicros: number; | |
| 494 | entries: number; | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 495 | /** Usage at price, and what the discount took off: charged is the price less the discount and what paid for it. */ |
| 496 | priceMicros?: number; | |
| 497 | discountMicros?: number; | |
| 498 | /** The account's discount now, in percent; absent without one. */ | |
| 499 | discountPercent?: number | null; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 500 | /** What paid for usage before it was charged, such as "Paid by g1t's open-source pool". */ |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 501 | covered?: { source: "included" | "trial" | "oss_pool" | "given" | string; label: string; micros: number }[]; |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 502 | /** Owed when the month closed but under the minimum charge: on the next invoice. */ |
| 503 | carriedMicros?: number; | |
| Merge Stripe Tax, the card fee on card payments, and one free workspace per person | 504 | /** Tax and card processing fees paid with the month's payments, on top of `paidMicros`. */ |
| 505 | taxMicros?: number; | |
| 506 | cardFeeMicros?: number; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 507 | }; |
| The statement is a month at a time, a line per kind of charge | 508 | }; |
| 509 | ||
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 510 | export type MonthFigures = { |
| 511 | month: string; | |
| 512 | /** Usage charged, after what paid for it first. */ | |
| 513 | chargedMicros: number; | |
| 514 | /** What usage cost g1t: never a workspace's own model provider. */ | |
| 515 | costMicros: number; | |
| 516 | paidMicros: number; | |
| 517 | /** The plan's monthly price, paid. */ | |
| 518 | plansMicros?: number; | |
| 519 | /** What g1t gave at price (internal use, trials, the open-source pool, goodwill, covered). Not margin. */ | |
| 520 | givenMicros?: number; | |
| 521 | }; | |
| 522 | ||
| 523 | /** What g1t gave this month from one source. */ | |
| 524 | export type GivenFigures = { source: "internal" | "trial" | "oss_pool" | "goodwill" | "covered" | string; label: string; micros: number; costMicros: number }; | |
| 525 | ||
| 526 | /** One internal workspace's use this month, and why it is not charged. */ | |
| 527 | export type InternalUse = { workspace: string; reason: string; costMicros: number; entries: number }; | |
| Two limits, real invoices, trust that grows by itself, sales signals | 528 | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 529 | export type SignalKind = "at_limit" | "near_ceiling" | "declined" | "growing" | "established" | "first_payment" | "high_spend" | "cost_over_revenue"; |
| Two limits, real invoices, trust that grows by itself, sales signals | 530 | |
| 531 | /** Why a workspace is worth reaching out to. */ | |
| 532 | export type Signal = { | |
| 533 | workspace: string; | |
| 534 | kind: SignalKind; | |
| 535 | detail: string; | |
| 536 | valueMicros: number; | |
| 537 | stage: string | null; | |
| 538 | owner: string | null; | |
| Billing lists every invoice and every staff change; signals carry follow-ups | 539 | nextStep?: string | null; |
| 540 | /** When the next step is due, YYYY-MM-DD. */ | |
| 541 | nextAt?: string | null; | |
| 542 | }; | |
| 543 | ||
| 544 | /** One invoice g1t has sent, a workspace's or an enterprise's. */ | |
| 545 | export type InvoiceSummary = { | |
| 546 | invoiceId: string; | |
| 547 | kind: "workspace" | "enterprise"; | |
| 548 | account: string; | |
| 549 | name: string; | |
| 550 | reason: string; | |
| 551 | period: string; | |
| 552 | amountMicros: number; | |
| 553 | status: string; | |
| 554 | hostedUrl: string | null; | |
| 555 | createdAt: string; | |
| 556 | paidAt: string | null; | |
| Two limits, real invoices, trust that grows by itself, sales signals | 557 | }; |
| 558 | ||
| 559 | export type SalesStage = "none" | "lead" | "contacted" | "negotiating" | "won" | "lost" | "churn_risk"; | |
| 560 | ||
| 561 | export type SalesRecord = { | |
| 562 | workspace: string; | |
| 563 | stage: SalesStage | string; | |
| 564 | owner: string | null; | |
| 565 | nextStep: string | null; | |
| 566 | nextAt: string | null; | |
| 567 | notes: { id: string; text: string; by: string; createdAt: string }[]; | |
| 568 | updatedAt: string | null; | |
| 569 | }; | |
| 570 | ||
| 571 | export type Overview = { | |
| 572 | month: string; | |
| 573 | months: MonthFigures[]; | |
| 574 | byKind: { kind: string; chargedMicros: number; costMicros: number }[]; | |
| 575 | payingWorkspaces: number; | |
| 576 | stopped: number; | |
| 577 | nearCeiling: number; | |
| 578 | declined: number; | |
| 579 | openInvoicesMicros: number; | |
| 580 | followUpsDue: number; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 581 | /** g1t's capped budgets for free usage, this month. */ |
| 582 | pools?: Pools | null; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 583 | /** Usage charged plus the plan's price paid, this month. */ |
| 584 | revenueMicros?: number; | |
| 585 | activePlans?: number; | |
| 586 | planMrrMicros?: number; | |
| 587 | /** What g1t gave this month, by source, apart from its margin. */ | |
| 588 | given?: GivenFigures[]; | |
| 589 | /** g1t's own and Flagon's workspaces: what their use cost, and why they are not charged. */ | |
| 590 | internal?: InternalUse[]; | |
| 591 | openRequests?: number; | |
| 592 | overages?: number; | |
| 593 | openSpikes?: number; | |
| Two limits, real invoices, trust that grows by itself, sales signals | 594 | }; |
| 595 | ||
| Billing on Stripe's pages, month-end charges, warnings; sudo by workspace | 596 | /** A customer's Stripe billing page, for staff to send them. */ |
| 597 | export type BillingLink = { | |
| 598 | /** One-time and short-lived, signed in already. */ | |
| 599 | portalUrl: string; | |
| 600 | /** The page's sign-in, which does not expire: the customer signs in by email. */ | |
| 601 | loginUrl: string | null; | |
| 602 | customerEmail: string | null; | |
| 603 | expiresNote: string; | |
| Billing accounts, terms and enterprises; g1t is no longer free | 604 | }; |
| 605 | ||
| 606 | export type AdminAction = { id: string; account: string; action: string; detail: string; by: string; createdAt: string }; | |
| 607 | ||
| 608 | export type AccountDetail = { | |
| 609 | summary: AccountSummary; | |
| 610 | workspaces: Limit[]; | |
| 611 | ledger: LedgerEntry[]; | |
| 612 | audit: AdminAction[]; | |
| 613 | }; | |
| 614 | ||
| 615 | /** Staff-only billing, for sudo.g1t.sh. Every change names who made it. */ | |
| 616 | export interface BillingAdminApi { | |
| 617 | accounts(query?: string): Promise<AccountSummary[]>; | |
| 618 | account(id: string): Promise<Result<AccountDetail>>; | |
| 619 | setTerms(id: string, terms: Terms, by: string): Promise<Result<PayingAccount>>; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 620 | /** Team on or off without charge, and the account's share of the pools. Needs a note. */ |
| 621 | setAllowances(id: string, allowances: Allowances, note: string, by: string): Promise<Result<PayingAccount>>; | |
| Billing accounts, terms and enterprises; g1t is no longer free | 622 | createEnterprise(name: string, workspaces: string[], by: string): Promise<Result<PayingAccount>>; |
| 623 | attach(workspace: string, account: string | null, by: string): Promise<Result<PayingAccount>>; | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 624 | /** Credit for a workspace: promotional, goodwill or a refund; the owners are emailed. */ |
| 625 | credit(workspace: string, amountMicros: number, note: string, by: string, options?: CreditOptions): Promise<Result<LedgerEntry>>; | |
| 626 | /** Every credit g1t gave, filtered, with each month's totals by kind. */ | |
| 627 | credits(filter?: { workspace?: string | null; kind?: CreditKind | null; month?: string | null; by?: string | null }): Promise<AdminCredits>; | |
| 628 | /** What is left of a credit, taken back, with why. */ | |
| 629 | revokeCredit(id: string, note: string, by: string): Promise<Result<CreditGrant>>; | |
| sudo: reset a test workspace's billing so it starts again as a new customer; refused on a live Stripe key, for comped workspaces and for an enterprise's | 630 | /** A test workspace's billing wiped, to start again as a new customer. Only on Stripe's test key; never comped or enterprise. Logged. */ |
| 631 | resetBilling(workspace: string, confirm: string, note: string, by: string): Promise<Result<BillingReset>>; | |
| Billing on Stripe's pages, month-end charges, warnings; sudo by workspace | 632 | /** The workspace's Stripe billing page, to send to the customer. Logged. */ |
| 633 | billingLink(workspace: string, by: string): Promise<Result<BillingLink>>; | |
| Stripe webhooks, enterprise invoices, and sudo for both | 634 | /** Where billing stands with Stripe; with `setup`, registers the webhook first. */ |
| Stripe's webhook secret is a Worker secret, STRIPE_WEBHOOK_SECRET, from a destination made in Stripe's dashboard | 635 | /** Stripe's state for billing; `fix` enables the destination and adds missing events first. */ |
| 636 | stripe(fix?: boolean, by?: string): Promise<StripeStatus>; | |
| Stripe webhooks, enterprise invoices, and sudo for both | 637 | /** Where an enterprise's invoices go; makes its Stripe customer. */ |
| 638 | enterpriseBilling(id: string, email: string, by: string): Promise<Result<PayingAccount>>; | |
| Merge Stripe Tax, the card fee on card payments, and one free workspace per person | 639 | /** The enterprise's billing address and tax ID, on its Stripe customer: Stripe Tax works its invoices out from them. */ |
| 640 | enterpriseAddress(id: string, address: PostalAddress, taxIdType: string | null, taxId: string | null, by: string): Promise<Result<boolean>>; | |
| Stripe webhooks, enterprise invoices, and sudo for both | 641 | /** Sends an enterprise its invoice now, for what its workspaces owe. */ |
| 642 | invoiceEnterprise(id: string, by: string): Promise<Result<EnterpriseInvoice>>; | |
| 643 | /** Exactly these workspaces' accounts, such as one page of the list. */ | |
| 644 | accountsFor(workspaces: string[]): Promise<AccountSummary[]>; | |
| Two limits, real invoices, trust that grows by itself, sales signals | 645 | /** Every workspace worth reaching out to, most urgent first. */ |
| 646 | signals(): Promise<Signal[]>; | |
| 647 | /** The business at a glance. */ | |
| 648 | overview(): Promise<Overview>; | |
| 649 | /** A workspace's sales record. */ | |
| 650 | sales(workspace: string): Promise<SalesRecord>; | |
| 651 | setSales(workspace: string, record: { stage: string; owner?: string | null; nextStep?: string | null; nextAt?: string | null }, by: string): Promise<Result<SalesRecord>>; | |
| 652 | addNote(workspace: string, text: string, by: string): Promise<Result<SalesRecord>>; | |
| 653 | /** A workspace's invoices from g1t, for staff. */ | |
| 654 | workspaceInvoices(workspace: string): Promise<WorkspaceInvoice[]>; | |
| Billing lists every invoice and every staff change; signals carry follow-ups | 655 | /** Every invoice g1t has sent, newest first. */ |
| 656 | allInvoices(filter?: { status?: string; month?: string }): Promise<InvoiceSummary[]>; | |
| 657 | /** Every change made in sudo and by Stripe, newest first, 100 at a time. */ | |
| 658 | audit(filter?: { by?: string; action?: string; before?: string }): Promise<AdminAction[]>; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 659 | /** Limit and overage requests, with each workspace's history; `open` by default. */ |
| 660 | limitRequests(status?: "open" | "approved" | "declined" | "all"): Promise<LimitRequestReview[]>; | |
| 661 | /** Approve (at the amount asked, or another) or decline; the owner is told in the app and by email. */ | |
| 662 | decideLimitRequest(id: string, decision: "approve" | "decline", amountMicros: number | null, note: string, by: string): Promise<Result<LimitRequest>>; | |
| 663 | /** The Overages queue. */ | |
| 664 | overages(): Promise<Overage[]>; | |
| 665 | /** A goodwill credit; no amount is the one-click credit. Larger, or a second in 12 months, needs a reason. */ | |
| 666 | goodwill(workspace: string, amountMicros: number | null, reason: string, by: string, day?: string | null): Promise<Result<LedgerEntry>>; | |
| 667 | /** Workspaces spending in the last day, fastest first. */ | |
| 668 | velocity(): Promise<Velocity[]>; | |
| 669 | /** Money that reached g1t outside the card pages, such as a bank transfer: entered as a payment. */ | |
| 670 | recordPayment(workspace: string, amountMicros: number, reference: string, note: string, by: string): Promise<Result<LedgerEntry>>; | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 671 | /** Costs & margin: Cloudflare's bill against what g1t charged, over the last `days` (7 to 90, 30 by default). */ |
| 672 | costs(days?: number): Promise<CostsReport>; | |
| 673 | /** The open margin alerts, for the banner on every page. */ | |
| 674 | costAlerts(): Promise<MarginAlert[]>; | |
| Spend caps: a monthly budget for comped workspaces and a daily breaker on what g1t pays | 675 | /** g1t's own spend against its caps: the daily breaker and comped budgets. */ |
| 676 | spendCaps(): Promise<SpendCaps>; | |
| 677 | /** Lets hosted-model runs start again for the rest of today (UTC); needs a note. */ | |
| 678 | liftBreaker(note: string, by: string): Promise<Result<SpendCaps>>; | |
| 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) | 679 | /** Platform pauses, the last hour of platform usage, the month so far and the last day's breaches (billing's platform.rs). */ |
| 680 | platformGuard(): Promise<PlatformGuard>; | |
| 681 | /** Pauses or resumes one level across g1t; needs a note, recorded in the audit log. */ | |
| 682 | setPause(level: PauseLevel, paused: boolean, note: string, by: string): Promise<Result<PlatformGuard>>; | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 683 | /** Approve or reject a price proposal; a rejection needs a note. An approved rise waits out the notice period. */ |
| 684 | decideProposal(id: string, decision: "approve" | "reject", note: string, by: string): Promise<Result<PriceProposal>>; | |
| 685 | setCostSettings(settings: CostSettings, by: string): Promise<Result<CostSettings>>; | |
| 686 | setCostMapping(mapping: CostMappingInput, by: string): Promise<Result<CostMapping>>; | |
| 687 | /** Reads Cloudflare's bill and reconciles now, as the daily run does. */ | |
| 688 | runCosts(by: string): Promise<Result<CostsRun>>; | |
| Merge branch 'main' into actions-toolkit-oidc-artifacts | 689 | /** Agents & models: the catalogue, each purpose's default, and the latest checks. */ |
| 690 | models(): Promise<AdminModels>; | |
| 691 | /** Approve a model (its prices confirmed), retire it, or restore it. Needs a reason. */ | |
| 692 | decideModel( | |
| 693 | model: string, | |
| 694 | decision: "approve" | "retire" | "restore", | |
| 695 | details: { name?: string | null; tierHint?: string | null; prices?: ModelPrices | null }, | |
| 696 | reason: string, | |
| 697 | by: string, | |
| 698 | ): Promise<Result<CatalogueModel>>; | |
| 699 | /** One purpose's default: a model, or for a job its tier and effort. Needs a reason. */ | |
| 700 | setModelDefault( | |
| 701 | purpose: string, | |
| 702 | value: { model?: string | null; tier?: string | null; effort?: string | null }, | |
| 703 | reason: string, | |
| 704 | by: string, | |
| 705 | ): Promise<Result<ModelDefault>>; | |
| Billing accounts, terms and enterprises; g1t is no longer free | 706 | } |
| 707 | ||
| Usage limits: unpaid usage can only go so far | 708 | /** How much a workspace has earned g1t's trust with money. */ |
| Two limits, real invoices, trust that grows by itself, sales signals | 709 | export type Trust = "new" | "paid" | "established" | "reviewed" | "internal"; |
| Usage limits: unpaid usage can only go so far | 710 | |
| 711 | /** | |
| 712 | * How far a workspace's unpaid usage has gone this month, and where its | |
| 713 | * work stops: past `ceilingMicros`, no new sandboxes, builds or app | |
| 714 | * requests. Usage counts at its cost to g1t or its charge, whichever is | |
| 715 | * more, so it counts while g1t is free too. | |
| 716 | */ | |
| 717 | export type Limit = { | |
| 718 | workspace: string; | |
| Billing accounts, terms and enterprises; g1t is no longer free | 719 | /** The account that pays: the workspace's own (`ws_<slug>`), or its enterprise's. */ |
| 720 | account: string; | |
| 721 | accountName: string; | |
| Usage limits: unpaid usage can only go so far | 722 | trust: Trust; |
| 723 | exposureMicros: number; | |
| 724 | /** The lower of g1t's ceiling and the owner's spend limit; null for g1t's own. */ | |
| 725 | ceilingMicros: number | null; | |
| 726 | trustCeilingMicros: number | null; | |
| 727 | spendLimitMicros: number | null; | |
| 728 | state: "ok" | "warning" | "stopped"; | |
| 729 | message: string | null; | |
| Spend adds up on one ledger. Charged this month has one definition, price less discount, included usage and credit, shared by the plan card, the spend limit, Spend and the top bar; the limit had counted usage not yet closed at full price before the discount, so a comped workspace read as charged a cent. Every agent line on the ledger names the agent and who asked, repository runs by g1t included, so Spent is the sum of its products, Agents is the agent product, and by agent adds up to it; the billing API returns by_agent and by_person. The usage and billing guide says how spend is counted. | 730 | /** |
| 731 | * Charged this month, which the spend limit is measured against: usage at | |
| 732 | * price less the discount, included usage, the trial, pools and credit, | |
| 733 | * with usage metered through the month counted on the same terms. The | |
| 734 | * same number as the month's `UsageTotals.chargedMicros`. | |
| 735 | */ | |
| Two limits, real invoices, trust that grows by itself, sales signals | 736 | spentMicros?: number; |
| 737 | /** True while the owners have not chosen a limit, so the automatic one applies: $200, or twice last month's spend. */ | |
| 738 | defaultSpendLimit?: boolean; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 739 | /** The most owners may set their own limit to without asking: the highest ceiling ever, plus what is prepaid. */ |
| Two limits, real invoices, trust that grows by itself, sales signals | 740 | availableMicros?: number | null; |
| 741 | /** How the ceiling grows from here, in a sentence. */ | |
| 742 | growth?: string | null; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 743 | /** Paid in advance and not used yet; raises what can be used before work stops by as much. */ |
| 744 | prepaidMicros?: number; | |
| 745 | /** The highest ceiling the workspace has had. */ | |
| 746 | maxCeilingMicros?: number | null; | |
| 747 | /** The most owners may raise the limit to themselves, once: twice the highest ceiling. Null once used. */ | |
| 748 | raiseOnceMicros?: number | null; | |
| 749 | /** When the one-time raise was used. */ | |
| 750 | raisedAt?: string | null; | |
| 751 | /** A paid workspace's first billing cycle, on the starting ceiling. */ | |
| 752 | firstMonth?: boolean; | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 753 | /** The budget's alerts, in percent of the spend limit: some of 50, 75, 90 and 100. */ |
| 754 | alertLevels?: number[]; | |
| 755 | /** Whether usage pauses at the spend limit (the default); off, it only alerts. */ | |
| 756 | pauseAtLimit?: boolean; | |
| 757 | /** An HTTPS address told of each budget alert. */ | |
| 758 | budgetWebhook?: string | null; | |
| Usage limits: unpaid usage can only go so far | 759 | }; |
| 760 | ||
| Prices keep themselves current with what g1t pays | 761 | /** One metered unit: what it costs g1t and what it is sold at; the price follows the cost. */ |
| 762 | export type Price = { | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 763 | meter: |
| 764 | | "sandbox_second" | |
| 765 | | "build_second" | |
| 766 | | "app_requests" | |
| 767 | | "app_cpu" | |
| 768 | | "app_month" | |
| 769 | | "custom_domain_month" | |
| 770 | | "private_storage" | |
| 771 | | "embedding_tokens" | |
| 772 | | "scan_cpu" | |
| 773 | | "scan_rows" | |
| 774 | | string; | |
| Prices keep themselves current with what g1t pays | 775 | title: string; |
| 776 | unit: string; | |
| 777 | costMicros: number; | |
| 778 | markupPercent: number; | |
| 779 | priceMicros: number; | |
| 780 | /** `list`: Cloudflare's published price. `cloudflare`: measured from Cloudflare's bill. */ | |
| 781 | source: "list" | "cloudflare" | string; | |
| 782 | checkedAt: string | null; | |
| 783 | updatedAt: string; | |
| 784 | }; | |
| 785 | ||
| 786 | export type PriceChange = { | |
| 787 | meter: string; | |
| 788 | oldCostMicros: number; | |
| 789 | newCostMicros: number; | |
| 790 | markupPercent: number; | |
| Prices are what g1t pays plus 20%, from the first second | 791 | /** The markup before, when the change was to the markup rather than the cost. */ |
| 792 | oldMarkupPercent?: number; | |
| Prices keep themselves current with what g1t pays | 793 | reason: string; |
| 794 | createdAt: string; | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 795 | /** When a change still to come takes effect: a rise is announced before it is charged. */ |
| 796 | effectiveAt?: string; | |
| Prices keep themselves current with what g1t pays | 797 | }; |
| 798 | ||
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 799 | export type PriceBook = { |
| 800 | prices: Price[]; | |
| 801 | changes: PriceChange[]; | |
| 802 | modelMarginPercent: number; | |
| 803 | /** Every plan, as sold now. */ | |
| 804 | plans?: FeaturePlan[]; | |
| 805 | /** What is free, and the capped budgets that pay for it. */ | |
| 806 | free?: FreeTier | null; | |
| 807 | }; | |
| Prices keep themselves current with what g1t pays | 808 | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 809 | /** One kind of meter's usage this month, from `usage_meters`. */ |
| 810 | export type MeterUsage = { | |
| 811 | /** `agents`, `builds`, `requests`, `domains`, `git_storage` or `search_scans`. */ | |
| 812 | key: string; | |
| 813 | label: string; | |
| 814 | /** At price (cost plus 20%, on the account's terms), before what paid for it. */ | |
| 815 | micros: number; | |
| 816 | /** How much, when it is known: `12 runs`, `41 build minutes`. */ | |
| 817 | quantity?: string | null; | |
| 818 | }; | |
| 819 | ||
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 820 | /** What g1t gives without a plan; each is paid for by a capped budget. */ |
| 821 | export type FreeTier = { | |
| 822 | /** Each new workspace's trial credit, once. */ | |
| 823 | trialWorkspaceMicros: number; | |
| 824 | /** Trial grants each month, in all; new trials wait when it is spent. */ | |
| 825 | trialMonthlyPoolMicros: number; | |
| 826 | /** g1t's open-source pool each month, and any one repository's share. */ | |
| 827 | ossPoolMicros: number; | |
| 828 | ossRepoMicros: number; | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 829 | /** Private repository storage free for every workspace. Past it, the plan pays; a free workspace's pushes stop. */ |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 830 | freePrivateStorageBytes: number; |
| Audit logs are kept by plan: a week on free, 90 days on the plan, and what staff set for an account in sudo | 831 | /** Days of audit log a free workspace keeps. */ |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 832 | auditRetentionDays: number; |
| Audit logs are kept by plan: a week on free, 90 days on the plan, and what staff set for an account in sudo | 833 | /** Days of audit log the g1t plan keeps, and g1t's own and enterprise workspaces; longer by arrangement. */ |
| 834 | planAuditRetentionDays?: number; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 835 | /** The smallest amount a card is charged when a month closes; less carries over. */ |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 836 | minChargeMicros: number; |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 837 | /** Git operations free for every workspace each month. Past it, the plan pays; a free workspace is slowed down. */ |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 838 | gitOperationsIncluded?: number; |
| 839 | /** A new paid workspace's ceiling in its first month. */ | |
| 840 | paidStartCeilingMicros?: number; | |
| 841 | /** The most a one-click goodwill credit can cost g1t. */ | |
| 842 | overageForgiveCostMicros?: number; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 843 | }; |
| 844 | ||
| 845 | /** | |
| 846 | * A workspace's trial credit: one grant per workspace, made the first time | |
| 847 | * it uses something, out of a pool that resets each calendar month. Mirrors | |
| 848 | * `Trial` in `crates/contracts/src/billing.rs`. | |
| 849 | */ | |
| Deploy scripts live in the repository | 850 | export type Trial = { |
| 851 | open: boolean; | |
| 852 | usedMicros: number; | |
| 853 | limitMicros: number; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 854 | /** No longer used: trials do not end on a date. */ |
| Deploy scripts live in the repository | 855 | endsAt: string | null; |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 856 | /** Why it is closed: `off`, `used` (this workspace's grant is spent) or `pool` (this month's are given out). */ |
| Deploy scripts live in the repository | 857 | reason: "off" | "ended" | "used" | "pool" | null; |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 858 | /** Whether the workspace has its grant already. */ |
| 859 | granted?: boolean; | |
| 860 | /** With `pool`: when new trials start again, the first of next month. */ | |
| 861 | waitsUntil?: string | null; | |
| Deploy scripts live in the repository | 862 | }; |
| 863 | ||
| 864 | /** | |
| Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how. | 865 | * What a workspace has: the g1t plan (`plan`), and Security and quality |
| 866 | * (`security`), which comes with the plan at no price of its own. Deployments | |
| 867 | * are part of the plan too; `has_feature` for either answers whether the | |
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 868 | * workspace has the plan. Mirrors `Feature` in `crates/contracts/src/billing.rs`. |
| Deploy scripts live in the repository | 869 | */ |
| Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar | 870 | export type Feature = "plan" | "deployments" | "security"; |
| Deploy scripts live in the repository | 871 | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 872 | /** |
| 873 | * What deployments cost g1t, in millionths of a dollar: fallbacks for when | |
| 874 | * billing's price book cannot be read. Not an allowance: on the plan every | |
| 875 | * unit is metered from the first, at cost plus 20%, and drawn from the | |
| 876 | * plan's included usage first. Projects, previews and the apps behind them | |
| 877 | * are not metered at all. Mirrors `deployment_costs`. | |
| 878 | */ | |
| 879 | export const DEPLOYMENT_COSTS = { | |
| Deploy scripts live in the repository | 880 | microsPerMillionRequests: 300_000, |
| 881 | microsPerMillionCpuMs: 20_000, | |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 882 | /** One second of a build's sandbox: a fallback; billing charges the price book's `build_second`. */ |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 883 | microsPerBuildSecond: 15, |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 884 | /** One custom domain for a month. */ |
| Agents and memory, checks and conflicts, profiles, slug renames, custom domains | 885 | microsPerDomainMonth: 100_000, |
| Deploy scripts live in the repository | 886 | } as const; |
| 887 | ||
| 888 | export type FeaturePlan = { | |
| 889 | feature: Feature; | |
| 890 | title: string; | |
| Merge Stripe Tax, the card fee on card payments, and one free workspace per person | 891 | /** Charged every month while the plan is on, in cents, excluding tax. */ |
| Deploy scripts live in the repository | 892 | monthlyCents: number; |
| Merge Stripe Tax, the card fee on card payments, and one free workspace per person | 893 | /** The card processing fee on top each month, in cents (0 when off), excluding tax. */ |
| 894 | cardFeeCents?: number; | |
| Deploy scripts live in the repository | 895 | /** What the price includes, one line each. */ |
| 896 | includes: string[]; | |
| 897 | /** How usage past the allowance is charged. */ | |
| 898 | overage: string; | |
| 899 | }; | |
| 900 | ||
| 901 | export type SubscriptionStatus = "active" | "canceling" | "past_due" | "canceled"; | |
| 902 | ||
| 903 | export type Subscription = { | |
| 904 | feature: Feature; | |
| 905 | status: SubscriptionStatus; | |
| 906 | /** RFC 3339: when the period paid for ends. */ | |
| 907 | periodEnd: string | null; | |
| 908 | startedBy: string; | |
| 909 | startedAt: string; | |
| 910 | }; | |
| 911 | ||
| 912 | /** A feature as a workspace sees it. */ | |
| 913 | export type FeatureState = { | |
| 914 | plan: FeaturePlan; | |
| 915 | subscription: Subscription | null; | |
| 916 | /** Whether the feature works for the workspace now. */ | |
| 917 | on: boolean; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 918 | /** On without a plan: comped terms, or given by g1t. Nothing to pay or turn off. */ |
| 919 | included?: boolean; | |
| Deploy scripts live in the repository | 920 | }; |
| 921 | ||
| 922 | export interface BillingApi { | |
| 923 | status(): Promise<BillingStatus>; | |
| 924 | /** Members of the workspace only. */ | |
| 925 | account(workspace: string, viewer: Viewer): Promise<Result<BillingAccount>>; | |
| 926 | /** Newest first. Members of the workspace only. */ | |
| 927 | ledger(workspace: string, viewer: Viewer): Promise<Result<LedgerEntry[]>>; | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 928 | /** Credits from g1t, newest first, with what is left of each. Members only. */ |
| 929 | credits(workspace: string, viewer: Viewer): Promise<Result<Credits>>; | |
| The statement is a month at a time, a line per kind of charge | 930 | /** A month of the ledger, grouped by `day` (default) or `project`. Members only. */ |
| 931 | statement(workspace: string, viewer: Viewer, month?: string | null, group?: "day" | "project"): Promise<Result<Statement>>; | |
| 932 | /** One statement line's entries, 50 at a time; `before` is the last id seen. */ | |
| 933 | statementEntries( | |
| 934 | workspace: string, | |
| 935 | viewer: Viewer, | |
| 936 | filter: { month: string; kind: string; day?: string | null; project?: string | null; before?: string | null }, | |
| 937 | ): Promise<Result<LedgerEntry[]>>; | |
| Deploy scripts live in the repository | 938 | /** What the workspace's agents cost since `since`, broken down. Members only. */ |
| 939 | usage(workspace: string, viewer: Viewer, since: string): Promise<Result<Usage>>; | |
| 940 | /** | |
| Mission control shows model usage, yours and the workspace's: tokens, cost, active days, cache share, each day, and the mix | 941 | * The model tokens the workspace's runs used, day by day over the last |
| 942 | * `days` (42, at most 366), for everyone or for one `person`. Members | |
| 943 | * only; a member may ask only for themselves, an owner for anyone. | |
| 944 | */ | |
| 945 | tokenUsage(workspace: string, viewer: User, options?: { person?: string; days?: number }): Promise<Result<TokenUsage>>; | |
| 946 | /** | |
| 947 | * What one model answer used, added to its run's count for the day. The | |
| 948 | * model proxy sends it; for usage views only, as runs are priced from AI | |
| 949 | * Gateway. False when there was nothing to count. | |
| 950 | */ | |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 951 | /** What the AI Gateway offers on g1t's key, with prices per million tokens. */ |
| 952 | gatewayModels(): Promise<GatewayModel[]>; | |
| Merge branch 'main' into actions-toolkit-oidc-artifacts | 953 | /** Every purpose's default model as it applies now, and each job's tier and effort. */ |
| 954 | modelDefaults(): Promise<ModelDefaults>; | |
| 955 | /** What one provider lists now, from the models service's discovery. */ | |
| 956 | recordDiscovery(provider: string, models: ProviderModel[], by: string, error?: string | null): Promise<DiscoveryResult>; | |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 957 | /** |
| 958 | * Whether a workspace's next AI Gateway request may go to g1t's models: | |
| 959 | * fails with `payment_required` and what to do when it is over its spend | |
| 960 | * limit, out of AI credit, or not on the plan. | |
| 961 | */ | |
| 962 | gatewayAdmit(workspace: string): Promise<Result<boolean>>; | |
| 963 | /** Logs one AI Gateway request, and charges it when it used tokens on g1t's models. */ | |
| 964 | recordGateway(record: GatewayRecord): Promise<Result<boolean>>; | |
| 965 | /** A workspace's recent AI Gateway requests, newest first. Members only. */ | |
| 966 | gatewayRequests(workspace: string, viewer: Viewer, options?: { limit?: number; before?: string | null }): Promise<Result<GatewayRequests>>; | |
| Mission control shows model usage, yours and the workspace's: tokens, cost, active days, cache share, each day, and the mix | 967 | recordTokens(usage: { |
| 968 | workspace: string; | |
| 969 | /** The model session's id, one per run. */ | |
| 970 | session: string; | |
| 971 | /** The person the run is for, by username. */ | |
| 972 | person?: string | null; | |
| 973 | model: string; | |
| Merge branch 'model-routing' | 974 | tier?: "small" | "large" | "frontier" | null; |
| Mission control shows model usage, yours and the workspace's: tokens, cost, active days, cache share, each day, and the mix | 975 | input: number; |
| 976 | output: number; | |
| 977 | cacheRead: number; | |
| 978 | cacheWrite: number; | |
| 979 | }): Promise<Result<boolean>>; | |
| 980 | /** | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 981 | * Prepays usage ($25 at least) and returns the page to send the person to: |
| 982 | * by card with 3-D Secure, or by bank transfer from $1,000. Owners only. | |
| 983 | * The payment's id comes back to `returnUrl` as `session`. | |
| Deploy scripts live in the repository | 984 | */ |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 985 | checkout( |
| 986 | actor: User, | |
| 987 | workspace: string, | |
| 988 | amountCents: number, | |
| 989 | returnUrl: string, | |
| 990 | method?: "card" | "bank_transfer", | |
| 991 | ): Promise<Result<{ url: string }>>; | |
| Billing on Stripe's pages, month-end charges, warnings; sudo by workspace | 992 | /** |
| 993 | * Stripe's hosted billing page for the workspace: card, invoices, billing | |
| 994 | * email and address. g1t never handles card numbers. Owners only. | |
| 995 | */ | |
| 996 | billingPortal(actor: User, workspace: string, returnUrl: string): Promise<Result<{ url: string }>>; | |
| Deploy scripts live in the repository | 997 | /** Credits a payment once the processor says it was made. Safe to repeat. */ |
| 998 | confirm(workspace: string, viewer: Viewer, session: string): Promise<Result<BillingAccount>>; | |
| 999 | /** | |
| 1000 | * Whether a workspace may start an agent now, asked before anything is | |
| 1001 | * opened for it. A failure, with the reason to show, when it has no credit. | |
| 1002 | */ | |
| 1003 | canStart(workspace: string): Promise<Result<boolean>>; | |
| 1004 | /** A workspace's free allowance on g1t's hosted models; `exempt` are open to them anyway. */ | |
| 1005 | trial(workspace: string, exempt: string[]): Promise<Trial>; | |
| 1006 | /** | |
| 1007 | * Asks whether a workspace may start an agent and opens the run it will be | |
| 1008 | * charged for. Null when billing is off; a failure when there is no credit. | |
| 1009 | */ | |
| 1010 | /** Every paid feature and the workspace's plan for each. Members only. */ | |
| 1011 | features(workspace: string, viewer: Viewer): Promise<Result<FeatureState[]>>; | |
| 1012 | /** | |
| 1013 | * Starts the card page for a feature's monthly plan. Owners only. The | |
| 1014 | * page's id comes back to `returnUrl` as `session`. | |
| 1015 | */ | |
| 1016 | subscribe(actor: User, workspace: string, feature: Feature, returnUrl: string): Promise<Result<{ url: string }>>; | |
| 1017 | /** Turns the feature on once the plan is paid for. Safe to repeat. */ | |
| 1018 | confirmSubscription(workspace: string, viewer: Viewer, session: string): Promise<Result<FeatureState>>; | |
| 1019 | /** Ends a plan at the end of its period, or (`resume`) takes that back. Owners only. */ | |
| 1020 | cancelSubscription(actor: User, workspace: string, feature: Feature, resume?: boolean): Promise<Result<FeatureState>>; | |
| Merge Stripe Tax, the card fee on card payments, and one free workspace per person | 1021 | /** Which of the workspaces are free (on no paid plan); none where payments are not set up. */ |
| 1022 | freeWorkspaces(workspaces: string[]): Promise<string[]>; | |
| Deploy scripts live in the repository | 1023 | /** Whether a feature works for a workspace now; a failure with the reason when not. */ |
| 1024 | hasFeature(workspace: string, feature: Feature): Promise<Result<boolean>>; | |
| 1025 | /** | |
| 1026 | * Usage past a plan's allowance, charged from credit at cost plus the | |
| 1027 | * margin, once per `reference`. False if it was charged before. | |
| 1028 | */ | |
| 1029 | chargeFeature(charge: { | |
| 1030 | workspace: string; | |
| 1031 | feature: Feature; | |
| 1032 | costMicros: number; | |
| 1033 | description: string; | |
| 1034 | repo?: string | null; | |
| 1035 | reference: string; | |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 1036 | /** For a build: how long it ran, so the plan's included build time pays for what it can. */ |
| 1037 | buildSeconds?: number | null; | |
| Deploy scripts live in the repository | 1038 | }): Promise<Result<boolean>>; |
| Prices keep themselves current with what g1t pays | 1039 | /** |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 1040 | * What a source cost g1t so far this month, so the workspace's limit |
| 1041 | * counts it now. Replaces the last report. Billing charges `context` | |
| 1042 | * and `security` itself once the month is over; `deployments` charges | |
| 1043 | * its own. | |
| Prices keep themselves current with what g1t pays | 1044 | */ |
| status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas | 1045 | notePending( |
| 1046 | workspace: string, | |
| 1047 | source: "deployments" | "domains" | "context" | "security", | |
| 1048 | costMicros: number, | |
| 1049 | /** How much of it, for the Billing page: `1.2 million requests and 3.4 million CPU ms`. */ | |
| 1050 | detail?: string | null, | |
| 1051 | ): Promise<boolean>; | |
| 1052 | /** | |
| 1053 | * This month's usage, one line per kind of meter, at what it is charged | |
| 1054 | * before the plan's included usage or a pool paid for it. Members only. | |
| 1055 | */ | |
| 1056 | usageMeters(workspace: string, viewer: Viewer): Promise<Result<MeterUsage[]>>; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 1057 | /** What the workspace may do now: its plan, caps, pause, trial, and what the plan gives it. */ |
| Team plan, an open-source pool, monthly trials and honest metering; the sidebar for everyone; a workspace that stays put | 1058 | entitlements(workspace: string): Promise<Entitlements>; |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 1059 | /** |
| 1060 | * Holds a start's estimated cost before the work starts. A failure's code says why not: | |
| 1061 | * `paused`, `limit`, `not_paid`, `trial_used` or `oss_pool_empty`, with a message for the owner. | |
| 1062 | */ | |
| 1063 | reserve(reservation: { | |
| 1064 | workspace: string; | |
| 1065 | repo: RepoPath; | |
| 1066 | public: boolean; | |
| 1067 | kind: ComputeKind; | |
| 1068 | /** The most the work is expected to cost g1t, before the margin. */ | |
| 1069 | estimateMicros: number; | |
| 1070 | }): Promise<Result<ReservationHeld>>; | |
| 1071 | /** Releases a reservation's hold with what the work cost g1t, before the margin. Safe to repeat. */ | |
| 1072 | settle(reservationId: string, actualMicros: number): Promise<Result<boolean>>; | |
| 1073 | /** Stripe's page to save and verify a card (3-D Secure, never charged). Owners only. */ | |
| 1074 | cardCheck(actor: User, workspace: string, returnUrl: string): Promise<Result<{ url: string }>>; | |
| 1075 | /** Records the card check once Stripe says it passed, and grants the trial if it can. Safe to repeat. */ | |
| 1076 | confirmCardCheck(workspace: string, viewer: Viewer, session: string): Promise<Result<Entitlements>>; | |
| 1077 | /** An owner asks for a higher limit, or for help with usage past what was meant. */ | |
| 1078 | requestLimit( | |
| 1079 | actor: User, | |
| 1080 | workspace: string, | |
| 1081 | request: { kind: "limit" | "overage"; amountMicros: number; reason: string; expectedMonthlyMicros: number }, | |
| 1082 | ): Promise<Result<LimitRequest>>; | |
| 1083 | /** The workspace's requests and their answers, newest first. Members only. */ | |
| 1084 | limitRequests(workspace: string, viewer: Viewer): Promise<Result<LimitRequest[]>>; | |
| 1085 | /** | |
| 1086 | * The owners' own caps on agents: one run's spend ($0.10 to $100) and one issue's ($1 to $1,000). | |
| 1087 | * Null goes back to the default ($2 and $10). A cap staff set wins. Owners only. | |
| 1088 | */ | |
| 1089 | setCaps(actor: User, workspace: string, caps: { runCapMicros: number | null; issueCapMicros: number | null }): Promise<Result<Entitlements>>; | |
| 1090 | /** An owner's answer to a spend spike: keep going for 24 hours, or stop. */ | |
| 1091 | confirmSpike(actor: User, workspace: string, keepGoing: boolean): Promise<Result<Entitlements>>; | |
| Prices keep themselves current with what g1t pays | 1092 | /** Every metered price and the recent changes. Public. */ |
| 1093 | prices(): Promise<PriceBook>; | |
| Usage limits: unpaid usage can only go so far | 1094 | /** A workspace's limit, for its members. */ |
| 1095 | limit(workspace: string, viewer: Viewer): Promise<Result<Limit>>; | |
| 1096 | /** The same, for the services that enforce it. */ | |
| 1097 | checkLimit(workspace: string): Promise<Result<Limit>>; | |
| Every sandbox is metered by the second | 1098 | /** |
| Two limits, real invoices, trust that grows by itself, sales signals | 1099 | * The owners' own monthly limit, up to what is available; null goes back |
| 1100 | * to the default, and `useFullLimit` uses everything available. Owners only. | |
| 1101 | */ | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 1102 | setSpendLimit( |
| 1103 | actor: User, | |
| 1104 | workspace: string, | |
| 1105 | spendLimitMicros: number | null, | |
| 1106 | useFullLimit?: boolean, | |
| 1107 | /** Use the one-time raise: up to twice the highest ceiling, once per workspace. */ | |
| 1108 | raiseOnce?: boolean, | |
| 1109 | ): Promise<Result<Limit>>; | |
| Two limits, real invoices, trust that grows by itself, sales signals | 1110 | /** The workspace's invoices from g1t, newest first. Members only. */ |
| 1111 | invoices(workspace: string, viewer: Viewer): Promise<Result<WorkspaceInvoice[]>>; | |
| 1112 | /** | |
| Every sandbox is metered by the second | 1113 | * How long a sandbox ran for a workspace, reported when it stops. Its |
| Prices are what g1t pays plus 20%, from the first second | 1114 | * cost is recorded and every second is charged, from the first. False if |
| 1115 | * `reference` was recorded before. | |
| Every sandbox is metered by the second | 1116 | */ |
| 1117 | recordSandbox(usage: { | |
| 1118 | workspace: string; | |
| 1119 | seconds: number; | |
| 1120 | description: string; | |
| 1121 | repo?: string | null; | |
| 1122 | reference: string; | |
| Invite-only launch: sign in with GitHub, repository access and lifecycle, many emails, a new look | 1123 | /** What ran; checks, workflows and the merge queue on public repositories may use the open-source pool. */ |
| 1124 | kind?: ComputeKind | null; | |
| 1125 | /** vCPU-seconds used, when the sandbox can tell: the run is priced on its own CPU. */ | |
| 1126 | cpuSeconds?: number | null; | |
| 1127 | /** The reservation it started under, settled with this cost. */ | |
| 1128 | reservationId?: string | null; | |
| Fast pages, required checks on the branch, self-hosted runners, honest incidents | 1129 | /** It ran on one of the workspace's self-hosted runners: its minutes go on usage at $0. */ |
| 1130 | selfHosted?: boolean; | |
| 1131 | /** The machine it ran on, by label (`g1t-4core`); absent, the standard one. */ | |
| 1132 | instance?: string | null; | |
| Spend adds up on one ledger. Charged this month has one definition, price less discount, included usage and credit, shared by the plan card, the spend limit, Spend and the top bar; the limit had counted usage not yet closed at full price before the discount, so a comped workspace read as charged a cent. Every agent line on the ledger names the agent and who asked, repository runs by g1t included, so Spent is the sum of its products, Agents is the agent product, and by agent adds up to it; the billing API returns by_agent and by_person. The usage and billing guide says how spend is counted. | 1133 | /** The agent whose work this was, by handle (`g1t` for g1t's own runs on a repository); absent for checks, workflows and builds. */ |
| 1134 | agent?: string | null; | |
| 1135 | /** Who asked for the work, by username. */ | |
| 1136 | askedBy?: string | null; | |
| Every sandbox is metered by the second | 1137 | }): Promise<Result<boolean>>; |
| Deploy scripts live in the repository | 1138 | startRun(run: { |
| 1139 | workspace: string; | |
| 1140 | repo: RepoPath; | |
| 1141 | number: number; | |
| 1142 | task: string; | |
| 1143 | model: string; | |
| 1144 | /** `workspace` when the run uses the workspace's own model provider. */ | |
| 1145 | billedTo?: "g1t" | "workspace"; | |
| Merge branch 'model-routing' | 1146 | /** |
| 1147 | * The model session's id: the run is settled at AI Gateway's price by | |
| 1148 | * it, and on the workspace's own provider its tokens are counted under | |
| 1149 | * it for the agent rate. | |
| 1150 | */ | |
| Prices keep themselves current with what g1t pays | 1151 | session?: string | null; |
| Merge branch 'model-routing' | 1152 | /** The tier g1t routed the run to: `small`, `large` or `frontier`. */ |
| 1153 | tier?: "small" | "large" | "frontier" | null; | |
| Spend adds up on one ledger. Charged this month has one definition, price less discount, included usage and credit, shared by the plan card, the spend limit, Spend and the top bar; the limit had counted usage not yet closed at full price before the discount, so a comped workspace read as charged a cent. Every agent line on the ledger names the agent and who asked, repository runs by g1t included, so Spent is the sum of its products, Agents is the agent product, and by agent adds up to it; the billing API returns by_agent and by_person. The usage and billing guide says how spend is counted. | 1154 | /** The agent doing the work, by handle: a workspace agent's, or `g1t` for g1t's own work on a repository. Every line of the run carries it. */ |
| 1155 | agent?: string | null; | |
| 1156 | /** Who asked, by username; none for a routine's or another agent's work. */ | |
| 1157 | askedBy?: string | null; | |
| Deploy scripts live in the repository | 1158 | }): Promise<Result<RunTicket | null>>; |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 1159 | /** Usage over a range of days (`YYYY-MM-DD`, both included), at price, by product, meter, project and day. Members only. */ |
| 1160 | usageReport( | |
| 1161 | workspace: string, | |
| 1162 | viewer: Viewer, | |
| 1163 | range: { from: string; until: string; products?: string[]; projects?: string[] }, | |
| 1164 | ): Promise<Result<UsageReport>>; | |
| 1165 | /** The workspace's prepaid AI credit, auto-reload and prices. Members only. */ | |
| 1166 | aiCredit(workspace: string, viewer: Viewer): Promise<Result<AiCredit>>; | |
| 1167 | /** Stripe's page to buy AI credit ( to ,000, the card fee on its own line). Owners only. The page's id comes back to `returnUrl` as `ai_credit`. */ | |
| 1168 | buyAiCredit(actor: User, workspace: string, amountCents: number, returnUrl: string): Promise<Result<{ url: string }>>; | |
| 1169 | /** Credits a purchase once Stripe says it was paid, once. Safe to repeat. */ | |
| 1170 | confirmAiCredit(workspace: string, viewer: Viewer, session: string): Promise<Result<AiCredit>>; | |
| 1171 | /** Auto-reload's settings. Owners only. */ | |
| 1172 | setAiReload( | |
| 1173 | actor: User, | |
| 1174 | workspace: string, | |
| 1175 | reload: { enabled: boolean; thresholdMicros: number; targetMicros: number; monthlyMaxMicros: number }, | |
| 1176 | ): Promise<Result<AiCredit>>; | |
| 1177 | /** The monthly budget: the spend limit, its alerts, whether usage pauses at 100%, and a webhook. Owners only. */ | |
| 1178 | setBudget( | |
| 1179 | actor: User, | |
| 1180 | workspace: string, | |
| 1181 | budget: { amountMicros: number | null; alerts: number[]; pauseAtLimit: boolean; webhook: string | null; keepLimit?: boolean }, | |
| 1182 | ): Promise<Result<Limit>>; | |
| 1183 | /** Invoice details from the Stripe customer, the default payment method, invoices and the next invoice. Members only. */ | |
| 1184 | billingDetails(workspace: string, viewer: Viewer): Promise<Result<BillingDetails>>; | |
| 1185 | /** Saves invoice details on the Stripe customer; absent fields stay, empty clears. Owners only. */ | |
| 1186 | setBillingDetails(actor: User, workspace: string, details: BillingDetailsInput): Promise<Result<BillingDetails>>; | |
| Deploy scripts live in the repository | 1187 | } |
| 1188 | ||
| 1189 | ||
| 1190 | /** One slice of usage: what it was for, what it cost, how many runs. */ | |
| 1191 | export type UsageSlice = { key: string; micros: number; runs: number }; | |
| 1192 | ||
| Mission control shows model usage, yours and the workspace's: tokens, cost, active days, cache share, each day, and the mix | 1193 | /** The model tokens runs used over a window of days. */ |
| 1194 | export type TokenUsage = { | |
| 1195 | /** `YYYY-MM-DD`, the first day counted. */ | |
| 1196 | since: string; | |
| 1197 | /** The window's length: 42 unless asked, 366 at most. */ | |
| 1198 | days: number; | |
| 1199 | /** Null for the whole workspace. */ | |
| 1200 | person: string | null; | |
| 1201 | totalTokens: number; | |
| 1202 | inputTokens: number; | |
| 1203 | outputTokens: number; | |
| 1204 | cacheReadTokens: number; | |
| 1205 | cacheWriteTokens: number; | |
| 1206 | /** What those runs were charged, as `usage` measures it. */ | |
| 1207 | costMicros: number; | |
| 1208 | /** Days in the window with any tokens. */ | |
| 1209 | activeDays: number; | |
| 1210 | /** Every day in the window, oldest first, zeros included. */ | |
| 1211 | byDay: { day: string; tokens: number }[]; | |
| 1212 | }; | |
| 1213 | ||
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1214 | // --- AI Gateway ------------------------------------------------------------- |
| 1215 | ||
| 1216 | /** A model the AI Gateway offers on g1t's key, with its prices per million tokens. */ | |
| 1217 | export type GatewayModel = { | |
| AI Gateway: OpenAI's format, open models, and your own providers | 1218 | /** |
| 1219 | * The provider's own id, such as `claude-sonnet-5-5` or | |
| 1220 | * `@cf/openai/gpt-oss-120b`. A request names it as it is or with its | |
| 1221 | * provider in front (`anthropic/claude-sonnet-5-5`). | |
| 1222 | */ | |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1223 | model: string; |
| 1224 | /** For people: `Claude Sonnet 5.5`. */ | |
| 1225 | name: string; | |
| AI Gateway: OpenAI's format, open models, and your own providers | 1226 | /** `anthropic` or `workers-ai`. */ |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1227 | provider: string; |
| AI Gateway: OpenAI's format, open models, and your own providers | 1228 | /** `chat`, or `embeddings` for a model that only embeds text. */ |
| 1229 | kind?: "chat" | "embeddings"; | |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1230 | inputMicros: number; |
| 1231 | outputMicros: number; | |
| 1232 | cacheReadMicros: number; | |
| AI Gateway: OpenAI's format, open models, and your own providers | 1233 | /** Cache writes that live five minutes. */ |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1234 | cacheWriteMicros: number; |
| AI Gateway: OpenAI's format, open models, and your own providers | 1235 | /** Cache writes that live an hour. */ |
| 1236 | cacheWrite1hMicros?: number; | |
| 1237 | /** | |
| 1238 | * Priced by the prompt's length: a request whose prompt (input, cache | |
| 1239 | * read and cache write tokens) is longer than this is charged entirely at | |
| 1240 | * the `over` prices. 0 or absent for one price. | |
| 1241 | */ | |
| 1242 | threshold?: number; | |
| 1243 | overInputMicros?: number; | |
| 1244 | overOutputMicros?: number; | |
| 1245 | overCacheReadMicros?: number; | |
| 1246 | overCacheWriteMicros?: number; | |
| 1247 | overCacheWrite1hMicros?: number; | |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1248 | }; |
| 1249 | ||
| Merge branch 'main' into actions-toolkit-oidc-artifacts | 1250 | // --- The model catalogue ------------------------------------------------------ |
| 1251 | ||
| 1252 | /** Where a model stands: only `available` ones are routed to. */ | |
| 1253 | export type ModelStatus = "available" | "new" | "deprecated" | "retired"; | |
| 1254 | ||
| 1255 | /** One model in g1t's catalogue: its prices and what g1t knows about it. */ | |
| 1256 | export type CatalogueModel = GatewayModel & { | |
| 1257 | /** Other ids the provider lists it by, such as a dated one. */ | |
| 1258 | aliases: string[]; | |
| 1259 | family: string; | |
| 1260 | /** The agent tier it suits: `small`, `large`, `frontier`, or empty. */ | |
| 1261 | tierHint: string; | |
| 1262 | contextWindow: number; | |
| 1263 | maxOutput: number; | |
| 1264 | /** Any of `effort`, `thinking`, `tools`, `vision`, `embeddings`. */ | |
| 1265 | capabilities: string[]; | |
| 1266 | dimensions: number; | |
| 1267 | status: ModelStatus; | |
| 1268 | /** Its prices are known. An unpriced model is never routed to, offered or charged for. */ | |
| 1269 | priced: boolean; | |
| 1270 | source: "discovered" | "staff"; | |
| 1271 | firstSeenAt: string | null; | |
| 1272 | lastSeenAt: string | null; | |
| 1273 | missingSince: string | null; | |
| 1274 | approvedBy: string | null; | |
| 1275 | approvedAt: string | null; | |
| 1276 | note: string; | |
| 1277 | /** A typical agent run on it, in millionths of a dollar; 0 when unpriced or embeddings. */ | |
| 1278 | typicalRunMicros: number; | |
| 1279 | }; | |
| 1280 | ||
| 1281 | /** One model as its provider lists it, from the models service's discovery. */ | |
| 1282 | export type ProviderModel = { | |
| 1283 | id: string; | |
| 1284 | name: string; | |
| 1285 | /** `chat`, `embeddings`, or anything else (counted as listed, never added). */ | |
| 1286 | kind: string; | |
| 1287 | contextWindow: number; | |
| 1288 | maxOutput: number; | |
| 1289 | capabilities: string[]; | |
| 1290 | /** Workers AI lists a price per million tokens; Anthropic does not. */ | |
| 1291 | price: { inputMicros: number; outputMicros: number } | null; | |
| 1292 | }; | |
| 1293 | ||
| 1294 | /** What one check of a provider found. */ | |
| 1295 | export type DiscoveryResult = { | |
| 1296 | provider: string; | |
| 1297 | checkedAt: string; | |
| 1298 | by: string; | |
| 1299 | listed: number; | |
| 1300 | added: string[]; | |
| 1301 | deprecated: string[]; | |
| 1302 | restored: string[]; | |
| 1303 | error: string | null; | |
| 1304 | }; | |
| 1305 | ||
| 1306 | /** The purposes a default model is chosen for. */ | |
| 1307 | export type ModelPurpose = "tier_small" | "tier_large" | "tier_frontier" | "background" | "gateway_first"; | |
| 1308 | ||
| 1309 | /** One purpose's default, as staff last set it. */ | |
| 1310 | export type ModelDefault = { | |
| 1311 | /** A `ModelPurpose`, or `job_<kind>`. */ | |
| 1312 | purpose: string; | |
| 1313 | model: string | null; | |
| 1314 | /** For a job: `small`, `large`, `frontier` or `change`. */ | |
| 1315 | tier: string | null; | |
| 1316 | effort: string | null; | |
| 1317 | updatedAt: string; | |
| 1318 | updatedBy: string; | |
| 1319 | reason: string; | |
| 1320 | }; | |
| 1321 | ||
| 1322 | /** A model purpose's default as it applies now. */ | |
| 1323 | export type ResolvedModel = { | |
| 1324 | purpose: string; | |
| 1325 | chosen: string; | |
| 1326 | /** The model to use; null when nothing suits (callers keep their own fallback). */ | |
| 1327 | model: GatewayModel | null; | |
| 1328 | capabilities: string[]; | |
| 1329 | /** Why it is not the chosen model, in a sentence. */ | |
| 1330 | note: string | null; | |
| 1331 | }; | |
| 1332 | ||
| 1333 | /** One kind of agent job's starting tier and effort. */ | |
| 1334 | export type JobDefault = { kind: string; tier: string; effort: string | null }; | |
| 1335 | ||
| 1336 | /** Every purpose's model as it applies now, and each job's tier and effort. */ | |
| 1337 | export type ModelDefaults = { models: ResolvedModel[]; jobs: JobDefault[] }; | |
| 1338 | ||
| 1339 | /** One check of one provider. */ | |
| 1340 | export type ModelCheck = { | |
| 1341 | id: string; | |
| 1342 | provider: string; | |
| 1343 | checkedAt: string; | |
| 1344 | by: string; | |
| 1345 | listed: number; | |
| 1346 | added: string[]; | |
| 1347 | deprecated: string[]; | |
| 1348 | error: string | null; | |
| 1349 | }; | |
| 1350 | ||
| 1351 | /** The tokens of the typical agent run estimates are priced from. */ | |
| 1352 | export type TypicalRun = { requests: number; input: number; output: number; cacheRead: number; cacheWrite: number }; | |
| 1353 | ||
| 1354 | /** sudo's Agents & models. */ | |
| 1355 | export type AdminModels = { | |
| 1356 | catalogue: CatalogueModel[]; | |
| 1357 | defaults: ModelDefault[]; | |
| 1358 | resolved: ModelDefaults; | |
| 1359 | checks: ModelCheck[]; | |
| 1360 | typical: TypicalRun; | |
| 1361 | }; | |
| 1362 | ||
| 1363 | /** A model's prices as staff confirm them, per million tokens in millionths of a dollar. */ | |
| 1364 | export type ModelPrices = { | |
| 1365 | inputMicros: number; | |
| 1366 | outputMicros: number; | |
| 1367 | cacheReadMicros: number; | |
| 1368 | cacheWriteMicros: number; | |
| 1369 | cacheWrite1hMicros: number; | |
| 1370 | threshold: number; | |
| 1371 | overInputMicros: number; | |
| 1372 | overOutputMicros: number; | |
| 1373 | overCacheReadMicros: number; | |
| 1374 | overCacheWriteMicros: number; | |
| 1375 | overCacheWrite1hMicros: number; | |
| 1376 | }; | |
| 1377 | ||
| 1378 | /** The models service's `Discovery` entrypoint, for sudo's "Check for new models". */ | |
| 1379 | export interface ModelDiscoveryApi { | |
| 1380 | /** Lists every provider's models now and records what changed: one result per provider. */ | |
| 1381 | check(by: string): Promise<DiscoveryResult[]>; | |
| 1382 | } | |
| 1383 | ||
| AI Gateway: OpenAI's format, open models, and your own providers | 1384 | /** The format a gateway request was sent in. */ |
| 1385 | export type GatewayFormat = "anthropic" | "openai"; | |
| 1386 | ||
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1387 | /** One AI Gateway request, as the model proxy reports it to billing. */ |
| 1388 | export type GatewayRecord = { | |
| 1389 | /** `gw_…`, chosen by the proxy; recording it twice records it once. */ | |
| 1390 | id: string; | |
| 1391 | workspace: string; | |
| 1392 | tokenId: string; | |
| 1393 | tokenName?: string | null; | |
| 1394 | model: string; | |
| 1395 | input: number; | |
| 1396 | output: number; | |
| 1397 | cacheRead: number; | |
| AI Gateway: OpenAI's format, open models, and your own providers | 1398 | /** Every cache write, of either lifetime. */ |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1399 | cacheWrite: number; |
| AI Gateway: OpenAI's format, open models, and your own providers | 1400 | /** Of `cacheWrite`, those that live an hour. */ |
| 1401 | cacheWriteHour?: number; | |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1402 | /** The HTTP status the caller was answered with. */ |
| 1403 | status: number; | |
| 1404 | /** On the workspace's own provider key: counted, never charged. */ | |
| 1405 | ownKey: boolean; | |
| AI Gateway: OpenAI's format, open models, and your own providers | 1406 | format: GatewayFormat; |
| 1407 | /** | |
| 1408 | * Who served it: `anthropic` or `workers-ai` on g1t's key, the | |
| 1409 | * connection's provider on the workspace's own. Empty when it never got | |
| 1410 | * that far. | |
| 1411 | */ | |
| 1412 | provider: string; | |
| 1413 | /** On the workspace's own provider: the connection's name. */ | |
| 1414 | connection?: string | null; | |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1415 | streamed: boolean; |
| 1416 | durationMs: number; | |
| 1417 | error?: string | null; | |
| 1418 | }; | |
| 1419 | ||
| 1420 | /** One AI Gateway request, as its log keeps it. */ | |
| 1421 | export type GatewayRequest = { | |
| 1422 | id: string; | |
| 1423 | createdAt: string; | |
| 1424 | model: string; | |
| 1425 | tokenId: string; | |
| 1426 | tokenName: string | null; | |
| 1427 | input: number; | |
| 1428 | output: number; | |
| 1429 | cacheRead: number; | |
| 1430 | cacheWrite: number; | |
| AI Gateway: OpenAI's format, open models, and your own providers | 1431 | /** Of `cacheWrite`, those that live an hour. */ |
| 1432 | cacheWriteHour: number; | |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1433 | /** What the tokens cost at the model's price. */ |
| 1434 | costMicros: number; | |
| 1435 | /** What the workspace was charged, before included usage and credit paid for it; 0 on its own key. */ | |
| 1436 | chargedMicros: number; | |
| 1437 | status: number; | |
| 1438 | ownKey: boolean; | |
| AI Gateway: OpenAI's format, open models, and your own providers | 1439 | format: GatewayFormat; |
| 1440 | /** `anthropic` or `workers-ai` on g1t's key; the connection's provider on the workspace's own. */ | |
| 1441 | provider: string; | |
| 1442 | /** On the workspace's own provider: the connection's name. */ | |
| 1443 | connection: string | null; | |
| Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens | 1444 | streamed: boolean; |
| 1445 | durationMs: number; | |
| 1446 | error: string | null; | |
| 1447 | }; | |
| 1448 | ||
| 1449 | /** A page of AI Gateway requests, newest first. */ | |
| 1450 | export type GatewayRequests = { | |
| 1451 | requests: GatewayRequest[]; | |
| 1452 | /** The `before` for the next page, when there is one. */ | |
| 1453 | next: string | null; | |
| 1454 | /** How many days requests are kept. */ | |
| 1455 | retentionDays: number; | |
| 1456 | }; | |
| 1457 | ||
| Deploy scripts live in the repository | 1458 | /** What a workspace's agents cost over a period. */ |
| 1459 | export type Usage = { | |
| 1460 | since: string; | |
| 1461 | /** Charged, including g1t's margin. */ | |
| 1462 | spentMicros: number; | |
| Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged | 1463 | /** What g1t's usage came to at price, less what was charged: the plan's included usage, the trial, a pool or a free period paid it. Usage at price is `spentMicros` plus this. */ |
| Billing's usage total is labeled at price, and Usage says what part of it was paid for | 1464 | coveredMicros?: number; |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 1465 | /** What the account's discount took off the price; usage at price is spent + covered + this. */ |
| 1466 | discountMicros?: number; | |
| 1467 | /** The account's discount now, in percent; with one, the slices are at price. */ | |
| 1468 | discountPercent?: number | null; | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 1469 | /** Usage at price: spent + covered + discount, from the same ledger lines. The one usage figure every page shows. */ |
| 1470 | priceMicros?: number; | |
| Deploy scripts live in the repository | 1471 | /** What g1t's model provider charged, before the margin. */ |
| 1472 | costMicros: number; | |
| 1473 | /** What runs on the workspace's own provider cost there, estimated. Not charged by g1t. */ | |
| 1474 | providerMicros: number; | |
| 1475 | /** What the runs used, at cost: g1t's models and the workspace's own provider together. */ | |
| 1476 | usedMicros: number; | |
| 1477 | /** g1t charges nothing for now; the slices then measure usage at cost. */ | |
| 1478 | free: boolean; | |
| 1479 | runs: number; | |
| 1480 | /** Spend per day and task, keyed `YYYY-MM-DD/task`. */ | |
| 1481 | byDay: UsageSlice[]; | |
| 1482 | byTask: UsageSlice[]; | |
| 1483 | byRepo: UsageSlice[]; | |
| 1484 | /** Keyed `namespace/name#number`. */ | |
| 1485 | byPull: UsageSlice[]; | |
| 1486 | byModel: UsageSlice[]; | |
| 1487 | /** Credit bought in the period. */ | |
| 1488 | addedMicros: number; | |
| 1489 | }; | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 1490 | |
| 1491 | /** One of g1t's products (a "bucket") on one day. Money in micros. */ | |
| 1492 | export type CostDay = { day: string; bucket: string; cfCostMicros: number; ownCostMicros: number; valueMicros: number; cashMicros: number }; | |
| 1493 | ||
| 1494 | /** One product over the range: what customers were charged at price against what it cost. */ | |
| 1495 | export type ProductMargin = { | |
| 1496 | bucket: string; | |
| 1497 | title: string; | |
| 1498 | /** Cloudflare's bill, or g1t's own figure where Cloudflare does not bill it (`costSource`). */ | |
| 1499 | costMicros: number; | |
| 1500 | cfCostMicros: number; | |
| 1501 | ownCostMicros: number; | |
| 1502 | valueMicros: number; | |
| 1503 | marginMicros: number; | |
| 1504 | marginPercent: number | null; | |
| 1505 | costSource: "cloudflare" | "ledger" | string; | |
| 1506 | /** Running g1t, paid for by the plan. */ | |
| 1507 | overhead: boolean; | |
| 1508 | }; | |
| 1509 | ||
| 1510 | /** All of g1t: money in (usage and the plan) against every cost. */ | |
| Costs: margin is measured on what was sold; comped workspaces, free periods, the trial and the pools are given away, a budget shown beside it | 1511 | export type OverallMargin = { |
| 1512 | usageMicros: number; | |
| 1513 | plansMicros: number; | |
| 1514 | costMicros: number; | |
| 1515 | marginMicros: number; | |
| 1516 | marginPercent: number | null; | |
| 1517 | /** Of costMicros, what went on usage g1t gave away on purpose: comped workspaces, free periods, the trial and the open-source pool. */ | |
| 1518 | givenMicros?: number; | |
| 1519 | /** Money in against costMicros - givenMicros. */ | |
| 1520 | soldMarginMicros?: number; | |
| 1521 | soldMarginPercent?: number | null; | |
| Costs: a statement that keeps usage sold, running g1t, subscriptions and what was given away (comped, free use, trial, pool) apart, and says who was paid; free use carries its own cost; the run button says it is running | 1522 | /** Usage sold: usageMicros against what that usage cost, less what was given. */ |
| 1523 | usageCostMicros?: number; | |
| 1524 | usageMarginMicros?: number; | |
| 1525 | usageMarginPercent?: number | null; | |
| 1526 | /** Running g1t: plansMicros against the platform's cost, less its given share. */ | |
| 1527 | runningCostMicros?: number; | |
| 1528 | /** Cost no mapping names, less its given share. */ | |
| 1529 | unmappedCostMicros?: number; | |
| 1530 | /** givenMicros by why. Free is free periods, free allowances and overruns g1t covered. */ | |
| 1531 | givenCompedMicros?: number; | |
| 1532 | givenFreeMicros?: number; | |
| 1533 | givenTrialMicros?: number; | |
| 1534 | givenPoolMicros?: number; | |
| Merge branch 'worktree-agent-a633ac0f7f66d419d' | 1535 | /** What discounts on an account's terms took below cost plus the margin: given, not margin lost. */ |
| 1536 | givenDiscountMicros?: number; | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 1537 | /** Credits from g1t spent on usage, by kind: given, never money in. Refunds come off money in instead. */ |
| 1538 | givenCreditPromotionalMicros?: number; | |
| 1539 | givenCreditGoodwillMicros?: number; | |
| Merge branch 'main' into worktree-agent-a69aeabc4b0deeb97 | 1540 | /** What testing resets wiped that g1t paid for: the usage still happened, so its cost is given, never a leak. */ |
| 1541 | givenResetMicros?: number; | |
| Billing: credits with a kind and expiry, discounts instead of comped, and safer charging | 1542 | /** Credits over the range: given (every kind), spent on usage, and refunds' money given back. */ |
| 1543 | creditsGivenMicros?: number; | |
| 1544 | creditsUsedMicros?: number; | |
| 1545 | creditsRefundedMicros?: number; | |
| Costs: a statement that keeps usage sold, running g1t, subscriptions and what was given away (comped, free use, trial, pool) apart, and says who was paid; free use carries its own cost; the run button says it is running | 1546 | /** costMicros by who g1t pays: Cloudflare's bill (billed, after included allowances) and model providers (tokens, not on Cloudflare's bill). */ |
| Costs: the plan's included usage counts as paid for the usage it covered, out of what plans leave for running g1t; the run button shows it is running with CSS alone (sudo ships no JavaScript) | 1547 | /** What the plan's included usage paid for, at price: money in for usage, paid out of plansMicros. */ |
| 1548 | includedMicros?: number; | |
| Costs: a statement that keeps usage sold, running g1t, subscriptions and what was given away (comped, free use, trial, pool) apart, and says who was paid; free use carries its own cost; the run button says it is running | 1549 | cloudflareCostMicros?: number; |
| 1550 | modelsCostMicros?: number; | |
| Merge Stripe Tax, the card fee on card payments, and one free workspace per person | 1551 | /** Tax collected with payments over the range, net of refunds: owed to tax authorities, never cash or revenue. */ |
| 1552 | taxCollectedMicros?: number; | |
| 1553 | /** Card processing fees passed on with card payments, net of refunds: they pay Stripe's fee, not revenue. */ | |
| 1554 | cardFeesMicros?: number; | |
| Merge Cloudflare's usage over its billing cycle: every page read, included amounts once a cycle, a projection, test-mode charges never money in (billing 0052) | 1555 | /** What workspaces were charged while payments were not live (Stripe's test mode): given, never money in. */ |
| 1556 | givenUnpaidMicros?: number; | |
| 1557 | /** Cloudflare's subscriptions over the range: each day's share of the billing cycle it is in. */ | |
| 1558 | subscriptionsMicros?: number; | |
| 1559 | /** What AI Gateway priced g1t's own provider traffic at over the range, beside the ledger's model cost. */ | |
| 1560 | gatewayCostMicros?: number; | |
| Costs: margin is measured on what was sold; comped workspaces, free periods, the trial and the pools are given away, a budget shown beside it | 1561 | }; |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 1562 | |
| 1563 | /** A count, cost or leak that does not add up. */ | |
| 1564 | export type CostDrift = { | |
| 1565 | bucket: string; | |
| 1566 | title: string; | |
| 1567 | kind: "count" | "cost" | "leak" | string; | |
| 1568 | ours: number; | |
| 1569 | cloudflare: number; | |
| 1570 | deltaPercent: number | null; | |
| 1571 | detail: string; | |
| 1572 | foundAt: string; | |
| 1573 | }; | |
| 1574 | ||
| 1575 | export type MarginAlert = { | |
| 1576 | id: string; | |
| 1577 | kind: "margin" | "overall" | "leak" | "drift" | "workspace" | string; | |
| 1578 | /** The product, or the workspace. */ | |
| 1579 | subject: string; | |
| 1580 | detail: string; | |
| 1581 | since: string; | |
| 1582 | openedAt: string; | |
| 1583 | emailedAt: string | null; | |
| 1584 | }; | |
| 1585 | ||
| 1586 | /** A change to a price, measured from what Cloudflare charged. */ | |
| 1587 | export type PriceProposal = { | |
| 1588 | id: string; | |
| 1589 | meter: string; | |
| 1590 | title: string; | |
| 1591 | unit: string; | |
| 1592 | currentCostMicros: number; | |
| 1593 | proposedCostMicros: number; | |
| 1594 | changePercent: number; | |
| 1595 | markupPercent: number; | |
| 1596 | reason: string; | |
| 1597 | source: "keeper" | "reconciler" | string; | |
| 1598 | /** Far off the current cost: look before approving. */ | |
| 1599 | suspect: boolean; | |
| 1600 | status: "open" | "applied" | "approved" | "rejected" | "superseded" | string; | |
| 1601 | createdAt: string; | |
| 1602 | decidedAt: string | null; | |
| 1603 | decidedBy: string | null; | |
| 1604 | note: string | null; | |
| 1605 | effectiveAt: string | null; | |
| 1606 | }; | |
| 1607 | ||
| 1608 | /** One version of one meter's price; never changed once written. */ | |
| 1609 | export type PriceVersion = { | |
| 1610 | id: string; | |
| 1611 | meter: string; | |
| 1612 | version: number; | |
| 1613 | costMicros: number; | |
| 1614 | markupPercent: number; | |
| 1615 | priceMicros: number; | |
| 1616 | effectiveAt: string; | |
| 1617 | reason: string; | |
| 1618 | createdBy: string; | |
| 1619 | appliedAt: string | null; | |
| Merge costs and margin review: gateway query, own spend, discount meters, superseded rises | 1620 | /** |
| 1621 | * What `costMicros` is: `cost`, what g1t pays for a unit; `rate`, a price | |
| 1622 | * g1t sets with no cost behind it (the agent rate), so it is no cost; | |
| 1623 | * `weight`, a multiplier in millionths, not money. Absent from older | |
| 1624 | * billing: read as `cost`. | |
| 1625 | */ | |
| 1626 | basis?: "cost" | "rate" | "weight" | ""; | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 1627 | }; |
| 1628 | ||
| sudo: reset a test workspace's billing so it starts again as a new customer; refused on a live Stripe key, for comped workspaces and for an enterprise's | 1629 | /** What `resetBilling` removed. */ |
| sudo: a billing reset runs the costs analysis again so every figure is fresh; every submit button shows it is working (CSS only); no margin percentage on less than a cent sold | 1630 | export type BillingReset = { workspace: string; rows: number; refreshed?: boolean }; |
| sudo: reset a test workspace's billing so it starts again as a new customer; refused on a live Stripe key, for comped workspaces and for an enterprise's | 1631 | |
| Costs: margin is measured on what was sold; comped workspaces, free periods, the trial and the pools are given away, a budget shown beside it | 1632 | export type WorkspaceCost = { workspace: string; costMicros: number; revenueMicros: number; givenMicros?: number; internal: boolean }; |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 1633 | |
| 1634 | export type CostLineSummary = { | |
| 1635 | product: string; | |
| 1636 | meter: string; | |
| 1637 | rawName: string; | |
| 1638 | unit: string; | |
| 1639 | source: string; | |
| 1640 | quantity: number; | |
| 1641 | costMicros: number; | |
| 1642 | /** Absent when no mapping claims it. */ | |
| 1643 | bucket: string | null; | |
| 1644 | }; | |
| 1645 | ||
| 1646 | export type CostMapping = { | |
| 1647 | product: string; | |
| 1648 | meter: string; | |
| 1649 | bucket: string; | |
| 1650 | priceMeter: string | null; | |
| 1651 | ownMeter: string | null; | |
| 1652 | scaleToOwn: boolean; | |
| 1653 | driftPercent: number; | |
| 1654 | note: string; | |
| 1655 | updatedAt: string; | |
| 1656 | updatedBy: string; | |
| 1657 | }; | |
| 1658 | ||
| 1659 | export type CostMappingInput = { | |
| 1660 | product: string; | |
| 1661 | meter: string; | |
| 1662 | bucket?: string; | |
| 1663 | priceMeter?: string | null; | |
| 1664 | ownMeter?: string | null; | |
| 1665 | scaleToOwn?: boolean; | |
| 1666 | driftPercent?: number | null; | |
| 1667 | note?: string; | |
| 1668 | remove?: boolean; | |
| 1669 | }; | |
| 1670 | ||
| 1671 | export type CostSettings = { | |
| 1672 | autoApply: boolean; | |
| 1673 | autoApplyPercent: number; | |
| 1674 | noticeDays: number; | |
| 1675 | marginFloorPercent: number; | |
| 1676 | alertDays: number; | |
| 1677 | minDailyCostMicros: number; | |
| 1678 | anomalyFactor: number; | |
| 1679 | anomalyFloorMicros: number; | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 1680 | /** Pass Stripe's card fee on as its own line when AI credit is bought by card. */ |
| 1681 | cardFee: boolean; | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 1682 | }; |
| 1683 | ||
| 1684 | export type CostsReport = { | |
| 1685 | configured: boolean; | |
| 1686 | fetchedAt: string | null; | |
| 1687 | since: string; | |
| 1688 | until: string; | |
| 1689 | days: CostDay[]; | |
| 1690 | products: ProductMargin[]; | |
| 1691 | overall: OverallMargin; | |
| 1692 | drift: CostDrift[]; | |
| 1693 | alerts: MarginAlert[]; | |
| 1694 | proposals: PriceProposal[]; | |
| 1695 | versions: PriceVersion[]; | |
| 1696 | topWorkspaces: WorkspaceCost[]; | |
| 1697 | lines: CostLineSummary[]; | |
| 1698 | mappings: CostMapping[]; | |
| 1699 | settings: CostSettings; | |
| Spend caps: a monthly budget for comped workspaces and a daily breaker on what g1t pays | 1700 | /** g1t's own spend against its two caps. */ |
| 1701 | caps: SpendCaps; | |
| Merge Cloudflare's usage over its billing cycle: every page read, included amounts once a cycle, a projection, test-mode charges never money in (billing 0052) | 1702 | /** Cloudflare's current billing cycle: usage cost so far by meter, and the projection. Absent until the bill is read. */ |
| 1703 | cycle?: CloudflareCycle | null; | |
| 1704 | /** The last read of Cloudflare's billable usage: what came back. */ | |
| 1705 | billRead?: BillRead | null; | |
| 1706 | /** Of the range's cost, what no workspace's usage could carry: running g1t, attributed to no one. */ | |
| 1707 | unattributedMicros?: number; | |
| 1708 | }; | |
| 1709 | ||
| 1710 | /** Cloudflare's billing cycle, as its Billable usage page shows it. */ | |
| 1711 | export type CloudflareCycle = { | |
| 1712 | /** First and last days, YYYY-MM-DD, UTC. */ | |
| 1713 | start: string; | |
| 1714 | end: string; | |
| 1715 | days: number; | |
| 1716 | /** Days from its start to today, today included. */ | |
| 1717 | daysElapsed: number; | |
| 1718 | /** Usage cost so far, after the included allowances. */ | |
| 1719 | usageMicros: number; | |
| 1720 | /** usageMicros over the days elapsed, times the cycle's days. */ | |
| 1721 | projectedMicros: number; | |
| 1722 | averageDailyMicros: number; | |
| 1723 | /** Cloudflare's subscriptions for the cycle (not on the usage bill). */ | |
| 1724 | subscriptionsMicros: number; | |
| 1725 | meters: CycleMeter[]; | |
| 1726 | }; | |
| 1727 | ||
| 1728 | /** One of Cloudflare's meters over the cycle so far. */ | |
| 1729 | export type CycleMeter = { | |
| 1730 | product: string; | |
| 1731 | meter: string; | |
| 1732 | rawName: string; | |
| 1733 | unit: string; | |
| 1734 | quantity: number; | |
| 1735 | /** What the cycle includes; null without a list price. */ | |
| 1736 | included: number | null; | |
| 1737 | billableQuantity: number; | |
| 1738 | costMicros: number; | |
| 1739 | /** cloudflare: Cloudflare's own cost; list: the list price past the included amount; none: no list price known. */ | |
| 1740 | basis: "cloudflare" | "list" | "none" | string; | |
| Spend caps: a monthly budget for comped workspaces and a daily breaker on what g1t pays | 1741 | }; |
| 1742 | ||
| Merge Cloudflare's usage over its billing cycle: every page read, included amounts once a cycle, a projection, test-mode charges never money in (billing 0052) | 1743 | /** What the last read of Cloudflare's billable usage got back. */ |
| 1744 | export type BillRead = { | |
| 1745 | readAt: string; | |
| 1746 | since: string; | |
| 1747 | until: string; | |
| 1748 | rows: number; | |
| 1749 | pages: number; | |
| 1750 | consumedRows: number; | |
| 1751 | pricingOnlyRows: number; | |
| 1752 | costedRows: number; | |
| 1753 | }; | |
| 1754 | ||
| 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) | 1755 | /** One level of the platform pause, as sudo shows it. Snake case, as billing sends it. */ |
| 1756 | export type PauseState = { | |
| 1757 | level: PauseLevel; | |
| 1758 | paused: boolean; | |
| 1759 | note: string | null; | |
| 1760 | set_by: string | null; | |
| 1761 | set_at: string | null; | |
| 1762 | /** Set by billing's usage watcher, not a person. */ | |
| 1763 | auto: boolean; | |
| 1764 | }; | |
| 1765 | ||
| 1766 | /** One platform metric over an hour or the month so far. */ | |
| 1767 | export type PlatformMetric = { | |
| 1768 | metric: string; | |
| 1769 | title: string; | |
| 1770 | value: number; | |
| 1771 | /** Its hourly threshold (`PLATFORM_HOURLY_*`); 0: none. */ | |
| 1772 | threshold: number; | |
| 1773 | /** The script, queue, database or namespace that counted most. */ | |
| 1774 | top_name: string | null; | |
| 1775 | top_value: number | null; | |
| 1776 | }; | |
| 1777 | ||
| 1778 | /** A breach billing's usage watcher found. */ | |
| 1779 | export type PlatformBreach = { | |
| 1780 | id: string; | |
| 1781 | metric: string; | |
| 1782 | hour: string; | |
| 1783 | rule: "threshold" | "spike"; | |
| 1784 | value: number; | |
| 1785 | threshold: number; | |
| 1786 | severe: boolean; | |
| 1787 | top_name: string | null; | |
| 1788 | detail: string; | |
| 1789 | /** Levels it paused. */ | |
| 1790 | paused: PauseLevel[]; | |
| 1791 | opened_at: string; | |
| 1792 | emailed_at: string | null; | |
| 1793 | }; | |
| 1794 | ||
| The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were. | 1795 | /** Billing's `admin_platform_guard`: the platform pause and usage watcher |
| 1796 | * (docs.g1t.sh/guides/deploy-to-cloudflare/#spend-guardrails). */ | |
| 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) | 1797 | export type PlatformGuard = { |
| 1798 | levels: PauseState[]; | |
| 1799 | /** The last hour read, `YYYY-MM-DDTHH:00:00Z`. */ | |
| 1800 | hour: string | null; | |
| 1801 | last_hour: PlatformMetric[]; | |
| 1802 | month: string; | |
| 1803 | month_to_date: PlatformMetric[]; | |
| 1804 | breaches: PlatformBreach[]; | |
| 1805 | /** Whether billing can read Cloudflare's analytics. */ | |
| 1806 | can_read: boolean; | |
| 1807 | /** `AUTO_PAUSE`: the levels a severe breach may pause. */ | |
| 1808 | auto_pause: PauseLevel[]; | |
| 1809 | /** What the latest run could not see: each query that failed, with its error. */ | |
| 1810 | blind?: { key: string; dataset: string; error: string }[]; | |
| 1811 | /** The latest run found every dataset empty: the wrong account, or a token that cannot see it. */ | |
| 1812 | empty?: boolean; | |
| 1813 | /** The hour the latest run read. */ | |
| 1814 | last_run?: string | null; | |
| 1815 | }; | |
| 1816 | ||
| Spend caps: a monthly budget for comped workspaces and a daily breaker on what g1t pays | 1817 | /** What g1t pays for itself, at cost, against its caps (billing's `budget`). */ |
| 1818 | export type SpendCaps = { | |
| 1819 | /** Today (UTC), YYYY-MM-DD, and this month, YYYY-MM. */ | |
| 1820 | day: string; | |
| 1821 | month: string; | |
| 1822 | /** What g1t paid for itself today across every workspace. */ | |
| 1823 | todayMicros: number; | |
| 1824 | /** `PLATFORM_DAILY_SPEND_CAP_MICROS`; 0: no breaker. */ | |
| 1825 | dailyCapMicros: number; | |
| 1826 | /** New hosted-model agent runs g1t would pay for are paused. */ | |
| 1827 | tripped: boolean; | |
| 1828 | trippedAt: string | null; | |
| 1829 | liftedBy: string | null; | |
| 1830 | liftedAt: string | null; | |
| 1831 | liftNote: string | null; | |
| 1832 | /** This month so far, by what paid: comped, trial, oss, given, unpaid. */ | |
| 1833 | monthBuckets: { bucket: string; title: string; micros: number }[]; | |
| 1834 | comped: CompedBudget[]; | |
| 1835 | /** Free workspaces' share of reconciled costs this month (git, storage, platform). */ | |
| 1836 | freeTierMicros: number; | |
| Costs: Cloudflare's subscriptions read from Cloudflare each day, the estimate only until then; sudo's costs split into Costs & margin and Bill & pricing | 1837 | /** Cloudflare's subscriptions a month: read from Cloudflare each day, else `CLOUDFLARE_FIXED_MONTHLY_MICROS`, an estimate. */ |
| Spend caps: a monthly budget for comped workspaces and a daily breaker on what g1t pays | 1838 | fixedMonthlyMicros: number; |
| Costs: Cloudflare's subscriptions read from Cloudflare each day, the estimate only until then; sudo's costs split into Costs & margin and Bill & pricing | 1839 | fixedSource?: "cloudflare" | "estimate" | string; |
| 1840 | fixedReadAt?: string | null; | |
| 1841 | /** Each subscription, when read from Cloudflare. */ | |
| 1842 | fixedItems?: { name: string; monthlyMicros: number }[]; | |
| Merge Cloudflare's usage over its billing cycle: every page read, included amounts once a cycle, a projection, test-mode charges never money in (billing 0052) | 1843 | /** Of fixedMonthlyMicros, this calendar month's days so far, each at its billing cycle's daily share. */ |
| 1844 | fixedMonthMicros?: number; | |
| Spend caps: a monthly budget for comped workspaces and a daily breaker on what g1t pays | 1845 | /** Money in this month, through the last reconciled day. */ |
| 1846 | revenueMicros: number; | |
| Merge costs and margin review: gateway query, own spend, discount meters, superseded rises | 1847 | /** |
| 1848 | * Of this month's buckets, what was spent on workspaces whose billing a | |
| 1849 | * testing reset later wiped (still g1t's spend; the reconciled figures | |
| 1850 | * have it only where the reset kept it), and those workspaces. | |
| 1851 | */ | |
| 1852 | resetMicros?: number; | |
| 1853 | resetWorkspaces?: string[]; | |
| Spend caps: a monthly budget for comped workspaces and a daily breaker on what g1t pays | 1854 | }; |
| 1855 | ||
| 1856 | /** A comped account's monthly budget, at cost. */ | |
| 1857 | export type CompedBudget = { | |
| 1858 | account: string; | |
| 1859 | name: string; | |
| 1860 | usedMicros: number; | |
| 1861 | /** 0: no budget. */ | |
| 1862 | ceilingMicros: number; | |
| 1863 | /** `COMPED_MONTHLY_CEILING_MICROS`, not the account's own limit. */ | |
| 1864 | defaultCeiling: boolean; | |
| 1865 | /** 50, 75, 90, 100, or 0. */ | |
| 1866 | level: number; | |
| Git storage hardened, pages in tens of milliseconds, honest security alerts, and costs reconciled daily | 1867 | }; |
| 1868 | ||
| 1869 | export type CostsRun = { lines: number; days: number; proposals: number; alerts: number; problems: string[] }; | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 1870 | |
| 1871 | /** The product families the Usage page groups meters into, in order. */ | |
| 1872 | export const PRODUCTS = [ | |
| 1873 | { key: "agent", label: "Agent" }, | |
| 1874 | { key: "sandboxes", label: "Sandboxes" }, | |
| 1875 | { key: "gateway", label: "AI Gateway" }, | |
| 1876 | { key: "deployments", label: "Deployments" }, | |
| 1877 | { key: "git_storage", label: "Git & storage" }, | |
| 1878 | { key: "packages", label: "Packages" }, | |
| 1879 | { key: "security", label: "Security & quality" }, | |
| 1880 | { key: "search", label: "Search" }, | |
| 1881 | ] as const; | |
| 1882 | ||
| 1883 | export type ProductKey = (typeof PRODUCTS)[number]["key"]; | |
| 1884 | ||
| 1885 | /** What usage came to over a range, and what paid for it: price − discount − included − credits = charged. */ | |
| 1886 | export type UsageTotals = { | |
| 1887 | /** Usage at price, pending usage included. */ | |
| 1888 | priceMicros: number; | |
| 1889 | discountMicros: number; | |
| 1890 | /** Paid by the plan's included usage, the trial and g1t's pools. */ | |
| 1891 | includedMicros: number; | |
| 1892 | /** Paid by AI credit and credit from g1t. */ | |
| 1893 | creditsMicros: number; | |
| 1894 | /** Left for the workspace to pay. */ | |
| 1895 | chargedMicros: number; | |
| 1896 | /** Metered this month, charged when it closes. */ | |
| 1897 | pendingMicros: number; | |
| Money is written one way. A single formatter turns millionths of a dollar into dollars, rounding half up on whole micros rather than on a float, so the same sum reads the same on every page: under a cent reads <$0.01 on a total and exactly nothing is $0.00, while the statement's lines, a session's receipt, the price book and an agent's effort costs carry up to four places where the fraction of a cent is the point; the six formatters that each rounded their own way are gone. This month is the calendar month in UTC from its first day to today everywhere, and billing counts the month's not-yet-closed usage in any range that reaches into the current month, so the top bar's pill, Spend, Home and Usage ask for the same days and get the same figure; Home now reads the usage report the others read instead of adding up statements. Usage's pending sentence says what of that usage the close will charge after the discount and included usage, which the billing API returns as pending_charged_micros. A reconciliation test holds the pill, Spend, Home and Usage to one number for one month. The usage and billing guide says how amounts are written and what this month means. | 1898 | /** What of `pendingMicros` will be charged at the close, after the discount and what g1t covers; absent from an older billing. */ |
| 1899 | pendingChargedMicros?: number; | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 1900 | costMicros: number; |
| 1901 | }; | |
| 1902 | ||
| 1903 | export type UsageDay = { day: string; product: string; micros: number }; | |
| 1904 | ||
| Spend adds up on one ledger. Charged this month has one definition, price less discount, included usage and credit, shared by the plan card, the spend limit, Spend and the top bar; the limit had counted usage not yet closed at full price before the discount, so a comped workspace read as charged a cent. Every agent line on the ledger names the agent and who asked, repository runs by g1t included, so Spent is the sum of its products, Agents is the agent product, and by agent adds up to it; the billing API returns by_agent and by_person. The usage and billing guide says how spend is counted. | 1905 | /** One agent's (by handle) or one person's (by username) share of the agent product, at price; an empty key for lines attributed to no one. */ |
| 1906 | export type UsageShare = { key: string; label: string; micros: number; count: number }; | |
| 1907 | ||
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 1908 | export type UsageAllowance = { used: number; of: number; unit: string }; |
| 1909 | ||
| 1910 | export type ProjectUsage = { project: string; micros: number; quantity: number }; | |
| 1911 | ||
| 1912 | /** One meter over a range. */ | |
| 1913 | export type MeterLine = { | |
| 1914 | key: string; | |
| 1915 | label: string; | |
| 1916 | product: string; | |
| 1917 | /** `tokens`, `seconds`, `bytes`, `operations`, `requests` or `entries`. */ | |
| 1918 | unit: string; | |
| 1919 | quantity: number; | |
| 1920 | micros: number; | |
| 1921 | pendingMicros?: number; | |
| 1922 | /** Every day of the range, oldest first, at price. */ | |
| 1923 | daily: number[]; | |
| 1924 | allowance?: UsageAllowance | null; | |
| 1925 | byProject: ProjectUsage[]; | |
| Merge branch 'model-routing' | 1926 | /** How the quantity is counted, when that needs saying (the agent rate's token weights). */ |
| 1927 | note?: string | null; | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 1928 | }; |
| 1929 | ||
| 1930 | export type FeatureUsage = { key: string; label: string; micros: number; count: number }; | |
| 1931 | ||
| 1932 | export type ProductUsage = { key: string; label: string; micros: number; meters: MeterLine[]; features?: FeatureUsage[] }; | |
| 1933 | ||
| Merge branch 'model-routing' | 1934 | /** The tokens one model used over a range, as the model proxy counted them. */ |
| 1935 | export type ModelTokens = { model: string; input: number; output: number; cacheRead: number; cacheWrite: number }; | |
| 1936 | ||
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 1937 | export type UsageReport = { |
| 1938 | from: string; | |
| 1939 | until: string; | |
| 1940 | totals: UsageTotals; | |
| 1941 | days: UsageDay[]; | |
| 1942 | products: ProductUsage[]; | |
| 1943 | projects: string[]; | |
| Merge branch 'model-routing' | 1944 | /** Agent tokens by model over the range, most first. */ |
| 1945 | models?: ModelTokens[]; | |
| Spend adds up on one ledger. Charged this month has one definition, price less discount, included usage and credit, shared by the plan card, the spend limit, Spend and the top bar; the limit had counted usage not yet closed at full price before the discount, so a comped workspace read as charged a cent. Every agent line on the ledger names the agent and who asked, repository runs by g1t included, so Spent is the sum of its products, Agents is the agent product, and by agent adds up to it; the billing API returns by_agent and by_person. The usage and billing guide says how spend is counted. | 1946 | /** The agent product by the agent that did the work, most first; their sum is the agent product's total. */ |
| 1947 | byAgent?: UsageShare[]; | |
| 1948 | /** The agent product by who asked; work no person asked for under an empty key. */ | |
| 1949 | byPerson?: UsageShare[]; | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 1950 | /** The plan's included usage this month, in micros. */ |
| 1951 | included?: UsageAllowance | null; | |
| 1952 | discountPercent?: number | null; | |
| 1953 | aiCreditMicros: number; | |
| 1954 | creditMicros: number; | |
| 1955 | trialMicros?: number | null; | |
| 1956 | plan: PlanKind; | |
| 1957 | free: boolean; | |
| 1958 | }; | |
| 1959 | ||
| 1960 | export type AiReload = { | |
| 1961 | enabled: boolean; | |
| 1962 | thresholdMicros: number; | |
| 1963 | targetMicros: number; | |
| 1964 | monthlyMaxMicros: number; | |
| 1965 | reloadedMicros?: number; | |
| 1966 | failedAt?: string | null; | |
| 1967 | error?: string | null; | |
| 1968 | }; | |
| 1969 | ||
| 1970 | export type CardFee = { on: boolean; percentMicros: number; fixedCents: number }; | |
| 1971 | ||
| 1972 | /** Prepaid AI credit: what Agent and AI Gateway usage draws on. */ | |
| 1973 | export type AiCredit = { | |
| 1974 | balanceMicros: number; | |
| 1975 | purchasedMicros: number; | |
| 1976 | givenMicros: number; | |
| 1977 | grants: CreditGrant[]; | |
| 1978 | /** A 100% discount pays for AI usage: nothing to buy. */ | |
| 1979 | freeViaDiscount: boolean; | |
| 1980 | /** Invoiced after use (an enterprise). */ | |
| 1981 | postpaid: boolean; | |
| 1982 | /** New runs on g1t's models are refused for want of credit. */ | |
| 1983 | blocked: boolean; | |
| 1984 | canBuy: boolean; | |
| 1985 | presetsCents: number[]; | |
| 1986 | minCents: number; | |
| 1987 | maxCents: number; | |
| 1988 | cardFee: CardFee; | |
| 1989 | reload: AiReload; | |
| 1990 | /** The agent rate per million tokens, at price. */ | |
| 1991 | agentRateMicros: number; | |
| 1992 | modelMarkupPercent: number; | |
| 1993 | gatewayMarkupPercent: number; | |
| 1994 | upgradeCreditMicros: number; | |
| 1995 | expiresDays: number; | |
| 1996 | }; | |
| 1997 | ||
| 1998 | export type PostalAddress = { line1: string; line2: string; city: string; state: string; postalCode: string; country: string }; | |
| 1999 | ||
| 2000 | export type PaymentMethod = { | |
| 2001 | kind: string; | |
| 2002 | brand?: string | null; | |
| 2003 | last4?: string | null; | |
| 2004 | expMonth?: number | null; | |
| 2005 | expYear?: number | null; | |
| 2006 | }; | |
| 2007 | ||
| 2008 | export type StripeInvoice = { | |
| 2009 | id: string; | |
| 2010 | number?: string | null; | |
| 2011 | status: string; | |
| 2012 | totalCents: number; | |
| 2013 | currency: string; | |
| 2014 | createdAt: string; | |
| 2015 | description?: string | null; | |
| 2016 | hostedUrl?: string | null; | |
| 2017 | pdfUrl?: string | null; | |
| 2018 | }; | |
| 2019 | ||
| 2020 | export type UpcomingInvoice = { closesAt: string; subscriptionsMicros: number; usageMicros: number; totalMicros: number }; | |
| 2021 | ||
| 2022 | export type BillingDetails = { | |
| 2023 | customer: boolean; | |
| 2024 | email: string | null; | |
| 2025 | name: string | null; | |
| 2026 | address: PostalAddress | null; | |
| 2027 | taxIdType: string | null; | |
| 2028 | taxId: string | null; | |
| 2029 | poNumber: string | null; | |
| 2030 | language: string | null; | |
| 2031 | paymentMethod: PaymentMethod | null; | |
| 2032 | invoices: StripeInvoice[]; | |
| 2033 | upcoming: UpcomingInvoice; | |
| 2034 | unavailable?: string | null; | |
| Merge Stripe Tax, the card fee on card payments, and one free workspace per person | 2035 | /** Whether Stripe Tax can place the customer from the address; without it nothing is charged. */ |
| 2036 | taxLocation?: boolean; | |
| 2037 | /** Set when g1t did not charge for want of a billing address. */ | |
| 2038 | taxAddressNeededAt?: string | null; | |
| 2039 | /** Stripe's check of the tax ID: pending, verified, unverified or unavailable. */ | |
| 2040 | taxIdStatus?: string | null; | |
| 2041 | /** none, exempt or reverse, as set at Stripe. */ | |
| 2042 | taxExempt?: string | null; | |
| Usage, Billing settings and prepaid AI credit; fixes from the UX audit | 2043 | }; |
| 2044 | ||
| 2045 | export type BillingDetailsInput = { | |
| 2046 | email?: string; | |
| 2047 | name?: string; | |
| 2048 | address?: PostalAddress; | |
| 2049 | taxIdType?: string; | |
| 2050 | taxId?: string; | |
| 2051 | poNumber?: string; | |
| 2052 | language?: string; | |
| 2053 | }; |
This file's history is long; its oldest lines are credited to the oldest commit read.