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>
// 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

  1. Keyboard Navigation: All interactive elements are keyboard accessible
  2. Screen Reader Support: Proper ARIA labels and semantic markup
  3. Focus Management: Logical tab order and focus indicators
  4. High Contrast: Good color contrast for text and icons
  5. Responsive Design: Adapts to different screen sizes and orientations

Performance Optimizations

  1. Lazy Loading: Assistant lists are only rendered when tabs are active
  2. Efficient Rendering: Uses Command component for optimized list rendering
  3. Memoization: Tool objects are calculated once and reused
  4. Minimal Re-renders: State updates are localized to prevent unnecessary renders
  5. Scroll Virtualization: ScrollArea handles large lists efficiently

Error Handling

  1. Missing Data: Graceful handling of undefined assistant data
  2. Empty States: Helpful messages when lists are empty
  3. Avatar Fallbacks: Default avatars when images fail to load
  4. Tool Resolution: Safe handling of missing tool definitions
  5. 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