import { Ast } from 'thingtalk'; import type Engine from '../engine'; import type { DeviceInfo } from '../engine'; import ValueCategory from './value-category'; import StatementExecutor from './statement_executor'; import { EntityRecord } from './entity-linking/entity-finder'; import { Contact } from './entity-linking/contact_search'; import { PlatformData } from './protocol'; import { ConversationState } from './conversation'; import AbstractDialogueAgent, { DisambiguationHints } from './abstract_dialogue_agent'; interface AbstractConversation { id: string; getState(): ConversationState; } /** * The interface that the {@link ExecutionDialogueAgent} uses to communicate * with outside. * * In some code paths, {@link ExecutionDialogueAgent} needs to send messages * to the user or ask questions, in the middle of preparing for execution * and outside of the normal dialogue loop. * * It does so by calling this interface, which for the normal assistant is * implemented by {@link DialogueLoop}. * * TODO: This interface has some ugly inversion of control where the outside * code that drives the dialogue gets called synchronously by this code. * We should refactor all of this. */ export interface AbstractDialogueLoop { platformData: PlatformData; isAnonymous: boolean; _: (x: string) => string; conversation: AbstractConversation; reply(msg: string): Promise; replyLink(title: string, link: string, state?: ConversationState): Promise; interpolate(msg: string, args: Record): string; replyInterp(msg: string, args: Record): Promise; ask(expected: ValueCategory.PhoneNumber | ValueCategory.EmailAddress | ValueCategory.Location | ValueCategory.Time, question: string, args?: Record): Promise; askChoices(question: string, choices: string[]): Promise; } /** * The execution time dialogue agent. * * Provides access to the real user's information, stored in the engine. */ export default class ExecutionDialogueAgent extends AbstractDialogueAgent { private _engine; private _platform; private _dlg; private _executor; constructor(engine: Engine, dlg: AbstractDialogueLoop, debug: boolean); get _(): (x: string) => string; get executor(): StatementExecutor; getAllDevicesOfKind(kind: string): Promise; private _requireRegistration; protected checkForPermission(stmt: Ast.ExpressionStatement): Promise; disambiguate(type: 'device' | 'device-missing' | 'contact', name: string | null, choices: string[], hint?: string): Promise; protected tryConfigureDevice(kind: string): Promise; lookupContact(category: ValueCategory, name: string): Promise; askMissingContact(category: ValueCategory.EmailAddress | ValueCategory.PhoneNumber | ValueCategory.Contact, name: string): Promise; protected addDisplayToContact(contact: Ast.EntityValue): Promise; private _constructEntityQuery; protected resolveEntity(entityType: string, entityDisplay: string, hints: DisambiguationHints): Promise; private _tryGetCurrentLocation; protected lookupLocation(searchKey: string, previousLocations: Ast.AbsoluteLocation[]): Promise; private _tryGetStoredVariable; private _resolvePhoneNumber; private _resolveEmailAddress; protected resolveUserContext(variable: string): Promise; getPreferredUnit(type: string): string | undefined; protected configureNotifications(): Promise<{ backend: string; config: Record; } | undefined>; } export {};