Xzero UI
Pro library

Agent builderPro

A card for setting up an AI agent: an inline editable name, a model picker, instructions, tool toggles with real app marks, and knowledge files with upload progress. A Configure / Test switch opens a compact chat that answers with the tools you turned on, and Publish ships the setup with a saved or unsaved state.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/agent-builder
Live · keyboard ready

Drop it into the settings screen of a support, sales or ops agent. Pass defaultConfig (or a controlled config with onConfigChange) and publishedConfig from your server, so unsaved changes are measured against what is live. Wire onPublish(config, signal) to save the setup, onUpload(file, report, signal) to upload knowledge files with progress, and onSend(message, config, signal) to answer test messages with the unsaved setup. onSend returns { text, calls }, and each call's tool id must match an AgentTool id (or "knowledge") so its chip gets the right mark. models and tools take your own lists with 16px SVG marks. Leave any callback out and that part is simulated.

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/agent-builder

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { AgentBuilder, sampleAgentConfig } from "@/components/xzero/blocks/agent-builder/agent-builder";

export function SupportAgentSettings() {
  return (
    <AgentBuilder
      defaultConfig={sampleAgentConfig}
      onPublish={async (config, signal) => {
        const response = await fetch("/api/agents/billing", { method: "PUT", body: JSON.stringify(config), signal });
        if (!response.ok) throw new Error("Server rejected the config");
      }}
      onSend={async (message, config, signal) => {
        const response = await fetch("/api/agents/billing/test", { method: "POST", body: JSON.stringify({ message, config }), signal });
        return response.json(); // { text, calls: [{ tool: "stripe", label: "Searched customers", result: "2 charges" }] }
      }}
    />
  );
}

API reference

AgentBuilder

Configure an AI agent in one card: an inline editable name over its workspace and version, a model picker, instructions with a character count, tools as toggle rows, and knowledge files with upload progress. A Configure / Test switch swaps the body for a compact chat that answers with the configured model and tools, and Publish ships the config with an unsaved, publishing, failed and published state. With no props it plays the Lumen billing assistant sample with simulated uploads, replies and publishing.

PropTypeDefaultDescription
configAgentConfig–Controlled config: { name, tint, modelId, instructions, tools, files }. tint (1 to 4) colors the agent's mark beside its replies in Test. Pair with onConfigChange.
defaultConfigAgentConfigsampleAgentConfigStarting config when uncontrolled. Passing it turns off the sample's auto upload.
onConfigChange(config: AgentConfig) => void–Called with the next config on every edit, toggle, model change and file update.
publishedConfigAgentConfig–The config that is live now. Unsaved changes are measured against it, so reverting an edit clears the unsaved state. Defaults to the starting config.
modelsAgentModel[]defaultModelsModels in the picker: { id, name, note?, mark? }. Defaults to Claude Sonnet 5.5, Claude Opus 5.5, Claude Haiku 5.5, GPT-6.1 Sol and Gemini 4 Argon with their marks.
toolsAgentTool[]defaultToolsTools the agent can be given: { id, name, description, mark? }. Defaults to Gmail, Slack, Linear, Notion, Google Calendar and Stripe.
onPublish(config: AgentConfig, signal: AbortSignal) => Promise<void>–Saves and ships the config. Resolve to bump the version and show the published state; reject to show "Couldn't publish". Simulated when left out.
onUpload(file: File, report: (progress: number) => void, signal: AbortSignal) => Promise<void>–Uploads one knowledge file. Call report with 0 to 1 as bytes go out; reject with an Error to mark the row failed with its message and a retry button. The signal aborts when the row is removed. Simulated when left out (files over 20 MB fail).
onSend(message: string, config: AgentConfig, signal: AbortSignal) => Promise<TestReply>–Answers a Test message. Return { text, calls?: { tool, label, result? }[] }; calls render as tool chips with the tool's mark before the reply streams. Defaults to simulateReply, which follows the enabled tools.
versionnumber12Published version shown under the name. Counts up after each successful publish.
workspacestring"Lumen support"Short line under the name, such as the workspace or team.
maxInstructionsnumber2000Instruction length limit. The count turns to the warning color past 90%.
acceptstring".pdf,.md,.txt,.csv,.docx,.html"Accepted file types for the knowledge file picker.
mode"configure" | "test"–Controlled view. Pair with onModeChange.
defaultMode"configure" | "test""configure"Starting view when uncontrolled.
onModeChange(mode: AgentBuilderMode) => void–Called when the Configure / Test switch changes.
classNamestring–Extra class on the card.

simulateReply

The built in reply function used when onSend is left out. Matches billing, bug and booking requests and changes its answer and tool calls to the tools that are on, so it is useful for demos and tests.

PropTypeDefaultDescription
message (required)string–The test message.
config (required)AgentConfig–The current config. Disabled tools are never called.

Keyboard interactions

KeysAction
TabMoves through the name, view switch, model picker, instructions, each tool switch, file actions and Publish. The hidden view is inert and skipped.
Arrow keysMove between Configure and Test on the view switch, and between models in the open picker.
Enter / SpaceOpens the model picker, chooses a model, toggles a tool, and presses buttons.
EscapeCloses the model picker and returns focus to it. In the name, restores the name from before editing.
Enter (in the name)Finishes editing the name.
Enter (in Test)Sends the message. While a reply runs, the send button becomes Stop.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Guidance for AI tools

Blocks are complete, self-contained screens with sample data. Replace the sample data and connect the callbacks described above. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components