import type { TUserPrompt } from '../ai-model/index';
import Service from '../service/index';
import { type ActionParam, type ActionReturn, type AgentAssertOpt, type AgentDescribeElementAtPointResult, type AgentOpt, type AgentWaitForOpt, type DeepThinkOption, type DeviceAction, ExecutionDump, GroupedActionDump, type LocateOption, type LocateResultElement, type LocateValidatorResult, type LocatorValidatorOption, type OnTaskStartTip, type ScrollParam, type ServiceAction, type ServiceExtractOption, type ServiceExtractParam, type UIContext } from '../types';
export type TestStatus = 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interrupted';
import type { AbstractInterface } from '../device';
import type { TaskRunner } from '../task-runner';
import { ModelConfigManager } from '@midscene/shared/env';
import { TaskCache } from './task-cache';
import { TaskExecutor } from './tasks';
export type AiActOptions = {
    cacheable?: boolean;
    fileChooserAccept?: string | string[];
    deepThink?: DeepThinkOption;
    deepLocate?: boolean;
};
export declare class Agent<InterfaceType extends AbstractInterface = AbstractInterface> {
    interface: InterfaceType;
    service: Service;
    dump: GroupedActionDump;
    reportFile?: string | null;
    reportFileName?: string;
    taskExecutor: TaskExecutor;
    opts: AgentOpt;
    /**
     * If true, the agent will not perform any actions
     */
    dryMode: boolean;
    onTaskStartTip?: OnTaskStartTip;
    taskCache?: TaskCache;
    private dumpUpdateListeners;
    get onDumpUpdate(): ((dump: string, executionDump?: ExecutionDump) => void) | undefined;
    set onDumpUpdate(callback: ((dump: string, executionDump?: ExecutionDump) => void) | undefined);
    destroyed: boolean;
    modelConfigManager: ModelConfigManager;
    /**
     * Frozen page context for consistent AI operations
     */
    private frozenUIContext?;
    private get aiActContext();
    /**
     * Flag to track if VL model warning has been shown
     */
    private hasWarnedNonVLModel;
    /**
     * Screenshot scale factor derived from actual screenshot dimensions
     */
    private screenshotScale?;
    /**
     * Internal promise to deduplicate screenshot scale computation
     */
    private screenshotScalePromise?;
    private executionDumpIndexByRunner;
    private fullActionSpace;
    private reportGenerator;
    get page(): InterfaceType;
    /**
     * Ensures VL model warning is shown once when needed
     */
    private ensureVLModelWarning;
    /**
     * Lazily compute the ratio between the physical screenshot width and the logical page width
     */
    private getScreenshotScale;
    private resolveReplanningCycleLimit;
    constructor(interfaceInstance: InterfaceType, opts?: AgentOpt);
    getActionSpace(): Promise<DeviceAction[]>;
    getUIContext(action?: ServiceAction): Promise<UIContext>;
    _snapshotContext(): Promise<UIContext>;
    /**
     * @deprecated Use {@link setAIActContext} instead.
     */
    setAIActionContext(prompt: string): Promise<void>;
    setAIActContext(prompt: string): Promise<void>;
    resetDump(): GroupedActionDump;
    appendExecutionDump(execution: ExecutionDump, runner?: TaskRunner): void;
    dumpDataString(opt?: {
        inlineScreenshots?: boolean;
    }): string;
    reportHTMLString(opt?: {
        inlineScreenshots?: boolean;
    }): string;
    writeOutActionDumps(): void;
    private callbackOnTaskStartTip;
    wrapActionInActionSpace<T extends DeviceAction>(name: string): (param: ActionParam<T>) => Promise<ActionReturn<T>>;
    callActionInActionSpace<T = any>(type: string, opt?: T): Promise<any>;
    aiTap(locatePrompt: TUserPrompt, opt?: LocateOption & {
        fileChooserAccept?: string | string[];
    }): Promise<any>;
    aiRightClick(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
    aiDoubleClick(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
    aiHover(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
    aiInput(locatePrompt: TUserPrompt, opt: LocateOption & {
        value: string | number;
    } & {
        autoDismissKeyboard?: boolean;
    } & {
        mode?: 'replace' | 'clear' | 'typeOnly' | 'append';
    }): Promise<any>;
    /**
     * @deprecated Use aiInput(locatePrompt, opt) instead where opt contains the value
     */
    aiInput(value: string | number, locatePrompt: TUserPrompt, opt?: LocateOption & {
        autoDismissKeyboard?: boolean;
    } & {
        mode?: 'replace' | 'clear' | 'typeOnly' | 'append';
    }): Promise<any>;
    aiKeyboardPress(locatePrompt: TUserPrompt, opt: LocateOption & {
        keyName: string;
    }): Promise<any>;
    /**
     * @deprecated Use aiKeyboardPress(locatePrompt, opt) instead where opt contains the keyName
     */
    aiKeyboardPress(keyName: string, locatePrompt?: TUserPrompt, opt?: LocateOption): Promise<any>;
    aiScroll(locatePrompt: TUserPrompt | undefined, opt: LocateOption & ScrollParam): Promise<any>;
    /**
     * @deprecated Use aiScroll(locatePrompt, opt) instead where opt contains the scroll parameters
     */
    aiScroll(scrollParam: ScrollParam, locatePrompt?: TUserPrompt, opt?: LocateOption): Promise<any>;
    aiAct(taskPrompt: string, opt?: AiActOptions): Promise<string | undefined>;
    /**
     * @deprecated Use {@link Agent.aiAct} instead.
     */
    aiAction(taskPrompt: string, opt?: AiActOptions): Promise<string | undefined>;
    aiQuery<ReturnType = any>(demand: ServiceExtractParam, opt?: ServiceExtractOption): Promise<ReturnType>;
    aiBoolean(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<boolean>;
    aiNumber(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<number>;
    aiString(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<string>;
    aiAsk(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<string>;
    describeElementAtPoint(center: [number, number], opt?: {
        verifyPrompt?: boolean;
        retryLimit?: number;
        deepThink?: boolean;
    } & LocatorValidatorOption): Promise<AgentDescribeElementAtPointResult>;
    verifyLocator(prompt: string, locateOpt: LocateOption | undefined, expectCenter: [number, number], verifyLocateOption?: LocatorValidatorOption): Promise<LocateValidatorResult>;
    aiLocate(prompt: TUserPrompt, opt?: LocateOption): Promise<Pick<LocateResultElement, "center" | "rect"> & {
        dpr?: number;
    }>;
    aiAssert(assertion: TUserPrompt, msg?: string, opt?: AgentAssertOpt & ServiceExtractOption): Promise<{
        pass: boolean;
        thought: string | undefined;
        message: string | undefined;
    } | undefined>;
    aiWaitFor(assertion: TUserPrompt, opt?: AgentWaitForOpt): Promise<void>;
    ai(...args: Parameters<typeof this.aiAct>): Promise<string | undefined>;
    runYaml(yamlScriptContent: string): Promise<{
        result: Record<string, any>;
    }>;
    evaluateJavaScript(script: string): Promise<any>;
    /**
     * Add a dump update listener
     * @param listener Listener function
     * @returns A remove function that can be called to remove this listener
     */
    addDumpUpdateListener(listener: (dump: string, executionDump?: ExecutionDump) => void): () => void;
    /**
     * Remove a dump update listener
     * @param listener The listener function to remove
     */
    removeDumpUpdateListener(listener: (dump: string, executionDump?: ExecutionDump) => void): void;
    /**
     * Clear all dump update listeners
     */
    clearDumpUpdateListeners(): void;
    destroy(): Promise<void>;
    recordToReport(title?: string, opt?: {
        content: string;
    }): Promise<void>;
    /**
     * @deprecated Use {@link Agent.recordToReport} instead.
     */
    logScreenshot(title?: string, opt?: {
        content: string;
    }): Promise<void>;
    _unstableLogContent(): {
        groupName: string;
        groupDescription: string | undefined;
        executions: ExecutionDump[];
    };
    /**
     * Freezes the current page context to be reused in subsequent AI operations
     * This avoids recalculating page context for each operation
     */
    freezePageContext(): Promise<void>;
    /**
     * Unfreezes the page context, allowing AI operations to calculate context dynamically
     */
    unfreezePageContext(): Promise<void>;
    /**
     * Process cache configuration and return normalized cache settings
     */
    private processCacheConfig;
    private normalizeFilePaths;
    private normalizeFileInput;
    /**
     * Manually flush cache to file
     * @param options - Optional configuration
     * @param options.cleanUnused - If true, removes unused cache records before flushing
     */
    flushCache(options?: {
        cleanUnused?: boolean;
    }): Promise<void>;
}
export declare const createAgent: (interfaceInstance: AbstractInterface, opts?: AgentOpt) => Agent<AbstractInterface>;
