import { Ast, SchemaRetriever } from 'thingtalk';
import { Contact } from './entity-linking/contact_search';
import { EntityRecord } from './entity-linking/entity-finder';
import ValueCategory from './value-category';
interface AbstractDialogueAgentOptions {
    locale: string;
    timezone: string;
    debug: boolean;
}
declare type RawExecutionResult = Array<[string, Record<string, unknown>]>;
interface AbstractStatementExecutor<PrivateStateType> {
    executeStatement(stmt: Ast.ExpressionStatement, privateState: PrivateStateType | undefined): Promise<[Ast.DialogueHistoryResultList, RawExecutionResult, PrivateStateType]>;
}
export interface DisambiguationHints {
    devices: Map<string, [string | null, Ast.InputParam | undefined]>;
    idEntities: Map<string, EntityRecord[]>;
    previousLocations: Ast.AbsoluteLocation[];
}
export interface DeviceInfo {
    kind: string;
    uniqueId: string;
    name: string;
}
interface ExecutionResult<PrivateStateType> {
    newDialogueState: Ast.DialogueState;
    newExecutorState: PrivateStateType | undefined;
    newResults: Array<[string, Record<string, unknown>]>;
    anyChange: boolean;
}
/**
 * Base class of a dialogue agent.
 *
 * The class contains the code that is common between execution (aka inference time)
 * and simulation (aka training time).
 * Because it is used for simulation, the class is completely stateless
 *
 * The public API of this class is used by the entity linking & device choice code
 * (during the "prepare for execution" step) to abstract the access to the "user".
 *
 * There are two subclasses, one used during simulation, and one used for execution.
 */
export default abstract class AbstractDialogueAgent<PrivateStateType> {
    protected _schemas: SchemaRetriever;
    protected _debug: boolean;
    private _langPack;
    locale: string;
    timezone: string;
    constructor(schemas: SchemaRetriever, options: AbstractDialogueAgentOptions);
    /**
     * Execute the query or action implied by the current dialogue state.
     *
     * This method should return a new dialogue state with filled information
     * about the result. It should not modify the state in-place.
     *
     * This is the only public method in this class.
     *
     * @param {Ast.DialogueState} state - the current state, representing the query or action to execute
     * @param {any} privateState - additional state carried by the dialogue agent (per dialogue)
     * @return {Ast.DialogueState} - the new state, with information about the returned query or action
     */
    execute(state: Ast.DialogueState, privateState: PrivateStateType | undefined): Promise<ExecutionResult<PrivateStateType>>;
    private _collectDisambiguationHintsForState;
    /**
     * Prepare a statement for being executed.
     *
     * This will resolve all ThingTalk values that are relative to the user, such as
     * `$context.location.current_location`, and will assign device IDs to all Thingpedia
     * function calls.
     *
     * The statement is modified in place.
     *
     * @param {thingtalk.Ast.Statement} stmt - the statement to prepare
     * @param {any} hints - hints to use to resolve any ambiguity
     */
    protected _prepareForExecution(stmt: Ast.ExpressionStatement, hints: DisambiguationHints): Promise<void>;
    /**
     * Show a debug message.
     *
     * @param {any} msg - what to show
     * @protected
     */
    debug(...args: unknown[]): void;
    private _chooseDevice;
    private _addDisplayToDevice;
    private _maybeAddDisplayToValue;
    private _concretizeValue;
    /**
     * Retrieve the executor to use for each statement.
     */
    protected get executor(): AbstractStatementExecutor<PrivateStateType>;
    /**
     * List all configured devices that implement the given ThingTalk kind.
     *
     * @param {string} kind - the kind to check
     * @returns {Array<DeviceInfo>} - the list of configured devices
     * @abstract
     */
    protected getAllDevicesOfKind(kind: string): DeviceInfo[];
    /**
     * Attempt to automatically configure a device of the given kind.
     *
     * @param {string} kind - the kind to configure
     * @returns {DeviceInfo} - the newly configured device
     */
    protected tryConfigureDevice(kind: string): Promise<DeviceInfo | null>;
    /**
     * Disambiguate an entity by explicitly asking the user.
     *
     * @param {string} type - the type of disambiguation to perform, either `device`, `contact`,
     *   or `entity`
     * @param {string} name - the name to disambiguate
     * @param {string[]} choices - the choices among which to disambiguate
     * @param {string} hint - a type-specific hint to show to the user
     * @returns {number} - the index of the provided choice
     */
    disambiguate(type: 'device' | 'contact', name: string | null, choices: string[], hint?: string): Promise<number>;
    /**
     * Lookup a contact in the address book.
     *
     * @param {ValueCategory} category - the category of information to look up
     * @param {string} name - the name to look up
     * @returns {string[]} - the list of resolved information of all contacts matching the name
     */
    lookupContact(category: ValueCategory, name: string): Promise<Contact[]>;
    /**
     * Add the display field to a phone or email entity, by looking up the contact in the address book.
     *
     * @param {thingtalk.Ast.Value} contact - the entity to look up
     */
    protected addDisplayToContact(contact: Ast.EntityValue): Promise<void>;
    /**
     * Ask the user about a contact that is not in the address book.
     *
     * @param {ValueCategory} category - the category of information to look up
     * @param {string} name - the name to look up
     * @returns {thingtalk.Ast.Value.Entity} - the entity corresponding to the picked up information
     */
    askMissingContact(category: ValueCategory.EmailAddress | ValueCategory.PhoneNumber | ValueCategory.Contact, name: string): Promise<Ast.EntityValue>;
    /**
     * Resolve a location name to a specific point on Earth.
     *
     * @param {string} searchKey - the location name to look up
     * @param {thingtalk.Ast.Location[]} previousLocations - recently mentioned locations
     * @returns {thingtalk.Ast.Value} - the best match for the given name
     */
    protected lookupLocation(searchKey: string, previousLocations: Ast.AbsoluteLocation[]): Promise<Ast.LocationValue>;
    /**
     * Lookup all possible candidates for a given entity in the Thingpedia database or
     * by calling the underlying API.
     *
     * @param {string} entityType - the type of entity to look up
     * @param {string} entityDisplay - the display name of the entity look up
     * @param {any} hints - hints to use to resolve any ambiguity
     * @returns {ThingpediaEntity[]} - possible entities that match the given name, in Thingpedia API format
     * @abstract
     * @protected
     */
    protected lookupEntityCandidates(entityType: string, entityDisplay: string, hints: DisambiguationHints): Promise<EntityRecord[]>;
    /**
     * Resolve a `$context` variable to a concrete value.
     *
     * @param {string} variable - the variable name to lookup, including the `$context.` prefix
     * @returns {thingtalk.Ast.Value} - the resolved value
     * @abstract
     * @protected
     */
    protected resolveUserContext(variable: string): Promise<Ast.Value>;
    /**
     * Compute the user's preferred unit to use when the program specifies an ambiguous unit
     * such as "degrees".
     *
     * @param {string} type - the type of unit to retrieve (e.g. "temperature"), or undefined
     *   if the user has no preference
     * @returns {string} - the preferred unit
     * @abstract
     * @protected
     */
    getPreferredUnit(type: string): string | undefined;
}
export {};
