import type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';
import type { ToolHandler } from '../spi/tool.js';
import type { ToolPresentation } from '../tool-presentation.js';
import type { Actor, ToolSpec } from '../types.js';
import { type Catalog, type GenuiStreaming } from './catalog.js';
import { type GenuiChannels } from './channels.js';
import { type DefineSandboxOptions } from './sandbox.js';
import { type GenuiIssue, type JsonSchema } from './schema.js';
import { type TreeLimits, type TreeSchemaMode } from './tree.js';
/** A lib tool: register it with `aiTool(tool)` (AdonisJS) or `registry.register(tool.spec, tool.handler)`. */
export interface GenuiTool {
    spec: ToolSpec & {
        terminal?: boolean;
    };
    handler: ToolHandler;
}
/** What a genui tool returns to the model: what was pushed, and the `ui` frame's id. */
export interface GenuiToolOutput {
    shown: string;
    id: string;
    /** What a check found that did not refuse the call (a prop the kit component does not declare). */
    warnings?: string[];
}
/**
 * Who a catalog is being resolved for. `tenant` is `actor.tenantRef`. `threadId` is absent only
 * when a tool list is built outside a conversation (the MCP server's `tools/list`).
 */
export interface GenuiCatalogScope {
    actor: Actor;
    threadId?: string;
    tenant?: string;
    agentName?: string;
    /** The channel the turn runs on (`web`, `whatsapp`, …), when known. */
    channel?: string;
}
/** Answers which catalog applies to a request — a tenant's own, versioned components. */
export type ResolveGenuiCatalog = (scope: GenuiCatalogScope) => Catalog | Promise<Catalog>;
export interface GenuiToolsOptions {
    /**
     * `tree` (default): a single `ui__render` tool whose input is a nested `{ type, props, children }`
     * tree composed from the catalog (json-render's nested shape). A tree of one component with no
     * children is pushed as that component, exactly as its `ui__show_*` tool would push it.
     * `per-component`: one tool per model-facing component, `ui__show_<snake>`, whose input IS the
     * component's props — for small models, or when each tool should carry its exact schema. Layouts
     * (`children: true`) get none: they can only be composed in a tree.
     */
    mode?: 'per-component' | 'tree';
    /**
     * How the tree tool's input schema describes the nodes (see {@link treeJsonSchema}): `'strict'`
     * (default) — a recursive union by `type` with each component's exact props; `'loose'` — one
     * generic node shape, for a provider that refuses `$ref` in tool parameters.
     */
    treeSchema?: TreeSchemaMode;
    /**
     * The model's turn ends once a genui call succeeds — no further model call to narrate what the UI
     * already shows. Stamped as `spec.terminal`.
     */
    terminal?: boolean;
    /** Tool-name prefix for `per-component`. Default `ui__show_`. */
    namePrefix?: string;
    /** Tool name for `tree`. Default `ui__render`. */
    treeToolName?: string;
    /** Extra text prepended to the tree tool's description (when to call it, house rules). */
    treeInstructions?: string;
    /**
     * Tree mode: components that ALSO get a tool of their own whose input IS their props —
     * `componentTools: ['Sandbox']` adds `ui__sandbox`. For a big component a model writes on its
     * own (the sandbox): with no tree to nest it in, there is no `{ type, props }` envelope to leave
     * out. It still streams (`partialProps`) and may still be nested in a `ui__render` tree.
     */
    componentTools?: readonly string[];
    /** Tool-name prefix for {@link componentTools}. Default `ui__` (`Sandbox` → `ui__sandbox`). */
    componentToolPrefix?: string;
    /** Size limits for `tree`. */
    treeLimits?: TreeLimits;
    /**
     * Tree mode: whether the layout is drawn WHILE the model writes it.
     *
     * - `'complete'` (default): nothing is drawn until the call has run; then the validated tree
     *   appears whole.
     * - `'partial'`: the server parses the streaming `ui__render` arguments and pushes the tree so far
     *   as `partial` `ui` frames under the id the final push replaces — throttled, unvalidated, never
     *   persisted, never sent to a text channel. Nodes still being written are flagged `incomplete`; a
     *   component declared `streaming: 'complete'` is a `held` placeholder until its subtree closes.
     *
     * A component's own {@link ComponentDefinition.streaming} overrides this per component.
     */
    streaming?: GenuiStreaming;
    /** Least time between two partial tree frames of one call, in ms. Default 100. */
    streamingThrottleMs?: number;
    /**
     * Also offer ONE generic tool taking `{ component, props }`, validated against the (resolved)
     * catalog — how a model reaches components that only exist per request (a tenant's own), which a
     * boot-time tool list cannot name. `true` names it `ui__show`; a string names it.
     */
    showTool?: boolean | string;
    /** Extra text prepended to the show tool's description. */
    showInstructions?: string;
    /** Roles allowed to call the tools (the `ToolSpec.roles` gate). Undefined → the roles policy default. */
    roles?: string[];
    /**
     * The authorization ability the UI tools declare (`ToolSpec.ability`) — what an ability-aware
     * authorizer (`authzToolAuthorizer` from `@adonis-agora/agent/authz`) checks the actor against.
     * Under such an authorizer a tool with no ability is denied, so without this the UI tools are
     * never offered. A string for every tool; a map by tool name (`{ ui__render: 'genui.render',
     * ui__sandbox: 'genui.sandbox' }`, a tool it does not name declares none); or a function of the
     * tool name and the component it shows (`undefined` for the tree and show tools). The authorizer
     * still decides: nothing is allowed by default.
     */
    ability?: GenuiAbility;
    /** Override the generated presentation per component (or for the tree / show tool, under its tool name). */
    presentation?: (component: string) => ToolPresentation | undefined;
    /**
     * The catalog for THIS request, consulted when a call is validated and when the turn's tool list
     * is described to the model. The `catalog` argument is then the boot-time one: it names the
     * per-component tools and is what a list built without a resolver would show. Omit → the
     * `catalog` argument serves every request.
     */
    resolveCatalog?: ResolveGenuiCatalog;
    /**
     * Per-channel generative UI (see {@link GenuiChannels}): each entry sets the mode, streaming,
     * sandbox and rendering of one channel (`web`, `mobile`, `whatsapp`, `telegram`, `email`, or
     * `default` for the rest), over the top-level options. The tools of every mode in use are
     * registered; each turn is offered only those of its channel's mode, described with what that
     * channel can draw. Omitted → every channel is served by the top-level options, as before.
     */
    channels?: GenuiChannels;
    /**
     * The sandbox setting a channel without its own falls back to (`genui({ sandbox })` passes it).
     * Only read with {@link channels}: the sandbox itself is a component of `catalog`.
     */
    sandbox?: boolean | DefineSandboxOptions;
    /**
     * Generative-UI telemetry (see `ToolSpec.genui`): every UI call is recorded with its metadata —
     * tool, channel, mode, attempt, validity, error category, tokens and cost, time to first and to
     * complete frame. NEVER the generated HTML/JSX or props, unless `samplePayloads: true` (for
     * debugging; off by default — keep it off where the UI may show personal data). `false` records
     * nothing.
     */
    telemetry?: GenuiTelemetryOptions | false;
}
/** {@link GenuiToolsOptions.telemetry}. */
export interface GenuiTelemetryOptions {
    /** Also store each call's input (the generated code and props). Default `false`. */
    samplePayloads?: boolean;
}
/** The default name of the generic show tool ({@link GenuiToolsOptions.showTool}). */
export declare const GENUI_SHOW_TOOL = "ui__show";
/**
 * Tools that let a model push catalog components into the conversation as `ui` frames. Each call
 * validates its input against the catalog (a refused call reaches the model as a tool error it can
 * fix) and then pushes through `ctx.emitUi`, which streams the frame live and persists it on the
 * assistant message.
 */
export declare function genuiTools(catalog: Catalog, options?: GenuiToolsOptions): GenuiTool[];
/** {@link GenuiToolsOptions.ability}: one ability, one per tool name, or a function of the tool. */
export type GenuiAbility = string | Readonly<Record<string, string>> | ((tool: {
    name: string;
    component?: string;
}) => string | undefined);
/** The ability a UI tool declares, from {@link GenuiToolsOptions.ability}. */
export declare function genuiToolAbility(ability: GenuiAbility | undefined, tool: {
    name: string;
    component?: string;
}): string | undefined;
/** The show tool's input: a component name (one of the catalog's) and its props. */
export declare function showToolJsonSchema(catalog: Catalog): JsonSchema;
type JsonStandardSchema = StandardSchemaV1 & StandardJSONSchemaV1;
/**
 * A JSON Schema presented as a Standard Schema WITH the Standard JSON Schema extension, so the lib
 * validates tool input through `~standard.validate` and the AI SDK adapter hands the model the
 * schema itself (it reads `~standard.jsonSchema.input`).
 */
export declare function jsonStandardSchema(schema: JsonSchema, validate: (value: unknown) => GenuiIssue[]): JsonStandardSchema;
export {};
//# sourceMappingURL=tools.d.ts.map