import type { Catalog } from './catalog.js';
import { type GenuiValidation, type JsonSchema } from './schema.js';
/**
 * One node of a composed UI: a catalog component, its props, and — for components declared with
 * `children: true` — nested nodes. The shape json-render calls a "nested element", so a tree
 * converts to a json-render flat spec with {@link treeToFlatSpec}.
 */
export interface GenuiElement {
    type: string;
    props: Record<string, unknown>;
    children?: GenuiElement[];
}
/**
 * The `ui` frame component a tree-mode tool pushes: `{ component: GENUI_TREE_COMPONENT, props: {
 * root } }`. Not a valid component name, so it can never collide with a catalog entry.
 */
export declare const GENUI_TREE_COMPONENT = "genui:tree";
/** Props of a {@link GENUI_TREE_COMPONENT} frame. */
export interface GenuiTreeProps {
    root: GenuiElement;
}
export interface TreeLimits {
    /** Deepest nesting accepted. Default 12. */
    maxDepth?: number;
    /** Most nodes accepted in one tree. Default 200. */
    maxNodes?: number;
}
/**
 * Validate a model-composed tree against the catalog: every node's `type` must be a model-facing
 * component, its props must pass that component's schema, and only components declared with
 * `children: true` may have children. Returns the tree with each node's props as its schema
 * produced them (defaults applied by a Standard Schema, for instance).
 *
 * Lenient where what the model meant is unambiguous ({@link normalizeElement}):
 *  - a `children` array, a node's `props` — or the whole tree — sent as a JSON STRING (sometimes
 *    with a stray trailing `}`, or `>` for a key's `:` — {@link repairKeyArrows}) is parsed back;
 *  - a node that left out its `type` (`{ props: { html, css } }`, or the bare props `{ html, css }`)
 *    is the ONE component whose props schema those keys fit — every key one of its properties,
 *    every required one present; with two candidates (or none) it is still refused;
 *  - a node whose props sit beside its `type` (`{ type: 'Sandbox', html }`) gets them as `props`;
 *  - a whole element wrapped in one more key (`{ props: { type, props } }`, `{ root: "{…}" }`) is
 *    unwrapped when what it wraps names a component, and a component named under `component` or
 *    `root` instead of `type` is read from there.
 */
export declare function validateTree(catalog: Catalog, tree: unknown, limits?: TreeLimits, phase?: 'input' | 'output'): Promise<GenuiValidation<GenuiElement>>;
/**
 * How exactly a tree-mode tool's input is described to the model ({@link treeJsonSchema}):
 *
 * - `'strict'` (default): every node's `props` is its component's own props schema, and `children`
 *   is a discriminated union by `type` over the components — each variant with its exact props, and
 *   `children` only on components that take them (recursive, through `$defs` / `$ref`).
 * - `'loose'`: one `{ type, props: object, children }` node shape — for a provider that refuses
 *   `$ref` in tool parameters. The props are then only described in the tool's text.
 */
export type TreeSchemaMode = 'strict' | 'loose';
/**
 * The JSON Schema of a tree-mode tool's input. Whatever it says, {@link validateTree} remains the
 * check every call goes through: a provider is free to ignore the schema.
 *
 * Strict (the default), it is shaped for what the providers accept in tool parameters:
 *  - the root is a plain `type: 'object'` — OpenAI and Anthropic both refuse a union at the top
 *    level of a tool's parameters — whose `type` lists every component and whose `props` is any of
 *    their props schemas;
 *  - every `children` item is `{ $ref: '#/$defs/node' }`, an `anyOf` of one variant per component
 *    (`type` a one-value `enum`, `props` that component's schema, `children` only where taken,
 *    `additionalProperties: false`);
 *  - a component whose props schema is not self-contained (it carries its own `$ref`, `$defs` or
 *    `definitions`, as a recursive Zod schema does) is described as `{ type: 'object' }`, since its
 *    references would not resolve once embedded; `$schema` is dropped.
 */
export declare function treeJsonSchema(catalog: Catalog, options?: {
    schema?: TreeSchemaMode;
}): JsonSchema;
/** A json-render flat spec: `{ root, elements: { [id]: { type, props, children: id[] } } }`. */
export interface FlatSpec {
    root: string;
    elements: Record<string, {
        type: string;
        props: Record<string, unknown>;
        children: string[];
    }>;
}
/** Convert a tree to a json-render flat spec (ids are `el-0`, `el-1`, … in depth-first order). */
export declare function treeToFlatSpec(root: GenuiElement): FlatSpec;
/**
 * A node as the model plainly meant it (see {@link validateTree}): `props` parsed from a string,
 * props written beside `type` moved under it, and a missing `type` inferred from the props when
 * exactly one component's schema fits them. Anything else is returned as it came, to be refused.
 */
export declare function normalizeElement(catalog: Catalog, node: Record<string, unknown>, depth?: number): Record<string, unknown>;
/**
 * A tree-mode call's arguments as the model meant them — the leniency {@link validateTree} applies
 * (a stringified tree, a dropped envelope, a wrapper key; see {@link normalizeElement}), all the way
 * down, WITHOUT validating anything. For a client that draws a call from its arguments (CopilotKit
 * renders tool calls, an OpenUI artifact renderer reads them), so it draws the element the server
 * accepted rather than nothing. Safe on half-streamed arguments: what cannot be read yet is left as
 * it came.
 */
export declare function normalizeTreeInput(catalog: Catalog, input: unknown): unknown;
//# sourceMappingURL=tree.d.ts.map