'use client' /** * Agent Templates Gallery * Pre-built agent configurations that users can install in one click. */ import { useState } from 'react' import { Globe, Search, Eye, Settings, Plus, Loader2, } from 'lucide-react' import { toast } from 'sonner' import { useLanguage } from '@/lib/i18n' interface AgentTemplatesProps { onInstalled: () => void existingAgentNames: string[] } const templateConfig = [ { id: 'veilleAI', type: 'scraper', roleKey: 'agents.defaultRoles.scraper', 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', 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', urls: [ 'https://dev.to/feed/tag/javascript', 'https://dev.to/feed/tag/typescript', 'https://dev.to/feed/tag/react', ], frequency: 'weekly' }, { id: 'surveillant', type: 'monitor', roleKey: 'agents.defaultRoles.monitor', urls: [], frequency: 'weekly' }, { id: 'chercheur', type: 'researcher', roleKey: 'agents.defaultRoles.researcher', urls: [], frequency: 'manual' }, ] as const const typeIcons: Record = { scraper: Globe, researcher: Search, monitor: Eye, custom: Settings, } const typeColors: Record = { scraper: 'text-blue-600 bg-blue-50', researcher: 'text-purple-600 bg-purple-50', monitor: 'text-amber-600 bg-amber-50', custom: 'text-green-600 bg-green-50', } export function AgentTemplates({ onInstalled, existingAgentNames }: AgentTemplatesProps) { const { t } = useLanguage() const [installingId, setInstallingId] = useState(null) 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}` } 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: tpl.type === 'scraper' ? ['web_scrape', 'note_create'] : tpl.type === 'researcher' ? ['web_search', 'web_scrape', 'note_search', 'note_create'] : tpl.type === 'monitor' ? ['note_search', 'note_read', 'note_create'] : [], }) toast.success(t('agents.toasts.installSuccess', { name: resolvedName })) onInstalled() } catch { toast.error(t('agents.toasts.installError')) } finally { setInstallingId(null) } } return (

{t('agents.templates.title')}

{templateConfig.map(tpl => { const Icon = 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)}

{t(descKey)}

) })}
) }