167 lines · 6.6 KB · TypeScript
RawDownload
import * as Schema from "effect/Schema"; import {  ForwardCompatibleArray,  IsoDateTime,  NonNegativeInt,  TrimmedNonEmptyString,} from "./baseSchemas.ts";import { ProviderDriverKind, ProviderInstanceId } from "./providerInstance.ts";import { UsageLimitSourceId } from "./usageLimitSourceId.ts"; /** * One rolling quota window a subscription provider reports for the signed-in * account, e.g. Claude's five-hour session or Codex's weekly allowance. * * `id` is stable per provider (`five_hour`, `seven_day_opus`, `primary`) so a * sparse turn-driven update lands on the same row a full probe produced. * `kind` only orders and labels the bar. */export const ServerProviderUsageWindow = Schema.Struct({  id: TrimmedNonEmptyString,  kind: Schema.Literals(["session", "weekly", "monthly", "other"]),  label: TrimmedNonEmptyString,  usedPercent: Schema.Number.check(Schema.isBetween({ minimum: 0, maximum: 100 })),  resetsAt: Schema.optional(IsoDateTime),  windowDurationMins: Schema.optional(NonNegativeInt),});export type ServerProviderUsageWindow = typeof ServerProviderUsageWindow.Type; /** * Reset credits a provider banks on the account. Codex grants these when it * has rate-limited the user unfairly; redeeming one clears the current * windows. Only present when the provider reports them at all. */export const ServerProviderResetCredits = Schema.Struct({  availableCount: NonNegativeInt,  nextExpiresAt: Schema.optional(IsoDateTime),  /** Pins hub redemption to the displayed credit, including retries from another client. */  nextCreditId: Schema.optional(TrimmedNonEmptyString),});export type ServerProviderResetCredits = typeof ServerProviderResetCredits.Type; /** * Subscription usage the provider knows about the signed-in account. * * `unavailable` distinguishes an account that can never report windows (API * key, Bedrock) from a probe that failed this time, so clients can keep the * last good bars for the latter and clear them for the former. */export const ServerProviderUsageLimits = Schema.Struct({  checkedAt: IsoDateTime,  windows: ForwardCompatibleArray(ServerProviderUsageWindow),  resetCredits: Schema.optional(ServerProviderResetCredits),  unavailable: Schema.optional(    Schema.Struct({      reason: Schema.Literals(["unsupported", "probeFailed"]),      message: Schema.optional(TrimmedNonEmptyString),    }),  ),});export type ServerProviderUsageLimits = typeof ServerProviderUsageLimits.Type; /** * What an adapter reports when its runtime pushes a rate-limit update during * a turn. Sparse by contract: Claude's `rate_limit_event` names one window at * a time and Codex documents its notification as a partial. Windows merge by * `id` onto the instance's published snapshot; omitted windows are unchanged. */export const ProviderUsageLimitsUpdate = Schema.Struct({  windows: Schema.Array(ServerProviderUsageWindow),});export type ProviderUsageLimitsUpdate = typeof ProviderUsageLimitsUpdate.Type; /** * One account a usage-limit source reports on. `driver` is the provider the * account belongs to, for the icon and colour clients already have; the * account itself is not something this environment can run turns on. */export const UsageLimitSourceAccount = Schema.Struct({  id: TrimmedNonEmptyString,  driver: ProviderDriverKind,  /** The signed-in address, when the source names one; clients blur it like provider auth. */  email: Schema.optional(TrimmedNonEmptyString),  /** Plan as the matching provider would label it (`ChatGPT Pro 20x Subscription`). */  plan: Schema.optional(TrimmedNonEmptyString),  usageLimits: ServerProviderUsageLimits,});export type UsageLimitSourceAccount = typeof UsageLimitSourceAccount.Type; /** * The published state of one configured `usageLimitSources` entry. A source * that could not be read keeps `error` beside an empty account list rather * than vanishing, so the user can see it is configured but failing. */export const UsageLimitSourceSnapshot = Schema.Struct({  id: UsageLimitSourceId,  kind: Schema.Literal("cliproxy"),  label: TrimmedNonEmptyString,  checkedAt: IsoDateTime,  accounts: ForwardCompatibleArray(UsageLimitSourceAccount),  error: Schema.optional(TrimmedNonEmptyString),});export type UsageLimitSourceSnapshot = typeof UsageLimitSourceSnapshot.Type; export const UsageLimitSourceSnapshots = ForwardCompatibleArray(UsageLimitSourceSnapshot);export type UsageLimitSourceSnapshots = typeof UsageLimitSourceSnapshots.Type; export const UsageLimitSourceConsumeResetCreditInput = Schema.Struct({  sourceId: UsageLimitSourceId,  accountId: TrimmedNonEmptyString,  creditId: TrimmedNonEmptyString,});export type UsageLimitSourceConsumeResetCreditInput =  typeof UsageLimitSourceConsumeResetCreditInput.Type; export const ProviderConsumeResetCreditInput = Schema.Union([  Schema.Struct({ instanceId: ProviderInstanceId }),  UsageLimitSourceConsumeResetCreditInput,]);export type ProviderConsumeResetCreditInput = typeof ProviderConsumeResetCreditInput.Type; export class UsageLimitSourceError extends Schema.TaggedError<UsageLimitSourceError>()(  "UsageLimitSourceError",  { detail: Schema.String },) {  override get message(): string {    return this.detail;  }} /** Mirrors Codex's own outcome set; other providers map onto it. */export const ProviderConsumeResetCreditOutcome = Schema.Literals([  "reset",  "nothingToReset",  "noCredit",  "alreadyRedeemed",]);export type ProviderConsumeResetCreditOutcome = typeof ProviderConsumeResetCreditOutcome.Type; export const ProviderConsumeResetCreditResult = Schema.Struct({  outcome: ProviderConsumeResetCreditOutcome,  /** Redemption succeeded, but a follow-up such as clearing the hub cooldown failed. */  warning: Schema.optional(TrimmedNonEmptyString),});export type ProviderConsumeResetCreditResult = typeof ProviderConsumeResetCreditResult.Type; /** A point-in-time view of one provider's limits, built for the /usage-limits panel. */export const UsageLimitsReport = Schema.Struct({  createdAt: IsoDateTime,  accounts: Schema.Array(    Schema.Struct({      id: TrimmedNonEmptyString,      driver: ProviderDriverKind,      label: TrimmedNonEmptyString,      plan: Schema.optional(TrimmedNonEmptyString),      email: Schema.optional(TrimmedNonEmptyString),      sourceLabel: Schema.optional(TrimmedNonEmptyString),      instanceId: Schema.optional(ProviderInstanceId),      resetCreditInput: Schema.optional(ProviderConsumeResetCreditInput),      displayName: Schema.optional(Schema.String),      accentColor: Schema.optional(Schema.String),      limits: ServerProviderUsageLimits,    }),  ),  notices: Schema.Array(Schema.String),});export type UsageLimitsReport = typeof UsageLimitsReport.Type;