diff --git a/sim/app/w/agents/agents.tsx b/sim/app/w/agents/agents.tsx new file mode 100644 index 0000000000..7dc45ca045 --- /dev/null +++ b/sim/app/w/agents/agents.tsx @@ -0,0 +1,62 @@ +'use client' + +import { useEffect } from 'react' +import { useAgentStore } from './stores/store' + +/** + * Main Agent Builder Component + * + * This is the root component for the Agent Builder application: + * - Initializes and manages application state + * - Coordinates between components + * - Handles loading states and errors + * - Renders the main application layout + * + * @module Agents + */ + +export default function Agents() { + const { + agents, + filteredAgents, + mcpServers, + loading, + error, + setLoading, + setError, + setAgents, + setMCPServers, + } = useAgentStore() + + // Initialize store data on component mount + useEffect(() => { + // This would typically fetch data from an API + // For now, we'll just initialize with empty arrays + setAgents([]) + setMCPServers([]) + setLoading(false) + }, [setAgents, setMCPServers, setLoading]) + + if (loading) { + return
Loading agent builder...
+ } + + if (error) { + return
Error: {error}
+ } + + return ( +
+
+ {/* Main content would be rendered here */} +
+

Agent Builder

+

Create and manage your AI agents

+

Total agents: {agents.length}

+

Total MCP servers: {mcpServers.length}

+

This is a placeholder. Implement your components in the respective folders.

+
+
+
+ ) +} diff --git a/sim/app/w/agents/components/sidebar/sidebar.tsx b/sim/app/w/agents/components/sidebar/sidebar.tsx new file mode 100644 index 0000000000..4f48785257 --- /dev/null +++ b/sim/app/w/agents/components/sidebar/sidebar.tsx @@ -0,0 +1,8 @@ +/** + * Sidebar component for the Agent Builder + * + * This component provides navigation and management for agents: + * - Lists all available agents + * - Allows creation of new agents + * - Handles agent selection + */ diff --git a/sim/app/w/agents/components/toolbar/toolbar.tsx b/sim/app/w/agents/components/toolbar/toolbar.tsx new file mode 100644 index 0000000000..a72b12e553 --- /dev/null +++ b/sim/app/w/agents/components/toolbar/toolbar.tsx @@ -0,0 +1,10 @@ +/** + * Toolbar component for the Agent Builder + * + * This component provides configuration tools for agents: + * - Model selection controls + * - MCP server connection management + * - Prompt configuration options + * - Testing and deployment actions + * - Save/publish functionality + */ diff --git a/sim/app/w/agents/page.tsx b/sim/app/w/agents/page.tsx new file mode 100644 index 0000000000..9cdc64f758 --- /dev/null +++ b/sim/app/w/agents/page.tsx @@ -0,0 +1,3 @@ +import Agents from './agents' + +export default Agents diff --git a/sim/app/w/agents/stores/store.ts b/sim/app/w/agents/stores/store.ts new file mode 100644 index 0000000000..1b750ff0a4 --- /dev/null +++ b/sim/app/w/agents/stores/store.ts @@ -0,0 +1,190 @@ +/** + * Agent Builder Zustand Store + * + * Central state management for the Agent Builder application: + * - Maintains collections of agents, MCP servers, and chat sessions + * - Handles CRUD operations for all entities + * - Manages UI state including selections, filters, and sorting + * - Provides actions for modifying state + * - Implements filtering and sorting logic + * + * @module AgentStore + */ + +import { create } from 'zustand' +import { AgentState, Agent, MCPServer, ChatSession, ChatMessage } from './types' + +export const useAgentStore = create((set, get) => ({ + // Collections + agents: [], + mcpServers: [], + chatSessions: [], + + // UI state + selectedAgentId: null, + selectedSessionId: null, + isCreatingAgent: false, + isEditingAgent: false, + sortBy: 'name', + sortDirection: 'asc', + searchQuery: '', + filteredAgents: [], + + // Status + loading: true, + error: null, + + // Agent actions + setAgents: (agents) => { + set({ agents, filteredAgents: agents, loading: false }) + get().applyFilters() + }, + + addAgent: (agent) => { + set((state) => ({ + agents: [...state.agents, agent], + loading: false + })) + get().applyFilters() + }, + + updateAgent: (id, updates) => { + set((state) => ({ + agents: state.agents.map(agent => + agent.id === id ? { ...agent, ...updates } : agent + ) + })) + get().applyFilters() + }, + + deleteAgent: (id) => { + set((state) => ({ + agents: state.agents.filter(agent => agent.id !== id) + })) + get().applyFilters() + }, + + selectAgent: (id) => { + set({ selectedAgentId: id }) + }, + + // MCP Server actions + setMCPServers: (servers) => { + set({ mcpServers: servers }) + }, + + addMCPServer: (server) => { + set((state) => ({ + mcpServers: [...state.mcpServers, server] + })) + }, + + updateMCPServer: (id, updates) => { + set((state) => ({ + mcpServers: state.mcpServers.map(server => + server.id === id ? { ...server, ...updates } : server + ) + })) + }, + + deleteMCPServer: (id) => { + set((state) => ({ + mcpServers: state.mcpServers.filter(server => server.id !== id) + })) + }, + + // Chat session actions + setChatSessions: (sessions) => { + set({ chatSessions: sessions }) + }, + + addChatSession: (session) => { + set((state) => ({ + chatSessions: [...state.chatSessions, session] + })) + }, + + updateChatSession: (id, updates) => { + set((state) => ({ + chatSessions: state.chatSessions.map(session => + session.id === id ? { ...session, ...updates } : session + ) + })) + }, + + deleteChatSession: (id) => { + set((state) => ({ + chatSessions: state.chatSessions.filter(session => session.id !== id) + })) + }, + + selectChatSession: (id) => { + set({ selectedSessionId: id }) + }, + + addMessageToSession: (sessionId, message) => { + set((state) => ({ + chatSessions: state.chatSessions.map(session => + session.id === sessionId + ? { ...session, messages: [...session.messages, message] } + : session + ) + })) + }, + + // UI state actions + setSearchQuery: (query) => { + set({ searchQuery: query }) + get().applyFilters() + }, + + setSortBy: (sortBy) => { + set({ sortBy }) + get().applyFilters() + }, + + setSortDirection: (direction) => { + set({ sortDirection: direction }) + get().applyFilters() + }, + + // Status actions + setLoading: (loading) => set({ loading }), + setError: (error) => set({ error }), + + // Filters and sorting + applyFilters: () => { + const { agents, searchQuery, sortBy, sortDirection } = get() + + // Filter by search query + let filtered = [...agents] + if (searchQuery.trim()) { + const query = searchQuery.toLowerCase().trim() + filtered = filtered.filter(agent => + agent.name.toLowerCase().includes(query) || + agent.description.toLowerCase().includes(query) + ) + } + + // Sort agents + filtered.sort((a, b) => { + let comparison = 0 + + switch (sortBy) { + case 'name': + comparison = a.name.localeCompare(b.name) + break + case 'createdAt': + comparison = new Date(a.config.createdAt).getTime() - new Date(b.config.createdAt).getTime() + break + case 'updatedAt': + comparison = new Date(a.config.updatedAt).getTime() - new Date(b.config.updatedAt).getTime() + break + } + + return sortDirection === 'asc' ? comparison : -comparison + }) + + set({ filteredAgents: filtered }) + } +})) \ No newline at end of file diff --git a/sim/app/w/agents/stores/types.ts b/sim/app/w/agents/stores/types.ts new file mode 100644 index 0000000000..0d2ebf8feb --- /dev/null +++ b/sim/app/w/agents/stores/types.ts @@ -0,0 +1,109 @@ +/** + * Type Definitions for Agent Builder + * + * This module defines the TypeScript interfaces and types used throughout the Agent Builder: + * - Data models for agents, MCP servers, and chat sessions + * - State interfaces for Zustand stores + * - Type definitions for UI state and actions + * - Utility types for filtering and sorting + * + * @module AgentTypes + */ + +export interface MCPServer { + id: string + name: string + url: string + apiKey?: string + status: 'connected' | 'disconnected' | 'error' + lastConnected?: string +} + +export interface AgentConfig { + id: string + name: string + description: string + model: string + systemPrompt: string + mcpServerId?: string + createdAt: string + updatedAt: string +} + +export interface Agent { + id: string + name: string + description: string + config: AgentConfig + mcpServer?: MCPServer +} + +export interface ChatMessage { + id: string + agentId: string + role: 'user' | 'assistant' | 'system' + content: string + timestamp: string +} + +export interface ChatSession { + id: string + agentId: string + name: string + messages: ChatMessage[] + createdAt: string + updatedAt: string +} + +type AgentSortOption = 'name' | 'createdAt' | 'updatedAt' +type SortDirection = 'asc' | 'desc' + +export interface AgentState { + // Collections + agents: Agent[] + mcpServers: MCPServer[] + chatSessions: ChatSession[] + + // UI state + selectedAgentId: string | null + selectedSessionId: string | null + isCreatingAgent: boolean + isEditingAgent: boolean + sortBy: AgentSortOption + sortDirection: SortDirection + searchQuery: string + filteredAgents: Agent[] + + // Status + loading: boolean + error: string | null + + // Actions + setAgents: (agents: Agent[]) => void + addAgent: (agent: Agent) => void + updateAgent: (id: string, updates: Partial) => void + deleteAgent: (id: string) => void + selectAgent: (id: string | null) => void + + setMCPServers: (servers: MCPServer[]) => void + addMCPServer: (server: MCPServer) => void + updateMCPServer: (id: string, updates: Partial) => void + deleteMCPServer: (id: string) => void + + setChatSessions: (sessions: ChatSession[]) => void + addChatSession: (session: ChatSession) => void + updateChatSession: (id: string, updates: Partial) => void + deleteChatSession: (id: string) => void + selectChatSession: (id: string | null) => void + addMessageToSession: (sessionId: string, message: ChatMessage) => void + + setSearchQuery: (query: string) => void + setSortBy: (sortBy: AgentSortOption) => void + setSortDirection: (direction: SortDirection) => void + + setLoading: (loading: boolean) => void + setError: (error: string | null) => void + + // Filter and sort + applyFilters: () => void +} \ No newline at end of file diff --git a/sim/app/w/agents/utils/agent.ts b/sim/app/w/agents/utils/agent.ts new file mode 100644 index 0000000000..e867d8af4c --- /dev/null +++ b/sim/app/w/agents/utils/agent.ts @@ -0,0 +1,15 @@ +/** + * Agent Management Utilities + * + * This module provides utilities for working with agent configurations: + * - Validation of agent configurations + * - Creation of default agents with sensible defaults + * - Template generation for common agent use cases + * - ID generation and unique identifier management + * - Configuration transformation and normalization + * + * These utilities help maintain consistency in agent configurations + * and provide helper functions for common agent-related operations. + * + * @module AgentUtils + */ \ No newline at end of file diff --git a/sim/app/w/agents/utils/mcp-server.ts b/sim/app/w/agents/utils/mcp-server.ts new file mode 100644 index 0000000000..62fbc7d5e5 --- /dev/null +++ b/sim/app/w/agents/utils/mcp-server.ts @@ -0,0 +1,15 @@ +/** + * MCP Server Connection Utilities + * + * This module provides utilities for managing connections to MCP servers via Smithery: + * - Connection testing and validation + * - Connection pooling for efficient resource usage + * - Model discovery and capability detection + * - Agent execution on remote servers + * - Health monitoring and status checks + * + * These utilities abstract the complexities of Smithery integration and provide + * a clean API for the rest of the application to use when interacting with MCP servers. + * + * @module MCPServerUtils + */ \ No newline at end of file diff --git a/sim/app/w/components/sidebar/components/nav-item/nav-item.tsx b/sim/app/w/components/sidebar/components/nav-item/nav-item.tsx index 064f670352..b8068b157d 100644 --- a/sim/app/w/components/sidebar/components/nav-item/nav-item.tsx +++ b/sim/app/w/components/sidebar/components/nav-item/nav-item.tsx @@ -22,9 +22,9 @@ export function NavItem({ diff --git a/sim/app/w/components/sidebar/sidebar.tsx b/sim/app/w/components/sidebar/sidebar.tsx index b3e712daeb..898a614abc 100644 --- a/sim/app/w/components/sidebar/sidebar.tsx +++ b/sim/app/w/components/sidebar/sidebar.tsx @@ -4,7 +4,7 @@ import { useMemo, useState } from 'react' import Link from 'next/link' import { usePathname, useRouter } from 'next/navigation' import clsx from 'clsx' -import { HelpCircle, Plus, ScrollText, Settings } from 'lucide-react' +import { Anvil, HelpCircle, Plus, ScrollText, Settings } from 'lucide-react' import { AgentIcon } from '@/components/icons' import { Button } from '@/components/ui/button' import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip' @@ -97,6 +97,28 @@ export function Sidebar() {