import type { tool } from "@ai-sdk/provider-utils";
import type { ToolExecutionOptions } from "ai";
import type z from "zod";
import type { AiMode, AiEntityType, PlanContext, PromptContextEntity, PromptContextIntegration, AiToolPermission, AiToolExecutionErrorCode } from "@superblocksteam/library-shared/types";
import type { CompactionSummary } from "../../llm/context-v2/types.js";
import type { SubagentType } from "../subagents/types.js";
/**
 * Tool categories for grouping and middleware selection.
 */
export declare enum ToolCategory {
    FILE = "file",
    COMPONENT = "component",
    MULTI_FILE = "multi_file",
    GENERAL = "general",
    API = "api",
    SUBAGENT = "subagent",
    METADATA = "metadata",
    DATA = "data",
    MEMORY = "memory",
    PLAN = "plan",
    TEST = "test",
    DEBUG = "debug",
    GIT = "git",
    /**
     * Tools that manipulate UI state interactively.
     *
     * Used for tools that:
     * - Manipulate UI state (Redux, form fields, tabs)
     * - Require the user to be looking at the screen (they see what's happening)
     *
     * Combine with PermissionLevel.ALLOW or PermissionLevel.PROMPT to control
     * whether Clark executes immediately or asks for confirmation first.
     * e.g. filling a field (ALLOW) vs saving integration changes (PROMPT).
     */
    INTERACTIVE = "interactive"
}
/**
 * Entity reference extracted from tool input.
 *
 * Represents an entity (integration, file, etc.) that the tool
 * will access, requiring user approval.
 */
export interface EntityReference {
    /** Type of entity being accessed */
    type: AiEntityType;
    /** Unique identifier of the entity */
    id: string;
}
type ToolParams<Input, Output> = Parameters<typeof tool<Input, Output>>[0];
/**
 * Core tool interface.
 *
 * A tool is a unit of functionality that can be invoked with validated input
 * and returns validated output. Tools are registered in the registry and can
 * be executed with access control.
 */
export interface Tool<Input = any, Output = any> {
    /** Unique tool name */
    name: string;
    /** Human-readable description for LLM */
    description: string;
    /** Category for grouping tools */
    category: ToolCategory;
    /** Default permission level (can be overridden by rules) */
    defaultPermission?: PermissionLevel;
    /** Whether the tool is read-only (default: false) */
    readOnly?: boolean;
    /**
     * Optional function to determine whether to skip output size limiting for this tool.
     * Receives the output from execute() and returns true to skip the limit check.
     * Useful for tools that output content type with media parts (e.g., screenshots),
     * as media parts are handled separately by the AI SDK and don't contribute to token count
     * in the same way as text/JSON outputs.
     */
    skipOutputLimit?: (output: Output) => boolean;
    /** Zod schema for input validation */
    inputSchema: z.ZodType<Input>;
    /** Optional Zod schema for output validation */
    outputSchema?: z.ZodType<Output>;
    /**
     * Optional hook invoked immediately when the tool is called, before
     * permission checks and after input validation.
     *
     * Use this to perform side effects such as updating internal state
     * (e.g., clark context) as soon as a tool call arrives from the LLM.
     *
     * Throwing an error aborts execution — the registry catches it and
     * returns a `ToolExecutionError` to the LLM. Returning (or resolving)
     * normally allows execution to continue through the regular flow.
     *
     * @param input - Input from the LLM
     * @param options - Tool call options (toolCallId, messages, etc.)
     *
     * @example
     * onCall: (input) => {
     *   clark.updateContext({ lastToolCall: toolName });
     *   if (someCondition) throw new Error("Cannot call this tool right now");
     * }
     */
    onCall?: (input: Input, options?: ToolExecutionOptions) => void | Promise<void>;
    /** Execute the tool with validated input */
    execute: (input: Input, options: ToolExecutionOptions) => Promise<Output>;
    /**
     * Optional conversion function that maps the tool result to an output
     * that can be used by the language model.
     */
    toModelOutput?: ToolParams<Input, Output>["toModelOutput"];
    /**
     * Optional function to get the required permissions for the tool.
     *
     * @param input - Validated tool input
     * @returns Array of required permissions
     *
     * @example
     * getRequiredPermissions: (input) => [{
     *   entityType: AiEntityType.PAGE,
     *   entityId: input.filePath,
     *   permissionType: AiPermissionType.DELETE,
     * }]
     */
    getRequiredPermissions?: (input: Input) => Promise<AiToolPermission[]> | AiToolPermission[];
    /**
     * Optional function to get action name in different tenses.
     *
     * Used for displaying the tool action in messages before, during, and after
     * execution. Enables context-aware messaging without hardcoding tool names.
     * When input is provided, may return operation-specific action names.
     *
     * @param input - Optional validated tool input (e.g. when used in permission prompt)
     * @returns Action name in future, present, and past tense
     *
     * @example
     * getActionName: () => ({
     *   future: "execute SQL query",
     *   present: "executing SQL query",
     *   past: "executed SQL query"
     * })
     * @example
     * getActionName: (input) => input?.operation === 'commit' ? { future: "commit changes", ... } : { future: "run git", ... }
     */
    getActionName?: (input?: Input) => {
        future: string;
        present: string;
        past: string;
    };
    /**
     * Optional function to format tool input for human-readable display.
     *
     * Returns the target entities/resources being acted upon and optional details.
     * Used in prompts and messages to show the user what will be affected.
     * The action itself comes from getActionName(), so focus on the targets.
     *
     * @param input - Validated tool input
     * @returns Formatted input with targets array and optional details
     *
     * @example
     * formatInput: (input) => ({
     *   targets: [integrationName],
     *   details: input.params.query
     * })
     */
    formatInput?: (input: Input) => {
        targets: string[];
        details?: string;
        summary?: string;
    };
    /**
     * Optional function to generate summaries for the tool's input and output.
     *
     * Used during context compaction to provide meaningful summaries instead of
     * generic placeholders. Outputs are always compacted with summaries, while
     * inputs are only compacted when they exceed a size threshold.
     *
     * IMPORTANT: This function receives the original typed output, NOT the
     * potentially truncated string from outputLimiter. The middleware ordering
     * in tools.ts ensures summaryInjector runs BEFORE outputLimiter, so you
     * can safely access all properties on the output object.
     *
     * @param input - The validated tool input
     * @param output - The tool's original output (always the typed Output, never truncated)
     * @returns Separate summaries for input and output
     *
     * @example
     * getSummary: (input, output) => ({
     *   input: `pattern: "${input.pattern}"`,
     *   output: `Found ${output.matches} matches`
     * })
     */
    getSummary?: (input: Input, output: Output) => CompactionSummary;
}
/**
 * Permission levels for tool execution.
 */
export declare enum PermissionLevel {
    /** Execute immediately without user interaction */
    ALLOW = "allow",
    /** Prompt user for confirmation before execution */
    PROMPT = "prompt",
    /** Block execution completely */
    BLOCK = "block"
}
/**
 * Factory for creating tool instances.
 *
 * Allows tools to be registered before their dependencies are available,
 * then instantiated with dependencies at runtime.
 */
export interface ToolFactory<TDeps = any, T extends Tool = Tool> {
    /** Tool name for registration lookup */
    name: string;
    /** Factory function that creates a tool instance */
    create: (deps: TDeps) => T;
}
/**
 * Helper function to create a tool factory without name duplication.
 *
 * The name is defined once and automatically injected into the tool,
 * eliminating the need to repeat it in the tool definition.
 *
 * Provides full type inference from Zod schemas - input and output types
 * are automatically inferred from inputSchema and outputSchema.
 *
 * @param name - Unique tool name
 * @param factory - Factory function that receives dependencies and returns a tool (without name)
 * @returns Tool factory with full type inference
 *
 * @example
 * const myTool = createToolFactory('my-tool', (deps) => ({
 *   description: 'Does something',
 *   category: 'utilities',
 *   inputSchema: z.object({ count: z.number() }),
 *   outputSchema: z.object({ result: z.string() }),
 *   execute: async (input) => {
 *     // input is typed as { count: number }
 *     // return type must be { result: string }
 *     return { result: String(input.count) };
 *   }
 * }));
 */
export declare function createToolFactory<TInputSchema extends z.ZodTypeAny, TDeps, TOutputSchema extends z.ZodTypeAny | undefined = undefined, TInput = z.input<TInputSchema>, TOutput = TOutputSchema extends z.ZodTypeAny ? z.infer<TOutputSchema> : any>(name: string, factory: (deps: TDeps) => {
    description: string;
    category: ToolCategory;
    defaultPermission?: PermissionLevel;
    readOnly?: boolean;
    skipOutputLimit?: (output: TOutput) => boolean;
    inputSchema: TInputSchema;
    outputSchema?: TOutputSchema;
    onCall?: (input: TInput, options?: ToolExecutionOptions) => void | Promise<void>;
    execute: (input: TInput, options: ToolExecutionOptions) => Promise<TOutput>;
    toModelOutput?: ToolParams<TInput, TOutput>["toModelOutput"];
    getRequiredPermissions?: (input: TInput) => Promise<AiToolPermission[]> | AiToolPermission[];
    getActionName?: (input?: TInput) => {
        future: string;
        present: string;
        past: string;
    };
    formatInput?: (input: TInput) => {
        targets: string[];
        details?: string;
        summary?: string;
    };
    getSummary?: (input: TInput, output: TOutput) => CompactionSummary;
}): ToolFactory<TDeps, Tool<TInput, TOutput>>;
/**
 * Context passed to access control rules.
 *
 * Contains information about the execution environment, user, session, etc.
 */
export interface AccessControlContext {
    /** Subagent */
    subagent?: SubagentType;
    /** User ID */
    userId?: string;
    /** Session ID */
    sessionId?: string;
    /** User role */
    userRole?: string;
    /** Current AI mode (undefined defaults to BUILD) */
    mode?: AiMode;
    /** Detailed plan context information */
    planContext?: PlanContext;
    /** Integrations explicitly tagged or selected by the user */
    availableIntegrations?: PromptContextIntegration[];
    /** Entities explicitly tagged by the user in the prompt */
    taggedEntities?: PromptContextEntity[];
    /** Whether read access permission prompts are enabled for Clark AI */
    enableClarkAiReadAccessPermission?: boolean;
    /** Additional context properties */
    [key: string]: any;
}
/**
 * Access control rule function.
 *
 * Returns the permission level for a tool execution.
 * Rules are evaluated in order, most restrictive wins.
 */
export type AccessControlRule = (tool: Tool, context: AccessControlContext, input?: any) => PermissionLevel | Promise<PermissionLevel>;
/**
 * Handler for prompting user for confirmation.
 *
 * Called when a tool requires user approval before execution.
 * Should show a confirmation dialog and return user's decision.
 *
 * The handler receives the complete tool object, allowing access to:
 * - tool.name, tool.description, tool.category for context
 * - tool.getActionName() for tense-based display (if defined)
 * - tool.formatInput(input) for human-readable input summary (if defined)
 * - tool.getRequiredPermissions(input) to see what entities will be accessed (if defined)
 *
 * Returns:
 * - ALLOW: Execute once, don't store permission
 * - ALWAYS_ALLOW: Execute and store permission for future use (with alwaysAllowPermissions indicating which specific permissions to store)
 * - DENY: Block execution
 */
export type PromptHandler = (tool: Tool, input: any, permissions: AiToolPermission[], context: AccessControlContext, options?: ToolExecutionOptions) => Promise<void>;
/**
 * Middleware function that can transform tools.
 * Receives the tool name and tool instance, returns transformed tool.
 */
export type ToolMiddleware = (tool: Tool) => Tool;
/**
 * Result of tool execution.
 */
export type ToolExecutionResult<Output = any> = ToolExecutionSuccessResult<Output> | ToolExecutionErrorResult;
export type ToolExecutionSuccessResult<Output = any> = {
    type: "success";
    data: Output;
};
export type ToolExecutionErrorResult = {
    type: "error";
    error: ToolExecutionError;
};
/**
 * Severity level for tool execution errors.
 * Used to determine the appropriate log level.
 */
export type ToolExecutionErrorSeverity = "info" | "warn" | "error";
export interface ToolExecutionErrorOptions {
    toolName: string;
    input: any;
    context: AccessControlContext;
    cause?: unknown;
    code?: AiToolExecutionErrorCode;
    /** Severity level for logging. Defaults to "error" if not specified. */
    severity?: ToolExecutionErrorSeverity;
}
export declare class ToolExecutionError extends Error {
    readonly name: string;
    readonly options?: ToolExecutionErrorOptions;
    private _message?;
    constructor(message: string, options?: ToolExecutionErrorOptions);
    constructor(options?: ToolExecutionErrorOptions);
    private getMessage;
    /**
     * Returns only the descriptive error text from this error and its cause chain,
     * without serialized input/context. Used to prevent duplication when this error
     * is nested as a cause of another ToolExecutionError.
     */
    private getErrorText;
    get code(): AiToolExecutionErrorCode | undefined;
    get toolName(): string | undefined;
    get severity(): ToolExecutionErrorSeverity;
    get input(): any;
    get message(): string;
    get stack(): string | undefined;
    get cause(): unknown;
    /**
     * Custom JSON serialization to ensure the message getter is included.
     * This is necessary because JSON.stringify doesn't serialize getters by default.
     */
    toJSON(): {
        name: string;
        message: string;
        toolName: string | undefined;
        input: any;
        severity: ToolExecutionErrorSeverity;
        cause: unknown;
        stack: string | undefined;
    };
}
export {};
//# sourceMappingURL=types.d.ts.map