-
- {toolInfo.icon}
-
-
-
-
- {getToolDisplayName(toolName)}
-
-
handleToolToggle(toolName, checked)}
- className="flex-shrink-0"
- disabled={disabled}
- />
+
+
+ {toolInfo.icon}
-
- {toolInfo.description}
-
+
+
+
+ {getToolDisplayName(toolName)}
+
+
+
+ {toolInfo.description}
+
+
+
+
+ handleToolToggle(toolName, checked)}
+ disabled={disabled}
+ />
))}
{getFilteredTools().length === 0 && (
-
-
🔍
-
No tools found
-
Try adjusting your search criteria
+
+
+
+
+
+ No tools found
+
+
+ Try adjusting your search criteria
+
)}
diff --git a/frontend/src/components/agents/config/configuration-tab.tsx b/frontend/src/components/agents/config/configuration-tab.tsx
index 80ce2bb8..b5c0657b 100644
--- a/frontend/src/components/agents/config/configuration-tab.tsx
+++ b/frontend/src/components/agents/config/configuration-tab.tsx
@@ -393,7 +393,6 @@ export function ConfigurationTab({
-
Triggers
diff --git a/frontend/src/components/agents/knowledge-base/agent-knowledge-base-manager.tsx b/frontend/src/components/agents/knowledge-base/agent-knowledge-base-manager.tsx
index a7f0cc5c..92e1a438 100644
--- a/frontend/src/components/agents/knowledge-base/agent-knowledge-base-manager.tsx
+++ b/frontend/src/components/agents/knowledge-base/agent-knowledge-base-manager.tsx
@@ -9,7 +9,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@
import { Badge } from '@/components/ui/badge';
import { Skeleton } from '@/components/ui/skeleton';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
+import { CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import {
Plus,
Edit2,
@@ -621,7 +621,7 @@ export const AgentKnowledgeBaseManager = ({ agentId, agentName }: AgentKnowledge
return (
)}
-
-
-
setSearchQuery(e.target.value)}
- className="pl-9"
- />
+
+
Knowledge Base
+
Upload and manage knowledge for the agent
+
+
+
+
+ setSearchQuery(e.target.value)}
+ className="pl-9 h-9 w-48"
+ />
+
+
handleOpenAddDialog()} size="sm" className="gap-2">
+
+ Add Knowledge
+
-
handleOpenAddDialog()} className="gap-2 ml-4">
-
- Add Knowledge
-
{entries.length === 0 ? (
-
No Agent Knowledge Entries
-
+
No knowledge entries
+
Add knowledge entries to provide {agentName} with specialized context,
guidelines, and information it should always remember.
@@ -667,9 +673,16 @@ export const AgentKnowledgeBaseManager = ({ agentId, agentName }: AgentKnowledge
) : (
{filteredEntries.length === 0 ? (
-
-
-
No entries match your search
+
+
+
+
+
+ No entries match your search
+
+
+ Try adjusting your search criteria or add new knowledge entries
+
) : (
filteredEntries.map((entry) => {
@@ -678,106 +691,70 @@ export const AgentKnowledgeBaseManager = ({ agentId, agentName }: AgentKnowledge
const SourceIcon = getSourceIcon(entry.source_type || 'manual', entry.source_metadata?.filename);
return (
-
-
-
-
-
-
-
{entry.name}
- {!entry.is_active && (
-
-
- Disabled
-
- )}
- {entry.source_type && entry.source_type !== 'manual' && (
-
- {entry.source_type === 'git_repo' ? 'Git' :
- entry.source_type === 'zip_extracted' ? 'ZIP' : 'File'}
-
- )}
-
- {entry.description && (
-
- {entry.description}
-
- )}
-
- {entry.content}
-
-
-
-
-
- {contextConfig.label}
-
-
-
- {new Date(entry.created_at).toLocaleDateString()}
-
- {entry.file_size && (
-
- {(entry.file_size / 1024).toFixed(1)}KB
-
- )}
-
- {entry.content_tokens && (
-
- ~{entry.content_tokens.toLocaleString()} tokens
-
- )}
-
-
-
-
-
-
-
-
-
- handleOpenEditDialog(entry)}>
-
- Edit
-
- handleToggleActive(entry)}>
- {entry.is_active ? (
- <>
-
- Disable
- >
- ) : (
- <>
-
- Enable
- >
- )}
-
-
- setDeleteEntryId(entry.entry_id)}
- className="text-destructive focus:bg-destructive/10 focus:text-destructive"
- >
-
- Delete
-
-
-
+
+
+
{entry.name}
+ {entry.source_type && entry.source_type !== 'manual' && (
+
+ {entry.source_type === 'git_repo' ? 'Git' :
+ entry.source_type === 'zip_extracted' ? 'ZIP' : 'File'}
+
+ )}
-
-
+ {entry.description && (
+
+ {entry.description}
+
+ )}
+
+ {entry.content}
+
+
+
+
+
+ {contextConfig.label}
+
+
+
+ {new Date(entry.created_at).toLocaleDateString()}
+
+ {entry.file_size && (
+
+ {(entry.file_size / 1024).toFixed(1)}KB
+
+ )}
+
+ {entry.content_tokens && (
+
+ ~{entry.content_tokens.toLocaleString()} tokens
+
+ )}
+
+
+
+ handleOpenEditDialog(entry)}
+ >
+
+
+ setDeleteEntryId(entry.entry_id)}
+ >
+
+
+
+
);
})
)}
diff --git a/frontend/src/components/agents/mcp/configured-mcp-list.tsx b/frontend/src/components/agents/mcp/configured-mcp-list.tsx
index 982ac13e..2560b24b 100644
--- a/frontend/src/components/agents/mcp/configured-mcp-list.tsx
+++ b/frontend/src/components/agents/mcp/configured-mcp-list.tsx
@@ -2,7 +2,17 @@ import React from 'react';
import { Card } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
-import { Settings, X, Sparkles, Key, AlertTriangle } from 'lucide-react';
+import { Settings, X, Sparkles, Key, AlertTriangle, Trash2 } from 'lucide-react';
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+} from '@/components/ui/alert-dialog';
import { MCPConfiguration } from './types';
import { useCredentialProfilesForMcp } from '@/hooks/react-query/mcp/use-credential-profiles';
@@ -50,7 +60,7 @@ const MCPLogo: React.FC<{ mcp: MCPConfiguration }> = ({ mcp }) => {
const firstLetter = mcp.name.charAt(0).toUpperCase();
return (
-
+
{logoUrl ? (
-
-
+
+
+
-
-
-
-
{mcp.enabledTools?.length || 0} tools enabled
- {hasCredentialProfile && (
-
-
-
- {selectedProfile.profile_name}
-
-
- )}
-
+
+
+
+
{mcp.name}
+
+
+
{mcp.enabledTools?.length || 0} tools enabled
+ {hasCredentialProfile && (
+
+
+
+ {selectedProfile.profile_name}
+
+
+ )}
-
- {onConfigureTools && (
- onConfigureTools(index)}
- title="Configure tools"
- >
-
-
- )}
+
+
+ {onConfigureTools && (
onRemove(index)}
- title="Remove integration"
+ className="h-8 w-8 p-0"
+ onClick={() => onConfigureTools(index)}
+ title="Configure tools"
>
-
+
-
+ )}
+
onRemove(index)}
+ title="Remove integration"
+ >
+
+
-
+
);
};
@@ -139,20 +151,58 @@ export const ConfiguredMcpList: React.FC
= ({
onRemove,
onConfigureTools,
}) => {
+ const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);
+ const [mcpToDelete, setMcpToDelete] = React.useState<{ mcp: MCPConfiguration; index: number } | null>(null);
+
+ const handleDeleteClick = (mcp: MCPConfiguration, index: number) => {
+ setMcpToDelete({ mcp, index });
+ setDeleteDialogOpen(true);
+ };
+
+ const confirmDelete = () => {
+ if (mcpToDelete) {
+ onRemove(mcpToDelete.index);
+ setMcpToDelete(null);
+ setDeleteDialogOpen(false);
+ }
+ };
+
if (configuredMCPs.length === 0) return null;
return (
-
- {configuredMCPs.map((mcp, index) => (
-
- ))}
-
+ <>
+
+ {configuredMCPs.map((mcp, index) => (
+ handleDeleteClick(mcp, idx)}
+ onConfigureTools={onConfigureTools}
+ />
+ ))}
+
+
+
+
+
+ Remove Integration
+
+ Are you sure you want to remove the "{mcpToDelete?.mcp.name}" integration? This will disconnect all associated tools and cannot be undone.
+
+
+
+ Cancel
+
+ Remove Integration
+
+
+
+
+ >
);
};
\ No newline at end of file
diff --git a/frontend/src/components/agents/mcp/mcp-configuration-new.tsx b/frontend/src/components/agents/mcp/mcp-configuration-new.tsx
index 878a097f..e8da9587 100644
--- a/frontend/src/components/agents/mcp/mcp-configuration-new.tsx
+++ b/frontend/src/components/agents/mcp/mcp-configuration-new.tsx
@@ -110,56 +110,46 @@ export const MCPConfigurationNew: React.FC = ({
};
return (
-
-
- {configuredMCPs.length === 0 && (
-
-
-
-
-
- No integrations configured
-
-
- Browse the app registry to connect your apps through Composio or add custom MCP servers
-
-
- setShowRegistryDialog(true)} variant="default">
-
- Browse Apps
-
- setShowCustomDialog(true)} variant="outline">
-
- Custom MCP
-
-
-
- )}
-
- {configuredMCPs.length > 0 && (
-
-
-
- )}
+
+
+
+
Integrations
+
Connect external services via MCPs
+
+
+ setShowRegistryDialog(true)} size="sm" variant="default" className="gap-2">
+
+ Browse Apps
+
+ setShowCustomDialog(true)} size="sm" variant="outline" className="gap-2">
+
+ Custom MCP
+
+
- {configuredMCPs.length > 0 && (
-
-
-
setShowRegistryDialog(true)} variant="default">
-
- Browse Apps
-
-
setShowCustomDialog(true)} variant="outline">
-
- Custom MCP
-
+ {configuredMCPs.length === 0 && (
+
+
+
+
+ No integrations configured
+
+
+ Browse the app registry to connect your apps through Composio or add custom MCP servers
+
+
+ )}
+
+ {configuredMCPs.length > 0 && (
+
+
)}
diff --git a/frontend/src/components/agents/playbooks/agent-playbooks-configuration.tsx b/frontend/src/components/agents/playbooks/agent-playbooks-configuration.tsx
index 95192d54..1a7f4224 100644
--- a/frontend/src/components/agents/playbooks/agent-playbooks-configuration.tsx
+++ b/frontend/src/components/agents/playbooks/agent-playbooks-configuration.tsx
@@ -59,47 +59,59 @@ export function AgentPlaybooksConfiguration({ agentId, agentName }: AgentPlayboo
return (
-
-
-
-
Playbooks
-
Lightweight, variable-driven instructions stored via workflows
-
+
+
Playbooks
+
Simple variable-driven runs
-
{ setEditing(null); setIsCreateOpen(true); }}>
- New Playbook
+ { setEditing(null); setIsCreateOpen(true); }} size="sm" className="gap-2">
+
+ New Playbook
{isLoading ? (
Loading...
) : playbooks.length === 0 ? (
-
No playbooks yet.
+
+
+
+
+
+ No playbooks yet
+
+
+ Create your first playbook to automate common workflows with variable-driven runs
+
+
) : (
-
+
{playbooks.map((pb) => (
-
-
-
-
{pb.name}
- {pb.description ? (
-
{pb.description}
- ) : null}
+
+
+
+
-
-
-
{ setEditing(pb); setIsCreateOpen(true); }} aria-label="Edit playbook">
-
-
-
handleDelete(pb)} aria-label="Delete playbook">
-
-
-
setExecuting(pb)} aria-label="Run playbook">
-
-
+
+
+
{pb.name}
+
+ {pb.description && (
+
{pb.description}
+ )}
-
+
+
setExecuting(pb)} aria-label="Run playbook">
+
+
+
{ setEditing(pb); setIsCreateOpen(true); }} aria-label="Edit playbook">
+
+
+
handleDelete(pb)} aria-label="Delete playbook">
+
+
+
+
))}
)}
diff --git a/frontend/src/components/agents/triggers/agent-triggers-configuration.tsx b/frontend/src/components/agents/triggers/agent-triggers-configuration.tsx
index 56ae096c..89ff935d 100644
--- a/frontend/src/components/agents/triggers/agent-triggers-configuration.tsx
+++ b/frontend/src/components/agents/triggers/agent-triggers-configuration.tsx
@@ -127,35 +127,38 @@ export const AgentTriggersConfiguration: React.FC
-
-
-
- {triggers.length > 0 && (
-
- )}
-
- {!isLoading && triggers.length === 0 && (
-
-
-
-
-
- No triggers configured
-
-
- Click on a trigger provider above to get started
-
-
- )}
+
+
+
Triggers
+
Set up automated agent runs
+
+
+ {triggers.length > 0 && (
+
+ )}
+
+ {!isLoading && triggers.length === 0 && (
+
+
+
+
+
+ No triggers configured
+
+
+ Click on a trigger provider above to get started
+
+
+ )}
+
{configuringProvider && (
setConfiguringProvider(null)}>
= ({
onToggle,
isLoading = false,
}) => {
+ const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false);
+ const [triggerToDelete, setTriggerToDelete] = React.useState(null);
+
+ const handleDeleteClick = (trigger: TriggerConfiguration) => {
+ setTriggerToDelete(trigger);
+ setDeleteDialogOpen(true);
+ };
+
+ const confirmDelete = () => {
+ if (triggerToDelete) {
+ onRemove(triggerToDelete);
+ setTriggerToDelete(null);
+ setDeleteDialogOpen(false);
+ }
+ };
+
return (
@@ -147,7 +173,7 @@ export const ConfiguredTriggersList: React.FC = ({
)}
-
+
@@ -185,7 +211,7 @@ export const ConfiguredTriggersList: React.FC = ({
onRemove(trigger)}
+ onClick={() => handleDeleteClick(trigger)}
className="h-8 w-8 p-0 text-destructive hover:text-destructive"
disabled={isLoading}
>
@@ -200,6 +226,26 @@ export const ConfiguredTriggersList: React.FC = ({
))}
+
+
+
+
+ Delete Trigger
+
+ Are you sure you want to delete "{triggerToDelete?.name}"? This action cannot be undone and will stop all automated runs from this trigger.
+
+
+
+ Cancel
+
+ Delete Trigger
+
+
+
+
);
};
\ No newline at end of file