import { InferSchemaType, JSONSchema, SchemaInput, Tool, ToolExecuteFunction } from '../../../types.js';
import { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';
/**
 * Type-level brand key for {@link ToolApprovalCapabilityMarker}. Only ever used
 * in type positions, but it must stay exported: a `unique symbol` referenced by
 * an exported interface has to be nameable in the emitted declarations.
 *
 * @public
 */
export declare const toolApprovalCapability: unique symbol;
export interface ToolApprovalCapabilityMarker<TNeedsApproval extends boolean, TApprovalSchema> {
    readonly [toolApprovalCapability]?: {
        needsApproval: TNeedsApproval;
        approvalSchema: TApprovalSchema;
    };
}
export type ApprovalSchemaConfig = SchemaInput | {
    approve: SchemaInput;
    reject?: SchemaInput;
} | {
    approve?: SchemaInput;
    reject: SchemaInput;
};
type ApprovalConfig<TNeedsApproval extends boolean, TApprovalSchema extends ApprovalSchemaConfig | undefined> = TNeedsApproval extends true ? {
    needsApproval: TNeedsApproval;
    approvalSchema?: TApprovalSchema;
} : {
    needsApproval?: TNeedsApproval;
    approvalSchema?: never;
};
export type ApprovalCapabilityOf<TTool> = TTool extends ToolApprovalCapabilityMarker<infer TNeeds, unknown> ? TNeeds : false;
export type ApprovalSchemaOf<TTool> = TTool extends ToolApprovalCapabilityMarker<boolean, infer TSchema> ? TSchema : undefined;
export declare const noSchema: unique symbol;
export type NoSchema = typeof noSchema;
export type InputSchemaOf<TTool> = TTool extends {
    inputSchema: infer TInput;
} ? TInput extends undefined ? NoSchema : TInput : NoSchema;
export type OutputSchemaOf<TTool> = TTool extends {
    outputSchema: infer TOutput;
} ? TOutput extends undefined ? NoSchema : TOutput : NoSchema;
type BuiltToolSchemaFields<TInput extends SchemaInput | undefined, TOutput extends SchemaInput | undefined, TApprovalSchema extends ApprovalSchemaConfig | undefined> = {
    inputSchema: TInput;
    outputSchema: TOutput;
    approvalSchema: TApprovalSchema;
};
/**
 * Marker type for server-side tools
 */
export interface ServerTool<TInput extends SchemaInput | undefined = undefined, TOutput extends SchemaInput | undefined = undefined, TName extends string = string, TContext = unknown, TNeedsApproval extends boolean = false, TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined> extends Tool<TInput, TOutput, TName, TContext>, ToolApprovalCapabilityMarker<TNeedsApproval, TApprovalSchema> {
    __toolSide: 'server';
    inputSchema?: TInput;
    outputSchema?: TOutput;
    needsApproval?: TNeedsApproval;
    approvalSchema?: TApprovalSchema;
}
/**
 * Marker type for client-side tools
 */
export interface ClientTool<TInput extends SchemaInput | undefined = undefined, TOutput extends SchemaInput | undefined = undefined, TName extends string = string, TContext = unknown, TNeedsApproval extends boolean = false, TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined> extends ToolApprovalCapabilityMarker<TNeedsApproval, TApprovalSchema> {
    __toolSide: 'client';
    name: TName;
    description: string;
    inputSchema?: TInput;
    outputSchema?: TOutput;
    needsApproval?: TNeedsApproval;
    approvalSchema?: TApprovalSchema;
    lazy?: boolean;
    metadata?: Record<string, unknown>;
    execute?: ToolExecuteFunction<TInput, TOutput, TContext>;
}
/** Broad server-tool shape for heterogeneous internal collections. */
export type AnyServerTool = Omit<ServerTool<any, any, string, any, boolean, any>, 'execute'> & {
    execute?: ((args: any, context?: any) => any) | undefined;
};
/**
 * Tool definition that can be used directly or instantiated for server/client
 */
export interface ToolDefinitionInstance<TInput extends SchemaInput | undefined = undefined, TOutput extends SchemaInput | undefined = undefined, TName extends string = string, TContext = unknown, TNeedsApproval extends boolean = false, TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined> extends Tool<TInput, TOutput, TName, TContext> {
    __toolSide: 'definition';
    inputSchema: TInput;
    outputSchema: TOutput;
    needsApproval?: TNeedsApproval;
    approvalSchema: TApprovalSchema;
    readonly [toolApprovalCapability]?: {
        needsApproval: TNeedsApproval;
        approvalSchema: TApprovalSchema;
    };
}
/**
 * Union type for any kind of client-side tool (client tool or definition)
 */
export type AnyClientTool = (Omit<ClientTool<any, any, string, any, boolean, any>, 'execute'> & {
    execute?: ((args: any, context?: any) => any) | undefined;
}) | (Omit<ToolDefinitionInstance<any, any, string, any, boolean, any>, 'execute'> & {
    execute?: ((args: any, context?: any) => any) | undefined;
});
/**
 * Extract the tool name as a literal type
 */
export type InferToolName<T> = T extends {
    name: infer N;
} ? N : never;
/**
 * Extract the input type from a tool (inferred from Standard JSON Schema, or `unknown` for plain JSONSchema)
 */
export type InferToolInput<T> = T extends {
    inputSchema?: infer TInput;
} ? TInput extends JSONSchema ? unknown : InferSchemaType<TInput> : unknown;
/**
 * Extract the output type from a tool (inferred from Standard JSON Schema, or `unknown` for plain JSONSchema)
 */
export type InferToolOutput<T> = T extends {
    outputSchema?: infer TOutput;
} ? TOutput extends StandardJSONSchemaV1<any, any> ? InferSchemaType<TOutput> : TOutput extends StandardSchemaV1<any, any> ? InferSchemaType<TOutput> : TOutput extends JSONSchema ? unknown : InferSchemaType<TOutput> : unknown;
/**
 * Tool definition configuration
 */
export type ToolDefinitionConfig<TInput extends SchemaInput | undefined = undefined, TOutput extends SchemaInput | undefined = undefined, TName extends string = string, TNeedsApproval extends boolean = false, TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined> = {
    name: TName;
    description: string;
    inputSchema?: TInput;
    outputSchema?: TOutput;
    lazy?: boolean;
    metadata?: Record<string, unknown>;
} & ApprovalConfig<TNeedsApproval, TApprovalSchema>;
/**
 * Tool definition builder that allows creating server or client tools from a shared definition
 */
export interface ToolDefinition<TInput extends SchemaInput | undefined = undefined, TOutput extends SchemaInput | undefined = undefined, TName extends string = string, TNeedsApproval extends boolean = false, TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined> extends ToolDefinitionInstance<TInput, TOutput, TName, unknown, TNeedsApproval, TApprovalSchema> {
    /**
     * Create a server-side tool with execute function
     */
    server: <TContext = unknown>(execute: ToolExecuteFunction<TInput, TOutput, TContext>) => ServerTool<TInput, TOutput, TName, TContext, TNeedsApproval, TApprovalSchema> & BuiltToolSchemaFields<TInput, TOutput, TApprovalSchema>;
    /**
     * Create a client-side tool with optional execute function.
     * Carries the definition's `needsApproval` literal through to the client
     * tool so the tool-call part's `approval` field stays gated on it.
     */
    client: <TContext = unknown>(execute?: ToolExecuteFunction<TInput, TOutput, TContext>) => ClientTool<TInput, TOutput, TName, TContext, TNeedsApproval, TApprovalSchema> & BuiltToolSchemaFields<TInput, TOutput, TApprovalSchema>;
}
/**
 * Create an isomorphic tool definition that can be used directly or instantiated for server/client
 *
 * The definition contains all tool metadata (name, description, schemas) and can be:
 * 1. Used directly in chat() on the server (as a tool definition without execute)
 * 2. Instantiated as a server tool with .server()
 * 3. Instantiated as a client tool with .client()
 *
 * Supports any Standard JSON Schema compliant library (Zod v4+, ArkType, Valibot, etc.)
 * or plain JSON Schema objects.
 *
 * @example
 * ```typescript
 * import { toolDefinition } from '@tanstack/ai';
 * import { z } from 'zod';
 *
 * // Using Zod (natively supports Standard JSON Schema)
 * const addToCartTool = toolDefinition({
 *   name: 'addToCart',
 *   description: 'Add a guitar to the shopping cart (requires approval)',
 *   needsApproval: true,
 *   inputSchema: z.object({
 *     guitarId: z.string(),
 *     quantity: z.number(),
 *   }),
 *   outputSchema: z.object({
 *     success: z.boolean(),
 *     cartId: z.string(),
 *     totalItems: z.number(),
 *   }),
 * });
 *
 * // Use directly in chat (server-side, no execute function)
 * chat({
 *   tools: [addToCartTool],
 *   // ...
 * });
 *
 * // Or create server-side implementation
 * const addToCartServer = addToCartTool.server(async (args) => {
 *   // args is typed as { guitarId: string; quantity: number }
 *   return {
 *     success: true,
 *     cartId: 'CART_' + Date.now(),
 *     totalItems: args.quantity,
 *   };
 * });
 *
 * // Or create client-side implementation
 * const addToCartClient = addToCartTool.client(async (args) => {
 *   // Client-specific logic (e.g., localStorage)
 *   return { success: true, cartId: 'local', totalItems: 1 };
 * });
 * ```
 */
export declare function toolDefinition<TInput extends SchemaInput | undefined = undefined, TOutput extends SchemaInput | undefined = undefined, TName extends string = string, const TNeedsApproval extends boolean = false, TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined>(config: ToolDefinitionConfig<TInput, TOutput, TName, TNeedsApproval, TApprovalSchema>): ToolDefinition<TInput, TOutput, TName, TNeedsApproval, TApprovalSchema>;
export {};
