import { type GatewayCredentialResolution } from "#internal/resolve-model-endpoint-status.js";
import type { AgentModelSettingsPatch } from "#source-change/apply-agent-model-settings.js";
import { type SelectModelDeps } from "../boxes/select-model.js";
import { type GatewayModelCapabilities, type ReasoningLevel } from "../boxes/model-capabilities.js";
import { type VercelProjectOperationOptions } from "../project-resolution.js";
import type { AgentReasoningDefinition, ModelRouting } from "#shared/agent-definition.js";
import { type GatewayServiceTierState } from "#shared/gateway-service-tier.js";
import type { Prompter, SelectOption } from "../prompter.js";
import { type ApplyModelSettingsOutcome } from "./model-source-change.js";
import { runProviderFlow, type ModelProviderStatus } from "./provider.js";
/** The current model id, its routing, and whether `/model` can rewrite it. */
export interface CurrentAgentModel {
    id: string | null;
    routing: ModelRouting | null;
    reasoning: AgentReasoningDefinition | null;
    serviceTier: GatewayServiceTierState;
    /**
     * The authored `model` is a string the source editor can rewrite. False for a
     * source-backed SDK model call (`gateway(...)`, `anthropic(...)`), which is
     * not a string literal — independent of how the model routes.
     */
    editable: boolean;
    /** Whether the top-level agent config object can carry reasoning/tier edits. */
    settingsEditable: boolean;
}
export type { GatewayServiceTierState };
/**
 * Everything the composite Change-model screen edits, resolved before it
 * opens. The model section is a searchable catalog pick, or a fixed line when
 * the authored model is a source-backed SDK call `/model` cannot rewrite.
 */
export interface ModelSettingsRequest {
    model: {
        kind: "pick";
        options: readonly SelectOption<string>[];
        current: string | null;
    } | {
        kind: "fixed";
        current: string | null;
        reason: string;
    };
    /** Authored reasoning effort; null means the provider default. */
    reasoning: ReasoningLevel | null;
    /** Authored Gateway service tier. */
    serviceTier: GatewayServiceTierState;
    /** Whether the agent config object can carry reasoning/tier edits. */
    settingsEditable: boolean;
    /** True for a direct external provider, where Gateway tiers do not apply. */
    externalRouting: boolean;
    /** Capability lookup over the already-fetched catalog; called on every pick. */
    capabilitiesFor(modelId: string | null): GatewayModelCapabilities | undefined;
}
/**
 * The screen's draft on Done. Each field is present only when it differs from
 * the authored value; `"default"` and `"standard"` mean "remove the setting".
 */
export interface ModelSettingsResult {
    model?: string;
    reasoning?: "default" | ReasoningLevel;
    serviceTier?: "standard" | "priority";
}
/** Renderer-owned composite model screen; only the dev TUI implements this. */
export type ModelSettingsPicker = (request: ModelSettingsRequest) => Promise<ModelSettingsResult | undefined>;
/** Injected for tests; defaults to the real reads, fetches, and source edit. */
export interface ModelFlowDeps {
    /**
     * Reads the model the runtime currently serves and how it routes; both null
     * before the first compile.
     */
    readCurrentModel: (appRoot: string) => Promise<CurrentAgentModel>;
    /** Applies one completed `/model` draft to authored source. */
    applySettings: (input: {
        appRoot: string;
        patch: AgentModelSettingsPatch;
    }) => Promise<ApplyModelSettingsOutcome>;
    /** Catalog fetch behind the shared model picker. */
    selectModel?: SelectModelDeps;
    /** The composite Change-model screen; the dev TUI renderer implements it. */
    pickModelSettings?: ModelSettingsPicker;
    /** Reads how the model is backed right now, for the menu's provider row. */
    detectProviderStatus: typeof detectModelProviderStatus;
    /** The provider sub-flow behind the menu's provider row. */
    runProviderFlow: typeof runProviderFlow;
}
export type { ModelProviderStatus };
/**
 * A provider sub-flow run that actually moved the provider: the credential
 * the link flow verified landed in an env file (when one did), paired with
 * the re-detected {@link ModelProviderStatus} — the same read the menu's
 * provider row shows, so every surface reports one truth. The sub-flow's
 * external-provider branch only shows instructions — nothing changes on
 * disk — so it never surfaces as an outcome.
 */
export interface ModelProviderOutcome {
    /** The credential resolution the runtime will honor; see {@link LinkFlowResult}. */
    resolution?: GatewayCredentialResolution;
    status: ModelProviderStatus;
}
export type ModelFlowResult = {
    kind: "cancelled";
    /** True when Esc dropped drafted setting changes that Done would commit. */
    discardedDraft?: boolean;
} | {
    kind: "done";
    /** The last apply line, when the model was changed this session. */
    modelMessage?: string;
    /** The last provider sub-flow outcome, when one ran to completion. */
    providerOutcome?: ModelProviderOutcome;
};
export declare const MODEL_MENU_MESSAGE = "";
/**
 * Reads the provider status the menu shows. Detection order matters: a linked
 * project subsumes any pulled credential (the link is what the user manages),
 * and `AI_GATEWAY_API_KEY` outranks `VERCEL_OIDC_TOKEN` because it is the one
 * the provider sub-flow's own-key branch writes.
 */
export declare function detectModelProviderStatus(appRoot: string, options?: VercelProjectOperationOptions, env?: Record<string, string | undefined>): Promise<ModelProviderStatus>;
/**
 * THE MODEL FLOW for the dev TUI's `/model`: a root menu whose Change model
 * row opens the composite model screen (catalog pick, reasoning-effort slider,
 * service-tier toggle) and whose provider row runs {@link runProviderFlow}.
 * Authored setting changes stay in memory until Done, then land through one
 * source transform and atomic rename. A completed provider change commits the
 * current draft and returns to the prompt; cancelled flows and
 * external-provider instructions return to the menu.
 */
export declare function runModelFlow(input: {
    appRoot: string;
    prompter: Prompter;
    /** Opens provider setup before the root menu when runtime evidence requires it. */
    initialStep?: "provider";
    signal?: AbortSignal;
    deps?: Partial<ModelFlowDeps>;
}): Promise<ModelFlowResult>;
/**
 * Refusal message when `/model` can't rewrite the model — it is a source-backed
 * SDK model call (`gateway(...)`, `anthropic(...)`), not a string literal — or
 * null when the model is an editable string. Editability is independent of
 * routing: a `gateway(...)` call is gateway-routed yet still uneditable here.
 */
export declare function modelChangeRefusalForUneditableModel(appRoot: string): Promise<string | null>;
