Receive updates via email
Mobile and desktop alerts
Summary of activity every Monday
Receive updates via email
Mobile and desktop alerts
Summary of activity every Monday
<PreferencesPanel sections={[ { "items": [ { "id": "email-notifications", "label": "Email Notifications", "description": "Receive updates via email", "type": "switch", "defaultChecked": true }, { "id": "push-notifications", "label": "Push Notifications", "description": "Mobile and desktop alerts", "type": "switch", "defaultChecked": false }, { "id": "weekly-digest", "label": "Weekly Digest", "description": "Summary of activity every Monday", "type": "switch", "defaultChecked": true } ] } ]} onSave={(values) => { console.log("Saved:", values); }} onCancel={() => { console.log("Cancelled"); }}/>Run this once from your project root.
npx shadcn@latest add @tool-ui/preferences-panelRender PreferencesPanel in your UI with tool-compatible props.
import { PreferencesPanel } from "@/components/tool-ui/preferences-panel";export function Example() { return ( <PreferencesPanel id="preferences-panel-example" sections={[ { items: [ { id: "notifications", label: "Notifications", description: "Receive push notifications", type: "switch", defaultChecked: true, }, { id: "theme", label: "Theme", description: "Choose your appearance", type: "toggle", options: [ { value: "light", label: "Light" }, { value: "dark", label: "Dark" }, { value: "auto", label: "Auto" }, ], defaultValue: "auto", }, { id: "analytics", label: "Analytics", description: "Help improve the product", type: "switch", defaultChecked: false, }, ], }, ]} /> );}Register this renderer so tool results display as PreferencesPanel.
"use client";import { type Toolkit } from "@assistant-ui/react";import { PreferencesPanel } from "@/components/tool-ui/preferences-panel";import { safeParseSerializablePreferencesPanel, SerializablePreferencesPanelSchema,} from "@/components/tool-ui/preferences-panel/schema";import { createArgsToolRenderer } from "@/components/tool-ui/shared";export const toolkit: Toolkit = { show_preferences_panel: { description: "Display user preference settings with staged changes", parameters: SerializablePreferencesPanelSchema, render: createArgsToolRenderer({ safeParse: safeParseSerializablePreferencesPanel, idPrefix: "preferences-panel", render: (parsedArgs, { addResult }) => ( <PreferencesPanel {...parsedArgs} onSave={async (values) => { await addResult({ choice: values }); }} onCancel={() => { addResult({ choice: {} }); }} /> ), }), },};These snippets use assistant-ui for end-to-end wiring, but the PreferencesPanel component itself is framework-agnostic at the UI layer: you can use it in any React codebase with any LLM SDK or tool-calling interface that can provide compatible props.
Switch for binary choices, toggle for 2-4 options, select for 5+ options
Explicit Save/Cancel actions prevent accidental changes
Use PreferencesPanel.Receipt for confirmed selections with success
indicators
Group related settings with optional section headings
import { PreferencesPanel } from "@/components/tool-ui/preferences-panel";<PreferencesPanel.Receipt id="preferences-panel-receipt" title="Privacy Settings" sections={sections} choice={{ "profile-visibility": "private", "activity-status": false, }} error={{ "activity-status": "Requires premium plan", }}/>;Prop
Type
Use the receipt variant to display confirmed preferences or validation errors.
Prop
Type
Prop
Type
Prop
Type
Prop
Type
htmlFor and id attributesrole="status" for screen reader announcementsprefers-reduced-motion user preference