/** * @module teams-ai */ /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ import { Activity, BotAdapter, ChannelInfo, ConversationReference, FileConsentCardResponse, O365ConnectorCardActionQuery, ResourceResponse, Storage, TeamDetails, TeamsPagedMembersResult, TurnContext } from 'botbuilder'; import { ReadReceiptInfo } from 'botframework-connector'; import { AdaptiveCards, AdaptiveCardsOptions } from './AdaptiveCards'; import { AI, AIOptions } from './AI'; import { Meetings } from './Meetings'; import { Messages } from './Messages'; import { MessageExtensions } from './MessageExtensions'; import { TaskModules, TaskModulesOptions } from './TaskModules'; import { AuthenticationManager, AuthenticationOptions } from './authentication/Authentication'; import { TurnState } from './TurnState'; import { InputFileDownloader } from './InputFileDownloader'; import { TeamsAdapter } from './TeamsAdapter'; /** * Query arguments for a search-based message extension. * @template TParams Type of the query parameters. */ export interface Query> { /** * Number of items to return in the result set. */ count: number; /** * Number of items to skip in the result set. */ skip: number; /** * Query parameters. */ parameters: TParams; } /** * Options for the Application class. * @template TState Type of the turn state. */ export interface ApplicationOptions { /** * Optional. Options used to initialize your `BotAdapter` */ adapter?: TeamsAdapter; /** * Optional. OAuth prompt settings to use for authentication. */ authentication?: AuthenticationOptions; /** * Optional. Application ID of the bot. * @remarks * If using the `longRunningMessages` option or calling the continueConversationAsync() method, * this property is required. */ botAppId?: string; /** * Optional. Storage provider to use for the application. */ storage?: Storage; /** * Optional. AI options to use. When provided, a new instance of the AI system will be created. */ ai?: AIOptions; /** * Optional. Options used to customize the processing of Adaptive Card requests. */ adaptiveCards?: AdaptiveCardsOptions; /** * Optional. Options used to customize the processing of task module requests. */ taskModules?: TaskModulesOptions; /** * Optional. If true, the bot will automatically remove mentions of the bot's name from incoming * messages. Defaults to true. */ removeRecipientMention: boolean; /** * Optional. If true, the bot will automatically start a typing timer when messages are received. * This allows the bot to automatically indicate that it's received the message and is processing * the request. Defaults to true. */ startTypingTimer: boolean; /** * Optional. If true, the bot supports long running messages that can take longer then the 10 - 15 * second timeout imposed by most channels. Defaults to false. * @remarks * This works by immediately converting the incoming request to a proactive conversation. Care should * be used for bots that operate in a shared hosting environment. The incoming request is immediately * completed and many shared hosting environments will mark the bot's process as idle and shut it down. */ longRunningMessages: boolean; /** * Optional. Factory used to create a custom turn state instance. */ turnStateFactory: () => TState; /** * Optional. Array of input file download plugins to use. */ fileDownloaders?: InputFileDownloader[]; } /** * Data returned when the thumbsup or thumbsdown button is clicked and response sent when enable_feedback_loop is set to true in the AI Module. */ export interface FeedbackLoopData { actionName: 'feedback'; actionValue: { /** * 'like' or 'dislike' */ reaction: 'like' | 'dislike'; /** * The response the user provides when prompted with "What did you like/dislike?" after pressing one of the feedback buttons. */ feedback: string | Record; }; /** * The activity ID that the feedback was provided on. */ replyToId: string; } /** * Conversation update events. */ export type ConversationUpdateEvents = 'channelCreated' | 'channelRenamed' | 'channelDeleted' | 'channelRestored' | 'membersAdded' | 'membersRemoved' | 'teamRenamed' | 'teamDeleted' | 'teamHardDeleted' | 'teamArchived' | 'teamUnarchived' | 'teamRestored' | 'topicName' | 'historyDisclosed'; /** * Message related events. */ export type TeamsMessageEvents = 'undeleteMessage' | 'softDeleteMessage' | 'editMessage'; /** * Function for handling an incoming request. * @template TState Type of the turn state. * @param context Context for the current turn of conversation with the user. * @param state Current turn state. * @returns A promise that resolves when the handler completes its processing. */ export type RouteHandler = (context: TurnContext, state: TState) => Promise; /** * A selector function for matching incoming activities. */ export type Selector = (context: TurnContext) => Promise; /** * Function for selecting whether a route handler should be triggered. * @param context Context for the current turn of conversation with the user. * @returns A promise that resolves with a boolean indicating whether the route handler should be triggered. */ export type RouteSelector = Selector; /** * Message reaction event types. */ export type MessageReactionEvents = 'reactionsAdded' | 'reactionsRemoved'; /** * Turn event types. * @remarks * The `beforeTurn` event is triggered before the turn is processed. This allows for the turn state to be * modified before the turn is processed. Returning false from the event handler will prevent the turn from * being processed. * * The `afterTurn` event is triggered after the turn is processed. This allows for the turn state to be * modified or inspected after the turn is processed. Returning false from the event handler will prevent * the turn state from being saved. */ export type TurnEvents = 'beforeTurn' | 'afterTurn'; /** * Application class for routing and processing incoming requests. * @remarks * The Application object replaces the traditional ActivityHandler that a bot would use. It supports * a simpler fluent style of authoring bots versus the inheritance based approach used by the * ActivityHandler class. * * Additionally, it has built-in support for calling into the SDK's AI system and can be used to create * bots that leverage Large Language Models (LLM) and other AI capabilities. * @template TState Optional. Type of the turn state. This allows for strongly typed access to the turn state. */ export declare class Application { private readonly _options; private readonly _routes; private readonly _invokeRoutes; private readonly _adaptiveCards; private readonly _meetings; private readonly _messages; private readonly _messageExtensions; private readonly _taskModules; private readonly _ai?; private readonly _beforeTurn; private readonly _afterTurn; private readonly _authentication?; private readonly _adapter?; private _typingTimer; private readonly _startSignIn?; /** * Creates a new Application instance. * @param {ApplicationOptions} options Optional. Options used to configure the application. */ constructor(options?: Partial>); /** * Fluent interface for accessing Adaptive Card specific features. * @returns {AdaptiveCards} The AdaptiveCards instance. */ get adaptiveCards(): AdaptiveCards; /** * The bot's adapter. * @returns {BotAdapter} The bot's adapter that is configured for the application. */ get adapter(): BotAdapter; /** * Fluent interface for accessing AI specific features. * @remarks * This property is only available if the Application was configured with `ai` options. An * exception will be thrown if you attempt to access it otherwise. * @returns {AI} The AI instance. */ get ai(): AI; /** * @template TState * Fluent interface for accessing Authentication specific features. * @description * This property is only available if the Application was configured with `authentication` options. An * exception will be thrown if you attempt to access it otherwise. * @returns {AuthenticationManager} The Authentication instance. */ get authentication(): AuthenticationManager; /** * Fluent interface for accessing Messages specific features. * @returns {Messages} The Messages instance. */ get messages(): Messages; /** * Fluent interface for accessing Message Extensions' specific features. * @returns {MessageExtensions} The MessageExtensions instance. */ get messageExtensions(): MessageExtensions; /** * Fluent interface for accessing Meetings specific features. * @returns {Meetings} The Meetings instance. */ get meetings(): Meetings; /** * The application's configured options. * @returns {ApplicationOptions} The application's configured options. */ get options(): ApplicationOptions; /** * Fluent interface for accessing Task Module specific features. * @returns {TaskModules} The TaskModules instance. */ get taskModules(): TaskModules; /** * Sets the bot's error handler * @param {Function} handler Function to call when an error is encountered. * @returns {this} The application instance for chaining purposes. */ error(handler: (context: TurnContext, error: Error) => Promise): this; /** * Adds a new route to the application. * @remarks * Developers won't typically need to call this method directly as it's used internally by all * of the fluent interfaces to register routes for their specific activity types. * * Routes will be matched in the order they're added to the application. The first selector to * return `true` when an activity is received will have its handler called. * * Invoke-based activities receive special treatment and are matched separately as they typically * have shorter execution timeouts. * @param {RouteSelector} selector Function thats used to select a route. The function should return true to trigger the route. * @param {RouteHandler} handler Function to call when the route is triggered. * @param {boolean} isInvokeRoute Optional. Boolean indicating if the RouteSelector is for an activity that uses "invoke" which require special handling. Defaults to `false`. * @returns {this} The application instance for chaining purposes. */ addRoute(selector: RouteSelector, handler: RouteHandler, isInvokeRoute?: boolean): this; /** * Handles incoming activities of a given type. * @param {string | RegExp | RouteSelector | string[] | RegExp[] | RouteSelector[]} type Name of the activity type to match or a regular expression to match against the incoming activity type. An array of type names or expression can also be passed in. * @param {(context: TurnContext, state: TState) => Promise} handler Function to call when the route is triggered. * @param {TurnContext} handler.context The context object for the turn. * @param {TState} handler.state The state object for the turn. * @returns {this} The application instance for chaining purposes. */ activity(type: string | RegExp | RouteSelector | (string | RegExp | RouteSelector)[], handler: (context: TurnContext, state: TState) => Promise): this; /** * Handles conversation update events. * @param {ConversationUpdateEvents} event Name of the conversation update event to handle. * @param {(context: TurnContext, state: TState) => Promise} handler Function to call when the route is triggered. * @param {TurnContext} handler.context The context object for the turn. * @param {TState} handler.state The state object for the turn. * @returns {this} The application instance for chaining purposes. */ conversationUpdate(event: ConversationUpdateEvents, handler: (context: TurnContext, state: TState) => Promise): this; messageEventUpdate(event: TeamsMessageEvents, handler: (context: TurnContext, state: TState) => Promise): this; /** * @private * Starts a new "proactive" session with a conversation the bot is already a member of. * @remarks * Use of the method requires configuration of the Application with the `adapter.appId` * options. An exception will be thrown if either is missing. * @param context Context of the conversation to proactively message. This can be derived from either a TurnContext, ConversationReference, or Activity. * @param logic The bot's logic that should be run using the new proactive turn context. */ private continueConversationAsync; /** * Handles incoming messages with a given keyword. * @remarks * This method provides a simple way to have a bot respond anytime a user sends your bot a * message with a specific word or phrase. * * For example, you can easily clear the current conversation anytime a user sends "/reset": * * ```JavaScript * bot.message('/reset', async (context, state) => { * await state.conversation.delete(); * await context.sendActivity(`I have reset your state.`); * }); * ``` * @param {string | RegExp | RouteSelector | string[] | RegExp[] | RouteSelector[]} keyword Substring of text or a regular expression to match against the text of an incoming message. An array of keywords or expression can also be passed in. * @param {(context: TurnContext, state: TState) => Promise} handler Function to call when the route is triggered. * @returns {this} The application instance for chaining purposes. */ message(keyword: string | RegExp | RouteSelector | (string | RegExp | RouteSelector)[], handler: (context: TurnContext, state: TState) => Promise): this; /** * Handles message reaction events. * @param {MessageReactionEvents | MessageReactionEvents[]} event Name of the message reaction event(s) to handle. * @param {(context: TurnContext, state: TState) => Promise} handler Function to call when the route is triggered. * @returns {this} The application instance for chaining purposes. */ messageReactions(event: MessageReactionEvents, handler: (context: TurnContext, state: TState) => Promise): this; /** * Registers a handler to process when a file consent card is accepted by the user. * @param {(context: TurnContext, state: TState, fileConsentResponse: FileConsentCardResponse) => Promise} handler Function to call when the route is triggered. * @returns {this} The application instance for chaining purposes. */ fileConsentAccept(handler: (context: TurnContext, state: TState, fileConsentResponse: FileConsentCardResponse) => Promise): this; /** * Registers a handler to process when a file consent card is declined by the user. * @param {(context: TurnContext, state: TState, fileConsentResponse: FileConsentCardResponse) => Promise} handler Function to call when the route is triggered. * @returns {this} The application instance for chaining purposes. */ fileConsentDecline(handler: (context: TurnContext, state: TState, fileConsentResponse: FileConsentCardResponse) => Promise): this; /** * Registers a handler to process when a O365 Connector Card Action activity is received from the user. * @param {(context: TurnContext, state: TState, query: O365ConnectorCardActionQuery) => Promise} handler Function to call when the route is triggered. * @returns {this} The application instance for chaining purposes. */ O365ConnectorCardAction(handler: (context: TurnContext, state: TState, query: O365ConnectorCardActionQuery) => Promise): this; /** * Registers a handler to handoff conversations from one copilot to another. * @param {(context: TurnContext, state: TState, continuation: string) => Promise} handler Function to call when the route is triggered. * @returns {this} The application instance for chaining purposes. */ handoff(handler: (context: TurnContext, state: TState, continuation: string) => Promise): this; /** * Registers a handler for feedbackloop events when a user clicks the thumbsup or thumbsdown button on a response from AI. enable_feedback_loop must be set to true in the AI Module. * @param {(context: TurnContext, state: TState, feedbackLoopData: FeedbackLoopData) => Promise} handler - Function to call when the route is triggered * @returns {this} The application instance for chaining purposes. */ feedbackLoop(handler: (context: TurnContext, state: TState, feedbackLoopData: FeedbackLoopData) => Promise): this; /** * Dispatches an incoming activity to a handler registered with the application. * @remarks * This method should be called from your bot's "turn handler" (its primary message handler) * * ```JavaScript * server.post('/api/messages', async (req, res) => { * await adapter.processActivity(req, res, async (context) => { * await bot.run(context); * }); * }); * ``` * @param {TurnContext} turnContext Context class for the current turn of conversation with the user. * @returns {Promise} True if the activity was successfully dispatched to a handler. False if no matching handlers could be found. */ run(turnContext: TurnContext): Promise; /** * Sends a proactive activity to an existing conversation the bot is a member of. * @remarks * This method provides a simple way to send a proactive message to a conversation the bot is a member of. * * Use of the method requires you configure the Application with the `adapter.appId` * options. An exception will be thrown if either is missing. * @param context Context of the conversation to proactively message. This can be derived from either a TurnContext, ConversationReference, or Activity. * @param activityOrText Activity or message to send to the conversation. * @param speak Optional. Text to speak for channels that support voice. * @param inputHint Optional. Input hint for channels that support voice. * @returns A Resource response containing the ID of the activity that was sent. */ sendProactiveActivity(context: TurnContext, activityOrText: string | Partial, speak?: string, inputHint?: string): Promise; sendProactiveActivity(conversationReference: Partial, activityOrText: string | Partial, speak?: string, inputHint?: string): Promise; sendProactiveActivity(activity: Partial, activityOrText: string | Partial, speak?: string, inputHint?: string): Promise; /** * Retrieves the list of team channels for a given context. * @param context - The context of the conversation, which can be a TurnContext, * Partial, or Partial. * @returns A promise that resolves to an array of ChannelInfo objects if the bot is installed into a team, otherwise returns an empty array. */ getTeamChannels(context: TurnContext): Promise; getTeamChannels(conversationReference: Partial): Promise; getTeamChannels(activity: Partial): Promise; /** * Retrieves the team details for a given context. * @param context - The context of the conversation, which can be a TurnContext, * Partial, or Partial. * @returns A promise that resolves to an array of ChannelInfo objects if the bot is installed into a team, otherwise returns an empty array. */ getTeamDetails(context: TurnContext): Promise; getTeamDetails(conversationReference: Partial): Promise; getTeamDetails(activity: Partial): Promise; /** * Gets a paginated list of members of one-on-one, group, or team conversation. * @param context - The context for the current turn with the user. * @param {number} pageSize - Suggested number of entries on a page. Page sizes with less than 50 are treated as 50, and greater than 500, are capped at 500. * @param {string} continuationToken - A continuation token. * @returns The TeamsPagedMembersResult with the list of members. */ getPagedMembers(context: TurnContext, pageSize?: number, continuationToken?: string): Promise; getPagedMembers(reference: Partial, pageSize?: number, continuationToken?: string): Promise; getPagedMembers(activity: Partial, pageSize?: number, continuationToken?: string): Promise; /** * Manually start a timer to periodically send "typing" activities. * @remarks * The timer waits 1000ms to send its initial "typing" activity and then send an additional * "typing" activity every 1000ms. The timer will automatically end once an outgoing activity * has been sent. If the timer is already running or the current activity, is not a "message" * the call is ignored. * @param {TurnContext} context The context for the current turn with the user. */ startTypingTimer(context: TurnContext): void; /** * Manually stop the typing timer. * @remarks * If the timer isn't running nothing happens. */ stopTypingTimer(): void; /** * Registers a turn event handler. * @remarks * Turn events let you do something before or after a turn is run. Returning false from * `beforeTurn` lets you prevent the turn from running and returning false from `afterTurn` * lets you prevent the bots state from being saved. * * Returning false from `beforeTurn` does result in the bots state being saved which lets you * track the reason why the turn was not processed. It also means you can use `beforeTurn` as * a way to call into the dialog system. For example, you could use the OAuthPrompt to sign the * user in before allowing the AI system to run. * @param {TurnEvents | TurnEvents[]} event - Name of the turn event to handle. * @param {(context: TurnContext, state: TState) => Promise} handler - Function to call when the event is triggered. * @returns {this} The application instance for chaining purposes. */ turn(event: TurnEvents | TurnEvents[], handler: (context: TurnContext, state: TState) => Promise): this; /** * Adds a handler for Teams' readReceiptInfo event * @param {(context: TurnContext, state: TState, readReceiptInfo: ReadReceiptInfo) => Promise} handler Function to call when the event is triggered. * @returns {this} The application instance for chaining purposes. */ teamsReadReceipt(handler: (context: TurnContext, state: TState, readReceiptInfo: ReadReceiptInfo) => Promise): this; /** * Calls the given event handlers with the given context and state. * @param {TurnContext} context - The context for the current turn with the user. * @param {TState} state - The current state of the conversation. * @param {ApplicationEventHandler[]} handlers - The event handlers to call. * @returns {Promise} A Promise that resolves to a boolean indicating whether the event handlers completed successfully. * @private */ private callEventHandlers; /** * Calls the given handler with the given context, either directly or by continuing the conversation * if the message is a long-running message. * @param {TurnContext} context - The context for the current turn with the user. * @param {(context: TurnContext) => Promise} handler - The handler function to call. * @returns {Promise} A Promise that resolves to a boolean indicating whether the handler completed successfully. * @private */ private startLongRunningCall; /** * If the user is signed in, get the access token. If not, triggers the sign in flow for the provided authentication setting name * and returns. In this case, the bot should end the turn until the sign in flow is completed. * @summary * Use this method to get the access token for a user that is signed in to the bot. * If the user isn't signed in, this method starts the sign-in flow. * The bot should end the turn in this case until the sign-in flow completes and the user is signed in. * @param {TurnContext} context - The context for the current turn with the user. * @param {TState} state - The current state of the conversation. * @param {string} settingName The name of the authentication setting. * @returns {string | undefined} The token for the user if they are signed in, otherwise undefined. */ getTokenOrStartSignIn(context: TurnContext, state: TState, settingName: string): Promise; } //# sourceMappingURL=Application.d.ts.map