Skip to content

A card is how a tool’s call shows in the conversation. The package brings seven, and cards on AssistedProvider replaces any of them for the whole app. A card you leave out stays the package’s.

Write a component that takes the tool call’s props, and pass it under the card’s key. Define it at module scope, so it keeps its identity across renders:

import { type AssistedCards, AssistedProvider } from "@super-assist/react";
import { Fragment } from "react";
const Spec: NonNullable<AssistedCards["spec"]> = ({ args, result }) => {
if (typeof result !== "string") return null;
return (
<dl className="my-2 grid grid-cols-2 gap-1 rounded border p-2 text-sm">
{args.rows.map(({ label, value }) => (
<Fragment key={label}>
<dt className="text-muted-foreground">{label}</dt>
<dd>{value}</dd>
</Fragment>
))}
</dl>
);
};
const cards: AssistedCards = { spec: Spec };
<AssistedProvider runtime={runtime} cards={cards}>
{children}
</AssistedProvider>;

args holds the model’s arguments, typed per card. result is the call’s answer once it has one. The package’s show cards wait for it, so a call the browser has not run yet shows nothing.

The confirm and choices cards pause the call until the user answers. Their components get interrupt, set while the call waits, and resume, which answers it:

const Confirm: NonNullable<AssistedCards["confirm"]> = ({ interrupt, resume, result }) => {
const ask = interrupt?.payload as { label: string } | undefined;
if (!ask) return result === undefined ? null : <p className="text-xs">Answered.</p>;
return (
<div className="my-2 flex items-center gap-2 rounded border p-2 text-sm">
<span className="flex-1">{ask.label}</span>
<button onClick={() => resume({ approved: false })}>Deny</button>
<button onClick={() => resume({ approved: true })}>Approve</button>
</div>
);
};
Key interrupt.payload Answer with
confirm { name, label, id? } resume({ approved: true }) or resume({ approved: false })
choices { question, options } resume(option), one of the options

The confirm card serves every consequential action and tool. A tool’s own render on useAssistedTool replaces it for that tool only.

Key Tool args
confirm Every consequential action and tool The action’s or tool’s arguments
choices offer_choices { question, options }
links show_links { items: { to, id?, title, gist? }[] }
table show_table { title?, columns, rows }
spec show_spec { title, rows }
comparison show_comparison { traits, options, recommended, reason }
sources search_knowledge, on the server { query, knowledgeBase? }

What each tool sends and answers is on its card’s page under Cards. The model still calls the same tools: a card changes how a call looks, never what the model sees.