Documents
tool-group
tool-group
Type
External
Status
Published
Created
Mar 17, 2026
Updated
Mar 17, 2026

import {
ToolGroupSample,
ToolGroupStreamingSample,
} from "@/components/docs/samples/tool-group";

A wrapper component that groups consecutive tool calls together, displaying them in a collapsible container with auto-expand behavior during streaming.

Getting Started#

Add tool-group#

<InstallCommand shadcn={["tool-group"]} />

This adds a /components/assistant-ui/tool-group.tsx file to your project, which you can adjust as needed.

Use it in your application#

Pass the ToolGroup component to the MessagePrimitive.Parts component

import { ToolGroup } from "@/components/assistant-ui/tool-group";

const AssistantMessage = () => {
  return (
    <MessagePrimitive.Root>
      <MessagePrimitive.Parts>
        {({ part }) => {
          if (part.type === "tool-call") return <ToolGroup {...part} />;
          return null;
        }}
      </MessagePrimitive.Parts>
    </MessagePrimitive.Root>
  );
};

Variants#

Use the variant prop on ToolGroup.Root to change the visual style:

<ToolGroup.Root variant="outline">...</ToolGroup.Root>
<ToolGroup.Root variant="muted">...</ToolGroup.Root>
VariantDescription
outlineRounded border (default)
ghostNo additional styling
mutedMuted background with border

Examples#

Streaming Demo (Custom UI + Fallback)#

Interactive demo showing tool group with custom tool UIs and ToolFallback working together. Watch as weather cards stream in with loading states, followed by a search tool using the fallback UI.

Custom Tool UIs#

ToolGroup works with any custom tool UI components:

// Custom Weather Tool UI
function WeatherToolUI({ location, temperature, condition }) {
  return (
    <div className="flex items-center gap-3 rounded-lg border p-3">
      <WeatherIcon condition={condition} />
      <div>
        <div className="text-xs text-muted-foreground">{location}</div>
        <div className="text-lg font-medium">{temperature}°F</div>
      </div>
    </div>
  );
}

// Use in ToolGroup
<ToolGroupRoot variant="outline">
  <ToolGroupTrigger count={3} />
  <ToolGroupContent>
    <WeatherToolUI location="New York" temperature={65} condition="Cloudy" />
    <WeatherToolUI location="London" temperature={55} condition="Rainy" />
    <SearchToolUI query="best restaurants" results={24} />
  </ToolGroupContent>
</ToolGroupRoot>

Composable API#

All sub-components are exported for custom layouts:

ComponentDescription
ToolGroup.RootCollapsible container with scroll lock and variants
ToolGroup.TriggerHeader with tool count, shimmer animation, and chevron
ToolGroup.ContentAnimated collapsible content wrapper
import {
  ToolGroup,
  ToolGroupRoot,
  ToolGroupTrigger,
  ToolGroupContent,
} from "@/components/assistant-ui/tool-group";

// Compound component syntax
<ToolGroup.Root variant="outline" defaultOpen>
  <ToolGroup.Trigger count={3} active={false} />
  <ToolGroup.Content>
    {/* Any tool UI components - custom or ToolFallback */}
  </ToolGroup.Content>
</ToolGroup.Root>

API Reference#

ToolGroupRoot#

<ParametersTable
type="ToolGroupRootProps"
parameters={[
{
name: "variant",
type: '"outline" | "ghost" | "muted"',
default: '"outline"',
description: "Visual variant of the tool group container.",
},
{
name: "open",
type: "boolean",
description: "Controlled open state.",
},
{
name: "onOpenChange",
type: "(open: boolean) => void",
description: "Callback when open state changes.",
},
{
name: "defaultOpen",
type: "boolean",
default: "false",
description: "Initial open state for uncontrolled usage.",
},
]}
/>

ToolGroupTrigger#

<ParametersTable
type="ToolGroupTriggerProps"
parameters={[
{
name: "count",
type: "number",
required: true,
description: "Number of tool calls to display in the label.",
},
{
name: "active",
type: "boolean",
default: "false",
description: "Shows loading spinner and shimmer animation when true.",
},
]}
/>

ToolGroup (Default Export)#

<ParametersTable
type="ToolGroupProps"
parameters={[
{
name: "startIndex",
type: "number",
required: true,
description: "The index of the first tool call in the group.",
},
{
name: "endIndex",
type: "number",
required: true,
description: "The index of the last tool call in the group.",
},
{
name: "children",
type: "ReactNode",
required: true,
description: "The rendered tool call components.",
},
]}
/>

  • ToolFallback - Default UI for tools without custom renderers
  • PartGrouping - Advanced message part grouping (experimental)