Commands
Commands provide powerful shortcuts for users to interact with your chat application. There are two types of commands: AI Commands that are processed by the LLM, and UI Commands that execute directly on the client.
Commands Demo
• Theme: light | Debug: OFFCommand Types
AI Commands
AI commands send targeted messages to the LLM with specific tools and system prompts. They’re perfect for content generation, analysis, and complex operations that benefit from AI reasoning.
UI Commands
UI commands execute directly on the client without involving the AI. They’re ideal for settings changes, navigation, data management, and instant UI actions.
Command Syntax
Commands use a slash prefix followed by the command name and parameters:
/commandname param1:value1 param2:value2Examples:
/clear- Simple command with no parameters/theme mode:dark- Command with one parameter/summarize url:https://example.com style:brief- Command with multiple parameters
AI Commands
AI commands are registered with useAIChatCommand and require a corresponding frontend tool:
import { useAIChatCommand, useAIFrontendTool } from "ai-chat-bootstrap";
import { z } from "zod";
function MyAICommands() {
// Register the frontend tool
useAIFrontendTool({
name: "url_summarizer",
description: "Summarize content from a URL",
parameters: z.object({
url: z.string().url(),
style: z.enum(["brief", "detailed", "bullet-points"]),
}),
execute: async (params) => {
const response = await fetch("/api/summarize", {
method: "POST",
body: JSON.stringify(params),
});
return response.json();
},
});
// Register the AI command
useAIChatCommand({
name: "summarize",
description: "Summarize a URL using AI",
toolName: "url_summarizer",
parameters: z.object({
url: z.string().url().describe("URL to summarize"),
style: z.enum(["brief", "detailed", "bullet-points"])
.default("brief")
.describe("Summary style"),
}),
systemPrompt: "You are a concise summarizer. Extract key points and provide clear, factual summaries."
});
return null;
}AI Command Flow
- User types
/summarize url:https://example.com style:brief - System parses and validates parameters
- AI receives the command with the custom system prompt
- AI calls the
url_summarizertool with the parameters - Tool executes and returns results
- AI processes the results and generates a response
UI Commands
UI commands are registered with useUIChatCommand and execute immediately:
import { useUIChatCommand } from "ai-chat-bootstrap";
import { z } from "zod";
function MyUICommands() {
const [theme, setTheme] = useState("light");
useUIChatCommand({
name: "theme",
description: "Change the application theme",
parameters: z.object({
mode: z.enum(["light", "dark", "auto"]).describe("Theme mode"),
}),
execute: async ({ mode }) => {
setTheme(mode);
document.documentElement.setAttribute("data-theme", mode);
localStorage.setItem("theme", mode);
}
});
useUIChatCommand({
name: "clear",
description: "Clear the chat history",
parameters: z.object({}),
execute: async () => {
clearMessages();
console.log("Chat cleared");
}
});
return null;
}UI Command Flow
- User types
/theme mode:dark - System parses and validates parameters
- Execute function runs immediately
- UI updates happen synchronously
- No AI involvement
Demo reference
- Centralized command registration (AI + UI) used by the landing page: packages/ai-chat-bootstrap-demo/src/hooks/use-demo-ai.ts
- Popout command palette and toolbar entry points that surface the commands: packages/ai-chat-bootstrap-demo/src/app/page.tsx
Complete Example
Here’s a comprehensive example showing both command types:
"use client";
import React, { useState } from "react";
import {
ChatContainer,
useAIChatCommand,
useAIFrontendTool,
useChatStore,
useUIChatCommand,
} from "ai-chat-bootstrap";
import { z } from "zod";
export function ChatWithCommands() {
const messages = useChatStore((state) => state.messages);
const clearMessages = useChatStore((state) => state.clearMessages);
const [theme, setTheme] = useState("light");
const [debugMode, setDebugMode] = useState(false);
// Frontend tool for AI commands
useAIFrontendTool({
name: "content_analyzer",
description: "Analyze text content",
parameters: z.object({
text: z.string(),
type: z.enum(["sentiment", "keywords", "summary"]),
}),
execute: async (params) => {
// Simulate analysis
const results = {
sentiment: { score: 0.8, label: "positive" },
keywords: ["example", "content", "analysis"],
summary: "This is a summary of the content.",
};
return {
success: true,
analysis: results[params.type],
type: params.type,
};
},
});
// AI Command - processed by LLM
useAIChatCommand({
name: "analyze",
description: "Analyze text content using AI",
toolName: "content_analyzer",
parameters: z.object({
text: z.string().describe("Text to analyze"),
type: z.enum(["sentiment", "keywords", "summary"])
.default("summary")
.describe("Type of analysis"),
}),
systemPrompt: `You are an expert content analyst. When analyzing content:
- For sentiment: Explain the emotional tone and provide insights
- For keywords: Identify key themes and important terms
- For summary: Create a concise, informative summary
Always be thorough and provide actionable insights.`,
});
// UI Commands - execute directly
useUIChatCommand({
name: "theme",
description: "Change the application theme",
parameters: z.object({
mode: z.enum(["light", "dark", "auto"]).describe("Theme mode"),
}),
execute: async ({ mode }) => {
setTheme(mode);
document.documentElement.setAttribute("data-theme", mode);
localStorage.setItem("theme", mode);
},
});
useUIChatCommand({
name: "clear",
description: "Clear the chat history",
parameters: z.object({}),
execute: async () => {
clearMessages();
},
});
useUIChatCommand({
name: "debug",
description: "Toggle debug mode",
parameters: z.object({
enabled: z.boolean().optional().describe("Enable or disable debug"),
}),
execute: async ({ enabled }) => {
const newState = enabled !== undefined ? enabled : !debugMode;
setDebugMode(newState);
console.log(`Debug mode: ${newState ? "ON" : "OFF"}`);
},
});
return (
<div className="space-y-4">
<div className="h-[500px] w-full">
<ChatContainer
transport={{ api: "/api/chat" }}
messages={{
systemPrompt:
"You are an assistant that understands slash commands and can analyze content.",
}}
header={{
title: "Chat with Commands",
subtitle: "Try AI: /analyze or UI: /theme, /clear, /debug",
}}
ui={{ placeholder: "Type / to see available commands" }}
/>
</div>
{debugMode && (
<div className="p-4 bg-muted rounded-lg">
<h3 className="font-bold mb-2">Debug Info</h3>
<pre className="text-xs overflow-auto">
{JSON.stringify(
{
messageCount: messages.length,
theme,
debugMode,
timestamp: new Date().toISOString(),
},
null,
2
)}
</pre>
</div>
)}
</div>
);
}Command Parameters
Commands use Zod schemas for parameter validation:
Simple Parameters
parameters: z.object({
message: z.string().describe("Message to display"),
count: z.number().default(1).describe("Number of times to repeat"),
})Complex Parameters
parameters: z.object({
source: z.object({
type: z.enum(["url", "file", "text"]),
value: z.string(),
}).describe("Source to process"),
options: z.object({
format: z.enum(["json", "markdown", "html"]).default("markdown"),
includeMetadata: z.boolean().default(false),
maxLength: z.number().optional(),
}).describe("Processing options"),
filters: z.array(z.string()).optional().describe("Content filters"),
})Parameter Validation
parameters: z.object({
email: z.string().email().describe("Valid email address"),
age: z.number().min(0).max(120).describe("Age in years"),
tags: z.array(z.string()).min(1).describe("At least one tag required"),
url: z.string().url().describe("Valid URL"),
})Command Discovery
Users can discover available commands by:
- Typing
/- Shows all available commands - Auto-completion - Suggests commands as user types
- Help command - Can implement
/helpto list commands - Parameter hints - Shows parameter requirements for each command
Best Practices
Error Handling
// For UI commands
execute: async (params) => {
try {
await performOperation(params);
toast.success("Operation completed");
} catch (error) {
console.error("Command failed:", error);
toast.error("Operation failed: " + error.message);
}
}
// For AI commands (in the tool)
execute: async (params) => {
try {
const result = await processData(params);
return { success: true, result };
} catch (error) {
return {
success: false,
error: error.message,
details: "Please check your input and try again"
};
}
}Backend Integration
For AI commands, the backend receives the tools automatically:
// app/api/chat/route.ts
import { createAzure } from "@ai-sdk/azure";
import { createAIChatHandler } from "ai-chat-bootstrap/server";
const azure = createAzure({
resourceName: process.env.AZURE_RESOURCE_NAME!,
apiKey: process.env.AZURE_API_KEY!,
apiVersion: process.env.AZURE_API_VERSION ?? "preview",
});
const model = azure(process.env.AZURE_DEPLOYMENT_ID!);
export const POST = createAIChatHandler({
model,
});Common Command Examples
Content Management
// AI: Generate content
useAIChatCommand({
name: "generate",
description: "Generate content using AI",
toolName: "content_generator",
parameters: z.object({
type: z.enum(["blog", "email", "summary"]),
topic: z.string().describe("Content topic"),
length: z.enum(["short", "medium", "long"]).default("medium"),
}),
});
// UI: Save content
useUIChatCommand({
name: "save",
description: "Save current content",
parameters: z.object({
name: z.string().describe("File name"),
}),
execute: async ({ name }) => {
await saveContent(name, getCurrentContent());
}
});Data Operations
// AI: Analyze data
useAIChatCommand({
name: "analyze",
description: "Analyze data with AI insights",
toolName: "data_analyzer",
parameters: z.object({
data: z.string().describe("Data to analyze"),
type: z.enum(["statistical", "trends", "predictions"]),
}),
});
// UI: Export data
useUIChatCommand({
name: "export",
description: "Export data in various formats",
parameters: z.object({
format: z.enum(["csv", "json", "excel"]),
filter: z.string().optional(),
}),
execute: async ({ format, filter }) => {
const data = getData(filter);
downloadFile(data, format);
}
});Application Control
// UI: Settings
useUIChatCommand({
name: "settings",
description: "Update application settings",
parameters: z.object({
theme: z.enum(["light", "dark"]).optional(),
language: z.string().optional(),
notifications: z.boolean().optional(),
}),
execute: async (params) => {
Object.entries(params).forEach(([key, value]) => {
if (value !== undefined) {
updateSetting(key, value);
}
});
}
});
// UI: Navigation
useUIChatCommand({
name: "goto",
description: "Navigate to a page",
parameters: z.object({
page: z.enum(["home", "settings", "profile", "help"]),
newTab: z.boolean().default(false),
}),
execute: async ({ page, newTab }) => {
const url = getPageUrl(page);
if (newTab) {
window.open(url, "_blank");
} else {
router.push(url);
}
}
});API Reference
useAIChatCommand- Register AI commandsuseUIChatCommand- Register UI commandsuseAIFrontendTool- Register tools for AI commandsuseAIChat- Main chat hook
Next Steps
Commands open up powerful possibilities for your chat application:
- Custom Workflows: Create domain-specific commands for your use case
- Integration: Connect commands to external APIs and services
- Automation: Build commands that automate complex multi-step processes
- User Experience: Design intuitive command interfaces for your users
Commands transform your chat from simple conversation to a powerful interface for interacting with your application and AI capabilities.