INTEGRATED_ASSISTANT_SWITCHER_COMPONENT.md
Overview
The IntegratedAssistantSwitcher component is a sophisticated navigation hub that provides users with a comprehensive interface for switching between AI assistants, managing tools, and accessing assistant creation features. It serves as the primary navigation component within the chat interface.
Purpose
- Assistant Navigation: Quick switching between recent, favorite, and user-created assistants
- Tool Visualization: Display and management of enabled tools for the current assistant
- Assistant Discovery: Browse and organize assistants across different categories
- Quick Actions: Fast access to common actions like tool configuration and assistant creation
Key Features
Multi-Tab Interface
- Recent: Recently used assistants with usage history
- Favorites: Starred/favorited assistants for quick access
- Mine: User-created assistants with ownership management
- Tools: Current assistant’s tool configuration and description
Current Assistant Display
- Avatar and name display with tool count badge
- Expandable popover interface
- Tool status indicators
- Quick access to tool configuration
Assistant Management
- Assistant selection and navigation
- Tool configuration access
- Assistant creation workflow
- Direct links to admin and list pages
Component Interface
interface IntegratedAssistantSwitcherProps {
currentAssistantId?: string; // Active assistant identifier
currentAssistant?: AssistantDisplay; // Current assistant data object
recentAssistants: AssistantDisplay[]; // Recently used assistants
favorites?: AssistantDisplay[]; // Favorited assistants
userAssistants?: AssistantDisplay[]; // User-created assistants
onSelectAssistant: (assistantId: string) => void; // Assistant selection handler
onCreateAssistant?: () => void; // Assistant creation handler
tools?: string[]; // Current tool IDs array
toolConfigs?: Record<string, Record<string, any>>; // Tool configuration objects
}
// AssistantDisplay type structure:
interface AssistantDisplay {
assistantId: string;
name: string;
avatar?: string;
initialInstructions?: string;
tools?: string[];
// Additional assistant metadata...
}
Core Functionality
1. Current Assistant Display
// Main assistant card with tool badge
<div className="flex items-center p-3 border rounded-lg bg-white shadow-sm">
<PopoverTrigger asChild>
<Button variant="ghost" className="flex items-center justify-between p-0 h-auto w-full">
<div className="flex items-center">
<Avatar className="h-12 w-12 mr-3">
<AvatarImage src={currentAssistant?.avatar} alt={currentAssistant?.name || 'Assistant'} />
<AvatarFallback className="text-lg">{currentAssistant?.name?.[0] || '?'}</AvatarFallback>
</Avatar>
<div className="text-left">
<div className="font-semibold truncate max-w-[140px]">{currentAssistant?.name || 'Assistant'}</div>
<div className="flex items-center text-xs text-muted-foreground">
{tools.length > 0 && (
<Badge variant="outline" className="mr-1 py-0">
<Settings className="h-2.5 w-2.5 mr-1" />
{tools.length} {tools.length === 1 ? 'Tool' : 'Tools'}
</Badge>
)}
<span>Aitana Chat</span>
</div>
</div>
</div>
<ChevronRight className="h-4 w-4 ml-2 text-muted-foreground" />
</Button>
</PopoverTrigger>
</div>
2. Multi-Tab Navigation Interface
<Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
<TabsList className="w-full border-b rounded-none p-0">
<TabsTrigger value="recent" className="flex-1 rounded-none">
<Clock className="h-3.5 w-3.5 mr-1.5" /> Recent
</TabsTrigger>
<TabsTrigger value="favorites" className="flex-1 rounded-none">
<Star className="h-3.5 w-3.5 mr-1.5" /> Favorites
</TabsTrigger>
<TabsTrigger value="mine" className="flex-1 rounded-none">
<User className="h-3.5 w-3.5 mr-1.5" /> Mine
</TabsTrigger>
<TabsTrigger value="tools" className="flex-1 rounded-none">
<Wrench className="h-3.5 w-3.5 mr-1.5" /> Tools
</TabsTrigger>
</TabsList>
</Tabs>
3. Assistant List Rendering
// Generic assistant item display across all tabs
const AssistantItem = ({ assistant }) => (
<CommandItem
key={assistant.assistantId}
value={assistant.assistantId}
onSelect={() => {
onSelectAssistant(assistant.assistantId);
setOpen(false);
}}
className={`p-2 ${currentAssistantId === assistant.assistantId ? 'bg-accent' : ''}`}
>
<div className="flex items-center gap-3">
<Avatar className="h-12 w-12 rounded-md">
<AvatarImage src={assistant.avatar} alt={assistant.name} />
<AvatarFallback className="rounded-md">
{assistant.name ? assistant.name[0].toUpperCase() : 'A'}
</AvatarFallback>
</Avatar>
<div className="flex flex-col">
<span className="font-medium">{assistant.name}</span>
<div className="flex items-center text-xs text-muted-foreground mt-1">
{assistant.tools && assistant.tools.length > 0 && (
<Badge variant="outline" className="mr-1 py-0">
<Settings className="h-2.5 w-2.5 mr-1" />
{assistant.tools.length}
</Badge>
)}
<span className="truncate max-w-[140px]">
{assistant.initialInstructions
? `${assistant.initialInstructions.substring(0, 40)}${assistant.initialInstructions.length > 40 ? "..." : ""}`
: "No description"
}
</span>
</div>
</div>
</div>
</CommandItem>
);
4. Tool Visualization Tab
// Tools tab displaying current assistant's enabled tools
<TabsContent value="tools" className="mt-0">
<ScrollArea className="h-64 px-2 py-3">
{tools.length === 0 ? (
<div className="py-6 text-center text-sm text-muted-foreground">
No tools enabled for this assistant
</div>
) : (
<div className="space-y-4">
<div className="px-2">
<h4 className="text-sm font-medium">Current Assistant Tools</h4>
<p className="text-xs text-muted-foreground">
This assistant has {tools.length} {tools.length === 1 ? 'tool' : 'tools'} enabled
</p>
</div>
{allToolObjects.map(tool => tool && (
<div key={tool.id} className="space-y-1 px-2">
<div className="flex items-center gap-2">
<tool.icon className="h-4 w-4 text-primary" />
<h4 className="font-medium text-sm">{tool.name}</h4>
</div>
<p className="text-xs text-muted-foreground pl-6">
{tool.description}
</p>
</div>
))}
</div>
)}
</ScrollArea>
</TabsContent>
5. Tool Object Resolution
// Resolve tool IDs to full tool objects with metadata
const allToolObjects = tools
.map(toolId => AVAILABLE_TOOLS.find(t => t.id === toolId))
.filter(tool => !!tool);
// Each tool object contains:
// {
// id: string,
// name: string,
// description: string,
// icon: React.ComponentType,
// // Additional tool metadata...
// }
6. Quick Access Buttons
// External quick access buttons for common actions
<div className="flex gap-2">
<Button
variant="outline"
className="flex-1 h-9 text-xs"
onClick={() => {
setActiveTab('tools');
setOpen(true);
}}
>
<Wrench className="h-3.5 w-3.5 mr-1.5" />
Tools
</Button>
<Button
variant="outline"
className="flex-1 h-9 text-xs"
onClick={() => {
setActiveTab('recent');
setOpen(true);
}}
>
<Sparkles className="h-3.5 w-3.5 mr-1.5" />
Assistants
</Button>
</div>
7. Footer Action Buttons
// Footer actions within the popover
<div className="p-2 flex flex-col gap-2 border-t">
<Link href="/list" className="w-full">
<Button
variant="outline"
className="w-full justify-between"
onClick={() => setOpen(false)}
>
<span>View All Assistants</span>
<ArrowRight className="h-4 w-4" />
</Button>
</Link>
{onCreateAssistant && (
<Button
className="w-full gap-2"
onClick={() => {
onCreateAssistant();
setOpen(false);
}}
>
<Plus className="h-4 w-4" />
<span>Create New Assistant</span>
</Button>
)}
</div>
Tab-Specific Features
Recent Tab
- Usage History: Shows recently interacted assistants
- Activity Indicators: Last interaction timestamps
- Quick Selection: One-click assistant switching
- Empty State: Helpful message when no recent activity
Favorites Tab
- Starred Assistants: User-favorited assistants for quick access
- Persistent Storage: Favorites persist across sessions
- Priority Access: Frequently used assistants at fingertips
- Organization: Helps organize large assistant collections
Mine Tab
- Ownership Filter: Only user-created assistants
- Management Access: Direct access to editing owned assistants
- Creation History: All assistants created by current user
- Admin Rights: Full control over owned assistants
Tools Tab
- Tool Visualization: Visual display of enabled tools with icons
- Tool Descriptions: Detailed explanations of each tool’s purpose
- Configuration Access: Direct link to tool configuration
- Tool Count: Summary of enabled tools for current assistant
State Management
Local State Variables
const [open, setOpen] = useState(false); // Popover open/closed state
const [activeTab, setActiveTab] = useState('recent'); // Current active tab
Tab Navigation Logic
// External quick access that opens specific tabs
const openToolsTab = () => {
setActiveTab('tools');
setOpen(true);
};
const openAssistantsTab = () => {
setActiveTab('recent');
setOpen(true);
};
UI Components Integration
External Dependencies
- Popover: Main container for the switcher interface
- Tabs: Multi-tab navigation system
- Command: Searchable/selectable list interface
- ScrollArea: Scrollable content areas for long lists
- Avatar: Assistant avatar display with fallbacks
- Badge: Tool count and status indicators
Icon Usage
- ChevronRight: Expand indicator for main button
- Clock: Recent assistants tab indicator
- Star: Favorites tab indicator
- User: User assistants tab indicator
- Wrench: Tools tab and tool-related indicators
- Settings: Tool configuration and management
- Plus: Assistant creation actions
- ArrowRight: Navigation and external link indicators
Integration Examples
Basic Usage
// Basic implementation with required props
<IntegratedAssistantSwitcher
currentAssistantId="current-assistant-id"
currentAssistant={currentAssistantData}
recentAssistants={recentAssistantsList}
onSelectAssistant={(assistantId) => {
// Handle assistant switching
router.push(`/assistant/${assistantId}`);
}}
tools={enabledToolIds}
/>
Full Feature Usage
// Complete implementation with all features
<IntegratedAssistantSwitcher
currentAssistantId={currentId}
currentAssistant={currentAssistant}
recentAssistants={recentList}
favorites={favoritesList}
userAssistants={userCreatedList}
onSelectAssistant={handleAssistantSelection}
onCreateAssistant={() => router.push('/create')}
tools={enabledTools}
toolConfigs={toolConfigurations}
/>
Integration with Navigation
// Usage within a chat interface with navigation
function ChatInterface() {
const handleAssistantSwitch = (assistantId: string) => {
// Update current chat context
setCurrentAssistant(assistantId);
// Optionally navigate to new URL
router.push(`/assistant/${assistantId}`);
};
return (
<div className="chat-layout">
<IntegratedAssistantSwitcher
currentAssistantId={currentAssistantId}
currentAssistant={currentAssistant}
recentAssistants={recentAssistants}
onSelectAssistant={handleAssistantSwitch}
tools={currentTools}
/>
{/* Rest of chat interface */}
</div>
);
}
Accessibility Considerations
- Keyboard Navigation: All interactive elements are keyboard accessible
- Screen Reader Support: Proper ARIA labels and semantic markup
- Focus Management: Logical tab order and focus indicators
- High Contrast: Good color contrast for text and icons
- Responsive Design: Adapts to different screen sizes and orientations
Performance Optimizations
- Lazy Loading: Assistant lists are only rendered when tabs are active
- Efficient Rendering: Uses Command component for optimized list rendering
- Memoization: Tool objects are calculated once and reused
- Minimal Re-renders: State updates are localized to prevent unnecessary renders
- Scroll Virtualization: ScrollArea handles large lists efficiently
Error Handling
- Missing Data: Graceful handling of undefined assistant data
- Empty States: Helpful messages when lists are empty
- Avatar Fallbacks: Default avatars when images fail to load
- Tool Resolution: Safe handling of missing tool definitions
- Navigation Errors: Error boundaries around navigation actions
Styling and Customization
CSS Classes
- Custom spacing: Specific padding and margin adjustments
- Color variants: Primary, muted, and accent color usage
- Interactive states: Hover, focus, and selected states
- Responsive breakpoints: Mobile-first responsive design
- Animation classes: Smooth transitions and micro-interactions
Theme Integration
- Uses design system tokens for consistent styling
- Adapts to light/dark theme variations
- Maintains brand consistency across the interface
- Supports customization through CSS custom properties