import type { StandardSchemaV1 } from '@standard-schema/spec';
import type { AiToolCtx, ToolHandler } from './spi/tool.js';
import type { ToolPresentation } from './tool-presentation.js';
import type { Actor, ToolSpec } from './types.js';
/**
 * The symbol the `@AiTool` decorator stamps its options onto (the tool class), read back by
 * discovery to register the class into the {@link import('./tool-registry.js').ToolRegistry}. A
 * global-registry symbol (`Symbol.for`) so it survives duplicate copies of this package in a tree.
 */
export declare const AI_TOOL_META_KEY: unique symbol;
/**
 * Brand stamped on the object {@link defineTool} returns so discovery picks it up when it walks a
 * module's exports — the functional alternative to an `@AiTool` class.
 */
export declare const AGENT_TOOL_BRAND: unique symbol;
export interface AiToolOptions {
    /**
     * What the model calls it. Omit on a class → the class name, camelCased, with a trailing `Tool`
     * dropped (`GetWeatherTool` → `getWeather`). Required on {@link defineTool}, which has no class.
     */
    name?: string;
    /**
     * `read` auto-executes; `action` requires HITL approval. Default `'read'`. (Core's `ToolKind` also
     * has `agent` for delegation, but that kind is synthesized from an agent's `delegatesTo` — never
     * authored here.)
     */
    kind?: 'read' | 'action';
    description: string;
    /**
     * Input schema as a [Standard Schema](https://standardschema.dev) — Zod, Valibot, or ArkType.
     * Validated (again) before the handler runs.
     */
    input: StandardSchemaV1;
    /** Roles allowed to invoke. Omit to inherit the config's `defaultRoles` (unrestricted by default). */
    roles?: string[];
    /**
     * Authz ability checked by an ability-aware `RolesPolicy` (e.g. an `@adonis-agora/authz` Bouncer
     * adapter → `bouncer.forUser(actor).allows(ability)`). Ignored by the default role-based policy.
     */
    ability?: string;
    /**
     * Whether this tool exists in this deployment. `false` — or a predicate returning `false`, which
     * is re-evaluated every turn — drops it before the role filter, so the model is never shown it.
     * Omit → enabled.
     *
     * Use this for availability that is knowable without the container (a constant, `env.get(...)`, a
     * closure over something the app already holds). When the answer lives in an injected service,
     * implement `isEnabled()` on the tool class instead: this object is built at import time and
     * cannot reach the container.
     */
    enabled?: boolean | (() => boolean | Promise<boolean>);
    /**
     * How a chat surface talks about this tool without naming it — sentence templates over the call's
     * input, an icon key, the approval prompt's wording, and how its output reads. Never shown to the
     * model. Served by `GET <path>/tools` to the actors who can reach the tool:
     *
     * ```ts
     * presentation: {
     *   label: 'Cache purge', running: 'Purging {key}', done: 'Purged {key}', icon: 'cache',
     *   tone: 'destructive', confirm: { title: 'Purge {key}?', verb: 'Purge' },
     * }
     * ```
     */
    presentation?: ToolPresentation;
    replacementKey?: ToolSpec['replacementKey'];
    /** A successful call ends the turn — no model call narrates what it already showed. */
    terminal?: boolean;
}
/**
 * The metadata a tool class carries for discovery + registration — from `@AiTool` or `static tool` —
 * with the defaults applied.
 */
export type AiToolMeta = AiToolOptions & {
    name: string;
    kind: 'read' | 'action';
};
/** `GetWeatherTool` → `getWeather`; `SQLQueryTool` → `sqlQuery`. */
export declare function toolNameFromClass(className: string): string;
/** Structural shape of a tool class: a constructor whose instance implements `execute`. */
export type ToolClass = abstract new (...args: never[]) => ToolHandler;
/**
 * Marks a class as an AI tool. The class must implement `execute(input, ctx)`. The provider's
 * `app/agent_tools` discovery (or the generated `hooks/tools` barrel) registers every `@AiTool`
 * class into the shared `ToolRegistry` at boot.
 *
 * ```ts
 * @AiTool({ name: 'getWeather', kind: 'read', description: '...', input: z.object({ city: z.string() }) })
 * export default class GetWeatherTool implements ToolHandler<{ city: string }> {
 *   async execute(input: { city: string }, ctx: AiToolCtx) { return { tempC: 21 } }
 * }
 * ```
 */
export declare function AiTool(options: AiToolOptions): <T extends ToolClass>(target: T) => T;
/**
 * Read a tool class's {@link AiToolMeta}. Two authoring forms are supported:
 *
 * 1. The `@AiTool({ … })` decorator (stamps {@link AI_TOOL_META_KEY}).
 * 2. A decorator-free `static tool = { name, kind, description, input, … }` config on the class — the
 *    same shape, mirroring `@adonis-agora/durable`'s `static workflow`. Preferred where you'd rather
 *    not rely on decorators.
 *
 * Accepts either the class itself or an instance: each mechanism is tried on the value, then on its
 * constructor (so an instance resolves the class's metadata).
 */
export declare function readAiToolMeta(target: unknown): AiToolMeta | undefined;
/**
 * What {@link defineTool} takes: the `@AiTool` options with a required `name`, plus the per-actor
 * gate a class would implement as a `canUse()` method.
 */
export interface DefineToolOptions extends AiToolOptions {
    name: string;
    /**
     * Whether THIS actor may use the tool, decided per turn — after `enabled` and the `RolesPolicy`,
     * on both the offered list and the invoke. For a decision the app-wide policy cannot express (the
     * actor's plan, an entitlement row, ownership of the record). Omit → the role gate alone decides.
     */
    canUse?: (actor: Actor) => boolean | Promise<boolean>;
}
/** A tool expressed as data + handler (from {@link defineTool}), not an `@AiTool` class. */
export interface FunctionalTool {
    spec: ToolSpec;
    handler: ToolHandler;
}
/** A {@link FunctionalTool} carrying {@link AGENT_TOOL_BRAND} — what {@link defineTool} returns. */
export interface BrandedFunctionalTool extends FunctionalTool {
    readonly [AGENT_TOOL_BRAND]: true;
}
/** Narrows an arbitrary module export to a branded functional tool for boot-time registration. */
export declare function isBrandedFunctionalTool(value: unknown): value is BrandedFunctionalTool;
/**
 * The functional form of a tool: pass the same options as `@AiTool` plus an `execute` function, get
 * back a branded `{ spec, handler }` that discovery auto-registers. Export it from an `app/agent_tools`
 * module (or pass it to `defineConfig({ tools })`).
 *
 * ```ts
 * export const purgeCache = defineTool(
 *   { name: 'purgeCache', kind: 'action', description: '...', input: z.object({ key: z.string() }) },
 *   async ({ key }, ctx) => { ... },
 * )
 * ```
 */
export type DefineToolObjectOptions<S extends StandardSchemaV1, O> = Omit<DefineToolOptions, 'input'> & {
    input: S;
} & ToolHandler<StandardSchemaV1.InferOutput<S>, O>;
export declare function defineTool<S extends StandardSchemaV1, O>(options: DefineToolObjectOptions<S, O>): BrandedFunctionalTool;
export declare function defineTool<I = unknown, O = unknown>(options: DefineToolOptions, execute: ((input: I, ctx: AiToolCtx) => Promise<O> | O) | ToolHandler<I, O>): BrandedFunctionalTool;
//# sourceMappingURL=ai-tool-ref.d.ts.map