Composer Trigger Hooks

Unstable assistant-ui hooks for mention menus, slash commands, and custom composer trigger popovers.

API Reference

unstable_useTriggerPopoverRootContext

const unstable_useTriggerPopoverRootContext: () => TriggerPopoverRootContextValue;

unstable_useTriggerPopoverRootContextOptional

const unstable_useTriggerPopoverRootContextOptional: () => TriggerPopoverRootContextValue | null;

unstable_useTriggerPopoverScopeContext

const unstable_useTriggerPopoverScopeContext: () => TriggerPopoverResourceOutput;

unstable_useTriggerPopoverScopeContextOptional

const unstable_useTriggerPopoverScopeContextOptional: () => TriggerPopoverResourceOutput | null;

unstable_useTriggerPopoverTriggers

Live map of registered triggers, re-rendering on change. Prefer subscribeLifecycle for incremental add/remove handling.

const unstable_useTriggerPopoverTriggers: () => ReadonlyMap<string, RegisteredTrigger>;

unstable_useTriggerPopoverTriggersOptional

Like useTriggerPopoverTriggers but returns an empty map outside a root.

const unstable_useTriggerPopoverTriggersOptional: () => ReadonlyMap<string, RegisteredTrigger>;

unstable_useLiveCompletionAdapter

Tip

Experimental. Under active development and may change without notice.

Bridges an async completion source (a server search, a gateway RPC) into the synchronous Unstable_TriggerAdapter that ComposerTriggerPopover consumes. search(query) returns the last fetched items synchronously and schedules a debounced fetch when the query changes; when results arrive the returned adapter identity changes, which re-runs the popover's lookup so the fresh items render. This is a search-only adapter (categories are empty).

isLoading is true while a fetch is in flight. Pass it to the popover's isLoading prop to render a loading state.

const mentions = unstable_useLiveCompletionAdapter({
  fetcher: (query) => searchUsers(query),
});

<ComposerTriggerPopover
  char="@"
  adapter={mentions.adapter}
  isLoading={mentions.isLoading}
  directive={{ onInserted }}
/>
unstable_useLiveCompletionAdapter
optionsUnstable_UseLiveCompletionAdapterOptions

Unstable_UseLiveCompletionAdapterOptions
fetcher(query: string) => Promise<readonly Unstable_TriggerItem[]>

Fetches the items for a query from an async source. Called debounced; the resolved items are cached and returned synchronously to the popover on the next render.

cacheKey?string | number | undefined

Identifies the fetcher's data source. Change this when switching accounts, workspaces, or another boundary that should invalidate cached results.

debounceMsnumber | undefined= 60

Debounce applied before a fetch fires, in milliseconds.

enabledboolean | undefined= true

When `false`, no fetch is scheduled and the adapter stays empty.

unstable_useMentionAdapter

Tip

Experimental. Under active development and might change without notice.

Creates a spreadable { adapter, directive } bundle for @ mentions. Supports tools registered in model context, explicit items, or both — flat or categorized.

const mention = unstable_useMentionAdapter();
<ComposerTriggerPopover char="@" {...mention} />
unstable_useMentionAdapter
options?Unstable_UseMentionAdapterOptions

Unstable_UseMentionAdapterOptions
items?readonly Unstable_Mention[]

Flat mention list. Ignored when `categories` is set, and keeps the adapter flat when a tool `category` is configured.

categories?readonly Unstable_MentionCategory[]

Categorized mentions for drill-down navigation.

includeModelContextTools?boolean | Unstable_ModelContextToolsOptions

How tools registered in model context integrate. - `false`: exclude. - `true`: include (default when no `items`/`categories`; as a category if `categories` is set, flat otherwise). - object: explicit config; `category` also selects drill-down mode. Omitted → defaults to `true` iff neither `items` nor `categories`.

formatterUnstable_DirectiveFormatter= unstable_defaultDirectiveFormatter

Directive formatter.

Unstable_DirectiveFormatter
serialize(item: Unstable_TriggerItem) => string

Serialize a trigger item to directive text.

parse(text: string) => readonly Unstable_DirectiveSegment[]

Parse text into alternating text and directive segments.

onInserted?(item: Unstable_TriggerItem) => void

Fires after an item is inserted into the composer.

iconMap?Record<string, Unstable_IconComponent>

Maps `metadata.icon` / `category.id` string keys to React components.

fallbackIcon?Unstable_IconComponent

Fallback icon when no entry in `iconMap` matches.

unstable_useSlashCommandAdapter

Tip

Experimental. Under active development and may change without notice.

Bundles slash command definitions (with inline execute callbacks) into {adapter, action} that plug directly into ComposerTriggerPopover. execute stays in the hook closure and is never attached to the returned TriggerItem, keeping items serializable.

const slash = unstable_useSlashCommandAdapter({
  commands: [
    { id: "summarize", execute: () => runSummarize(), icon: "FileText" },
    { id: "translate", execute: () => runTranslate(), icon: "Languages" },
  ],
});

<ComposerTriggerPopover char="/" {...slash} />
unstable_useSlashCommandAdapter
optionsUnstable_UseSlashCommandAdapterOptions

Unstable_UseSlashCommandAdapterOptions
commandsreadonly Unstable_SlashCommand[]

removeOnExecuteboolean | undefined= false

Strip the trigger text from the composer after executing.

iconMap?Record<string, Unstable_IconComponent>

Maps `metadata.icon` / `category.id` string keys to React components.

fallbackIcon?Unstable_IconComponent

Fallback icon when no entry in `iconMap` matches.