| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- 'use client';
- import { Label } from '@/components/ui/label';
- import { Input } from '@/components/ui/input';
- import { Checkbox } from '@/components/ui/checkbox';
- import { AlertCircle, User, Users, Sparkles, Info } from 'lucide-react';
- import { cn } from '@/lib/utils';
- import { useI18n } from '@/lib/hooks/use-i18n';
- import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
- interface Agent {
- id: string;
- name: string;
- avatar: string;
- role: string;
- priority: number;
- allowedActions: string[];
- }
- interface AgentSettingsProps {
- agents: Agent[];
- selectedAgentIds: string[];
- maxTurns: string;
- agentMode: 'preset' | 'auto';
- onToggleAgent: (agentId: string) => void;
- onMaxTurnsChange: (value: string) => void;
- onAgentModeChange: (mode: 'preset' | 'auto') => void;
- }
- export function AgentSettings({
- agents,
- selectedAgentIds,
- maxTurns,
- agentMode,
- onToggleAgent,
- onMaxTurnsChange,
- onAgentModeChange,
- }: AgentSettingsProps) {
- const { t } = useI18n();
- const getAgentName = (agent: Agent) => {
- const key = `settings.agentNames.${agent.id}`;
- const translated = t(key);
- return translated !== key ? translated : agent.name;
- };
- const getAgentRole = (agent: Agent) => {
- const key = `settings.agentRoles.${agent.role}`;
- const translated = t(key);
- return translated !== key ? translated : agent.role;
- };
- return (
- <div className="space-y-6 max-w-2xl">
- <div className="space-y-4">
- {/* Mode Toggle */}
- <div className="space-y-2">
- <Label>{t('settings.agentMode')}</Label>
- <div className="inline-flex rounded-lg border bg-muted/30 p-0.5">
- <button
- onClick={() => onAgentModeChange('preset')}
- className={cn(
- 'px-4 py-1.5 text-sm font-medium rounded-md transition-all',
- agentMode === 'preset'
- ? 'bg-background shadow-sm text-foreground'
- : 'text-muted-foreground hover:text-foreground',
- )}
- >
- {t('settings.agentModePreset')}
- </button>
- <button
- onClick={() => onAgentModeChange('auto')}
- className={cn(
- 'px-4 py-1.5 text-sm font-medium rounded-md transition-all flex items-center gap-1.5',
- agentMode === 'auto'
- ? 'bg-background shadow-sm text-foreground'
- : 'text-muted-foreground hover:text-foreground',
- )}
- >
- <Sparkles className="h-3.5 w-3.5" />
- {t('settings.agentModeAuto')}
- </button>
- </div>
- </div>
- {agentMode === 'preset' ? (
- <>
- {/* Preset mode: existing agent multi-select */}
- <div className="space-y-2">
- <Label>{t('settings.selectAgents')}</Label>
- <p className="text-sm text-muted-foreground">{t('settings.agentSettingsDesc')}</p>
- </div>
- <div className="space-y-2 border rounded-lg p-2 bg-muted/30">
- {agents.map((agent) => (
- <div
- key={agent.id}
- className={cn(
- 'flex items-center space-x-3 p-3 rounded-lg border transition-all cursor-pointer',
- selectedAgentIds.includes(agent.id)
- ? 'bg-primary/10 border-primary/50 shadow-sm'
- : 'bg-background hover:bg-muted/50 border-transparent',
- )}
- onClick={() => onToggleAgent(agent.id)}
- >
- <Checkbox
- id={`agent-${agent.id}`}
- checked={selectedAgentIds.includes(agent.id)}
- onCheckedChange={() => onToggleAgent(agent.id)}
- disabled={agent.role === 'teacher'}
- />
- <Avatar className="size-10">
- <AvatarImage src={agent.avatar} alt={getAgentName(agent)} />
- <AvatarFallback>{getAgentName(agent).charAt(0)}</AvatarFallback>
- </Avatar>
- <div className="flex-1">
- <div className="font-medium text-sm flex items-center gap-1.5">
- {getAgentName(agent)}
- {agent.role === 'teacher' && (
- <span className="text-[10px] px-1.5 py-0.5 rounded bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300 leading-none">
- {t('settings.required')}
- </span>
- )}
- </div>
- <div className="text-xs text-muted-foreground">{getAgentRole(agent)}</div>
- </div>
- </div>
- ))}
- </div>
- {/* Mode indicator */}
- <div
- className={`p-3 rounded-lg text-sm ${
- selectedAgentIds.length === 0
- ? 'bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-300 border border-red-200 dark:border-red-800'
- : selectedAgentIds.length === 1
- ? 'bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300 border border-blue-200 dark:border-blue-800'
- : 'bg-purple-50 dark:bg-purple-900/20 text-purple-700 dark:text-purple-300 border border-purple-200 dark:border-purple-800'
- }`}
- >
- {selectedAgentIds.length === 0 && (
- <span className="flex items-center gap-1.5">
- <AlertCircle className="h-4 w-4" />
- {t('settings.atLeastOneAgent')}
- </span>
- )}
- {selectedAgentIds.length === 1 && (
- <span className="flex items-center gap-1.5">
- <User className="h-4 w-4" />
- <strong>{t('settings.singleAgentMode')}</strong> -{' '}
- {(() => {
- const agent = agents.find((a) => a.id === selectedAgentIds[0]);
- return agent ? getAgentName(agent) : t('settings.selectedAgent');
- })()}{' '}
- {t('settings.directAnswer')}
- </span>
- )}
- {selectedAgentIds.length > 1 && (
- <span className="flex items-center gap-1.5">
- <Users className="h-4 w-4" />
- <strong>{t('settings.multiAgentMode')}</strong> -{' '}
- {t('settings.agentsCollaboratingCount', {
- count: selectedAgentIds.length,
- })}
- </span>
- )}
- </div>
- {/* Max turns config - only show for multi-agent */}
- {selectedAgentIds.length > 1 && (
- <div className="space-y-2 border-l-4 border-purple-500 pl-4">
- <Label>{t('settings.maxTurns')}</Label>
- <p className="text-xs text-muted-foreground">{t('settings.maxTurnsDesc')}</p>
- <Input
- type="number"
- min="1"
- max="20"
- value={maxTurns}
- onChange={(e) => onMaxTurnsChange(e.target.value)}
- className="w-24"
- />
- </div>
- )}
- </>
- ) : (
- <>
- {/* Auto mode: description */}
- <div className="flex items-start gap-2.5 p-3 rounded-lg bg-green-50 dark:bg-green-900/20 text-green-700 dark:text-green-300 border border-green-200 dark:border-green-800 text-sm">
- <Info className="h-4 w-4 mt-0.5 shrink-0" />
- <span>{t('settings.agentModeAutoDesc')}</span>
- </div>
- </>
- )}
- </div>
- </div>
- );
- }
|