'use client' import { useState } from 'react' import { Globe, Search, Eye, Settings, Plus, Loader2, Presentation, Pencil, ListChecks, Newspaper, Youtube, BookMarked, FileText, Tag, Brain, } from 'lucide-react' import { toast } from 'sonner' import { useLanguage } from '@/lib/i18n' interface AgentTemplatesProps { onInstalled: () => void existingAgentNames: string[] } const templateConfig = [ // ── Scrapers & Veille ────────────────────────────────────────────────── { id: 'veilleAI', type: 'scraper', roleKey: 'agents.defaultRoles.scraper', category: 'veille', urls: [ 'https://www.theverge.com/rss/ai-artificial-intelligence/index.xml', 'https://techcrunch.com/category/artificial-intelligence/feed/', 'https://feeds.arstechnica.com/arstechnica/technology-lab', 'https://www.technologyreview.com/feed/', 'https://www.wired.com/feed/', 'https://korben.info/feed', ], frequency: 'weekly' }, { id: 'veilleTech', type: 'scraper', roleKey: 'agents.defaultRoles.scraper', category: 'veille', urls: [ 'https://news.ycombinator.com/rss', 'https://dev.to/feed', 'https://www.producthunt.com/feed', ], frequency: 'daily' }, { id: 'veilleDev', type: 'scraper', roleKey: 'agents.defaultRoles.scraper', category: 'veille', urls: [ 'https://dev.to/feed/tag/javascript', 'https://dev.to/feed/tag/typescript', 'https://dev.to/feed/tag/react', ], frequency: 'weekly' }, // ── Digest & Résumés ────────────────────────────────────────────────── { id: 'dailyDigest', type: 'digest', roleKey: 'agents.defaultRoles.researcher', category: 'digest', urls: [], frequency: 'daily' }, { id: 'weeklyRecap', type: 'monitor', roleKey: 'agents.defaultRoles.monitor', category: 'digest', urls: [], frequency: 'weekly' }, // ── Outils ──────────────────────────────────────────────────────────── { id: 'surveillant', type: 'monitor', roleKey: 'agents.defaultRoles.monitor', category: 'tools', urls: [], frequency: 'weekly' }, { id: 'chercheur', type: 'researcher', roleKey: 'agents.defaultRoles.researcher', category: 'tools', urls: [], frequency: 'manual' }, { id: 'autoTagger', type: 'auto-tagger', roleKey: 'agents.defaultRoles.researcher', category: 'tools', urls: [], frequency: 'weekly' }, // ── Génération ──────────────────────────────────────────────────────── { id: 'slideGenerator', type: 'slide-generator', roleKey: 'agents.defaultRoles.slideGenerator', category: 'generate', urls: [], frequency: 'manual' }, { id: 'excalidrawGenerator', type: 'excalidraw-generator', roleKey: 'agents.defaultRoles.excalidrawGenerator', category: 'generate', urls: [], frequency: 'manual' }, { id: 'taskExtractor', type: 'task-extractor', roleKey: 'agents.defaultRoles.taskExtractor', category: 'generate', urls: [], frequency: 'manual' }, { id: 'knowledgeSynthesis', type: 'researcher', roleKey: 'agents.defaultRoles.researcher', category: 'generate', urls: [], frequency: 'weekly' }, ] as const type TemplateId = typeof templateConfig[number]['id'] type CategoryId = 'all' | 'veille' | 'digest' | 'tools' | 'generate' const CATEGORIES: { id: CategoryId; label: string }[] = [ { id: 'all', label: 'Tous' }, { id: 'veille', label: '📡 Veille' }, { id: 'digest', label: '📰 Digest' }, { id: 'tools', label: '🔧 Outils' }, { id: 'generate', label: '✨ Génération' }, ] const typeIcons: Record = { scraper: Globe, researcher: Search, monitor: Eye, custom: Settings, 'slide-generator': Presentation, 'excalidraw-generator': Pencil, 'task-extractor': ListChecks, digest: Newspaper, 'youtube-transcript': Youtube, 'readwise-sync': BookMarked, 'auto-tagger': Tag, 'knowledge-synthesis': Brain, } // Extra icons for specific template IDs const templateIcons: Partial> = { dailyDigest: Newspaper, weeklyRecap: FileText, autoTagger: Tag, knowledgeSynthesis: Brain, } export function AgentTemplates({ onInstalled, existingAgentNames }: AgentTemplatesProps) { const { t } = useLanguage() const [installingId, setInstallingId] = useState(null) const [activeCategory, setActiveCategory] = useState('all') const handleInstall = async (tpl: typeof templateConfig[number]) => { setInstallingId(tpl.id) try { const { createAgent } = await import('@/app/actions/agent-actions') const nameKey = `agents.templates.${tpl.id}.name` as const const descKey = `agents.templates.${tpl.id}.description` as const const baseName = t(nameKey) let resolvedName = baseName if (existingAgentNames.includes(baseName)) { let n = 2 while (existingAgentNames.includes(`${baseName} ${n}`)) n++ resolvedName = `${baseName} ${n}` } const toolMap: Record = { scraper: ['web_scrape', 'note_create'], researcher: ['web_search', 'web_scrape', 'note_search', 'note_create'], monitor: ['note_search', 'note_read', 'note_create'], 'slide-generator': ['note_search', 'note_read', 'generate_pptx'], 'excalidraw-generator': ['note_search', 'note_read', 'generate_excalidraw'], 'task-extractor': ['note_search', 'note_read', 'task_extract', 'note_create'], digest: ['note_search', 'note_read', 'note_create'], 'auto-tagger': ['note_search', 'note_read', 'note_update'], } await createAgent({ name: resolvedName, description: t(descKey), type: tpl.type, role: t(tpl.roleKey), sourceUrls: tpl.urls.length > 0 ? [...tpl.urls] : undefined, frequency: tpl.frequency, tools: toolMap[tpl.type] ?? [], }) toast.success(t('agents.toasts.installSuccess', { name: resolvedName })) onInstalled() } catch { toast.error(t('agents.toasts.installError')) } finally { setInstallingId(null) } } const filtered = activeCategory === 'all' ? templateConfig : templateConfig.filter((tpl) => tpl.category === activeCategory) return (
{/* Category filter */}
{CATEGORIES.map((cat) => ( ))}
{/* Template grid */}
{filtered.map(tpl => { const Icon = templateIcons[tpl.id as TemplateId] ?? typeIcons[tpl.type] ?? Settings const isInstalling = installingId === tpl.id const nameKey = `agents.templates.${tpl.id}.name` const descKey = `agents.templates.${tpl.id}.description` return (

{t(nameKey)}

{tpl.frequency !== 'manual' && ( {tpl.frequency === 'daily' ? '📅 Quotidien' : '📆 Hebdo'} )}

{t(descKey)}

) })}
) }