import { type Api, AuthStorage, type CompletionProbe, type Model } from "@oh-my-pi/pi-ai"; import { type AuthGatewayClient, type ModelResolveOptions } from "@oh-my-pi/pi-ai/auth-gateway"; import { ModelRegistry } from "../config/model-registry.js"; import type { Settings } from "../config/settings.js"; export type AuthGatewayAction = "serve" | "stdio" | "token" | "status" | "check"; export interface AuthGatewayCommandArgs { action: AuthGatewayAction; flags: { json?: boolean; bind?: string; regenerate?: boolean; trustProxyHeaders?: boolean; /** * Disable bearer-token auth on inbound requests. Useful when the gateway * is bound to loopback (the default `127.0.0.1:4000`) and you don't want * to wire token-paste plumbing into every local client. */ noAuth?: boolean; /** * Strict mode for `check` — additionally exercise every credential * against its provider's chat-completion endpoint. The usage probe (run * unconditionally) can pass while the chat endpoint still 401s the same * bearer, so strict mode is the definitive "is this credential * actually usable" signal. Slower and consumes a tiny amount of quota. */ strict?: boolean; /** * `serve`: JSON file of scoped client tokens, each limited to its own * models and broker OAuth accounts. Re-read while serving. */ clients?: string; }; } declare const ACTIONS: readonly AuthGatewayAction[]; /** * Re-read a `--clients` file and apply it when its text changed. A file that * cannot be read or parsed, or that the gateway rejects, revokes every client * token until it is fixed: keeping the previous table would keep serving a * client the operator just removed. Polls never overlap, so a slow read cannot * apply an older file over a newer one. `appliedText` is the file text the * gateway started with. */ export declare function createAuthGatewayClientsReloader(filePath: string, appliedText: string, setClients: (clients: readonly AuthGatewayClient[]) => void): () => Promise; /** Every registry model of a kind the gateway can route, bundled catalog order within each kind. */ export declare function gatewayRoutableModels(registry: ModelRegistry): Model[]; /** * Providers the broker holds a credential for, minus `disabledProviders`. Recomputed on * every rebuild so a later login or logout reaches the served catalog. */ export declare function gatewayRoutableProviders(storage: AuthStorage, settings: Settings): Set; /** * One catalog rebuild's served models, indexed by the ids clients send. Built by * {@link indexModelsByRequestId}, read by {@link resolveGatewayModel} and `/v1/models`. */ export interface GatewayModelIndex { /** * Every served model, catalog order. One array per rebuild: * `resolveProviderModelReference` caches its lookups on the array identity. */ readonly models: readonly Model[]; /** `provider/id` → model. */ readonly qualified: ReadonlyMap>; /** * Bare `id` → its models grouped into provider-priority tiers, best first. * A tier holds the providers sharing one rank (every provider the priority * order leaves unranked shares the last), sorted by provider id. */ readonly bare: ReadonlyMap[])[]>; } /** * Index the models of credentialed providers by the request ids clients may * send: `provider/id` names one model, a bare `id` every served model of that * id. Bare ids rank by provider priority (`providerOrder`, the * `modelProviderOrder` setting, ahead of the built-in native-before-mirror * order), then provider id — never catalog position, which every discovery * refresh reshuffles. */ export declare function indexModelsByRequestId(models: readonly Model[], providersWithCreds: ReadonlySet, providerOrder?: readonly string[]): GatewayModelIndex; /** * Resolve a client-requested model id: the exact `provider/id`, else the bare * `id`'s best candidate — the first priority tier `options.accepts` admits any * model from, preferring one on the route's `options.api` within it — else an * OpenRouter routing-variant selector the catalog does not list * (`openrouter/:floor`, `:nitro`, …), cloned from its base model under the * requested id so the suffix reaches OpenRouter — the same selectors `--model` * accepts. A refused `provider/id` resolves to nothing. */ export declare function resolveGatewayModel(id: string, index: GatewayModelIndex, options?: ModelResolveOptions): Model | undefined; /** * Serialize catalog rebuilds so `registry.refresh()` passes never overlap, * while guaranteeing a forced rebuild requested mid-flight runs a forced pass * afterward. Without the follow-up pass a credential change arriving during a * weaker cached rebuild would piggyback on it and miss an account-scoped * catalog change. Non-forced requests during an in-flight rebuild simply * coalesce onto it. Returns `rebuild(force?)`; its promise resolves once the * catalog reflects that call's requirement. */ export declare function createSerializedRebuilder(run: (force: boolean) => Promise): (force?: boolean) => Promise; export declare function runAuthGatewayCommand(cmd: AuthGatewayCommandArgs): Promise; /** * Build the {@link CompletionProbe} consumed by * {@link AuthStorage.health.check} in `--strict` mode. Walks the cheapest * candidates per provider, retrying on "model not found / invalid model" * errors so a stale catalog entry doesn't masquerade as a bad credential. * Stops as soon as one model returns a successful response (the credential * authenticated against at least one model in the catalog). */ export declare function createStrictCompletionProbe(): CompletionProbe; export { ACTIONS as AUTH_GATEWAY_ACTIONS };