ai-sdk

📁 dinequickly/json-renderskill 📅 Jan 28, 2026
8
总安装量
3
周安装量
#35757
全站排名
安装命令
npx skills add https://github.com/dinequickly/json-renderskill --skill ai-sdk

Agent 安装分布

claude-code 3
github-copilot 3
codex 3
kimi-cli 3
gemini-cli 3
opencode 3

Skill 文档

AI SDK UI Rendering

Overview

Use this skill to turn AI SDK tool calls into UI components, either by rendering on the client from tool outputs or streaming UI from the server with RSC.

Quick Decision

  • Use client-side rendering when you already receive message parts on the client and want a simple mapping from tool outputs to components.
  • Use server-side streaming (RSC) when you want the server to render components during tool execution and stream them to the client.

Task: Return JSON from tools for UI

  1. Define a tool with a clear input schema and return a JSON object that matches the UI props.
  2. Keep outputs serializable (no functions, Dates, or class instances).
  3. If multiple tools share a UI pattern, normalize output shape or add a kind field.

Example:

const result = await generateText({
  model,
  prompt,
  tools: {
    getWeather: {
      description: 'Get the weather for a location',
      inputSchema: z.object({
        city: z.string(),
        unit: z.enum(['C', 'F']),
      }),
      execute: async ({ city, unit }) => {
        const weather = getWeather({ city, unit });
        return {
          temperature: weather.temperature,
          unit,
          description: weather.description,
          forecast: weather.forecast,
        };
      },
    },
  },
});

Task: Client-side mapping from tool outputs to components

  1. Iterate message parts.
  2. Guard on part.state === 'output-available'.
  3. Map part.type (tool name) to the right component.

Example:

const renderers: Record<string, (output: any) => JSX.Element> = {
  'tool-getWeather': output => (
    <WeatherCard weather={output} />
  ),
  'tool-searchCourses': output => (
    <Courses courses={output} />
  ),
};

return messages.map(message => (
  <div key={message.id}>
    {message.parts.map(part => {
      if (part.state !== 'output-available') return null;
      if (part.type === 'text') return <div>{part.text}</div>;
      const render = renderers[part.type];
      return render ? render(part.output) : null;
    })}
  </div>
));

Task: Server-side UI streaming with RSC

  1. Create a UI stream with createStreamableUI.
  2. In a tool execute, render a component and call uiStream.done(...).
  3. Return uiStream.value from the server action and render it directly on the client.

Example:

import { createStreamableUI } from '@ai-sdk/rsc';

const uiStream = createStreamableUI();

await generateText({
  model,
  prompt,
  tools: {
    getWeather: {
      description: 'Get the weather for a location',
      inputSchema: z.object({
        city: z.string(),
        unit: z.enum(['C', 'F']),
      }),
      execute: async ({ city, unit }) => {
        const weather = getWeather({ city, unit });
        uiStream.done(<WeatherCard weather={weather} />);
      },
    },
  },
});

return { display: uiStream.value };

Client render:

return (
  <div>
    {messages.map(message => (
      <div key={message.id}>{message.display}</div>
    ))}
  </div>
);

Multi-tool UI scaling

  • Prefer a registry map over large switch statements.
  • Normalize tool outputs or include a kind field for shared components.
  • For multi-step tool chains, keep the UI stream open until the final result is ready.

References

  • See references/ui-rendering.md for patterns, edge cases, and suggested message-part helpers.

Resources

references/

  • references/ui-rendering.md: patterns for tool output shapes, part rendering helpers, and streaming guidance.