import { Agent } from '../agent/index.js';
import type { MastraBrowser } from '../browser/browser.js';
import { Mastra } from '../mastra/index.js';
import { RequestContext } from '../request-context/index.js';
import type { ObservationalMemoryRecord } from '../storage/types.js';
import { Workspace } from '../workspace/workspace.js';
import { Session } from './session.js';
import type { AvailableModel, IntervalHandler, AgentControllerConfig, AgentControllerMode, ModelAuthStatus, ToolCategory } from './types.js';
/**
 * Returns Anthropic `providerOptions` that enable a server-side fallback to
 * {@link FABLE_FALLBACK_MODEL} when the active model is `claude-fable-5`, and
 * `undefined` otherwise.
 *
 * fable-5 can have a turn blocked server-side by its safety classifiers. With
 * a fallback configured, Anthropic transparently retries the blocked turn on
 * the fallback model and returns that model's answer instead of refusing. If
 * the whole chain refuses, the run still ends on a `content-filter` finish
 * reason, which is handled as a terminal error.
 *
 * The match is suffix-based so it covers `anthropic/claude-fable-5`, a bare
 * `claude-fable-5`, and any pack/provider-prefixed form.
 */
export declare function buildFableFallbackProviderOptions(modelId: string): {
    anthropic: {
        fallbacks: {
            model: string;
        }[];
    };
} | undefined;
/**
 * Build a user-facing notice when a turn was served by an Anthropic
 * server-side fallback model instead of the primary model.
 *
 * When the primary model's safety classifiers decline a turn and a fallback
 * chain is configured (see {@link buildFableFallbackProviderOptions}), the API
 * transparently retries on the fallback model and reports this via
 * `fallback_message` entries in `providerMetadata.anthropic.iterations`.
 * Without a notice the user has no way to tell that the response did not come
 * from the model they selected.
 */
/**
 * The AgentController orchestrates multiple agent modes, shared state, memory, and storage.
 * It's the core abstraction that a TUI (or other UI) controls.
 *
 * @example
 * ```ts
 * const controller = new AgentController({
 *   id: "my-coding-agent",
 *   storage: new LibSQLStore({ url: "file:./data.db" }),
 *   stateSchema: z.object({
 *     currentModelId: z.string().optional(),
 *   }),
 *   modes: [
 *     { id: "plan", name: "Plan", default: true, agent: planAgent },
 *     { id: "build", name: "Build", agent: buildAgent },
 *   ],
 * })
 *
 * controller.subscribe((event) => {
 *   if (event.type === "message_update") renderMessage(event.message)
 * })
 *
 * await controller.init()
 * await controller.sendMessage({ content: "Hello!" })
 * ```
 */
export declare class AgentController<TState = {}> {
    #private;
    readonly id: string;
    private config;
    private workspaceInitialized;
    private initPromise;
    private browser;
    private workspace;
    private intervalTimers;
    private availableModelsCache;
    private availableModelsCacheTime;
    constructor(config: AgentControllerConfig<TState>);
    /**
     * Create a new, fully-wired {@link Session} and bring it online: it starts in
     * the default mode with the seeded model, is connected to the AgentController's shared
     * machinery (agent, storage/lock, config catalog), and has a current thread
     * (the most recent thread for `resourceId`, or a freshly created one).
     *
     * The AgentController owns no session of its own — every consumer creates its own
     * session and drives all work through it (`session.sendMessage`,
     * `session.mode.switch`, `session.thread.*`, `session.subscribe`, ...). In a
     * server / multiplayer setting, each request / thread / user gets its own
     * session, isolated from every other: independent event bus, mode, model,
     * state, and current thread.
     *
     * Call {@link init} once before creating sessions so shared storage and
     * workspace are ready.
     *
     * @param id - Stable session identifier (mirrors `SessionRecord.id`). Defaults to the controller `id`.
     * @param ownerId - Stable session owner (mirrors `SessionRecord.ownerId`). Defaults to the controller `id`.
     * @param resourceId - Memory resource to bind this session to. Defaults to the controller `resourceId` or `id`.
     */
    createSession({ resourceId, ownerId, id, tags, workspace, browser, requestContext, }?: {
        resourceId?: string;
        id?: string;
        ownerId?: string;
        /**
         * Arbitrary string tags that scope this session. Each tag is seeded into the
         * session's state and used to filter initial thread selection: a thread is a
         * resume candidate only when its metadata matches every provided tag. This
         * lets worktrees sharing a resourceId each resume their own thread (via a
         * `projectPath` tag) and leaves room for future scoping dimensions without
         * changing the API. Falls back to `initialState` when omitted.
         */
        tags?: Record<string, string>;
        workspace?: Workspace;
        browser?: MastraBrowser;
        requestContext?: RequestContext;
    }): Promise<Session<TState>>;
    /**
     * Resolve a live session by resourceId, if one was created for it via
     * {@link createSession}. Returns `undefined` when no session owns the
     * resource. Used by notification delivery to run woken signals as the session
     * that owns the target thread, rather than an arbitrary session.
     */
    getSessionByResource(resourceId: string): Promise<Session<TState> | undefined>;
    /**
     * Access the Mastra instance backing this AgentController.
     *
     * Returns the parent Mastra when this AgentController is registered on one (see
     * {@link __registerMastra}); otherwise the internal Mastra created during
     * `init()` when storage is configured.
     *
     * Useful for scorer registration, observability access, and eval tooling.
     */
    getMastra(): Mastra | undefined;
    /**
     * Whether a workspace is configured on this AgentController (static instance, dynamic
     * factory, or config object). Sessions without an explicit workspace override
     * fall back to this.
     */
    hasWorkspace(): boolean;
    /**
     * Whether the AgentController-level static workspace has been initialized. Dynamic
     * factory workspaces are resolved and initialized per-session during
     * `createSession`, so this returns `false` for factory configs until a
     * session is created.
     */
    isWorkspaceReady(): boolean;
    /**
     * The AgentController-level workspace, if it is a static instance. Dynamic factory
     * workspaces are not resolved here — use {@link resolveWorkspace} to resolve
     * a factory against a session's request context.
     */
    getWorkspace(): Workspace | undefined;
    /**
     * Eagerly resolve the workspace. For dynamic workspaces (factory function),
     * this triggers resolution against the given session's request context and
     * caches the result so {@link getWorkspace} returns it. Useful for code paths
     * outside the request flow (e.g. slash commands).
     */
    resolveWorkspace({ session, requestContext, }: {
        session: Session<TState>;
        requestContext?: RequestContext;
    }): Promise<Workspace | undefined>;
    /**
     * Register this AgentController on a parent Mastra. Called by Mastra during
     * construction when a harness is passed in its config. Once registered, the
     * AgentController uses the parent Mastra (its storage, agents, gateways, and
     * observability) instead of building its own internal one during `init()`.
     *
     * @internal
     */
    __registerMastra(mastra: Mastra): void;
    private resolveConfiguredMemory;
    /**
     * Sets or updates the harness-level browser and propagates it to mode agents.
     */
    setBrowser(browser: MastraBrowser | undefined): void;
    /**
     * Initialize the harness — loads storage and workspace.
     * Must be called before using the harness. Idempotent: repeated calls
     * return the same in-flight/completed initialization instead of rebuilding
     * the internal Mastra instance (which would orphan registered agents).
     */
    init(): Promise<void>;
    private runInit;
    private getMemoryStorage;
    /**
     * The shared-host storage gateway the Session's thread domain reads/writes
     * through. The Session owns the thread-domain logic; this adapter just maps
     * raw storage rows to AgentController types — it does not call back into Session.
     */
    private createThreadDataStore;
    /** Persist a thread row to memory storage (gateway primitive for the Session thread domain). */
    private persistThreadRow;
    /** Delete a thread row from memory storage (gateway primitive for the Session thread domain). */
    private deleteThreadRow;
    /** Clone a thread (and messages) via the host's memory (gateway primitive for the Session thread domain). */
    private cloneThreadRow;
    private readThreadMetadataValue;
    private writeThreadMetadataValue;
    private removeThreadMetadataValue;
    private queryThreadById;
    private queryThreads;
    private queryThreadMessages;
    private queryFirstUserMessages;
    listModes(): AgentControllerMode[];
    private propagateRuntimeServicesToAgent;
    private getAgentForMode;
    /**
     * Resolve the combined instructions for the current mode: harness-level
     * instructions + mode-specific instructions. Passed at call time via
     * `buildAgentMessageStreamOptions` so the agent's own instructions are
     * never mutated.
     */
    private resolveCurrentModeInstructions;
    /**
     * Convert AgentInstructions (string | string[] | system message objects) to
     * a plain string for combining with mode instructions.
     */
    private instructionsToString;
    /**
     * Get the agent for the current mode.
     */
    /**
     * Resolve the Agent backing the current mode, with runtime services (storage,
     * pubsub, telemetry) propagated. Public so consumers like MastraCode's
     * GoalManager can drive the agent's native objective methods
     * (`setObjective`/`getObjective`/`clearObjective`/`updateObjectiveOptions`),
     * which read/write the durable `threadState` `'goal'` slot.
     */
    getCurrentAgent(session: Session<TState>): Agent;
    /**
     * Check if the current model's provider has authentication configured.
     * Delegates to the {@link GatewayManager} auth chain (the same resolution
     * the model router uses at run time). Returns `hasAuth: true` only when no
     * model is selected; gateway-chain failures return `hasAuth: false` so the
     * auth-status endpoint stays stable instead of erroring.
     */
    getCurrentModelAuthStatus(session: Session<TState>): Promise<ModelAuthStatus>;
    /**
     * Get available models from the app-provided catalog hook with use counts applied.
     */
    listAvailableModels(): Promise<AvailableModel[]>;
    invalidateAvailableModelsCache(): void;
    /**
     * Point the session at a different memory resourceId. The resourceId itself
     * lives on the session (`session.identity`); the AgentController orchestrates the
     * surrounding teardown — dropping the current thread subscription and clearing
     * the active thread — since those are AgentController-owned.
     */
    setResourceId(session: Session<TState>, { resourceId }: {
        resourceId: string;
    }): Promise<void>;
    getKnownResourceIds(session: Session<TState>): Promise<string[]>;
    /**
     * Load observational memory progress for the current thread.
     * Reads the OM record and recent messages to reconstruct status,
     * then emits an `om_status` event for the UI.
     */
    loadOMProgress(session: Session<TState>): Promise<void>;
    getObservationalMemoryRecord(session: Session<TState>): Promise<ObservationalMemoryRecord | null>;
    getToolCategory({ toolName }: {
        toolName: string;
    }): ToolCategory | null;
    /**
     * Resolve the `activeTools` allowlist for the current mode's run.
     *
     * Returns `undefined` when the mode has no `availableTools` configured
     * (no restriction — all tools visible). When the mode declares
     * `availableTools`, returns that list filtered to remove tools whose
     * permission category is denied.
     *
     * Per-tool `deny` is already handled by `buildToolsets` (denied tools are
     * deleted from the toolsets), so those tools won't exist at execution time
     * regardless of whether they appear in the allowlist.
     *
     * The returned list uses the same exposed tool names the execution pipeline
     * checks against (e.g. `view`, `write_file`, `ask_user`), which matches the
     * names workspace tools are renamed to via `TOOL_NAME_OVERRIDES`.
     */
    private resolveModeActiveTools;
    private buildAgentMessageStreamOptions;
    private formatToolProgressOutput;
    /**
     * Options that every harness-driven agent run must carry — the initial stream
     * AND every `resumeStream`. Centralized so the two paths can't drift: a
     * missing `maxSteps` on resume silently caps the resumed run at the agent's
     * small default and ends it mid-task (see {@link HARNESS_MAX_STEPS}).
     */
    private buildSharedRunOptions;
    /**
     * Persist a system-reminder message for a thread (host-owned storage). Throws
     * when no storage is configured — the Session guards the no-thread case before
     * calling. Returns the saved message converted to {@link AgentControllerMessage}.
     */
    private saveSystemReminder;
    /**
     * Resolve the mode the session transitions to when a plan is approved: the
     * current mode's `transitionsTo`, else the configured default mode. The mode
     * catalog is AgentController config, so this is host-owned. Returns `undefined` when
     * no default mode is configured.
     */
    private resolveTransitionModeId;
    private convertToControllerMessage;
    private getSubagentDisplayName;
    /**
     * Build the toolsets object that includes built-in harness tools (ask_user, submit_plan,
     * and optionally subagent) plus any user-configured tools.
     * Used by sendMessage, handleToolApprove, and handleToolDecline.
     */
    private buildToolsets;
    /**
     * Build request context for agent execution.
     * Tools can access controller state via requestContext.get('controller').
     */
    private buildRequestContext;
    /**
     * Resolve memory from config — handles both static instances and dynamic factory functions.
     */
    private resolveMemory;
    private persistTokenUsage;
    private startIntervals;
    registerInterval(handler: IntervalHandler): void;
    removeInterval({ id }: {
        id: string;
    }): Promise<void>;
    stopIntervals(): Promise<void>;
    destroy(): Promise<void>;
    private generateId;
}
//# sourceMappingURL=agent-controller.d.ts.map