import type { CredentialStore } from "@earendil-works/pi-ai"; import { resolveCliModel } from "../core/model-resolver.ts"; import { ModelRuntime } from "../core/model-runtime.ts"; import { InMemoryCodingAgentModelsStore } from "../core/models-store.ts"; import type { Args } from "./args.ts"; import { AuthCommandError, getAuthCredential, validateAuthCommandArgs } from "./auth-command.ts"; export type AuthCheckStatus = "ready" | "not_ready" | "invalid"; export type AuthCheckReason = | "provider_not_found" | "credentials_not_configured" | "credential_not_available" | "invalid_state"; export interface AuthCheckResult { status: AuthCheckStatus; provider: string; reason?: AuthCheckReason; authType?: "api_key" | "oauth"; } export async function checkProviderAuth( args: Args, modelRuntime: ModelRuntime, options: { refresh: boolean } = { refresh: false }, ): Promise { const { provider: cliProvider, model: cliModel } = validateAuthCommandArgs(args, "check"); let provider = cliProvider; if (cliModel) { const resolved = resolveCliModel({ cliProvider, cliModel, modelRuntime }); if (resolved.error || !resolved.model) { throw new AuthCommandError(resolved.error ?? `Unable to resolve model "${cliModel}"`); } provider = resolved.model.provider; } if (!provider) throw new AuthCommandError("Unable to resolve an auth provider"); if (modelRuntime.getError()) { return { status: "invalid", provider, reason: "invalid_state" }; } if (!modelRuntime.getProvider(provider)) { return { status: "not_ready", provider, reason: "provider_not_found" }; } try { const auth = await modelRuntime.checkAuth(provider); if (!auth) return { status: "not_ready", provider, reason: "credentials_not_configured" }; if (options.refresh && !(await modelRuntime.getAuth(provider))) { return { status: "not_ready", provider, reason: "credentials_not_configured" }; } return { status: "ready", provider, authType: auth.type }; } catch { return { status: "invalid", provider, reason: "invalid_state" }; } } export async function getProviderCredential( providerId: string, modelRuntime: ModelRuntime, credentials: CredentialStore, options: { refresh: boolean }, ): Promise { const credential = await credentials.read(providerId); if (!options.refresh && credential?.type === "oauth") return credential.access; return getAuthCredential(await modelRuntime.getAuth(providerId)); } export async function createAuthCheckModelRuntime(credentials: CredentialStore): Promise { return ModelRuntime.create({ credentials, modelsStore: new InMemoryCodingAgentModelsStore(), allowModelNetwork: false, refreshOnCreate: false, }); }