FluxyChat

How-to Guides

Generative UI

Tool-name-prefixed parts for rendering AI tool results as UI components. Framework-agnostic core with `ComponentRegistry` for mapping tool names to renderers.

Generative UI

Tool-name-prefixed parts for rendering AI tool results as UI components. Framework-agnostic core with ComponentRegistry for mapping tool names to renderers.

AG-UI-shaped stream events map through createAgUiAdapter in @fluxy-chat/sdk (packages/sdk/src/ag-ui-adapter.ts). That is an event bridge, not a CopilotKit / LangGraph host.

A LangGraph / CrewAI / Pydantic AI process can join a room and read the latest stored run:

curl -X POST "$WORKER/ag-ui/join" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{"roomId":"deal-1"}'

curl "$WORKER/ag-ui/events?roomId=deal-1&stream=1" \
  -H "Authorization: Bearer $JWT"

/ag-ui/events replays agent_runs as RUN_STARTED / TOOL_CALL_* / RUN_FINISHED. Live tokens still come from the room WebSocket or Agent DO. Python: FluxyChatClient.join_ag_ui / ag_ui_events.

Parts

import { createTextPart, createToolCallPart, createToolResultPart } from "@fluxy-chat/sdk";

const parts = [
  createTextPart("The weather is:"),
  createToolCallPart("getWeather", "call-1", { location: "SF" }),
  createToolResultPart("getWeather", "call-1", "output-available", { temp: 72 }),
];

Component Registry

import { createComponentRegistry, renderParts } from "@fluxy-chat/sdk";

const registry = createComponentRegistry();
registry.register("getWeather", {
  component: { render: (props) => `Weather: ${props.temp}°` },
  loadingComponent: { render: () => "Loading..." },
  errorComponent: { render: (props) => `Error: ${props.errorText}` },
});

const result = renderParts(parts, registry);
// ["The weather is:", "[getWeather loading...]", "Weather: 72°"]

Type Guards

import { isTextPart, isToolPart, isToolCallPart, isToolResultPart } from "@fluxy-chat/sdk";

if (isToolResultPart(part) && part.state === "output-available") {
  renderComponent(part.toolName, part.output);
}

On this page