Recipes
Tool Renderers
Render tool calls in chat using client definitions while keeping server tools out of the client bundle.
Tool renderers make demos and production assistants easier to understand.
Define a renderer
"use client";
import { ToolCallCard } from "@tulip-systems/ai/chat/client";
import { defineToolClient } from "@tulip-systems/ai/tools/client";
import { Search } from "lucide-react";
import type { searchCrmRecords } from "./tool.server";
export const searchCrmRecordsToolClient = defineToolClient<typeof searchCrmRecords>({
toolName: "search_crm_records",
render: (part) => (
<ToolCallCard
part={part}
title="CRM records zoeken"
icon={<Search className="size-3.5" />}
labels={{ output: "Gevonden records" }}
/>
),
});Share renderers
Centralize tool renderers near the chat configuration:
export const ASSISTANT_TOOL_CLIENTS = [
webSearchToolClient,
delegateToSalesToolClient,
searchCrmRecordsToolClient,
createProspectToolClient,
];Then pass them to messages:
<ChatThreadMessage message={message} toolRenderers={ASSISTANT_TOOL_CLIENTS} />Guidance
- Use
import typefor server tools. - Start with
ToolCallCardbefore building custom cards. - Render important mutation tools more clearly than background read tools.
- Keep renderers stable and reusable across full-page chat and sidepanel chat.