Skip to content

Install the panel and pick a mode

The styled panel ships through a shadcn registry served by this site. The npm package stays headless.

The panel pulls assistant-ui’s Thread from the @assistant-ui registry. Name that registry in components.json. From examples/app/components.json:

"registries": {
"@assistant-ui": "https://r.assistant-ui.com/styles/{style}/{name}.json"
},

Add the panel and the cards’ styles:

Terminal window
npx shadcn@latest add https://super-assist.dogar.biz/r/assisted-panel.json https://super-assist.dogar.biz/r/assisted-cards.json

The result is components/assisted-panel.tsx and the cards’ rules in your global CSS. The panel also brings shadcn’s button and native-select and assistant-ui’s thread element.

Render AssistedPanel inside AssistedProvider and pick a mode. The example switches on a query parameter in development. Each branch below is from examples/app/app/assistant.tsx.

Floating: a window in the bottom-right corner that the user drags, resizes, minimizes and maximizes. While it is closed, a corner button opens it.

return (
<>
<main className="min-h-dvh p-6">{children}</main>
<AssistedPanel mode="floating" threads description={description} />
</>
);

Sheet: a column beside the page that takes the page’s space, with no overlay. Closed, it is a slim rail with a button.

if (mode === "sheet") {
return (
<div className="flex h-dvh">
<main className="min-w-0 flex-1 overflow-y-auto p-6">{children}</main>
<AssistedPanel mode="sheet" threads description={description} />
</div>
);
}

Embedded: the bare Thread, placed where your layout puts it. It has no header and no trigger, and it is always shown.

if (mode === "embedded") {
return (
<div className="flex h-dvh">
<aside className="w-64 shrink-0 border-e p-2">
<ThreadList />
</aside>
<main className="min-w-0 flex-1 overflow-y-auto p-6">{children}</main>
<div className="w-md shrink-0 border-s">
<AssistedPanel mode="embedded" />
</div>
</div>
);
}

In the framed modes, description is the header’s line when no assisted page is open. threads shows a thread picker. Set it only when your runtime has a thread list, see Bring your own thread list.

AssistedTrigger comes with the panel. It toggles the floating window or the sheet. From examples/app/app/shell.tsx:

<div className="ms-auto flex gap-2">
{mode !== "embedded" && <AssistedTrigger />}
<Button variant="outline" size="sm" onClick={() => shop.call("reset")}>
Reset shop
</Button>
</div>

To open the panel with a message already sent, call open from useAssisted:

export function AskAboutOrder({ id }: { id: string }) {
const { open } = useAssisted();
return (
<Button onClick={() => open(`Why hasn't order #${id} shipped?`)}>Ask the assistant</Button>
);
}

The floating panel sits at z-index 50, above the ring. A modal dialog’s backdrop still blocks it. Make assisted dialogs non-modal, see Make a dialog assisted.