import * as _tanstack_react_query from '@tanstack/react-query';
import { createApiClient } from '@btst/stack/plugins/client';
import { M as Message, C as Conversation, S as SerializedConversation, a as SerializedMessage } from './stack.Be1QIHEn.js';
import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
import * as better_call from 'better-call';
import * as zod_v4_core from 'zod/v4/core';
import * as zod from 'zod';
import { Tool, LanguageModel } from 'ai';

/**
 * Context passed to AI Chat API hooks
 */
interface ChatApiContext<TBody = any, TParams = any, TQuery = any> {
    body?: TBody;
    params?: TParams;
    query?: TQuery;
    request?: Request;
    headers?: Headers;
    [key: string]: any;
}
/**
 * Configuration hooks for AI Chat backend plugin
 * All hooks are optional and allow consumers to customize behavior
 */
interface AiChatBackendHooks {
    /**
     * Called before processing a chat message. Throw an error to deny access.
     * @param messages - Array of messages being sent
     * @param context - Request context with headers, etc.
     */
    onBeforeChat?: (messages: Array<{
        role: string;
        content: string;
    }>, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called before listing conversations. Throw an error to deny access.
     * @param context - Request context with headers, etc.
     */
    onBeforeListConversations?: (context: ChatApiContext) => Promise<void> | void;
    /**
     * Called before getting a single conversation. Throw an error to deny access.
     * @param conversationId - ID of the conversation being accessed
     * @param context - Request context with headers, etc.
     */
    onBeforeGetConversation?: (conversationId: string, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called before creating a conversation. Throw an error to deny access.
     * @param data - Conversation data being created
     * @param context - Request context with headers, etc.
     */
    onBeforeCreateConversation?: (data: {
        id?: string;
        title?: string;
    }, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called before updating a conversation. Throw an error to deny access.
     * @param conversationId - ID of the conversation being updated
     * @param data - Updated conversation data
     * @param context - Request context with headers, etc.
     */
    onBeforeUpdateConversation?: (conversationId: string, data: {
        title?: string;
    }, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called before deleting a conversation. Throw an error to deny access.
     * @param conversationId - ID of the conversation being deleted
     * @param context - Request context with headers, etc.
     */
    onBeforeDeleteConversation?: (conversationId: string, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called after the structural routeName/allowlist validation, with the list
     * of tool names that passed. Return a filtered subset to further restrict
     * which tools the LLM sees, or return [] to suppress all page tools.
     * Throw an Error to abort the entire chat request with a 403 response.
     * Not called when no tools passed the structural validation step.
     *
     * @param toolNames - Names that passed the routeName allowlist check
     * @param routeName - routeName claimed by the request (may be undefined)
     * @param context   - Full request context (headers, body, etc.)
     */
    onBeforeToolsActivated?: (toolNames: string[], routeName: string | undefined, context: ChatApiContext) => Promise<string[]> | string[];
    /**
     * Called after a chat message is processed successfully
     * @param conversationId - ID of the conversation
     * @param messages - Array of messages in the conversation
     * @param context - Request context
     */
    onAfterChat?: (conversationId: string, messages: Message[], context: ChatApiContext) => Promise<void> | void;
    /**
     * Called after conversations are read successfully
     * @param conversations - Array of conversations that were read
     * @param context - Request context
     */
    onConversationsRead?: (conversations: Conversation[], context: ChatApiContext) => Promise<void> | void;
    /**
     * Called after a single conversation is read successfully
     * @param conversation - The conversation with messages
     * @param context - Request context
     */
    onConversationRead?: (conversation: Conversation & {
        messages: Message[];
    }, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called after a conversation is created successfully
     * @param conversation - The created conversation
     * @param context - Request context
     */
    onConversationCreated?: (conversation: Conversation, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called after a conversation is updated successfully
     * @param conversation - The updated conversation
     * @param context - Request context
     */
    onConversationUpdated?: (conversation: Conversation, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called after a conversation is deleted successfully
     * @param conversationId - ID of the deleted conversation
     * @param context - Request context
     */
    onConversationDeleted?: (conversationId: string, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called when a chat operation fails
     * @param error - The error that occurred
     * @param context - Request context
     */
    onChatError?: (error: Error, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called when listing conversations fails
     * @param error - The error that occurred
     * @param context - Request context
     */
    onListConversationsError?: (error: Error, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called when getting a conversation fails
     * @param error - The error that occurred
     * @param context - Request context
     */
    onGetConversationError?: (error: Error, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called when creating a conversation fails
     * @param error - The error that occurred
     * @param context - Request context
     */
    onCreateConversationError?: (error: Error, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called when updating a conversation fails
     * @param error - The error that occurred
     * @param context - Request context
     */
    onUpdateConversationError?: (error: Error, context: ChatApiContext) => Promise<void> | void;
    /**
     * Called when deleting a conversation fails
     * @param error - The error that occurred
     * @param context - Request context
     */
    onDeleteConversationError?: (error: Error, context: ChatApiContext) => Promise<void> | void;
}
/**
 * Plugin mode for AI Chat
 * - 'authenticated': Conversations persisted with userId (default)
 * - 'public': Stateless chat, no persistence (ideal for public chatbots)
 */
type AiChatMode = "authenticated" | "public";
/**
 * Configuration for AI Chat backend plugin
 */
/**
 * Extracts only the literal (non-index-signature) keys from a type.
 * For `Record<string, T>` this resolves to `never`, so collision checks are
 * skipped when the tools map is typed with a broad string index.
 */
type KnownKeys<T> = {
    [K in keyof T]: string extends K ? never : K;
}[keyof T];
/**
 * Ensures `TClientTools` has no keys that are also literal keys in `TTools`.
 * Colliding keys are mapped to `never`, which produces a compile-time error
 * at the point of the duplicate key. When `TTools` uses a string index
 * signature the check is skipped to avoid false positives.
 */
type NoKeyCollision<TTools, TClientTools extends Record<string, Tool>> = KnownKeys<TTools> & keyof TClientTools extends never ? TClientTools : {
    [K in keyof TClientTools]: K extends KnownKeys<TTools> ? never : TClientTools[K];
};
interface AiChatBackendConfig {
    /**
     * The language model to use for chat completions.
     * Supports any model from AI SDK providers (OpenAI, Anthropic, Google, etc.)
     */
    model: LanguageModel;
    /**
     * Plugin mode:
     * - 'authenticated': Conversations persisted with userId (requires getUserId)
     * - 'public': Stateless chat, no persistence (ideal for public chatbots)
     * @default 'authenticated'
     */
    mode?: AiChatMode;
    /**
     * Extract userId from request context (authenticated mode only).
     * Return null/undefined to deny access in authenticated mode.
     * This function is called for all conversation operations.
     * @example (ctx) => ctx.headers?.get('x-user-id')
     */
    getUserId?: (context: ChatApiContext) => string | null | undefined | Promise<string | null | undefined>;
    /**
     * Optional system prompt to prepend to all conversations
     */
    systemPrompt?: string;
    /**
     * Optional tools to make available to the model.
     * Uses AI SDK v5 tool format.
     * @see https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling
     */
    tools?: Record<string, Tool>;
    /**
     * Enable route-aware page tools.
     * When true, the server will include tool schemas for client-side page tools
     * (e.g. fillBlogForm, updatePageLayers) based on the availableTools list
     * sent with each request.
     * @default false
     */
    enablePageTools?: boolean;
    /**
     * Custom client-side tool schemas for non-BTST pages.
     * Merged with built-in page tool schemas (fillBlogForm, updatePageLayers).
     * Only included when enablePageTools is true and the tool name appears in
     * the availableTools list sent with the request.
     *
     * @example
     * clientToolSchemas: {
     *   addToCart: tool({
     *     description: "Add current product to cart",
     *     parameters: z.object({ quantity: z.number().int().min(1) }),
     *   }),
     * }
     */
    clientToolSchemas?: Record<string, Tool>;
    /**
     * Optional hooks for customizing plugin behavior
     */
    hooks?: AiChatBackendHooks;
}
/**
 * AI Chat backend plugin
 * Provides API endpoints for AI-powered chat with conversation history
 * Uses AI SDK v5 for model interactions
 *
 * @param config - Configuration including model, tools, and optional hooks
 */
declare const aiChatBackendPlugin: <TTools extends Record<string, Tool> = Record<never, Tool>, TClientTools extends Record<string, Tool> = Record<never, Tool>>(config: Omit<AiChatBackendConfig, "tools" | "clientToolSchemas"> & {
    tools?: TTools;
    clientToolSchemas?: NoKeyCollision<TTools, TClientTools>;
}) => _btst_stack_plugins_api.BackendPlugin<{
    chat: better_call.StrictEndpoint<"/chat", {
        method: "POST";
        body: zod.ZodObject<{
            messages: zod.ZodArray<zod.ZodUnion<readonly [zod.ZodObject<{
                role: zod.ZodEnum<{
                    system: "system";
                    user: "user";
                    assistant: "assistant";
                    data: "data";
                }>;
                content: zod.ZodString;
                id: zod.ZodOptional<zod.ZodString>;
            }, zod_v4_core.$strip>, zod.ZodObject<{
                role: zod.ZodEnum<{
                    system: "system";
                    user: "user";
                    assistant: "assistant";
                    data: "data";
                }>;
                parts: zod.ZodArray<zod.ZodObject<{
                    type: zod.ZodString;
                    text: zod.ZodOptional<zod.ZodString>;
                }, zod_v4_core.$loose>>;
                id: zod.ZodOptional<zod.ZodString>;
                metadata: zod.ZodOptional<zod.ZodAny>;
            }, zod_v4_core.$strip>]>>;
            conversationId: zod.ZodOptional<zod.ZodString>;
            model: zod.ZodOptional<zod.ZodString>;
            pageContext: zod.ZodOptional<zod.ZodString>;
            availableTools: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
            routeName: zod.ZodOptional<zod.ZodString>;
        }, zod_v4_core.$strip>;
    }, Response>;
    createConversation: better_call.StrictEndpoint<"/chat/conversations", {
        method: "POST";
        body: zod.ZodObject<{
            id: zod.ZodOptional<zod.ZodString>;
            title: zod.ZodOptional<zod.ZodString>;
        }, zod_v4_core.$strip>;
    }, Conversation>;
    listConversations: better_call.StrictEndpoint<"/chat/conversations", {
        method: "GET";
    }, Conversation[]>;
    getConversation: better_call.StrictEndpoint<"/chat/conversations/:id", {
        method: "GET";
    }, Conversation & {
        messages: Message[];
    }>;
    updateConversation: better_call.StrictEndpoint<"/chat/conversations/:id", {
        method: "PUT";
        body: zod.ZodObject<{
            title: zod.ZodOptional<zod.ZodString>;
        }, zod_v4_core.$strip>;
    }, Conversation>;
    deleteConversation: better_call.StrictEndpoint<"/chat/conversations/:id", {
        method: "DELETE";
    }, {
        success: boolean;
    }>;
}, {
    getAllConversations: (userId?: string) => Promise<Conversation[]>;
    getConversationById: (id: string) => Promise<(Conversation & {
        messages: Message[];
    }) | null>;
}>;
type AiChatApiRouter = ReturnType<ReturnType<typeof aiChatBackendPlugin>["routes"]>;

type ConversationWithMessages = SerializedConversation & {
    messages: SerializedMessage[];
};
declare function createAiChatQueryKeys(client: ReturnType<typeof createApiClient<AiChatApiRouter>>, headers?: HeadersInit): {
    conversations: {
        _def: readonly ["conversations"];
    } & {
        list: (() => Omit<{
            queryKey: readonly ["conversations", "list", string];
            queryFn: _tanstack_react_query.QueryFunction<SerializedConversation[], readonly ["conversations", "list", string]>;
        } & {
            _def: readonly ["conversations", "list"];
        }, "_def">) & {
            _def: readonly ["conversations", "list"];
        };
        detail: ((id: string) => Omit<{
            queryKey: readonly ["conversations", "detail", string];
            queryFn: _tanstack_react_query.QueryFunction<ConversationWithMessages | null, readonly ["conversations", "detail", string]>;
        } & {
            _def: readonly ["conversations", "detail"];
        }, "_def">) & {
            _def: readonly ["conversations", "detail"];
        };
    };
};

export { createAiChatQueryKeys as c, aiChatBackendPlugin as d };
export type { AiChatBackendHooks as A, ChatApiContext as C, AiChatMode as a, AiChatBackendConfig as b, AiChatApiRouter as e, ConversationWithMessages as f };
