import type { Chat, Adapter, CardElement, ChatConfig, Message, StateAdapter, Thread } from 'chat';
import type { Agent } from '../agent/agent.js';
import type { IMastraLogger } from '../logger/logger.js';
import type { Mastra } from '../mastra/index.js';
import type { InputProcessor, InputProcessorOrWorkflow } from '../processors/index.js';
import type { ApiRoute } from '../server/types.js';
/** Message content that can be posted to a channel. */
export type PostableMessage = string | CardElement;
/** Per-adapter configuration. */
export interface ChannelAdapterConfig {
    adapter: Adapter;
    /**
     * Start a persistent Gateway WebSocket listener for this adapter
     * (default: `true`).
     *
     * Only relevant for adapters that support it (e.g. Discord).
     * Required for receiving DMs, @mentions, and reactions. Set to `false` for
     * serverless deployments that only need slash commands via HTTP Interactions.
     */
    gateway?: boolean;
    /**
     * Use rich card formatting for tool calls, approvals, and results.
     * Set to `false` to use plain text formatting instead.
     *
     * Some platforms (e.g. Discord) may have rendering issues with cards.
     * @default true
     */
    cards?: boolean;
    /**
     * Override how tool calls are rendered in the chat.
     * Called once per tool invocation after the result is available.
     * Return `null` to suppress the message entirely.
     *
     * @default - A Card showing the function-call signature and result.
     */
    formatToolCall?: (info: {
        toolName: string;
        args: Record<string, unknown>;
        result: unknown;
        isError?: boolean;
    }) => PostableMessage | null;
    /**
     * Override how errors are rendered in the chat.
     * Return a user-friendly message instead of exposing the raw error.
     *
     * @default `"❌ Error: <error.message>"`
     */
    formatError?: (error: Error) => PostableMessage;
}
/**
 * Handler function for channel events.
 * Receives the thread, message, and the default handler implementation.
 * Call `defaultHandler` to run the built-in behavior, or ignore it to fully replace.
 */
export type ChannelHandler = (thread: Thread, message: Message, defaultHandler: (thread: Thread, message: Message) => Promise<void>) => Promise<void>;
/**
 * Handler configuration for channel events.
 * - `undefined` or omitted → use default handler
 * - `false` → disable handler entirely
 * - function → custom handler (receives defaultHandler as 3rd arg to wrap/extend)
 */
export type ChannelHandlerConfig = ChannelHandler | false | undefined;
/** Handler overrides for built-in channel event handlers. */
export interface ChannelHandlers {
    /**
     * Handler for direct messages to the bot.
     * Default: Routes to agent.stream and posts the response.
     */
    onDirectMessage?: ChannelHandlerConfig;
    /**
     * Handler for @mentions of the bot in channels.
     * Default: Routes to agent.stream and posts the response.
     */
    onMention?: ChannelHandlerConfig;
    /**
     * Handler for messages in subscribed threads.
     * Default: Routes to agent.stream and posts the response.
     */
    onSubscribedMessage?: ChannelHandlerConfig;
}
/** Configuration for agent chat channels. */
export interface ChannelConfig {
    /** Platform adapters keyed by name (e.g. 'slack', 'discord'). */
    adapters: Record<string, Adapter | ChannelAdapterConfig>;
    /**
     * Override built-in event handlers.
     * Use this to customize how the agent responds to DMs, mentions, etc.
     *
     * @example
     * ```ts
     * handlers: {
     *   // Wrap the default handler with logging
     *   onDirectMessage: async (thread, message, defaultHandler) => {
     *     console.log('Received DM:', message.text);
     *     await defaultHandler(thread, message);
     *   },
     *   // Disable mention handling entirely
     *   onMention: false,
     * }
     * ```
     */
    handlers?: ChannelHandlers;
    /**
     * Which media types to send inline to the model (as file parts).
     * Everything else is described as text metadata so the agent knows about the
     * file without crashing models that reject unsupported types.
     *
     * - **Array of globs** — e.g. `['image/*']` (default), `['image/*', 'video/*']`
     * - **Function** — `(mimeType: string) => boolean`
     *
     * @default `['image/*']`
     *
     * @example
     * ```ts
     * // Gemini supports video/audio natively
     * inlineMedia: ['image/*', 'video/*', 'audio/*']
     *
     * // Send everything inline
     * inlineMedia: () => true
     * ```
     */
    inlineMedia?: string[] | ((mimeType: string) => boolean);
    /**
     * Promote URLs found in message text to file parts so the model can "see" linked
     * content (images, videos, PDFs, etc.) instead of just the raw URL text.
     *
     * Each entry matches a domain. When a URL in the message matches, it's added as
     * a `file` part alongside the text. Use a string for domains where a HEAD request
     * determines the Content-Type, or an object to force a specific mime type (useful
     * for sites like YouTube where HEAD returns `text/html` but the model treats the
     * URL as video).
     *
     * - **String** — domain to match; HEAD determines the mime type
     * - **Object** `{ match, mimeType }` — domain + forced mime type (skips HEAD)
     * - `'*'` — match all URLs (HEAD each one)
     * - `undefined` (default) — disabled, no URLs are promoted
     *
     * For string entries (or `'*'`), the resolved Content-Type is checked against
     * `inlineMedia` — only matching types become file parts. For object entries with
     * a forced `mimeType`, the file part is always added.
     *
     * @example
     * ```ts
     * // Gemini can process YouTube URLs natively as video
     * inlineLinks: [
     *   { match: 'youtube.com', mimeType: 'video/*' },
     *   { match: 'youtu.be', mimeType: 'video/*' },
     * ]
     *
     * // HEAD-check linked images from any domain
     * inlineLinks: ['*']
     *
     * // Mix: force YouTube, HEAD-check everything else
     * inlineLinks: [
     *   { match: 'youtube.com', mimeType: 'video/*' },
     *   'imgur.com',
     *   'i.redd.it',
     * ]
     * ```
     */
    inlineLinks?: InlineLinkEntry[];
    /** State adapter for deduplication, locking, and subscriptions. Defaults to in-memory. */
    state?: StateAdapter;
    /** The bot's display name (default: agent's name, or `'Mastra'`). */
    userName?: string;
    /**
     * Fetch recent thread messages from the platform to provide context when the agent
     * is mentioned mid-conversation. Only fetches on the first mention in a thread —
     * once subscribed, the agent has full history via Mastra's memory system.
     *
     * @example
     * ```ts
     * threadContext: { maxMessages: 15 } // Fetch more context
     * threadContext: { maxMessages: 0 }  // Disable (opt-out)
     * ```
     */
    threadContext?: {
        /**
         * Maximum number of recent platform messages to fetch (default: 10).
         * Only applies to non-DM threads where the agent isn't already subscribed.
         * Set to 0 to disable.
         */
        maxMessages?: number;
    };
    /**
     * Whether to include channel tools (add_reaction, remove_reaction).
     * Set to `false` for models that don't support function calling.
     *
     * @default true
     */
    tools?: boolean;
    /**
     * Additional options passed directly to the Chat SDK.
     * Use this for advanced configuration not exposed by Mastra.
     *
     * @see https://github.com/vercel/chat
     * @example
     * ```ts
     * chatOptions: {
     *   dedupeTtlMs: 600000, // 10 minute deduplication window
     *   fallbackStreamingPlaceholderText: '⏳',
     * }
     * ```
     */
    chatOptions?: Omit<ChatConfig, 'adapters' | 'state' | 'userName'>;
}
/** A single entry in the `inlineLinks` config. */
export type InlineLinkEntry = string | {
    match: string;
    mimeType: string;
};
/** Check if a URL's hostname matches a domain pattern. @internal */
export declare function matchesDomain(url: string, pattern: string): boolean;
export declare function extractUrls(text: string): string[];
/**
 * Manages a single Chat SDK instance for an agent, wiring all adapters
 * to the Mastra pipeline (thread mapping → agent.stream → thread.post).
 *
 * One AgentChannels = one bot identity across multiple platforms.
 *
 * @internal Created automatically by the Agent when `channels` config is provided.
 */
export declare class AgentChannels {
    readonly adapters: Record<string, Adapter>;
    private chat;
    /** Stored initialization promise so webhook handlers can await readiness on serverless cold starts. */
    private initPromise;
    private agent;
    private logger?;
    private customState;
    private stateAdapter;
    private userName;
    /** Normalized per-adapter configs (gateway flags, hooks, etc.). */
    private adapterConfigs;
    /** Handler overrides from config. */
    private handlerOverrides;
    /** Additional Chat SDK options. */
    private chatOptions;
    /** Thread context config for fetching prior messages. */
    private threadContext;
    /** Determines whether a mime type should be sent inline to the model. */
    private shouldInline;
    /** Inline-link rules for promoting URLs in message text to file parts. */
    private inlineLinkRules;
    /** Whether channel tools (reactions, etc.) are enabled. */
    private toolsEnabled;
    /** Channel tool names whose effects are already visible on the platform (skip rendering cards). */
    private channelToolNames;
    constructor(config: ChannelConfig);
    /**
     * Bind this AgentChannels to its owning agent. Called by Agent constructor.
     * @internal
     */
    __setAgent(agent: Agent<any, any, any, any>): void;
    /**
     * Set the logger. Called by Mastra.addAgent.
     * @internal
     */
    __setLogger(logger: IMastraLogger): void;
    /**
     * Get the underlying Chat SDK instance.
     * Available after Mastra initialization. Use this to register additional
     * event handlers or access adapter-specific methods.
     *
     * @example
     * ```ts
     * agent.channels.sdk.onReaction((thread, reaction) => {
     *   console.log('Reaction received:', reaction);
     * });
     * ```
     */
    get sdk(): Chat | null;
    /**
     * Initialize the Chat SDK, register handlers, and start gateway listeners.
     * Called by Mastra.addAgent after the server is ready.
     */
    initialize(mastra: Mastra): Promise<void>;
    /**
     * Returns API routes for receiving webhook events from each adapter.
     * One POST route per adapter at `/api/agents/{agentId}/channels/{platform}/webhook`.
     */
    getWebhookRoutes(): ApiRoute[];
    /**
     * Returns channel input processors (e.g. system prompt injection).
     * Skips if the user already added a processor with the same id.
     */
    getInputProcessors(configuredProcessors?: InputProcessorOrWorkflow[]): InputProcessor[];
    /**
     * Returns generic channel tools (send_message, add_reaction, etc.)
     * that resolve the target adapter from the current request context.
     */
    getTools(): Record<string, unknown>;
    /**
     * Resolve the adapter for the current conversation from request context.
     */
    private getAdapterFromContext;
    /**
     * Core handler wired to Chat SDK's onDirectMessage, onNewMention,
     * and onSubscribedMessage. Streams the Mastra agent response and
     * updates the channel message in real-time via edits.
     */
    private handleChatMessage;
    private processChatMessage;
    /**
     * Fetch recent messages from the platform thread to provide context.
     * Returns messages in chronological order (oldest first), excluding the
     * current triggering message.
     */
    private fetchThreadHistory;
    /**
     * Consume the agent stream and render all chunks to the chat platform.
     *
     * Iterates the outer `fullStream` to handle all chunk types:
     * - `text-delta`: Accumulates text and posts when flushed.
     * - `tool-call`: Posts a "Running…" card eagerly.
     * - `tool-result`: Edits the "Running…" card with the result.
     * - `tool-call-approval`: Edits the card to show Approve/Deny buttons.
     * - `step-finish` / `finish`: Flushes accumulated text.
     */
    private editOrPost;
    private consumeAgentStream;
    /**
     * Resolves an existing Mastra thread for the given external IDs, or creates one.
     */
    private getOrCreateThread;
    /**
     * Generate generic channel tools that resolve the adapter from request context.
     * Tool names are platform-agnostic (e.g. `send_message`, not `discord_send_message`).
     */
    private makeChannelTools;
    /**
     * Persistent reconnection loop for Gateway-based adapters (e.g. Discord).
     */
    private startGatewayLoop;
    private log;
}
//# sourceMappingURL=agent-channels.d.ts.map