import { Activity, ActivityLike, AgenticIdentity, CloudEnvironment, DeprecatedInputActivity, InvokeResponse, SentActivity } from '@microsoft/teams.api';
import { Client as HttpClient, EventEmitter, EventHandler, ILogger, IStorage, LocalStorage } from '@microsoft/teams.common';
import { ActivitySender } from './activity-sender';
import { ApiClient, GraphClient } from './api';
import type { AppGetAgenticIdentityOptions, AppOptions, AppSendOptions } from './app.options';
export type { AppActivityOptions, AppGetAgenticIdentityOptions, AppOptions, AppSendOptions, AppTelemetryOptions, } from './app.options';
import { PluginManager } from './app.plugins';
import { Container } from './container';
import { IActivityContext, IFunctionContext } from './contexts';
import { IActivityEvent } from './events';
import { HttpServer } from './http/http-server';
import * as middleware from './middleware';
import { OAuthFlow } from './oauth';
import type { OAuthSignInOptions } from './oauth';
import { HttpPlugin } from './plugins';
import { Router } from './router';
import { IRoutes } from './routes';
import { IAppTokenProvider } from './token-provider';
import { AppEvents, IPlugin, PluginName, RouteHandler } from './types';
import { PluginAdditionalContext } from './types/app-routing';
/**
 * The orchestrator for receiving/sending activities
 */
export declare class App<TPlugin extends IPlugin = IPlugin> {
    readonly options: AppOptions<TPlugin>;
    readonly api: ApiClient;
    readonly cloud: CloudEnvironment;
    readonly graph: GraphClient;
    readonly log: ILogger;
    readonly server: HttpServer;
    readonly http?: HttpPlugin;
    readonly client: HttpClient;
    /**
     * The app's legacy shared storage instance.
     *
     * @deprecated Use `ctx.state` for turn state. Applications that need general
     * persistence should own and use their storage provider directly.
     */
    readonly storage: IStorage;
    readonly entraTokenValidator?: middleware.JwtValidator;
    /**
     * Graph API base URL derived from the configured cloud's `graphScope`.
     * Undefined when the scope isn't a URL — `GraphClient` then uses its public-cloud default.
     * Shared across every `GraphClient` the app constructs (`app.graph`, `ctx.appGraph`, `ctx.userGraph`)
     * so sovereign customers get consistent routing.
     */
    readonly graphBaseUrl?: string;
    /**
     * the apps credentials
     */
    get credentials(): import("@microsoft/teams.api").Credentials | undefined;
    /**
     * The app's token source, for acquiring a token for something the SDK does not
     * call for you, such as an OpenTelemetry exporter.
     */
    get tokenProvider(): IAppTokenProvider;
    /**
     * the apps id
     */
    get id(): string | undefined;
    get oauth(): {
        defaultConnectionName: string;
        fetchUserToken?: boolean;
    };
    protected container: Container;
    protected pluginManager: PluginManager<TPlugin>;
    protected router: Router<PluginAdditionalContext<TPlugin>>;
    protected tenantTokens: LocalStorage<string>;
    protected events: EventEmitter<AppEvents<TPlugin>>;
    protected isInitialized: boolean;
    protected port?: number | string;
    protected activitySender: ActivitySender;
    /**
     * The concrete token machinery: MSAL clients, credential resolution, and the
     * per-grant acquisition logic. Private because {@link App.tokenProvider} is
     * the supported way in.
     */
    private readonly tokenManager;
    private readonly _tokenProvider;
    private stateLoader?;
    private eventManager;
    private activityProcessor;
    private readonly oauthFlowRegistry;
    private readonly _userAgent;
    constructor(options?: AppOptions<TPlugin>);
    /**
     * initialize the app.
     */
    initialize(): Promise<void>;
    /**
     * start the server after initialization
     * @param port port to listen on
     */
    start(port?: number | string): Promise<void>;
    /**
     * stop the app
     */
    stop(): Promise<void>;
    /**
     * send an activity proactively to a conversation.
     *
     * Sends to the exact conversation ID provided. For channel threads,
     * the conversation ID must include `;messageid=` - use {@link toThreadedConversationId}
     * to construct it, or use {@link reply} which handles this automatically.
     *
     * @param conversationId the conversation to send to
     * @param activity the activity to send
     */
    /**
     * @deprecated Use MessageActivityInput or TypingActivityInput instead.
     */
    send(conversationId: string, activity: DeprecatedInputActivity, options?: AppSendOptions): Promise<SentActivity>;
    send(conversationId: string, activity: ActivityLike, options?: AppSendOptions): Promise<SentActivity>;
    send(conversationId: string, activity: ActivityLike | DeprecatedInputActivity, options?: AppSendOptions): Promise<SentActivity>;
    /**
     * send an activity proactively as a threaded reply.
     *
     * Constructs a threaded conversation ID from the conversation ID
     * and message ID via {@link toThreadedConversationId}, then sends
     * to that thread. The service determines whether threading is
     * supported for the given conversation type.
     *
     * @param conversationId the conversation ID
     * @param messageId the thread root message ID
     * @param activity the activity to send
     */
    /**
     * @deprecated Use MessageActivityInput or TypingActivityInput instead.
     */
    reply(conversationId: string, messageId: string, activity: DeprecatedInputActivity, options?: AppSendOptions): Promise<any>;
    reply(conversationId: string, messageId: string, activity: ActivityLike, options?: AppSendOptions): Promise<any>;
    reply(conversationId: string, messageId: string, activity: ActivityLike | DeprecatedInputActivity, options?: AppSendOptions): Promise<any>;
    /**
     * send an activity proactively to a conversation.
     *
     * Sends to the exact conversation ID provided - threaded if
     * it contains `;messageid=`, flat otherwise.
     *
     * @param conversationId the conversation to send to
     * @param activity the activity to send
     */
    /**
     * @deprecated Use MessageActivityInput or TypingActivityInput instead.
     */
    reply(conversationId: string, activity: DeprecatedInputActivity, options?: AppSendOptions): Promise<any>;
    reply(conversationId: string, activity: ActivityLike, options?: AppSendOptions): Promise<any>;
    reply(conversationId: string, activity: ActivityLike | DeprecatedInputActivity, options?: AppSendOptions): Promise<any>;
    /**
     * Create an AgenticIdentity for scoped proactive sends and API clients.
     *
     * AgenticIdentity is the SDK operation/request scope for Agent 365. This
     * helper fills the required blueprint and tenant identifiers from app
     * configuration while allowing app/user IDs to be omitted or set to `null`
     * when the operation is not scoped to a concrete agentic app or user.
     *
     * @param options identity fields and optional overrides
     */
    getAgenticIdentity(options?: AppGetAgenticIdentityOptions): AgenticIdentity;
    /**
     * Registers an OAuth flow for one Bot Framework OAuth connection.
     *
     * Connection names are matched case-insensitively. Registering the same
     * connection more than once throws. The first registration removes
     * the implicit legacy default. This method cannot be used when
     * `oauth.defaultConnectionName` was configured.
     *
     * @param connectionName OAuth connection name.
     * @param options Optional card defaults for the flow.
     * @returns The registered flow so callbacks can be chained.
     */
    addOAuthFlow(connectionName: string, options?: OAuthSignInOptions): OAuthFlow<TPlugin>;
    /**
     * Gets the OAuth flow for a connection.
     *
     * The implicit legacy default is available only until the first flow
     * is registered.
     *
     * @param connectionName Connection to resolve.
     * @throws When the connection name is blank or no matching flow is registered.
     */
    getOAuthFlow(connectionName: string): OAuthFlow<TPlugin>;
    /**
     * subscribe to an event
     * @param name event to subscribe to
     * @param cb callback to invoke
     */
    on<Name extends keyof IRoutes>(name: Name, cb: Exclude<IRoutes<PluginAdditionalContext<TPlugin>>[Name], undefined>): this;
    /**
     * subscribe to a message event for a specific pattern
     * @param pattern pattern to match against message text
     * @param cb callback to invoke
     */
    message(pattern: string | RegExp, cb: Exclude<IRoutes<PluginAdditionalContext<TPlugin>>['message'], undefined>): this;
    /**
     * register a middleware
     * @param cb callback to invoke
     */
    use(cb: RouteHandler<IActivityContext<Activity, PluginAdditionalContext<TPlugin>>, void | InvokeResponse>): this;
    /**
     * subscribe to an event
     * @param name the event to subscribe to
     * @param cb the callback to invoke
     */
    event<Name extends keyof AppEvents<TPlugin>>(name: Name, cb: EventHandler<AppEvents<TPlugin>[Name]>): this;
    /**
     * add a plugin
     * @param plugin plugin to add
     */
    plugin(plugin: TPlugin): this;
    /**
     * get a plugin
     */
    getPlugin(name: PluginName): IPlugin | undefined;
    /**
     * add/update a function that can be called remotely
     * @param name The unique function name
     * @param cb The callback to handle the function
     */
    function<TData>(name: string, cb: (context: IFunctionContext<TData>) => any | Promise<any>): this;
    function<TPluginOverride, TData>(name: string, cb: (context: IFunctionContext<TData>) => any | Promise<any>): this;
    /**
     * add/update a static tab.
     * the tab will be hosted at
     * `http://localhost:{{PORT}}/tabs/{{name}}` or `https://{{BOT_DOMAIN}}/tabs/{{name}}`
     * @remark scopes default to `personal`
     * @param name A unique identifier for the entity which the tab displays.
     * @param path The path to the web `dist` folder.
     */
    tab(name: string, path: string): this;
    /**
     * whether any registered route matches the inbound activity
     *
     * Useful for hosts that embed the app behind their own pipeline (e.g. the
     * Microsoft 365 Extension and need to decide whether to hand a turn
     * to this app or let it fall through, without running the activity.
     * @param activity the inbound activity to test against registered routes
     */
    hasMatchingRoute(activity: Activity): boolean;
    /**
     * activity handler called when an inbound activity is received
     * @param event the received activity event
     */
    process(event: IActivityEvent): Promise<InvokeResponse>;
    onActivity(event: IActivityEvent): Promise<InvokeResponse>;
    protected getBotToken(): Promise<import("@microsoft/teams.api").IToken | null>;
    /**
     * Acquires a Graph token for an Agentic User, via the federated identity exchange the token manager already performs.
     *
     * Separate from {@link getAppGraphToken} because the identity differs, not merely the scope: this reads as the agent, so it sees what was shared with the agent rather than everything the app may read.
     */
    protected getAgenticGraphToken(identity: AgenticIdentity, tenantId?: string): Promise<import("@microsoft/teams.api").IToken | null>;
    protected getAppGraphToken(tenantId?: string): Promise<import("@microsoft/teams.api").IToken | null>;
    /**
     * Whether deprecated context OAuth fields require an eager token lookup.
     *
     * Registered flows never enable this behavior. An explicit legacy
     * `oauth.fetchUserToken` wins; otherwise lookup is enabled only when the
     * legacy default connection was explicitly configured.
     *
     * @deprecated Registered flows fetch tokens only through `OAuthFlow` methods.
     */
    protected shouldFetchUserToken(): boolean;
    private enableOAuthState;
}
