/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { type FunctionDeclaration, type PartListUnion } from '@google/genai';
import { type ToolContext, type ContextAwareTool } from './tool-context.js';
import { ToolErrorType } from './tool-error.js';
import { type DiffUpdateResult } from '../ide/ideContext.js';
import type { MessageBus } from '../confirmation-bus/message-bus.js';
import { PolicyDecision } from '../policy/types.js';
import { ToolConfirmationOutcome, type ToolConfirmationPayload } from './tool-confirmation-types.js';
export { ToolConfirmationOutcome } from './tool-confirmation-types.js';
export type { ToolConfirmationPayload } from './tool-confirmation-types.js';
/**
 * Represents a validated and ready-to-execute tool call.
 * An instance of this is created by a `ToolBuilder`.
 */
export interface ToolInvocation<TParams extends object, TResult extends ToolResult> {
    /**
     * The validated parameters for this specific invocation.
     */
    params: TParams;
    /**
     * Gets a pre-execution description of the tool operation.
     *
     * @returns A markdown string describing what the tool will do.
     */
    getDescription(): string;
    /**
     * Determines what file system paths the tool will affect.
     * @returns A list of such paths.
     */
    toolLocations(): ToolLocation[];
    /**
     * Determines if the tool should prompt for confirmation before execution.
     * @returns Confirmation details or false if no confirmation is needed.
     */
    shouldConfirmExecute(abortSignal: AbortSignal): Promise<ToolCallConfirmationDetails | false>;
    /**
     * Executes the tool with the validated parameters.
     * @param signal AbortSignal for tool cancellation.
     * @param updateOutput Optional callback to stream output.
     * @returns Result of the tool execution.
     */
    execute(signal: AbortSignal, updateOutput?: (output: string) => void): Promise<TResult>;
}
/**
 * A convenience base class for ToolInvocation.
 */
export declare abstract class BaseToolInvocation<TParams extends object, TResult extends ToolResult> implements ToolInvocation<TParams, TResult> {
    readonly params: TParams;
    protected readonly messageBus?: MessageBus | undefined;
    constructor(params: TParams, messageBus?: MessageBus | undefined);
    abstract getDescription(): string;
    toolLocations(): ToolLocation[];
    /**
     * Returns confirmation details for this tool invocation.
     * Tools that require confirmation should override this method.
     * @returns Confirmation details or null if no confirmation needed.
     */
    protected getConfirmationDetails(): ToolCallConfirmationDetails | null;
    /**
     * Requests confirmation through the message bus and policy engine.
     * This integrates with the new policy-based confirmation flow.
     * @param abortSignal Signal to abort the confirmation request
     * @returns Decision from policy engine with requiresUserConfirmation flag
     */
    protected getMessageBusDecision(abortSignal: AbortSignal): Promise<{
        decision: PolicyDecision;
        requiresUserConfirmation?: boolean;
    }>;
    /**
     * Returns the tool name for this invocation.
     * Subclasses can override to provide a specific tool name.
     */
    protected getToolName(): string;
    /**
     * Returns the server name for MCP tools.
     * Regular tools should return undefined.
     */
    protected getServerName(): string | undefined;
    /**
     * Returns metadata used by the policy engine/message bus.
     */
    getPolicyContext(): {
        toolName: string;
        args: Record<string, unknown>;
        serverName?: string;
    };
    shouldConfirmExecute(_abortSignal: AbortSignal): Promise<ToolCallConfirmationDetails | false>;
    abstract execute(signal: AbortSignal, updateOutput?: (output: string) => void): Promise<TResult>;
}
/**
 * A type alias for a tool invocation where the specific parameter and result types are not known.
 */
export type AnyToolInvocation = ToolInvocation<object, ToolResult>;
/**
 * Interface for a tool builder that validates parameters and creates invocations.
 */
export interface ToolBuilder<TParams extends object, TResult extends ToolResult> {
    /**
     * The internal name of the tool (used for API calls).
     */
    name: string;
    /**
     * The user-friendly display name of the tool.
     */
    displayName: string;
    /**
     * Description of what the tool does.
     */
    description: string;
    /**
     * The kind of tool for categorization and permissions
     */
    kind: Kind;
    /**
     * Function declaration schema from @google/genai.
     */
    schema: FunctionDeclaration;
    /**
     * Whether the tool's output should be rendered as markdown.
     */
    isOutputMarkdown: boolean;
    /**
     * Whether the tool supports live (streaming) output.
     */
    canUpdateOutput: boolean;
    /**
     * Validates raw parameters and builds a ready-to-execute invocation.
     * @param params The raw, untrusted parameters from the model.
     * @returns A valid `ToolInvocation` if successful. Throws an error if validation fails.
     */
    build(params: TParams): ToolInvocation<TParams, TResult>;
}
/**
 * New base class for tools that separates validation from execution.
 * New tools should extend this class.
 */
export declare abstract class DeclarativeTool<TParams extends object, TResult extends ToolResult> implements ToolBuilder<TParams, TResult> {
    readonly name: string;
    readonly displayName: string;
    readonly description: string;
    readonly kind: Kind;
    readonly parameterSchema: unknown;
    readonly isOutputMarkdown: boolean;
    readonly canUpdateOutput: boolean;
    protected messageBus?: MessageBus;
    constructor(name: string, displayName: string, description: string, kind: Kind, parameterSchema: unknown, isOutputMarkdown?: boolean, canUpdateOutput?: boolean, messageBus?: MessageBus);
    /**
     * Sets the message bus for this tool.
     * Called by ToolRegistry after tool construction.
     */
    setMessageBus(messageBus: MessageBus): void;
    get schema(): FunctionDeclaration;
    /**
     * Validates the raw tool parameters.
     * Subclasses should override this to add custom validation logic
     * beyond the JSON schema check.
     * @param params The raw parameters from the model.
     * @returns An error message string if invalid, null otherwise.
     */
    validateToolParams(_params: TParams): string | null;
    /**
     * The core of the new pattern. It validates parameters and, if successful,
     * returns a `ToolInvocation` object that encapsulates the logic for the
     * specific, validated call.
     * @param params The raw, untrusted parameters from the model.
     * @returns A `ToolInvocation` instance.
     */
    abstract build(params: TParams): ToolInvocation<TParams, TResult>;
    /**
     * A convenience method that builds and executes the tool in one step.
     * Throws an error if validation fails.
     * @param params The raw, untrusted parameters from the model.
     * @param signal AbortSignal for tool cancellation.
     * @param updateOutput Optional callback to stream output.
     * @returns The result of the tool execution.
     */
    buildAndExecute(params: TParams, signal: AbortSignal, updateOutput?: (output: string) => void): Promise<TResult>;
    /**
     * Similar to `build` but never throws.
     * @param params The raw, untrusted parameters from the model.
     * @returns A `ToolInvocation` instance.
     */
    private silentBuild;
    /**
     * A convenience method that builds and executes the tool in one step.
     * Never throws.
     * @param params The raw, untrusted parameters from the model.
     * @params abortSignal a signal to abort.
     * @returns The result of the tool execution.
     */
    validateBuildAndExecute(params: TParams, abortSignal: AbortSignal): Promise<ToolResult>;
}
/**
 * New base class for declarative tools that separates validation from execution.
 * New tools should extend this class, which provides a `build` method that
 * validates parameters before deferring to a `createInvocation` method for
 * the final `ToolInvocation` object instantiation.
 */
export declare abstract class BaseDeclarativeTool<TParams extends object, TResult extends ToolResult> extends DeclarativeTool<TParams, TResult> {
    build(params: TParams): ToolInvocation<TParams, TResult>;
    validateToolParams(params: TParams): string | null;
    protected validateToolParamValues(_params: TParams): string | null;
    protected abstract createInvocation(params: TParams, messageBus?: MessageBus): ToolInvocation<TParams, TResult>;
}
/**
 * A type alias for a declarative tool where the specific parameter and result types are not known.
 */
export type AnyDeclarativeTool = DeclarativeTool<object, ToolResult>;
/**
 * Type guard to check if an object is a Tool.
 * @param obj The object to check.
 * @returns True if the object is a Tool, false otherwise.
 */
export declare function isTool(obj: unknown): obj is AnyDeclarativeTool;
export interface ToolResult {
    /**
     * Content meant to be included in LLM history.
     * This should represent the factual outcome of the tool execution.
     */
    llmContent: PartListUnion;
    /**
     * Markdown string for user display.
     * This provides a user-friendly summary or visualization of the result.
     * NOTE: This might also be considered UI-specific and could potentially be
     * removed or modified in a further refactor if the server becomes purely API-driven.
     * For now, we keep it as the core logic in ReadFileTool currently produces it.
     */
    returnDisplay: ToolResultDisplay;
    /**
     * Optional metadata about the tool execution
     */
    metadata?: Record<string, unknown>;
    /**
     * If this property is present, the tool call is considered a failure.
     */
    error?: {
        message: string;
        type?: ToolErrorType;
    };
}
/**
 * Detects cycles in a JSON schemas due to `$ref`s.
 * @param schema The root of the JSON schema.
 * @returns `true` if a cycle is detected, `false` otherwise.
 */
export declare function hasCycleInSchema(schema: object): boolean;
export type ToolResultDisplay = string | FileDiff;
export interface FileDiff {
    fileDiff: string;
    fileName: string;
    originalContent: string | null;
    newContent: string;
    diffStat?: DiffStat;
}
export interface DiffStat {
    ai_removed_lines: number;
    ai_added_lines: number;
    user_added_lines: number;
    user_removed_lines: number;
}
export interface ToolEditConfirmationDetails {
    type: 'edit';
    title: string;
    onConfirm: (outcome: ToolConfirmationOutcome, payload?: ToolConfirmationPayload) => Promise<void>;
    fileName: string;
    filePath: string;
    fileDiff: string;
    originalContent: string | null;
    newContent: string;
    isModifying?: boolean;
    ideConfirmation?: Promise<DiffUpdateResult>;
    correlationId?: string;
}
export interface ToolExecuteConfirmationDetails {
    type: 'exec';
    title: string;
    onConfirm: (outcome: ToolConfirmationOutcome) => Promise<void>;
    command: string;
    rootCommand: string;
    correlationId?: string;
}
export interface ToolMcpConfirmationDetails {
    type: 'mcp';
    title: string;
    serverName: string;
    toolName: string;
    toolDisplayName: string;
    onConfirm: (outcome: ToolConfirmationOutcome) => Promise<void>;
    correlationId?: string;
}
export interface ToolInfoConfirmationDetails {
    type: 'info';
    title: string;
    onConfirm: (outcome: ToolConfirmationOutcome) => Promise<void>;
    prompt: string;
    urls?: string[];
    correlationId?: string;
}
export type ToolCallConfirmationDetails = ToolEditConfirmationDetails | ToolExecuteConfirmationDetails | ToolMcpConfirmationDetails | ToolInfoConfirmationDetails;
export declare enum Kind {
    Read = "read",
    Edit = "edit",
    Delete = "delete",
    Move = "move",
    Search = "search",
    Execute = "execute",
    Think = "think",
    Fetch = "fetch",
    Other = "other"
}
export interface ToolLocation {
    path: string;
    line?: number;
}
/**
 * Legacy BaseTool class for backward compatibility with existing LLxprt tools.
 * New tools should use BaseDeclarativeTool instead.
 * @deprecated Use BaseDeclarativeTool for new tools
 */
export declare abstract class BaseTool<TParams extends object, TResult extends ToolResult> extends DeclarativeTool<TParams, TResult> implements ContextAwareTool {
    context?: ToolContext;
    constructor(name: string, displayName: string, description: string, kind: Kind, parameterSchema: unknown, isOutputMarkdown?: boolean, canUpdateOutput?: boolean);
    /**
     * Get the schema for this tool. Maintains backward compatibility.
     */
    get schema(): FunctionDeclaration;
    /**
     * Legacy method signature for getDescription.
     * Subclasses can override this method.
     */
    getDescription(_params: TParams): string;
    /**
     * Legacy method signature for validateToolParams.
     * Subclasses can override this method.
     * Note: The base class expects TParams, but legacy tools pass unknown.
     */
    validateToolParams(params: TParams): string | null;
    /**
     * Legacy validateToolParams method that accepts unknown params.
     * This maintains compatibility with existing tool implementations.
     */
    validateToolParamsLegacy?(params: unknown): string | null;
    /**
     * Legacy execute method signature.
     * Subclasses should implement this method.
     */
    abstract execute(params: TParams, signal: AbortSignal, updateOutput?: (output: string) => void): Promise<TResult>;
    /**
     * Implementation of the new declarative pattern.
     * Creates a tool invocation that bridges to the legacy execute method.
     */
    build(params: TParams): ToolInvocation<TParams, TResult>;
}
