import { AI_GATEWAY_API_KEY_ENV_VAR } from "../ai-gateway-api-key.js";
import { type SelectModelDeps } from "../boxes/select-model.js";
import { type ProjectDetectionOptions } from "../project-resolution.js";
import type { ModelRouting } from "#shared/agent-definition.js";
import type { Prompter } from "../prompter.js";
import { runVercelFlow } from "./vercel.js";
/** The current model id, its routing, and whether `/model` can rewrite it. */
export interface CurrentAgentModel {
    id: string | null;
    routing: ModelRouting | null;
    /**
     * 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;
}
/** 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 the picked slug to authored source. */
    applyModel: (input: {
        appRoot: string;
        slug: string;
    }) => Promise<ApplyModelOutcome>;
    /** Catalog fetch behind the shared model picker. */
    selectModel?: SelectModelDeps;
    /** 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. */
    runVercelFlow: typeof runVercelFlow;
}
/**
 * How the agent's model is backed right now, as far as the local directory
 * shows: a linked Vercel project, a gateway credential in an env file, or
 * nothing detectable. An external provider (own ANTHROPIC_API_KEY etc.)
 * leaves no marker eve owns, so it reads as `unset`.
 */
export type ModelProviderStatus = {
    kind: "unset";
} | {
    kind: "gateway-project";
    projectName: string;
    teamName?: string;
} | {
    kind: "gateway-key";
    envKey: typeof AI_GATEWAY_API_KEY_ENV_VAR | "VERCEL_OIDC_TOKEN";
    envFile: string;
};
/**
 * 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 {
    credential?: "VERCEL_OIDC_TOKEN" | typeof AI_GATEWAY_API_KEY_ENV_VAR;
    status: ModelProviderStatus;
}
export type ModelFlowResult = {
    kind: "cancelled";
} | {
    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?: ProjectDetectionOptions): Promise<ModelProviderStatus>;
/**
 * THE MODEL FLOW for the dev TUI's `/model`: a two-row action menu that
 * loops, uniting the model pick and the provider setup behind one entry
 * point. "Change model" runs the same searchable AI Gateway catalog picker
 * onboarding uses ({@link selectModel}), pre-selected on the model the
 * runtime currently serves, then the static source edit that bakes the
 * choice into `agent.ts` (activation is the dev server's HMR watcher).
 * The provider row runs {@link runVercelFlow} — the provider gate (AI
 * Gateway or your own), then link-or-paste-a-key.
 * Completed model and provider changes return to the prompt with their result.
 * 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>;
/** The outcome of applying a model slug to the agent's authored source. */
export type ApplyModelOutcome = {
    kind: "changed";
    to: string;
} | {
    kind: "unchanged";
    model: string;
}
/** Invalid slug or an uneditable source — `message` says which and why. */
 | {
    kind: "rejected";
    message: string;
};
/** The one-line transcript form of an apply outcome (`/model <slug>`'s reply). */
export declare function formatApplyModelOutcome(outcome: ApplyModelOutcome): string;
/**
 * Applies a `/model <slug>` change to the local agent's authored source.
 *
 * This is the caller layer for the static source-change registry: it
 * validates the slug against the AI Gateway model catalog, then edits
 * `agent.ts` via {@link createStaticSourceChange}. Activation is the dev
 * server's HMR watcher; {@link formatApplyModelOutcome} renders the outcome
 * as the TUI's one-line reply.
 */
export declare function changeAgentModel(input: {
    readonly appRoot: string;
    readonly slug: string;
}): Promise<ApplyModelOutcome>;
/**
 * 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>;
