improvement: refactor files, subblock spacing

This commit is contained in:
Emir Karabeg
2025-05-04 21:01:32 -07:00
parent 75c6582f91
commit 73600fbdb3
12 changed files with 30 additions and 436 deletions
@@ -10,7 +10,7 @@ import { checkEnvVarTrigger, EnvVarDropdown } from '@/components/ui/env-var-drop
import { checkTagTrigger, TagDropdown } from '@/components/ui/tag-dropdown'
import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
import { useCodeGeneration } from '@/hooks/use-code-generation'
import { useCodeGeneration } from '@/app/w/[id]/hooks/use-code-generation'
import { CodePromptBar } from '../../../../code-prompt-bar/code-prompt-bar'
import { useSubBlockValue } from '../hooks/use-sub-block-value'
@@ -1,14 +1,5 @@
import { useEffect, useMemo, useRef, useState } from 'react'
import { Code, FileJson, Trash2, Wand2, X } from 'lucide-react'
import { Button } from '@/components/ui/button'
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog'
import {
AlertDialog,
AlertDialogAction,
@@ -19,13 +10,22 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog'
import { Button } from '@/components/ui/button'
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog'
import { checkEnvVarTrigger, EnvVarDropdown } from '@/components/ui/env-var-dropdown'
import { Label } from '@/components/ui/label'
import { checkTagTrigger, TagDropdown } from '@/components/ui/tag-dropdown'
import { createLogger } from '@/lib/logs/console-logger'
import { cn } from '@/lib/utils'
import { useCustomToolsStore } from '@/stores/custom-tools/store'
import { useCodeGeneration } from '@/hooks/use-code-generation'
import { useCodeGeneration } from '@/app/w/[id]/hooks/use-code-generation'
import { CodePromptBar } from '../../../../../../../code-prompt-bar/code-prompt-bar'
import { CodeEditor } from '../code-editor/code-editor'
@@ -436,30 +436,30 @@ export function CustomToolModal({
const handleDelete = async () => {
if (!toolId || !isEditing) return
try {
setShowDeleteConfirm(false)
// Call API to delete the tool
const response = await fetch(`/api/tools/custom?id=${toolId}`, {
method: 'DELETE',
})
if (!response.ok) {
const errorData = await response.json().catch(() => ({}))
const errorMessage = errorData.error || response.statusText || 'Failed to delete tool'
throw new Error(errorMessage)
}
// Remove from local store
removeTool(toolId)
logger.info(`Deleted tool: ${toolId}`)
// Notify parent component if callback provided
if (onDelete) {
onDelete(toolId)
}
// Close the modal
handleClose()
} catch (error) {
@@ -489,7 +489,10 @@ export function CustomToolModal({
return (
<>
<Dialog open={open} onOpenChange={handleClose}>
<DialogContent className="sm:max-w-[700px] h-[80vh] flex flex-col p-0 gap-0" hideCloseButton>
<DialogContent
className="sm:max-w-[700px] h-[80vh] flex flex-col p-0 gap-0"
hideCloseButton
>
<DialogHeader className="px-6 py-4 border-b">
<div className="flex items-center justify-between">
<DialogTitle className="text-lg font-medium">
@@ -786,20 +789,23 @@ export function CustomToolModal({
</DialogFooter>
</DialogContent>
</Dialog>
{/* Delete Confirmation Dialog */}
<AlertDialog open={showDeleteConfirm} onOpenChange={setShowDeleteConfirm}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Are you sure you want to delete this tool?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete the tool
and remove it from any workflows that are using it.
This action cannot be undone. This will permanently delete the tool and remove it from
any workflows that are using it.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={handleDelete} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
<AlertDialogAction
onClick={handleDelete}
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
>
Delete
</AlertDialogAction>
</AlertDialogFooter>
@@ -1,3 +1,4 @@
import { Info } from 'lucide-react'
import { Label } from '@/components/ui/label'
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'
import { useSubBlockStore } from '@/stores/workflows/subblock/store'
@@ -25,7 +26,6 @@ import { Table } from './components/table'
import { TimeInput } from './components/time-input'
import { ToolInput } from './components/tool-input/tool-input'
import { WebhookConfig } from './components/webhook/webhook-config'
import { Info } from 'lucide-react'
interface SubBlockProps {
blockId: string
@@ -191,7 +191,7 @@ export function SubBlock({ blockId, config, isConnecting }: SubBlockProps) {
const required = isFieldRequired()
return (
<div className="space-y-1" onMouseDown={handleMouseDown}>
<div className="space-y-[6px] pt-[2px]" onMouseDown={handleMouseDown}>
{config.type !== 'switch' && (
<Label className="flex items-center gap-1">
{config.title}
-62
View File
@@ -1,62 +0,0 @@
'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 <div>Loading agent builder...</div>
}
if (error) {
return <div>Error: {error}</div>
}
return (
<div className="agents-container">
<div className="agents-layout">
{/* Main content would be rendered here */}
<div className="agents-empty-state">
<h1>Agent Builder</h1>
<p>Create and manage your AI agents</p>
<p>Total agents: {agents.length}</p>
<p>Total MCP servers: {mcpServers.length}</p>
<p>This is a placeholder. Implement your components in the respective folders.</p>
</div>
</div>
</div>
)
}
@@ -1,8 +0,0 @@
/**
* 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
*/
@@ -1,10 +0,0 @@
/**
* 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
*/
-3
View File
@@ -1,3 +0,0 @@
import Agents from './agents'
export default Agents
-190
View File
@@ -1,190 +0,0 @@
/**
* 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 { Agent, AgentState, ChatMessage, ChatSession, MCPServer } from './types'
export const useAgentStore = create<AgentState>((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 })
},
}))
-109
View File
@@ -1,109 +0,0 @@
/**
* 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<Agent>) => void
deleteAgent: (id: string) => void
selectAgent: (id: string | null) => void
setMCPServers: (servers: MCPServer[]) => void
addMCPServer: (server: MCPServer) => void
updateMCPServer: (id: string, updates: Partial<MCPServer>) => void
deleteMCPServer: (id: string) => void
setChatSessions: (sessions: ChatSession[]) => void
addChatSession: (session: ChatSession) => void
updateChatSession: (id: string, updates: Partial<ChatSession>) => 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
}
-15
View File
@@ -1,15 +0,0 @@
/**
* 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
*/
-15
View File
@@ -1,15 +0,0 @@
/**
* 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
*/