/** * Whether a chat for one (user, org) can reach a model, as one value. The * engine picker, the sidebar credit notice, the connect gate and the chat error * card each used to derive this on their own, so any one could disagree with * the rest: an org-connected Enterprise member was told their Builder credits * were used up while every chat ran fine. */ export type CredentialSubject = "provider" | "builder" | "agent"; export type CredentialFixer = "self" | "org_admin"; export type BuilderCreditPeriod = "daily" | "monthly"; export type CredentialState = { kind: "usable"; } | { kind: "missing"; credential: CredentialSubject; } | { kind: "rejected"; credential: CredentialSubject; } | { kind: "exhausted"; period?: BuilderCreditPeriod; plan?: "free" | "paid"; } | { kind: "notPermitted"; whoCanFix: CredentialFixer; }; export interface ChatCredentialInputs { /** The engine `resolveEngine` picks for this (user, org). */ engine: string; /** Whether that engine holds a credential it can run on. */ engineUsable: boolean; /** Live quota of the connected Builder credential; null when none is. */ builderCredits: { plan: "free" | "paid"; quota: { period: BuilderCreditPeriod; remaining: number; }; } | null; } export declare function describeChatCredentialState(input: ChatCredentialInputs): CredentialState; /** * Typed wire codes for credential failures. Clients map on these; matching * English error text is a legacy fallback for failures that arrive without one. * * `unauthorized` is deliberately absent: the browser gives that code to every * 401 without a body code, which is usually this app's own signed-out session, * not a provider refusing a key. */ export declare const CREDENTIAL_ERROR_CODES: { readonly missing_credentials: { readonly kind: "missing"; readonly credential: "provider"; }; readonly missing_api_key: { readonly kind: "missing"; readonly credential: "provider"; }; readonly authentication_error: { readonly kind: "rejected"; readonly credential: "provider"; }; readonly invalid_api_key: { readonly kind: "rejected"; readonly credential: "provider"; }; readonly http_401: { readonly kind: "rejected"; readonly credential: "provider"; }; readonly http_403: { readonly kind: "rejected"; readonly credential: "provider"; }; readonly builder_auth_error: { readonly kind: "rejected"; readonly credential: "builder"; }; readonly builder_oauth_lookup_failed: { readonly kind: "rejected"; readonly credential: "builder"; }; readonly builder_oauth_refresh_failed: { readonly kind: "rejected"; readonly credential: "builder"; }; readonly builder_oauth_reauthorization_required: { readonly kind: "rejected"; readonly credential: "builder"; }; readonly credential_missing: { readonly kind: "missing"; readonly credential: "agent"; }; readonly credential_rejected: { readonly kind: "rejected"; readonly credential: "agent"; }; readonly gateway_not_enabled: { readonly kind: "notPermitted"; readonly whoCanFix: "org_admin"; }; readonly personal_provider_keys_restricted: { readonly kind: "notPermitted"; readonly whoCanFix: "org_admin"; }; }; export type CredentialErrorCode = keyof typeof CREDENTIAL_ERROR_CODES; /** * Codes that carry only an upstream HTTP status. Some upstreams answer a spent * quota or a rate limit with 403, so the failure's own text decides first. */ export declare const AMBIGUOUS_HTTP_CREDENTIAL_CODES: ReadonlySet; export declare function credentialStateForErrorCode(errorCode: string | null | undefined): CredentialState | null; /** * The state as flat, bounded event properties, so a rate by kind, subject or * who can fix it is a GROUP BY. Carries no identifiers; the caller adds where * the state surfaced. */ export declare function credentialStateProperties(state: CredentialState): Record; /** `credentialStateProperties` for a wire code; empty when it names no state. */ export declare function credentialStateTrackingProperties(errorCode: string | null | undefined): Record;