@digitalsingularity/agent-ui-chat-components v1.4.3
Agent UI Components
A comprehensive React component library for AI agent interfaces with dependency injection architecture.
๐ Features.
- ๐ค Complete Agent Management: Full CRUD operations for AI agents
- ๐ฌ Chat Interface: Real-time streaming chat with agents
- ๐ Dependency Injection: Bring your own UI components and services
- ๐ TypeScript Support: Full type safety with comprehensive type definitions
- โก Streaming Support: Real-time chat with streaming responses
- ๐ Document Management: Upload and manage agent context documents
- ๐ญ Avatar System: Upload custom avatars or generate AI-powered ones
- ๐ท๏ธ Personality Tags: Configurable agent personality traits
- ๐ก๏ธ Temperature Control: Fine-tune AI response randomness
- ๐ Model Selection: Support for multiple AI models
- ๐ฑ Mobile Friendly: Responsive design out of the box
- ๐จ Highly Customizable: Configurable styling and behavior
- ๐ Framework Agnostic: Works with any UI component library (shadcn/ui, Chakra UI, Material-UI, etc.)
๐ฆ Installation
npm install @digitalsingularity/agent-ui-chat-components lucide-react๐ฏ Quick Start
AgentsPage Component
import { AgentsPage } from '@digitalsingularity/agent-ui-chat-components';
import { agentsPageServices } from '@/lib/agents-page-services';
function App() {
return (
<AgentsPage {...agentsPageServices} />
);
}AgentChatModal Component
import {
AgentChatModal,
UIComponents,
AgentService
} from '@digitalsingularity/agent-ui-chat-components';
// Import your UI components (example with shadcn/ui)
import { Dialog, DialogContent, Button, Input, /* ... */ } from '@/components/ui';
// Define UI components interface
const uiComponents: UIComponents = {
Dialog, DialogContent, DialogHeader, DialogTitle,
DialogDescription, Button, Input, ScrollArea,
Avatar, AvatarFallback, AvatarImage
};
// Define your agent service
const agentService: AgentService = {
sendMessage: async (message, agentId, onChunk, onError, onCompletion) => {
// Your streaming chat implementation
const response = await fetch(`/api/agents/${agentId}/chat`, {
method: 'POST',
body: JSON.stringify({ message }),
headers: { 'Content-Type': 'application/json' }
});
// Handle streaming response
const reader = response.body?.getReader();
// ... streaming logic
},
getUserAvatar: async () => {
// Your user avatar fetching logic
return await fetchUserAvatar();
}
};
// Use the component
function MyApp() {
const [isOpen, setIsOpen] = useState(false);
return (
<AgentChatModal
agent={selectedAgent}
isOpen={isOpen}
onClose={() => setIsOpen(false)}
uiComponents={uiComponents}
agentService={agentService}
toastService={{ toast }}
enableHistory={true}
maxMessages={100}
/>
);
}๐ API Reference
AgentsPage Props
The AgentsPage component requires extensive dependency injection. See the AgentsPageProps interface for the complete list of required props including:
- Navigation:
useLocationhook - React Query:
useMutation,useQueryClient,useQuery - API Functions: All agent-related API functions
- UI Components: Complete set of UI components (60+ components)
- Icons: Lucide React icons
- Services: Toast, agent, and UI services
interface AgentsPageProps {
// Navigation
useLocation: () => [string, (path: string) => void];
// React Query
useMutation: any;
useQueryClient: any;
useQuery: any;
// API functions
useAiAgents: () => any;
createAiAgent: (agent: any) => Promise<AiAgent>;
updateAiAgent: (id: string, agentData: any) => Promise<AiAgent>;
deleteAiAgent: (id: string) => Promise<void>;
// ... many more API functions
// UI Components (60+ required)
Card: React.ComponentType<any>;
Button: React.ComponentType<any>;
Dialog: React.ComponentType<any>;
// ... all required UI components
// Icons
Loader2: React.ComponentType<any>;
Edit: React.ComponentType<any>;
// ... all required icons
// Services
agentService: any;
toastService: any;
uiComponents: any;
}AgentChatModal Props
| Prop | Type | Required | Description |
|---|---|---|---|
agent | AiAgent \| null | โ | The agent to chat with |
isOpen | boolean | โ | Controls modal visibility |
onClose | () => void | โ | Called when modal should close |
uiComponents | UIComponents | โ | Your UI component implementations |
agentService | AgentService | โ | Your chat service implementation |
toastService | ToastService | โ | Optional toast notifications |
enableHistory | boolean | โ | Enable chat history (default: true) |
maxMessages | number | โ | Max messages to keep (default: 100) |
className | string | โ | Additional CSS classes |
Type Definitions
interface AiAgent {
id: string;
name: string;
description?: string | null;
systemInstruction: string;
temperature?: number;
model: string;
personalityTags?: string[];
avatarUrl?: string | null;
avatarType?: string;
avatarPrompt?: string;
isPublic?: boolean;
isOwner?: boolean;
userId: string;
createdAt: string;
updatedAt: string;
}
interface AiAgentDocument {
id: number;
fileName: string;
fileSize?: number;
}
interface AgentService {
sendMessage(
message: string,
agentId: string,
onChunk: (chunk: string) => void,
onError: (error: any) => void,
onCompletion: () => void
): Promise<void>;
getUserAvatar?(): Promise<string | null>;
}๐จ UI Framework Examples
shadcn/ui
import * as Dialog from '@radix-ui/react-dialog';
import { Button } from '@/components/ui/button';
// ... other imports
const uiComponents = { Dialog, DialogContent, Button, /* ... */ };Chakra UI
import { Modal, ModalContent, Button, Input } from '@chakra-ui/react';
const uiComponents = {
Dialog: Modal,
DialogContent: ModalContent,
Button,
Input,
// ... map other components
};๐งช Testing & Element Identification
All components include comprehensive identification attributes for automated testing, debugging, and analytics. The library uses a structured approach to element identification:
Identification Attribute Strategy
1. data-testid - For Automated Testing
Primary attribute for test automation (Jest, Cypress, Playwright):
data-testid="agent-chat-modal"
data-testid="create-agent-button"
data-testid="message-input"2. data-component - For Component Identification
Identifies the component type or functional role:
data-component="AgentChatModal"
data-component="form-input"
data-component="message-bubble"3. data-action - For User Actions
Identifies interactive elements and their actions:
data-action="send-message"
data-action="create-agent"
data-action="delete-agent"4. data-state - For Element States
Tracks dynamic states of components:
data-state="loading"
data-state="disabled"
data-state="selected"5. data-field - For Form Fields
Identifies form inputs and their purpose:
data-field="agent-name"
data-field="system-instruction"
data-field="temperature"Naming Conventions
Test IDs
- Format:
{component}-{element}-{modifier?} - Examples:
agent-chat-modal- Main chat modalcreate-agent-button- Agent creation buttonmessage-input- Message input fieldagent-row-{id}- Specific agent row with ID
Component Names
- Format:
{ComponentName}or{functional-role} - Examples:
AgentChatModal- Top-level component namemessage-avatar- Functional component roleinput-section- Semantic section name
Actions
- Format:
{verb}-{noun}or{verb}-{target} - Examples:
send-message- Send a messagecreate-agent- Create new agenttoggle-share- Toggle sharing state
States
- Format:
{state}or{property}-{value} - Examples:
loading- Element is loadingdisabled- Element is disabledpublic- Sharing state is public
Testing Examples
Cypress Tests
// Test agent creation
cy.get('[data-testid="create-agent-button"]').click();
cy.get('[data-testid="agent-name-input"]').type('Test Agent');
cy.get('[data-testid="submit-button"]').click();
// Test chat functionality
cy.get('[data-testid="agent-chat-modal"]').should('be.visible');
cy.get('[data-testid="message-input"]').type('Hello!');
cy.get('[data-testid="send-button"]').click();Jest/React Testing Library
import { render, fireEvent } from '@testing-library/react';
test('creates new agent', () => {
const { getByTestId } = render(<AgentsPage {...props} />);
fireEvent.click(getByTestId('create-agent-button'));
fireEvent.change(getByTestId('agent-name-input'), {
target: { value: 'Test Agent' }
});
fireEvent.click(getByTestId('submit-button'));
expect(getByTestId('agents-table')).toContainElement(
getByTestId('agent-row-test-agent')
);
});Playwright Tests
// Test responsive layout
await page.locator('[data-testid="agent-layout-compact"]').waitFor();
await page.locator('[data-testid="agent-item-123"]').click();
// Test form interactions
await page.locator('[data-testid="agent-form-modal"]').waitFor();
await page.fill('[data-field="name"]', 'New Agent');
await page.click('[data-action="submit"]');Debugging & Analytics
Debug Element Discovery
// Find all interactive elements
document.querySelectorAll('[data-action]');
// Find all form fields
document.querySelectorAll('[data-field]');
// Find elements by component type
document.querySelectorAll('[data-component="message-bubble"]');Analytics Integration
// Track user interactions
document.addEventListener('click', (e) => {
const action = e.target.getAttribute('data-action');
const component = e.target.getAttribute('data-component');
if (action) {
analytics.track('user_action', {
action,
component,
timestamp: Date.now()
});
}
});Component-Specific Test IDs
AgentChatModal
agent-chat-modal- Main modal containerchat-messages-area- Messages scroll areamessage-input- Message input fieldsend-message-button- Send buttonclear-history-button- Clear chat history
AgentFormModal
agent-form-modal- Main form modalagent-name-input- Agent name fieldsystem-instruction-textarea- System instruction fieldtemperature-slider- Temperature controlgenerate-avatar-button- Avatar generation button
AgentsPage
agents-page- Main page containercreate-agent-button- Create new agent buttonagents-table- Agents data tableagent-row-{id}- Individual agent rowsedit-button-{id}- Edit specific agentdelete-button-{id}- Delete specific agent
๐ง Development
# Clone the repository
git clone https://github.com/YOUR_USERNAME/agent-ui-chat-components.git
cd agent-ui-chat-components
# Install dependencies
npm install
# Build the library
npm run build
# Watch mode for development
npm run dev๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- Built with Vite and TypeScript
- Icons by Lucide React
- Inspired by the need for reusable AI chat interfaces
Made with โค๏ธ for the AI community!