import type{LyraEventDetailSnapshot}from'../../../internal/lyra-element.js';import{type TemplateResult,type PropertyValues}from'lit';import{LyraElement}from'../../../internal/lyra-element.js';import'../../forms/checkbox/checkbox.class.js';import'../../forms/switch/switch.class.js'; /** One selectable agent tool. `id` is the stable, nonempty selection identity; canonicalization * inspects at most the first 10,000 input positions, omits empty ids, and lets the first valid * admitted occurrence of a repeated id win before grouping, searching, counting, or rendering. * `category` groups the row; tools with no `category` (or an empty one) fall into the trailing * localized "Other" bucket. A literal caller category named "Other" remains a separate ordinary * category. */ export interface ToolSelectDialogTool{id:string;name:string;description?:string;category?:string; /** Literal icon hint (e.g. an emoji), rendered next to `name` -- same * "opaque string, not a registry lookup" convention as ``'s `icon`. */ icon?:string; /** Individually gates this tool regardless of `useDefaults`/`selectedToolIds` -- e.g. a tool that * requires admin approval before it can ever be enabled. */ disabled?:boolean; /** Supporting text shown under a `disabled` row (e.g. "requires admin approval"). Ignored when `disabled` is falsy. */ disabledReason?:string;} /** Predicate deciding whether `tool` matches a (already-trimmed, already-lowercased) `query`. * Mirrors ``'s `OptionFilter` convention -- override `filter` to replace the * built-in case-insensitive name/description substring match entirely. */ export type ToolSelectFilter=(tool:ToolSelectDialogTool,query:string)=>boolean; /** The proposed state carried by the cancelable `lr-change` event. */ export interface ToolSelectionChangeDetail{readonly selectedToolIds:readonly string[];readonly useDefaults:boolean;} /** * Reason the dialog was dismissed, forwarded as the `lr-close` event detail * -- mirrors ``'s own `DialogCloseReason` shape. `'escape'`/ * `'backdrop'` come from the dialog's own built-in dismiss triggers (the latter only while * `lightDismiss` is enabled); any * other string is whatever a caller passes to `close()` directly (e.g. a * consumer's own footer Done button). */ export type ToolSelectDialogCloseReason='escape'|'backdrop'|'api'|(string&Record);export interface LyraToolSelectDialogEventMap{'lr-change':CustomEvent>;'lr-close':CustomEvent;blur:CustomEvent;focus:CustomEvent;} /** * `` — a category-grouped, filterable, searchable * tool-enablement dialog for picking which agent tools are available in a * conversation. * * This renders its own dialog panel rather than nesting a `` in * its shadow template. Shared overlay infrastructure coordinates stacking, * focus trapping, Escape dismissal, optional backdrop dismissal, and focus * return with every other overlay in the same document. * * `useDefaults` is a single top-level switch: while `true`, every per-tool * checkbox below renders disabled (still reflecting whatever `selectedToolIds` * holds — a consumer should populate that with its own default tool set * whenever `useDefaults` is true) and a hint explains that turning the * switch off is how to customize. Turning it off is the "customize" * affordance — it's the only thing that both flips `useDefaults` to `false` * *and* unlocks the per-tool checkboxes for editing, so there's exactly one * control for that transition rather than a separate button duplicating it. * * There is no built-in footer/close button — like ``, dismissal * happens via Escape, an opted-in `lightDismiss` backdrop click, or a * consumer's own `footer`-slotted action calling `close()`. This also means the search input is the very * first focusable element in the panel with no special-casing needed, so * it's what receives focus on open (see `updated()`). * * Matching tools mount in user-driven batches of 200. Matching selected identities reserve batch * positions before ordinary input-order matches, so the checked rows behind the controlled * `selectedToolIds` summary remain available without first loading every preceding tool. When more * matches remain, a localized limit notice and Load more button make the bounded projection * explicit and provide a keyboard-reachable continuation; search can independently narrow the * catalog. Both canonical projections inspect at most their first 10,000 input positions. Within * that prefix, a repeated tool id's first valid admitted occurrence wins; selected ids retain * their first nonblank occurrence. Selected ids absent from `tools` remain in that canonical * selection and in `lr-change` proposals, preserving independently managed selection state. * * Public collection properties take bounded, clone-owned readonly snapshots. Create a new * collection and reassign it after changes; mutating the assigned array does not update the view. * Native/prefixed input and change events from the composed checkbox and switch controls stop at * this dialog's boundary, as do their own `lr-checkbox-toggle-request`/`lr-switch-toggle-request` * proposals; consumers receive only the aggregate `lr-change` proposal above. * * @customElement lr-tool-select-dialog * @slot footer - Optional action buttons (e.g. a "Done" button), rendered in a bottom row. * Changes already apply live via `lr-change`, so this is optional. * @event lr-change - A proposed enabled-tool selection or `useDefaults` toggle. * `detail: { selectedToolIds: string[], useDefaults: boolean }`, with `selectedToolIds` from the * canonical first-10,000-input-position selection. Cancelable; preventing it preserves both * properties, and the built-in checkbox or switch never flips at all -- the proposal is raised * from that control's own `lr-checkbox-toggle-request`/`lr-switch-toggle-request`, before it * writes its `checked` state, so a refused change shows no flip-and-snap-back. * @event lr-close - `detail: ToolSelectDialogCloseReason`. Fired exactly once per dismissal, * via Escape, an opted-in backdrop click, or a `close()` call. * @event focus - Re-dispatched when the internal search input receives focus. * @event blur - Re-dispatched when the internal search input loses focus. * @csspart backdrop - The full-viewport scrim behind the panel. * @csspart panel - The dialog panel itself (`role="dialog"` while open). * @csspart header - The wrapper around the title/subtitle. * @csspart title - The dialog's heading. * @csspart subtitle - The "N of M tools enabled" summary line. * @csspart search-row - The wrapper around the search input. * @csspart search-input - The filter text input. * @csspart defaults-row - The wrapper around the use-defaults switch and its hint. * @csspart defaults-toggle - The built-in `` bound to `useDefaults`. * @csspart defaults-hint - The "turn off to customize" hint, shown only while `useDefaults` is true. * @csspart body - The keyboard-focusable scrollable wrapper around the grouped tool list. * @csspart empty - The "no tools" / "no matches" message. * @csspart limit - Localized notice shown while additional matching tools remain unmounted. * @csspart load-more - Button that mounts the next bounded batch of matching tools. * @csspart category - A single category's wrapper (`role="group"`). * @csspart category-heading - A category's heading. * @csspart category-count - The terse, `aria-hidden` tool count next to a category heading * (the heading's accessible name gets the full sentence from an sr-only sibling instead). * @csspart category-list - The `
    ` of tool rows within a category. * @csspart tool-row - A single tool's `
  • ` row. * @csspart tool-checkbox - A row's ``. * @csspart tool-name - A row's name text (plus its `icon`, if set). * @csspart tool-icon - A row's leading icon glyph, when `icon` is set. * @csspart tool-description - A row's optional description text. * @csspart tool-disabled-reason - A disabled row's `disabledReason` text, slotted inside * `tool-checkbox` (alongside `tool-name`/`tool-description`) so it contributes to the * checkbox's accessible name/description instead of going unannounced. * @csspart search-clear - The clear-search button, replacing the native search-cancel glyph the * component resets. Only rendered while the field has text. * @csspart footer - The wrapper around the `footer` slot. * @cssprop [--lr-tool-select-dialog-overlay-color=var(--lr-color-overlay)] - Backdrop scrim color. * @cssprop [--lr-tool-select-dialog-search-min-height=auto] - Minimum row height of the search * field, for matching it to a themed search field of a chosen density tier. Point it at * `--lr-form-control-height-s` (or any tier of that ladder) to line this field up with the rest * of an application's controls. * @cssprop [--lr-tool-select-dialog-search-font-size=inherit] - Text size of the search field. * @cssprop [--lr-tool-select-dialog-search-padding-inline=var(--lr-space-m)] - Leading gutter of * the search field. The trailing gutter is reserved for the overlaid clear button. * @cssprop [--lr-tool-select-dialog-search-padding-block=var(--lr-space-s)] - Block gutter of the * search field. * @cssprop [--lr-tool-select-dialog-search-radius=var(--lr-radius)] - Corner radius of the search * field. * @cssprop [--lr-tool-select-dialog-body-hover-outline-width=var(--lr-border-width-thin)] - * Outline width of the mouse-hover preview on `[part="body"]`. * @cssprop [--lr-tool-select-dialog-body-hover-outline-style=solid] - Outline style of the * mouse-hover preview on `[part="body"]`. * @cssprop [--lr-tool-select-dialog-body-hover-outline-color=var(--lr-color-border)] - Outline * color of the mouse-hover preview on `[part="body"]`. Set to `transparent` to opt out of the * hover treatment entirely. * @cssprop [--lr-tool-select-dialog-body-hover-outline-offset=calc(-1 * var(--lr-border-width-thin))] - * Inward offset of the mouse-hover preview on `[part="body"]`, keeping the outline inside its * own scrollport so it is not clipped at the edge. * @status stable * @since 4.0.0 */ export declare class LyraToolSelectDialog extends LyraElement{protected static readonly ownedCollectionProperties:readonly string[];static styles:import("lit").CSSResultGroup[];protected static readonly immutableEventDetails:readonly string[]; /** Whether the dialog is open. Set this directly or use `show()`/`hide()`/`close()`. */ open:boolean; /** Dismisses the dialog on a backdrop click. Opt-in and `false` by default, matching * ``, ``, and ``. */ lightDismiss:boolean; /** The full set of tools a consumer offers, across all categories. The first 10,000 input * positions are inspected; empty ids are omitted and duplicate ids use a deterministic * first-valid-admitted-occurrence projection. */ tools:readonly ToolSelectDialogTool[]; /** The currently-enabled tool ids. The first 10,000 input positions form the canonicalization * prefix; empty ids are omitted and duplicates are treated as one selection. Ids absent from * `tools` remain independently selected. */ selectedToolIds:readonly string[]; /** Whether the conversation is using the default tool set (`true`) or a custom selection (`false`) — see the class doc for the exact interaction with `selectedToolIds`/per-tool editing. */ useDefaults:boolean; /** The dialog's visible heading and accessible name. Omission uses the localized default; any * supplied string, including `"Select tools"` or an empty string, remains literal. */ label?:string; /** Accessible name for the component. When assigned directly as a property without a host * attribute it names the dialog panel; a host `aria-label` remains on the host and the panel * stays labelled by its visible heading to avoid cloning the same owner. */ accessibleLabel:string|null; /** Search placeholder. Omission uses the localized default; supplied text remains literal even * when it matches the former English default or is empty. An empty/whitespace-only placeholder * leaves the field visually empty while its accessible name falls back to the localized default. */ searchPlaceholder?:string; /** Native editing-assistance and virtual-keyboard hints forwarded to the search input. */ autocomplete:string;spellcheck:boolean;autocapitalize:string;autoCorrect:string;inputMode:string;enterKeyHint:string; /** Overrides the built-in case-insensitive name/description substring match. */ filter:ToolSelectFilter|null;private query;private hasFooterSlot;private renderedToolLimit;private overlay?;private canonicalToolsCache?;private canonicalSelectedToolIdsCache?;private canonicalSelectedToolIdsSource?;private readonly titleId;private readonly categoryIds;protected willUpdate(changed:PropertyValues):void;protected updated(changed:PropertyValues):void;connectedCallback():void;disconnectedCallback():void;private activateOverlay;private onFooterSlotChange; /** * Close the dialog and return focus to whatever had it before the dialog * opened. `reason` is forwarded as the `lr-close` detail — built-in * triggers pass `'escape'`/`'backdrop'` (the latter only when `lightDismiss` is enabled); a * consumer's own close affordance (e.g. a footer Done button) should call this directly with its own * reason string, so every dismissal path funnels through the same event * instead of the consumer having to also toggle `open` itself. */ close(reason?:ToolSelectDialogCloseReason):void; /** Opens the dialog. No-op when already open. */ show():void; /** Closes the dialog through the same reasoned lifecycle as `close()`. */ hide(reason?:ToolSelectDialogCloseReason):void;private onBackdropClick;private emitChange;private onSearchInput;private onSearchFocus;private onSearchBlur;private onClearSearch;private stopNestedControlEvent; /** The composed switch proposes its toggle before writing it, so the aggregate proposal is * raised here and a refused change is vetoed on the child's own request -- the switch then * never slides at all, rather than sliding and being written back a frame later. */ private onDefaultsToggleRequest; /** Same request/veto path as {@link onDefaultsToggleRequest}, for one tool row's checkbox. */ private onToolToggleRequest;private categoryId;private get canonicalTools();private get canonicalSelectedToolIds(); /** Tools grouped by `category` (first-seen order), with an uncategorized * bucket always last, then filtered by the active search query -- a * category left with zero matches is dropped entirely rather than * rendered as an empty heading. */ private get projection();private onLoadMore;private renderTool;private renderCategory;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-tool-select-dialog':LyraToolSelectDialog;}}