From e3ed1a734bb9167451b27f60f68ab1fa42462539 Mon Sep 17 00:00:00 2001 From: WanderMotta Date: Sun, 4 Jan 2026 16:14:31 -0300 Subject: [PATCH] Commit inicial - upload de todos os arquivos da pasta --- .cursorrules | 231 + .dockerignore | 105 + .env.example | 72 + .flake8 | 8 + .gitignore | 132 + CHANGELOG.md | 101 + Dockerfile | 37 + LICENSE | 201 + Makefile | 86 + README.md | 387 ++ alembic.ini | 119 + conftest.py | 82 + docker-compose.yml | 56 + docker_build.sh | 2 + frontend/.cursorrules | 120 + frontend/.dockerignore | 61 + frontend/.env.example | 1 + frontend/.gitignore | 31 + frontend/CHANGELOG.md | 67 + frontend/Dockerfile | 60 + frontend/LICENSE | 201 + frontend/README.md | 237 + frontend/app/agents/AgentCard.tsx | 506 ++ frontend/app/agents/AgentList.tsx | 130 + frontend/app/agents/AgentSidebar.tsx | 186 + frontend/app/agents/AgentTypeSelector.tsx | 96 + frontend/app/agents/EmptyState.tsx | 107 + frontend/app/agents/SearchInput.tsx | 153 + frontend/app/agents/config/A2AAgentConfig.tsx | 73 + frontend/app/agents/config/LLMAgentConfig.tsx | 367 ++ .../agents/config/LoopAgentConfig copy.tsx | 133 + .../app/agents/config/ParallelAgentConfig.tsx | 125 + .../agents/config/SequentialAgentConfig.tsx | 120 + .../app/agents/config/TaskAgentConfig.tsx | 801 +++ .../app/agents/dialogs/AgentToolDialog.tsx | 184 + frontend/app/agents/dialogs/ApiKeysDialog.tsx | 445 ++ .../app/agents/dialogs/ConfirmationDialog.tsx | 93 + .../app/agents/dialogs/CustomMCPDialog.tsx | 237 + .../app/agents/dialogs/CustomToolDialog.tsx | 864 +++ frontend/app/agents/dialogs/FolderDialog.tsx | 158 + .../app/agents/dialogs/ImportAgentDialog.tsx | 239 + frontend/app/agents/dialogs/MCPDialog.tsx | 278 + .../app/agents/dialogs/MoveAgentDialog.tsx | 136 + .../app/agents/dialogs/ShareAgentDialog.tsx | 172 + frontend/app/agents/forms/AgentForm.tsx | 331 + frontend/app/agents/forms/BasicInfoTab.tsx | 243 + .../app/agents/forms/ConfigurationTab.tsx | 722 +++ frontend/app/agents/forms/SubAgentsTab.tsx | 246 + frontend/app/agents/page.tsx | 754 +++ frontend/app/agents/workflows/Canva.tsx | 689 ++ frontend/app/agents/workflows/ContextMenu.tsx | 118 + frontend/app/agents/workflows/HelperLines.tsx | 98 + frontend/app/agents/workflows/NodePanel.tsx | 273 + frontend/app/agents/workflows/canva.css | 188 + .../agents/workflows/edges/DefaultEdge.tsx | 119 + frontend/app/agents/workflows/edges/index.ts | 41 + .../app/agents/workflows/nodes/BaseNode.tsx | 166 + .../components/agent/AgentChatMessageList.tsx | 347 + .../nodes/components/agent/AgentForm.tsx | 631 ++ .../nodes/components/agent/AgentNode.tsx | 176 + .../components/agent/AgentTestChatModal.tsx | 470 ++ .../nodes/components/agent/styles.css | 68 + .../components/condition/ConditionDialog.tsx | 283 + .../components/condition/ConditionForm.tsx | 290 + .../components/condition/ConditionNode.tsx | 204 + .../nodes/components/delay/DelayForm.tsx | 256 + .../nodes/components/delay/DelayNode.tsx | 146 + .../nodes/components/message/MessageForm.tsx | 292 + .../nodes/components/message/MessageNode.tsx | 162 + .../nodes/components/start/StartNode.tsx | 100 + frontend/app/agents/workflows/nodes/index.ts | 109 + .../agents/workflows/nodes/nodeFunctions.ts | 65 + frontend/app/agents/workflows/nodes/style.css | 54 + frontend/app/agents/workflows/page.tsx | 218 + frontend/app/agents/workflows/utils.ts | 199 + .../app/chat/components/AgentInfoDialog.tsx | 497 ++ .../app/chat/components/AttachedFiles.tsx | 158 + .../app/chat/components/ChatContainer.tsx | 190 + frontend/app/chat/components/ChatInput.tsx | 270 + frontend/app/chat/components/ChatMessage.tsx | 375 ++ frontend/app/chat/components/FileUpload.tsx | 185 + .../chat/components/InlineDataAttachments.tsx | 182 + frontend/app/chat/components/SessionList.tsx | 248 + frontend/app/chat/page.tsx | 881 +++ frontend/app/client-layout.tsx | 52 + frontend/app/clients/loading.tsx | 31 + frontend/app/clients/page.tsx | 462 ++ .../components/A2AComplianceCard.tsx | 333 + .../documentation/components/CodeBlock.tsx | 78 + .../components/CodeExamplesSection.tsx | 317 + .../components/DocumentationSection.tsx | 588 ++ .../FrontendImplementationSection.tsx | 796 +++ .../documentation/components/HttpLabForm.tsx | 523 ++ .../documentation/components/LabSection.tsx | 201 + .../components/QuickStartTemplates.tsx | 179 + .../components/StreamLabForm.tsx | 366 ++ .../components/TechnicalDetailsSection.tsx | 470 ++ frontend/app/documentation/page.tsx | 1611 +++++ frontend/app/globals.css | 87 + frontend/app/layout.tsx | 73 + frontend/app/login/page.tsx | 556 ++ frontend/app/logout/page.tsx | 75 + frontend/app/mcp-servers/loading.tsx | 31 + frontend/app/mcp-servers/page.tsx | 940 +++ frontend/app/page.tsx | 33 + frontend/app/profile/page.tsx | 190 + frontend/app/security/page.tsx | 163 + frontend/app/security/reset-password/page.tsx | 198 + frontend/app/security/verify-email/page.tsx | 119 + frontend/app/shared-chat/AgentInfo.tsx | 302 + .../components/SharedChatPanel.tsx | 180 + .../components/SharedSessionList.tsx | 204 + frontend/app/shared-chat/page.tsx | 717 ++ frontend/components.json | 21 + frontend/components/ImpersonationBar.tsx | 129 + frontend/components/sidebar.tsx | 357 + frontend/components/theme-provider.tsx | 39 + frontend/components/toaster.tsx | 52 + frontend/components/ui/accordion.tsx | 58 + frontend/components/ui/alert-dialog.tsx | 141 + frontend/components/ui/alert.tsx | 59 + frontend/components/ui/aspect-ratio.tsx | 7 + frontend/components/ui/avatar.tsx | 50 + frontend/components/ui/badge.tsx | 29 + frontend/components/ui/breadcrumb.tsx | 115 + frontend/components/ui/button.tsx | 56 + frontend/components/ui/calendar.tsx | 66 + frontend/components/ui/card.tsx | 79 + frontend/components/ui/carousel.tsx | 262 + frontend/components/ui/chart.tsx | 365 ++ frontend/components/ui/checkbox.tsx | 28 + frontend/components/ui/collapsible.tsx | 11 + frontend/components/ui/command.tsx | 153 + frontend/components/ui/context-menu.tsx | 200 + frontend/components/ui/dialog.tsx | 122 + frontend/components/ui/drawer.tsx | 118 + frontend/components/ui/dropdown-menu.tsx | 200 + frontend/components/ui/form.tsx | 178 + frontend/components/ui/hover-card.tsx | 29 + frontend/components/ui/input-otp.tsx | 71 + frontend/components/ui/input.tsx | 22 + frontend/components/ui/label.tsx | 26 + frontend/components/ui/menubar.tsx | 236 + frontend/components/ui/navigation-menu.tsx | 128 + frontend/components/ui/pagination.tsx | 117 + frontend/components/ui/popover.tsx | 31 + frontend/components/ui/progress.tsx | 28 + frontend/components/ui/radio-group.tsx | 44 + frontend/components/ui/resizable.tsx | 45 + frontend/components/ui/scroll-area.tsx | 40 + frontend/components/ui/select.tsx | 160 + frontend/components/ui/separator.tsx | 31 + frontend/components/ui/sheet.tsx | 140 + frontend/components/ui/sidebar.tsx | 763 +++ frontend/components/ui/skeleton.tsx | 15 + frontend/components/ui/slider.tsx | 28 + frontend/components/ui/sonner.tsx | 31 + frontend/components/ui/switch.tsx | 29 + frontend/components/ui/table.tsx | 117 + frontend/components/ui/tabs.tsx | 55 + frontend/components/ui/textarea.tsx | 21 + frontend/components/ui/toast.tsx | 111 + frontend/components/ui/toaster.tsx | 35 + frontend/components/ui/toggle-group.tsx | 61 + frontend/components/ui/toggle.tsx | 45 + frontend/components/ui/tooltip.tsx | 30 + frontend/components/ui/use-mobile.tsx | 19 + frontend/components/ui/use-toast.ts | 179 + frontend/contexts/DnDContext.tsx | 68 + frontend/contexts/NodeDataContext.tsx | 118 + frontend/contexts/SourceClickContext.tsx | 65 + frontend/docker-compose.yml | 15 + frontend/docker-entrypoint.sh | 20 + frontend/docker_build.sh | 2 + frontend/hooks/use-agent-webSocket.ts | 165 + frontend/hooks/use-mobile.tsx | 47 + frontend/hooks/use-toast.ts | 223 + frontend/lib/env.ts | 15 + frontend/lib/file-utils.ts | 110 + frontend/lib/utils.ts | 235 + frontend/middleware.ts | 84 + frontend/next.config.mjs | 14 + frontend/package.json | 106 + frontend/pnpm-lock.yaml | 5765 +++++++++++++++++ frontend/postcss.config.mjs | 8 + frontend/public/favicon.svg | 4 + frontend/public/images/discord.webp | Bin 0 -> 21764 bytes frontend/public/images/email.webp | Bin 0 -> 9976 bytes frontend/public/images/evolution-ai-logo.png | Bin 0 -> 1513 bytes frontend/public/images/evolution.png | Bin 0 -> 3273 bytes frontend/public/images/facebook.png | Bin 0 -> 54771 bytes frontend/public/images/imessage.webp | Bin 0 -> 17574 bytes frontend/public/images/instagram.png | Bin 0 -> 1004190 bytes frontend/public/images/linkedin.webp | Bin 0 -> 22324 bytes frontend/public/images/mercadolivre.png | Bin 0 -> 7412 bytes frontend/public/images/sms.png | Bin 0 -> 14570 bytes frontend/public/images/svg/facebook.svg | 1 + frontend/public/images/svg/instagram.svg | 1 + frontend/public/images/svg/whatsapp.svg | 1 + frontend/public/images/telegram.webp | Bin 0 -> 26178 bytes frontend/public/images/threads.png | Bin 0 -> 23302 bytes frontend/public/images/tiktok.webp | Bin 0 -> 31110 bytes frontend/public/images/webchat.webp | Bin 0 -> 27504 bytes frontend/public/images/wechat.png | Bin 0 -> 125907 bytes frontend/public/images/whatsapp.png | Bin 0 -> 53944 bytes frontend/public/images/x-twitter.png | Bin 0 -> 6769 bytes frontend/public/images/youtube.webp | Bin 0 -> 1898 bytes frontend/public/placeholder-logo.png | Bin 0 -> 958 bytes frontend/public/placeholder-logo.svg | 1 + frontend/public/placeholder-user.jpg | Bin 0 -> 2615 bytes frontend/public/placeholder.jpg | Bin 0 -> 1596 bytes frontend/public/placeholder.svg | 1 + frontend/services/agentService.ts | 238 + frontend/services/api.ts | 122 + frontend/services/authService.ts | 56 + frontend/services/clientService.ts | 87 + frontend/services/mcpServerService.ts | 45 + frontend/services/sessionService.ts | 142 + frontend/styles/globals.css | 122 + frontend/tailwind.config.ts | 81 + frontend/tsconfig.json | 27 + frontend/types/agent.ts | 153 + frontend/types/aiModels.ts | 414 ++ frontend/types/auth.ts | 77 + frontend/types/mcpServer.ts | 60 + github.bat | 30 + migrations/env.py | 116 + migrations/script.py.mako | 28 + ...c7b564_add_task_agent_type_agents_table.py | 43 + ...4e70bb2_add_crew_ai_coluns_agents_table.py | 34 + .../versions/6db4a526335b_init_migrations.py | 147 + ...2e1_add_crew_ai_agent_type_agents_table.py | 43 + pyproject.toml | 104 + scripts/run_seeders.py | 150 + scripts/seeders/admin_seeder.py | 111 + scripts/seeders/client_seeder.py | 125 + scripts/seeders/mcp_server_seeder.py | 817 +++ scripts/seeders/tool_seeder.py | 110 + setup.py | 6 + src/__init__.py | 3 + src/api/__init__.py | 0 src/api/a2a_routes.py | 1805 ++++++ src/api/admin_routes.py | 205 + src/api/agent_routes.py | 705 ++ src/api/auth_routes.py | 327 + src/api/chat_routes.py | 316 + src/api/client_routes.py | 216 + src/api/mcp_server_routes.py | 127 + src/api/session_routes.py | 327 + src/api/tool_routes.py | 126 + src/config/__init__.py | 3 + src/config/database.py | 48 + src/config/redis.py | 99 + src/config/settings.py | 147 + src/core/__init__.py | 0 src/core/exceptions.py | 95 + src/core/jwt_middleware.py | 194 + src/main.py | 129 + src/models/__init__.py | 0 src/models/models.py | 267 + src/schemas/__init__.py | 0 src/schemas/a2a_enhanced_types.py | 612 ++ src/schemas/a2a_types.py | 396 ++ src/schemas/agent_config.py | 280 + src/schemas/audit.py | 74 + src/schemas/chat.py | 70 + src/schemas/schemas.py | 328 + src/schemas/streaming.py | 69 + src/schemas/user.py | 95 + src/services/__init__.py | 1 + src/services/a2a_sdk_adapter.py | 397 ++ src/services/adk/__init__.py | 0 src/services/adk/agent_builder.py | 458 ++ src/services/adk/agent_runner.py | 535 ++ src/services/adk/custom_agents/__init__.py | 0 src/services/adk/custom_agents/a2a_agent.py | 474 ++ src/services/adk/custom_agents/task_agent.py | 233 + .../adk/custom_agents/workflow_agent.py | 932 +++ src/services/adk/custom_tools.py | 204 + src/services/adk/mcp_service.py | 241 + src/services/agent_service.py | 1337 ++++ src/services/apikey_service.py | 195 + src/services/audit_service.py | 166 + src/services/auth_service.py | 186 + src/services/client_service.py | 204 + src/services/crewai/agent_builder.py | 219 + src/services/crewai/agent_runner.py | 595 ++ src/services/crewai/custom_tool.py | 369 ++ src/services/crewai/mcp_service.py | 264 + src/services/crewai/session_service.py | 637 ++ src/services/email_service.py | 305 + src/services/mcp_server_service.py | 147 + src/services/service_providers.py | 48 + src/services/session_service.py | 199 + src/services/tool_service.py | 128 + src/services/user_service.py | 525 ++ src/templates/emails/account_locked.html | 32 + src/templates/emails/base_email.html | 103 + src/templates/emails/password_reset.html | 29 + src/templates/emails/verification_email.html | 31 + src/templates/emails/welcome_email.html | 31 + src/utils/__init__.py | 0 src/utils/a2a_enhanced_client.py | 746 +++ src/utils/a2a_utils.py | 190 + src/utils/crypto.py | 68 + src/utils/logger.py | 92 + src/utils/mcp_discovery.py | 55 + src/utils/otel.py | 70 + src/utils/security.py | 83 + src/utils/streaming.py | 99 + 310 files changed, 62749 insertions(+) create mode 100644 .cursorrules create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .flake8 create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 alembic.ini create mode 100644 conftest.py create mode 100644 docker-compose.yml create mode 100644 docker_build.sh create mode 100644 frontend/.cursorrules create mode 100644 frontend/.dockerignore create mode 100644 frontend/.env.example create mode 100644 frontend/.gitignore create mode 100644 frontend/CHANGELOG.md create mode 100644 frontend/Dockerfile create mode 100644 frontend/LICENSE create mode 100644 frontend/README.md create mode 100644 frontend/app/agents/AgentCard.tsx create mode 100644 frontend/app/agents/AgentList.tsx create mode 100644 frontend/app/agents/AgentSidebar.tsx create mode 100644 frontend/app/agents/AgentTypeSelector.tsx create mode 100644 frontend/app/agents/EmptyState.tsx create mode 100644 frontend/app/agents/SearchInput.tsx create mode 100644 frontend/app/agents/config/A2AAgentConfig.tsx create mode 100644 frontend/app/agents/config/LLMAgentConfig.tsx create mode 100644 frontend/app/agents/config/LoopAgentConfig copy.tsx create mode 100644 frontend/app/agents/config/ParallelAgentConfig.tsx create mode 100644 frontend/app/agents/config/SequentialAgentConfig.tsx create mode 100644 frontend/app/agents/config/TaskAgentConfig.tsx create mode 100644 frontend/app/agents/dialogs/AgentToolDialog.tsx create mode 100644 frontend/app/agents/dialogs/ApiKeysDialog.tsx create mode 100644 frontend/app/agents/dialogs/ConfirmationDialog.tsx create mode 100644 frontend/app/agents/dialogs/CustomMCPDialog.tsx create mode 100644 frontend/app/agents/dialogs/CustomToolDialog.tsx create mode 100644 frontend/app/agents/dialogs/FolderDialog.tsx create mode 100644 frontend/app/agents/dialogs/ImportAgentDialog.tsx create mode 100644 frontend/app/agents/dialogs/MCPDialog.tsx create mode 100644 frontend/app/agents/dialogs/MoveAgentDialog.tsx create mode 100644 frontend/app/agents/dialogs/ShareAgentDialog.tsx create mode 100644 frontend/app/agents/forms/AgentForm.tsx create mode 100644 frontend/app/agents/forms/BasicInfoTab.tsx create mode 100644 frontend/app/agents/forms/ConfigurationTab.tsx create mode 100644 frontend/app/agents/forms/SubAgentsTab.tsx create mode 100644 frontend/app/agents/page.tsx create mode 100644 frontend/app/agents/workflows/Canva.tsx create mode 100644 frontend/app/agents/workflows/ContextMenu.tsx create mode 100644 frontend/app/agents/workflows/HelperLines.tsx create mode 100644 frontend/app/agents/workflows/NodePanel.tsx create mode 100644 frontend/app/agents/workflows/canva.css create mode 100644 frontend/app/agents/workflows/edges/DefaultEdge.tsx create mode 100644 frontend/app/agents/workflows/edges/index.ts create mode 100644 frontend/app/agents/workflows/nodes/BaseNode.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/agent/AgentChatMessageList.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/agent/AgentForm.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/agent/AgentNode.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/agent/AgentTestChatModal.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/agent/styles.css create mode 100644 frontend/app/agents/workflows/nodes/components/condition/ConditionDialog.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/condition/ConditionForm.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/condition/ConditionNode.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/delay/DelayForm.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/delay/DelayNode.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/message/MessageForm.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/message/MessageNode.tsx create mode 100644 frontend/app/agents/workflows/nodes/components/start/StartNode.tsx create mode 100644 frontend/app/agents/workflows/nodes/index.ts create mode 100644 frontend/app/agents/workflows/nodes/nodeFunctions.ts create mode 100644 frontend/app/agents/workflows/nodes/style.css create mode 100644 frontend/app/agents/workflows/page.tsx create mode 100644 frontend/app/agents/workflows/utils.ts create mode 100644 frontend/app/chat/components/AgentInfoDialog.tsx create mode 100644 frontend/app/chat/components/AttachedFiles.tsx create mode 100644 frontend/app/chat/components/ChatContainer.tsx create mode 100644 frontend/app/chat/components/ChatInput.tsx create mode 100644 frontend/app/chat/components/ChatMessage.tsx create mode 100644 frontend/app/chat/components/FileUpload.tsx create mode 100644 frontend/app/chat/components/InlineDataAttachments.tsx create mode 100644 frontend/app/chat/components/SessionList.tsx create mode 100644 frontend/app/chat/page.tsx create mode 100644 frontend/app/client-layout.tsx create mode 100644 frontend/app/clients/loading.tsx create mode 100644 frontend/app/clients/page.tsx create mode 100644 frontend/app/documentation/components/A2AComplianceCard.tsx create mode 100644 frontend/app/documentation/components/CodeBlock.tsx create mode 100644 frontend/app/documentation/components/CodeExamplesSection.tsx create mode 100644 frontend/app/documentation/components/DocumentationSection.tsx create mode 100644 frontend/app/documentation/components/FrontendImplementationSection.tsx create mode 100644 frontend/app/documentation/components/HttpLabForm.tsx create mode 100644 frontend/app/documentation/components/LabSection.tsx create mode 100644 frontend/app/documentation/components/QuickStartTemplates.tsx create mode 100644 frontend/app/documentation/components/StreamLabForm.tsx create mode 100644 frontend/app/documentation/components/TechnicalDetailsSection.tsx create mode 100644 frontend/app/documentation/page.tsx create mode 100644 frontend/app/globals.css create mode 100644 frontend/app/layout.tsx create mode 100644 frontend/app/login/page.tsx create mode 100644 frontend/app/logout/page.tsx create mode 100644 frontend/app/mcp-servers/loading.tsx create mode 100644 frontend/app/mcp-servers/page.tsx create mode 100644 frontend/app/page.tsx create mode 100644 frontend/app/profile/page.tsx create mode 100644 frontend/app/security/page.tsx create mode 100644 frontend/app/security/reset-password/page.tsx create mode 100644 frontend/app/security/verify-email/page.tsx create mode 100644 frontend/app/shared-chat/AgentInfo.tsx create mode 100644 frontend/app/shared-chat/components/SharedChatPanel.tsx create mode 100644 frontend/app/shared-chat/components/SharedSessionList.tsx create mode 100644 frontend/app/shared-chat/page.tsx create mode 100644 frontend/components.json create mode 100644 frontend/components/ImpersonationBar.tsx create mode 100644 frontend/components/sidebar.tsx create mode 100644 frontend/components/theme-provider.tsx create mode 100644 frontend/components/toaster.tsx create mode 100644 frontend/components/ui/accordion.tsx create mode 100644 frontend/components/ui/alert-dialog.tsx create mode 100644 frontend/components/ui/alert.tsx create mode 100644 frontend/components/ui/aspect-ratio.tsx create mode 100644 frontend/components/ui/avatar.tsx create mode 100644 frontend/components/ui/badge.tsx create mode 100644 frontend/components/ui/breadcrumb.tsx create mode 100644 frontend/components/ui/button.tsx create mode 100644 frontend/components/ui/calendar.tsx create mode 100644 frontend/components/ui/card.tsx create mode 100644 frontend/components/ui/carousel.tsx create mode 100644 frontend/components/ui/chart.tsx create mode 100644 frontend/components/ui/checkbox.tsx create mode 100644 frontend/components/ui/collapsible.tsx create mode 100644 frontend/components/ui/command.tsx create mode 100644 frontend/components/ui/context-menu.tsx create mode 100644 frontend/components/ui/dialog.tsx create mode 100644 frontend/components/ui/drawer.tsx create mode 100644 frontend/components/ui/dropdown-menu.tsx create mode 100644 frontend/components/ui/form.tsx create mode 100644 frontend/components/ui/hover-card.tsx create mode 100644 frontend/components/ui/input-otp.tsx create mode 100644 frontend/components/ui/input.tsx create mode 100644 frontend/components/ui/label.tsx create mode 100644 frontend/components/ui/menubar.tsx create mode 100644 frontend/components/ui/navigation-menu.tsx create mode 100644 frontend/components/ui/pagination.tsx create mode 100644 frontend/components/ui/popover.tsx create mode 100644 frontend/components/ui/progress.tsx create mode 100644 frontend/components/ui/radio-group.tsx create mode 100644 frontend/components/ui/resizable.tsx create mode 100644 frontend/components/ui/scroll-area.tsx create mode 100644 frontend/components/ui/select.tsx create mode 100644 frontend/components/ui/separator.tsx create mode 100644 frontend/components/ui/sheet.tsx create mode 100644 frontend/components/ui/sidebar.tsx create mode 100644 frontend/components/ui/skeleton.tsx create mode 100644 frontend/components/ui/slider.tsx create mode 100644 frontend/components/ui/sonner.tsx create mode 100644 frontend/components/ui/switch.tsx create mode 100644 frontend/components/ui/table.tsx create mode 100644 frontend/components/ui/tabs.tsx create mode 100644 frontend/components/ui/textarea.tsx create mode 100644 frontend/components/ui/toast.tsx create mode 100644 frontend/components/ui/toaster.tsx create mode 100644 frontend/components/ui/toggle-group.tsx create mode 100644 frontend/components/ui/toggle.tsx create mode 100644 frontend/components/ui/tooltip.tsx create mode 100644 frontend/components/ui/use-mobile.tsx create mode 100644 frontend/components/ui/use-toast.ts create mode 100644 frontend/contexts/DnDContext.tsx create mode 100644 frontend/contexts/NodeDataContext.tsx create mode 100644 frontend/contexts/SourceClickContext.tsx create mode 100644 frontend/docker-compose.yml create mode 100644 frontend/docker-entrypoint.sh create mode 100644 frontend/docker_build.sh create mode 100644 frontend/hooks/use-agent-webSocket.ts create mode 100644 frontend/hooks/use-mobile.tsx create mode 100644 frontend/hooks/use-toast.ts create mode 100644 frontend/lib/env.ts create mode 100644 frontend/lib/file-utils.ts create mode 100644 frontend/lib/utils.ts create mode 100644 frontend/middleware.ts create mode 100644 frontend/next.config.mjs create mode 100644 frontend/package.json create mode 100644 frontend/pnpm-lock.yaml create mode 100644 frontend/postcss.config.mjs create mode 100644 frontend/public/favicon.svg create mode 100644 frontend/public/images/discord.webp create mode 100644 frontend/public/images/email.webp create mode 100644 frontend/public/images/evolution-ai-logo.png create mode 100644 frontend/public/images/evolution.png create mode 100644 frontend/public/images/facebook.png create mode 100644 frontend/public/images/imessage.webp create mode 100644 frontend/public/images/instagram.png create mode 100644 frontend/public/images/linkedin.webp create mode 100644 frontend/public/images/mercadolivre.png create mode 100644 frontend/public/images/sms.png create mode 100644 frontend/public/images/svg/facebook.svg create mode 100644 frontend/public/images/svg/instagram.svg create mode 100644 frontend/public/images/svg/whatsapp.svg create mode 100644 frontend/public/images/telegram.webp create mode 100644 frontend/public/images/threads.png create mode 100644 frontend/public/images/tiktok.webp create mode 100644 frontend/public/images/webchat.webp create mode 100644 frontend/public/images/wechat.png create mode 100644 frontend/public/images/whatsapp.png create mode 100644 frontend/public/images/x-twitter.png create mode 100644 frontend/public/images/youtube.webp create mode 100644 frontend/public/placeholder-logo.png create mode 100644 frontend/public/placeholder-logo.svg create mode 100644 frontend/public/placeholder-user.jpg create mode 100644 frontend/public/placeholder.jpg create mode 100644 frontend/public/placeholder.svg create mode 100644 frontend/services/agentService.ts create mode 100644 frontend/services/api.ts create mode 100644 frontend/services/authService.ts create mode 100644 frontend/services/clientService.ts create mode 100644 frontend/services/mcpServerService.ts create mode 100644 frontend/services/sessionService.ts create mode 100644 frontend/styles/globals.css create mode 100644 frontend/tailwind.config.ts create mode 100644 frontend/tsconfig.json create mode 100644 frontend/types/agent.ts create mode 100644 frontend/types/aiModels.ts create mode 100644 frontend/types/auth.ts create mode 100644 frontend/types/mcpServer.ts create mode 100644 github.bat create mode 100644 migrations/env.py create mode 100644 migrations/script.py.mako create mode 100644 migrations/versions/2df073c7b564_add_task_agent_type_agents_table.py create mode 100644 migrations/versions/611d84e70bb2_add_crew_ai_coluns_agents_table.py create mode 100644 migrations/versions/6db4a526335b_init_migrations.py create mode 100644 migrations/versions/bdc5d363e2e1_add_crew_ai_agent_type_agents_table.py create mode 100644 pyproject.toml create mode 100644 scripts/run_seeders.py create mode 100644 scripts/seeders/admin_seeder.py create mode 100644 scripts/seeders/client_seeder.py create mode 100644 scripts/seeders/mcp_server_seeder.py create mode 100644 scripts/seeders/tool_seeder.py create mode 100644 setup.py create mode 100644 src/__init__.py create mode 100644 src/api/__init__.py create mode 100644 src/api/a2a_routes.py create mode 100644 src/api/admin_routes.py create mode 100644 src/api/agent_routes.py create mode 100644 src/api/auth_routes.py create mode 100644 src/api/chat_routes.py create mode 100644 src/api/client_routes.py create mode 100644 src/api/mcp_server_routes.py create mode 100644 src/api/session_routes.py create mode 100644 src/api/tool_routes.py create mode 100644 src/config/__init__.py create mode 100644 src/config/database.py create mode 100644 src/config/redis.py create mode 100644 src/config/settings.py create mode 100644 src/core/__init__.py create mode 100644 src/core/exceptions.py create mode 100644 src/core/jwt_middleware.py create mode 100644 src/main.py create mode 100644 src/models/__init__.py create mode 100644 src/models/models.py create mode 100644 src/schemas/__init__.py create mode 100644 src/schemas/a2a_enhanced_types.py create mode 100644 src/schemas/a2a_types.py create mode 100644 src/schemas/agent_config.py create mode 100644 src/schemas/audit.py create mode 100644 src/schemas/chat.py create mode 100644 src/schemas/schemas.py create mode 100644 src/schemas/streaming.py create mode 100644 src/schemas/user.py create mode 100644 src/services/__init__.py create mode 100644 src/services/a2a_sdk_adapter.py create mode 100644 src/services/adk/__init__.py create mode 100644 src/services/adk/agent_builder.py create mode 100644 src/services/adk/agent_runner.py create mode 100644 src/services/adk/custom_agents/__init__.py create mode 100644 src/services/adk/custom_agents/a2a_agent.py create mode 100644 src/services/adk/custom_agents/task_agent.py create mode 100644 src/services/adk/custom_agents/workflow_agent.py create mode 100644 src/services/adk/custom_tools.py create mode 100644 src/services/adk/mcp_service.py create mode 100644 src/services/agent_service.py create mode 100644 src/services/apikey_service.py create mode 100644 src/services/audit_service.py create mode 100644 src/services/auth_service.py create mode 100644 src/services/client_service.py create mode 100644 src/services/crewai/agent_builder.py create mode 100644 src/services/crewai/agent_runner.py create mode 100644 src/services/crewai/custom_tool.py create mode 100644 src/services/crewai/mcp_service.py create mode 100644 src/services/crewai/session_service.py create mode 100644 src/services/email_service.py create mode 100644 src/services/mcp_server_service.py create mode 100644 src/services/service_providers.py create mode 100644 src/services/session_service.py create mode 100644 src/services/tool_service.py create mode 100644 src/services/user_service.py create mode 100644 src/templates/emails/account_locked.html create mode 100644 src/templates/emails/base_email.html create mode 100644 src/templates/emails/password_reset.html create mode 100644 src/templates/emails/verification_email.html create mode 100644 src/templates/emails/welcome_email.html create mode 100644 src/utils/__init__.py create mode 100644 src/utils/a2a_enhanced_client.py create mode 100644 src/utils/a2a_utils.py create mode 100644 src/utils/crypto.py create mode 100644 src/utils/logger.py create mode 100644 src/utils/mcp_discovery.py create mode 100644 src/utils/otel.py create mode 100644 src/utils/security.py create mode 100644 src/utils/streaming.py diff --git a/.cursorrules b/.cursorrules new file mode 100644 index 0000000..7fd787c --- /dev/null +++ b/.cursorrules @@ -0,0 +1,231 @@ +# Evo AI - Project Rules and Structure + +## Main Technologies +- FastAPI: Web framework for building the API +- SQLAlchemy: ORM for database interaction +- Alembic: Database migration system +- PostgreSQL: Main database +- Pydantic: Data validation and serialization +- Uvicorn: ASGI server for application execution +- Redis: Cache and session management +- JWT: Secure token authentication +- Bcrypt: Secure password hashing +- SendGrid: Email service for notifications +- Jinja2: Template engine for email rendering + +## Project Structure +``` +src/ +├── api/ +│ ├── __init__.py # Package initialization +│ ├── admin_routes.py # Admin routes for management interface +│ ├── agent_routes.py # Routes to manage agents +│ ├── auth_routes.py # Authentication routes (login, registration) +│ ├── chat_routes.py # Routes for chat interactions with agents +│ ├── client_routes.py # Routes to manage clients +│ ├── mcp_server_routes.py # Routes to manage MCP servers +│ ├── session_routes.py # Routes to manage chat sessions +│ └── tool_routes.py # Routes to manage tools for agents +├── config/ +│ ├── database.py # Database configuration +│ └── settings.py # General settings +├── core/ +│ ├── middleware.py # API Key middleware (legacy) +│ └── jwt_middleware.py # JWT authentication middleware +├── models/ +│ └── models.py # SQLAlchemy models +├── schemas/ +│ ├── schemas.py # Main Pydantic schemas +│ ├── chat.py # Chat schemas +│ ├── user.py # User and authentication schemas +│ └── audit.py # Audit logs schemas +├── services/ +│ ├── agent_service.py # Business logic for agents +│ ├── agent_runner.py # Agent execution logic +│ ├── auth_service.py # JWT authentication logic +│ ├── audit_service.py # Audit logs logic +│ ├── client_service.py # Business logic for clients +│ ├── email_service.py # Email sending service +│ ├── mcp_server_service.py # Business logic for MCP servers +│ ├── session_service.py # Business logic for chat sessions +│ ├── tool_service.py # Business logic for tools +│ └── user_service.py # User management logic +├── templates/ +│ ├── emails/ +│ │ ├── base_email.html # Base template with common structure and styles +│ │ ├── verification_email.html # Email verification template +│ │ ├── password_reset.html # Password reset template +│ │ ├── welcome_email.html # Welcome email after verification +│ │ └── account_locked.html # Security alert for locked accounts +├── tests/ +│ ├── __init__.py # Package initialization +│ ├── api/ +│ │ ├── __init__.py # Package initialization +│ │ ├── test_auth_routes.py # Test for authentication routes +│ │ └── test_root.py # Test for root endpoint +│ ├── models/ +│ │ ├── __init__.py # Package initialization +│ │ ├── test_models.py # Test for models +│ ├── services/ +│ │ ├── __init__.py # Package initialization +│ │ ├── test_auth_service.py # Test for authentication service +│ │ └── test_user_service.py # Test for user service +└── utils/ + ├── logger.py # Logger configuration + └── security.py # Security utilities (JWT, hash) +``` + +## Code Standards + +### Language Requirements +- **ALL code comments, docstrings, and logging messages MUST be written in English** +- Variable names, function names, and class names must be in English +- API error messages must be in English +- Documentation (including inline comments) must be in English +- Code examples in documentation must be in English +- Commit messages must be in English + +### Project Configuration +- Dependencies managed in `pyproject.toml` using modern Python packaging standards +- Development dependencies specified as optional dependencies in `pyproject.toml` +- Single source of truth for project metadata in `pyproject.toml` +- Build system configured to use setuptools +- Pytest configuration in `pyproject.toml` under `[tool.pytest.ini_options]` +- Code formatting with Black configured in `pyproject.toml` +- Linting with Flake8 configured in `.flake8` + +### Schemas (Pydantic) +- Use `BaseModel` as base for all schemas +- Define fields with explicit types +- Use `Optional` for optional fields +- Use `Field` for validations and default values +- Implement `Config` with `from_attributes = True` for models +- Use `EmailStr` for email validation + +### Services +- Error handling with `SQLAlchemyError` +- Consistent logging with messages in English +- Strong typing with `Optional` for null returns +- Documentation with docstrings +- Rollback in case of error +- Standardized returns +- Use transactions for multiple operations + +### Email Templates +- All email templates extend a base template +- Templates written in English +- Use Jinja2 templating system +- Consistent styling using a common base template +- Responsive design for mobile compatibility +- Clear call-to-action buttons +- Fallback mechanisms for failed template rendering + +### Routes +- Appropriate status codes (201 for creation, 204 for deletion) +- Error handling with `HTTPException` +- Error messages in English +- Pagination for list endpoints +- Input validation with schemas +- JWT authentication for all protected routes +- Use of asynchronous functions with `async def` + +### Migrations +- Use Alembic for migration management +- Descriptive names for migrations +- Maintain change history +- Use CASCADE when necessary to remove dependencies + +### Authentication +- Use JWT for authentication with OAuth2PasswordBearer +- JWT tokens with expiration time defined in settings +- Access token containing essential user data (is_admin, client_id, etc.) +- Resource ownership verification based on client_id +- Protection of administrative routes with permission verification +- Email verification system via tokens +- Secure password recovery with one-time tokens +- Account locking after multiple failed login attempts + +### Audit +- Record important administrative actions +- Automatic collection of contextual data (IP, user-agent) +- Relationship with user who performed the action +- Filtering and querying by different criteria + +### Environment Variables +- Use .env file for sensitive settings +- Keep .env.example updated +- Document all environment variables +- Use safe default values +- Validate required variables +- Clear separation between development and production configurations + +## Conventions +- Variable and function names in English +- Log and error messages in English +- Documentation in English +- User-facing content (emails, responses) in English +- Indentation with 4 spaces +- Maximum of 79 characters per line + +## Commit Rules +- Use Conventional Commits format for all commit messages +- Format: `(): ` +- Types: + - `feat`: A new feature + - `fix`: A bug fix + - `docs`: Documentation changes + - `style`: Changes that do not affect code meaning (formatting, etc.) + - `refactor`: Code changes that neither fix a bug nor add a feature + - `perf`: Performance improvements + - `test`: Adding or modifying tests + - `chore`: Changes to build process or auxiliary tools +- Scope is optional and should be the module or component affected +- Description should be concise, in the imperative mood, and not capitalized +- Use body for more detailed explanations if needed +- Reference issues in the footer with `Fixes #123` or `Relates to #123` +- Examples: + - `feat(auth): add password reset functionality` + - `fix(api): correct validation error in client registration` + - `docs: update API documentation for new endpoints` + - `refactor(services): improve error handling in authentication` + +## Best Practices +- Always validate input data +- Implement appropriate logging +- Handle all possible errors +- Maintain consistency in returns +- Document functions and classes +- Follow SOLID principles +- Keep tests updated +- Protect routes with JWT authentication +- Use environment variables for sensitive configurations +- Implement resource ownership verification +- Store passwords only with secure hash (bcrypt) +- Implement appropriate expiration for tokens +- Use template inheritance for consistent email layouts + +## Security +- JWT tokens with limited lifetime +- Email verification with one-time tokens +- Secure password hashing with bcrypt and random salt +- Audit system for administrative actions +- Resource-based access control +- Clear separation between regular users and administrators +- Strict input validation with Pydantic +- Account lockout after multiple failed login attempts + +## Useful Commands +- `make run`: Start the server +- `make run-prod`: Start the server in production mode +- `make alembic-revision message="description"`: Create new migration +- `make alembic-upgrade`: Apply pending migrations +- `make alembic-downgrade`: Revert last migration +- `make alembic-migrate`: Create and apply new migration +- `make alembic-reset`: Reset database to initial state +- `make alembic-upgrade-cascade`: Force upgrade removing dependencies +- `make clear-cache`: Clean project cache +- `make seed-all`: Run all database seeders +- `make lint`: Run linting checks with flake8 +- `make format`: Format code with black +- `make install`: Install project for development +- `make install-dev`: Install project with development dependencies diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6f1b62b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,105 @@ +# Environment and IDE +.venv +venv +.env +.idea +.vscode +__pycache__ +*.pyc +*.pyo +*.pyd +.Python +.pytest_cache +.coverage +htmlcov/ +.tox/ + +# Version control +.git +.github +.gitignore + +# Logs and temp files +logs +*.log +tmp +.DS_Store + +# Docker +.dockerignore +Dockerfile* +docker-compose* + +# Documentation +README.md +LICENSE +docs/ + +# Development tools +tests/ +.flake8 +requirements-dev.txt + +# Python specific - don't exclude frontend +!frontend/ +frontend/node_modules/ +frontend/.next/ +frontend/dist/ + +# Ambiente virtual +venv/ +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +# lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# Arquivos específicos do Docker +.dockerignore +Dockerfile +docker-compose.yml + +# Git +.git +.gitignore + +# Logs e dados +logs/ +*.log +data/ + +# Configuração local +.env +.env.local +.env.development +.env.test +.env.production + +# IDEs e editores +.idea/ +.vscode/ +*.swp +*.swo + +# Arquivos de teste +tests/ +test_* +*_test.py + +# Documentação +docs/ diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..065cfec --- /dev/null +++ b/.env.example @@ -0,0 +1,72 @@ +API_TITLE="Evo API" +API_DESCRIPTION="API para execução de agentes de IA" +API_VERSION="1.0.0" +API_URL="http://localhost:8000" + +ORGANIZATION_NAME="Evo AI" +ORGANIZATION_URL="https://evoai.evoapicloud.com" + +# AI Engine configuration: "adk" or "crewai" +AI_ENGINE="adk" + +# Database settings +POSTGRES_CONNECTION_STRING="postgresql://postgres:root@localhost:5432/evo_ai" + +# Logging settings +LOG_LEVEL="INFO" +LOG_DIR="logs" + +# Redis settings +REDIS_HOST="localhost" +REDIS_PORT=6379 +REDIS_DB=0 +REDIS_PASSWORD="your-redis-password" +REDIS_SSL=false +REDIS_KEY_PREFIX="a2a:" +REDIS_TTL=3600 + +# Tools cache TTL in seconds (1 hour) +TOOLS_CACHE_TTL=3600 + +# JWT settings +JWT_SECRET_KEY="your-jwt-secret-key" +JWT_ALGORITHM="HS256" +# In seconds +JWT_EXPIRATION_TIME=3600 + +# Encryption key for API keys +ENCRYPTION_KEY="your-encryption-key" + +# Email provider settings +EMAIL_PROVIDER="sendgrid" + +# SendGrid +SENDGRID_API_KEY="your-sendgrid-api-key" +EMAIL_FROM="noreply@yourdomain.com" + +# SMTP settings +SMTP_HOST="your-smtp-host" +SMTP_FROM="noreply-smtp@yourdomain.com" +SMTP_USER="your-smtp-username" +SMTP_PASSWORD="your-smtp-password" +SMTP_PORT=587 +SMTP_USE_TLS=true +SMTP_USE_SSL=false + +APP_URL="https://yourdomain.com" + +LANGFUSE_PUBLIC_KEY="your-langfuse-public-key" +LANGFUSE_SECRET_KEY="your-langfuse-secret-key" +OTEL_EXPORTER_OTLP_ENDPOINT="https://cloud.langfuse.com/api/public/otel" + +# Server settings +HOST="0.0.0.0" +PORT=8000 +DEBUG=false + +# Seeder settings +ADMIN_EMAIL="admin@evoai.com" +ADMIN_INITIAL_PASSWORD="strongpassword123" +DEMO_EMAIL="demo@example.com" +DEMO_PASSWORD="demo123" +DEMO_CLIENT_NAME="Demo Client" diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..ba84055 --- /dev/null +++ b/.flake8 @@ -0,0 +1,8 @@ +[flake8] +max-line-length = 88 +exclude = .git,__pycache__,venv,alembic/versions/* +ignore = E203, W503, E501 +per-file-ignores = + __init__.py: F401 + src/models/models.py: E712 + alembic/*: E711,E712,F401 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7807dc9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,132 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +# lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ +docs/A2A + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# IDE +.idea/ +.vscode/ +*.sublime-project +*.sublime-workspace +.DS_Store + +# Logs +logs/ +*.log + +# Database +*.db +*.sqlite +*.sqlite3 +backup/ + +# Local +local_settings.py +local.py + +# Docker +.docker/ + +# Alembic versions +# alembic/versions/ + +# PyInstaller +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Translations +*.mo +*.pot + +# Django stuff: +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# IDE +*.swp +*.swo + +# OS +Thumbs.db + +uv.lock diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..cf0180a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,101 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.1.0] - 2025-05-24 + +### Added + +- Export and Import Agents + +### Changed + +- A2A implementation updated to version 0.2.1 (https://google.github.io/A2A/specification/#agent2agent-a2a-protocol-specification) +- Frontend redesign +- Fixed message order + +## [0.0.11] - 2025-05-16 + +### Changed + +- Fixes in email service and client service + +## [0.0.10] - 2025-05-15 + +### Added + +- Add Task Agent for structured single-task execution +- Improve context management in agent execution +- Add file support for A2A protocol (Agent-to-Agent) endpoints +- Implement multimodal content processing in A2A messages +- Add SMTP email provider support as alternative to SendGrid + +## [0.0.9] - 2025-05-13 + +### Added + +- Add API key sharing and flexible authentication for chat routes + +### Changed + +- Enhance user authentication with detailed error handling + +## [0.0.8] - 2025-05-13 + +### Changed + +- Update author information in multiple files + +## [0.0.7] - 2025-05-13 + +### Added + +- Docker image CI workflow for automated builds and pushes +- GitHub Container Registry (GHCR) integration +- Automated image tagging based on branch and commit +- Docker Buildx setup for multi-platform builds +- Cache optimization for faster builds +- Automated image publishing on push to main and develop branches + +## [0.0.6] - 2025-05-13 + +### Added + +- Initial public release of Evo AI platform +- FastAPI-based backend API +- JWT authentication with email verification +- Agent management (LLM, A2A, Sequential, Parallel, Loop, Workflow) +- Agent 2 Agent (A2A) protocol support (Google A2A spec) +- MCP server integration and management +- Custom tools management for agents +- Folder-based agent organization +- Secure API key management with encryption +- PostgreSQL and Redis integration +- Email notifications (SendGrid) with Jinja2 templates +- Audit log system for administrative actions +- LangGraph integration for workflow agents +- OpenTelemetry tracing and Langfuse integration +- Docker and Docker Compose support +- English documentation and codebase + +### Changed + +- N/A + +### Fixed + +- N/A + +### Security + +- JWT tokens with expiration and resource-based access control +- Secure password hashing (bcrypt) +- Account lockout after multiple failed login attempts +- Email verification and password reset flows + +--- + +Older versions and future releases will be listed here. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..040fc35 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,37 @@ +FROM python:3.10-slim + +WORKDIR /app + +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONPATH=/app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + libpq-dev \ + curl \ + gnupg \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt-get install -y nodejs \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN curl -fsSL https://get.docker.com | bash + +RUN curl -LsSf https://astral.sh/uv/install.sh | sh + +COPY . . + +RUN pip install --no-cache-dir -e . + +ENV PORT=8000 \ + HOST=0.0.0.0 \ + DEBUG=false + +# Expose port +EXPOSE 8000 + +CMD alembic upgrade head && python -m scripts.run_seeders && uvicorn src.main:app --host $HOST --port $PORT \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..727e6b0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Evolution API + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fc6b1f2 --- /dev/null +++ b/Makefile @@ -0,0 +1,86 @@ +.PHONY: migrate init revision upgrade downgrade run seed-admin seed-client seed-mcp-servers seed-tools seed-all docker-build docker-up docker-down docker-logs lint format install install-dev venv + +# Alembic commands +init: + alembic init alembics + +# make alembic-revision message="migration description" +alembic-revision: + alembic revision --autogenerate -m "$(message)" + +# Command to update database to latest version (execute existing migrations) +alembic-upgrade: + alembic upgrade head + +# Command to downgrade one version +alembic-downgrade: + alembic downgrade -1 + +# Command to run the server +run: + uvicorn src.main:app --host 0.0.0.0 --port 8000 --reload --env-file .env --reload-exclude frontend/ --reload-exclude "*.log" --reload-exclude "*.tmp" + +# Command to run the server in production mode +run-prod: + uvicorn src.main:app --host 0.0.0.0 --port 8000 --workers 4 + +# Command to clean cache in all project folders +clear-cache: + rm -rf ~/.cache/uv/environments-v2/* && find . -type d -name "__pycache__" -exec rm -r {} + + +# Command to create a new migration and apply it +alembic-migrate: + alembic revision --autogenerate -m "$(message)" && alembic upgrade head + +# Command to reset the database +alembic-reset: + alembic downgrade base && alembic upgrade head + +# Commands to run seeders +seed-admin: + python -m scripts.seeders.admin_seeder + +seed-client: + python -m scripts.seeders.client_seeder + +seed-mcp-servers: + python -m scripts.seeders.mcp_server_seeder + +seed-tools: + python -m scripts.seeders.tool_seeder + +seed-all: + python -m scripts.run_seeders + +# Docker commands +docker-build: + docker-compose build + +docker-up: + docker-compose up -d + +docker-down: + docker-compose down + +docker-logs: + docker-compose logs -f + +docker-seed: + docker-compose exec api python -m scripts.run_seeders + +# Testing, linting and formatting commands +lint: + flake8 src/ tests/ + +format: + black src/ tests/ + +# Virtual environment and installation commands +venv: + python -m venv venv + +install: + pip install -e . + +install-dev: + pip install -e ".[dev]" \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..c75cbd6 --- /dev/null +++ b/README.md @@ -0,0 +1,387 @@ +

Evo AI - AI Agents Platform

+ +
+ +[![Whatsapp Group](https://img.shields.io/badge/Group-WhatsApp-%2322BC18)](https://evolution-api.com/whatsapp) +[![Discord Community](https://img.shields.io/badge/Discord-Community-blue)](https://evolution-api.com/discord) +[![Postman Collection](https://img.shields.io/badge/Postman-Collection-orange)](https://evolution-api.com/postman) +[![Documentation](https://img.shields.io/badge/Documentation-Official-green)](https://doc.evolution-api.com) +[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](./LICENSE) +[![Support](https://img.shields.io/badge/Donation-picpay-green)](https://app.picpay.com/user/davidsongomes1998) +[![Sponsors](https://img.shields.io/badge/Github-sponsor-orange)](https://github.com/sponsors/EvolutionAPI) + +
+ +## Evo AI - AI Agents Platform + +Evo AI is an open-source platform for creating and managing AI agents, enabling integration with different AI models and services. + +## 🚀 Overview + +The Evo AI platform allows: + +- Creation and management of AI agents +- Integration with different language models +- Client management and MCP server configuration +- Custom tools management +- **[Google Agent Development Kit (ADK)](https://google.github.io/adk-docs/)**: Base framework for agent development +- **[CrewAI Support](https://github.com/crewAI/crewAI)**: Alternative framework for agent development (in development) +- JWT authentication with email verification +- **[Agent 2 Agent (A2A) Protocol Support](https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/)**: Interoperability between AI agents +- **[Workflow Agent with LangGraph](https://www.langchain.com/langgraph)**: Building complex agent workflows +- **Secure API Key Management**: Encrypted storage of API keys +- **Agent Organization**: Folder structure for organizing agents by categories + +## 🤖 Agent Types + +Evo AI supports different types of agents that can be flexibly combined: + +### 1. LLM Agent (Language Model) + +Agent based on language models like GPT-4, Claude, etc. Can be configured with tools, MCP servers, and sub-agents. + +### 2. A2A Agent (Agent-to-Agent) + +Agent that implements Google's A2A protocol for agent interoperability. + +### 3. Sequential Agent + +Executes a sequence of sub-agents in a specific order. + +### 4. Parallel Agent + +Executes multiple sub-agents simultaneously. + +### 5. Loop Agent + +Executes sub-agents in a loop with a defined maximum number of iterations. + +### 6. Workflow Agent + +Executes sub-agents in a custom workflow defined by a graph structure using LangGraph. + +### 7. Task Agent + +Executes a specific task using a target agent with structured task instructions. + +## 🛠️ Technologies + +### Backend +- **FastAPI**: Web framework for building the API +- **SQLAlchemy**: ORM for database interaction +- **PostgreSQL**: Main database +- **Alembic**: Migration system +- **Pydantic**: Data validation and serialization +- **Uvicorn**: ASGI server +- **Redis**: Cache and session management +- **JWT**: Secure token authentication +- **SendGrid/SMTP**: Email service for notifications (configurable) +- **Jinja2**: Template engine for email rendering +- **Bcrypt**: Password hashing and security +- **LangGraph**: Framework for building stateful, multi-agent workflows + +### Frontend +- **Next.js 15**: React framework with App Router +- **React 18**: User interface library +- **TypeScript**: Type-safe JavaScript +- **Tailwind CSS**: Utility-first CSS framework +- **shadcn/ui**: Modern component library +- **React Hook Form**: Form management +- **Zod**: Schema validation +- **ReactFlow**: Node-based visual workflows +- **React Query**: Server state management + +## 📊 Langfuse Integration (Tracing & Observability) + +Evo AI platform natively supports integration with [Langfuse](https://langfuse.com/) for detailed tracing of agent executions, prompts, model responses, and tool calls, using the OpenTelemetry (OTel) standard. + +### How to configure + +1. **Set environment variables in your `.env`:** + + ```env + LANGFUSE_PUBLIC_KEY="pk-lf-..." + LANGFUSE_SECRET_KEY="sk-lf-..." + OTEL_EXPORTER_OTLP_ENDPOINT="https://cloud.langfuse.com/api/public/otel" + ``` + +2. **View in the Langfuse dashboard** + - Access your Langfuse dashboard to see real-time traces. + +## 🤖 Agent 2 Agent (A2A) Protocol Support + +Evo AI implements the Google's Agent 2 Agent (A2A) protocol, enabling seamless communication and interoperability between AI agents. + +For more information about the A2A protocol, visit [Google's A2A Protocol Documentation](https://google.github.io/A2A/). + +## 📋 Prerequisites + +### Backend +- **Python**: 3.10 or higher +- **PostgreSQL**: 13.0 or higher +- **Redis**: 6.0 or higher +- **Git**: For version control +- **Make**: For running Makefile commands + +### Frontend +- **Node.js**: 18.0 or higher +- **pnpm**: Package manager (recommended) or npm/yarn + +## 🔧 Installation + +### 1. Clone the Repository + +```bash +git clone https://github.com/EvolutionAPI/evo-ai.git +cd evo-ai +``` + +### 2. Backend Setup + +#### Virtual Environment and Dependencies + +```bash +# Create and activate virtual environment +make venv +source venv/bin/activate # Linux/Mac +# or on Windows: venv\Scripts\activate + +# Install development dependencies +make install-dev +``` + +#### Environment Configuration + +```bash +# Copy and configure backend environment +cp .env.example .env +# Edit the .env file with your database, Redis, and other settings +``` + +#### Database Setup + +```bash +# Initialize database and apply migrations +make alembic-upgrade + +# Seed initial data (admin user, sample clients, etc.) +make seed-all +``` + +### 3. Frontend Setup + +#### Install Dependencies + +```bash +# Navigate to frontend directory +cd frontend + +# Install dependencies using pnpm (recommended) +pnpm install + +# Or using npm +# npm install + +# Or using yarn +# yarn install +``` + +#### Frontend Environment Configuration + +```bash +# Copy and configure frontend environment +cp .env.example .env +# Edit .env with your API URL (default: http://localhost:8000) +``` + +The frontend `.env` should contain: + +```env +NEXT_PUBLIC_API_URL=http://localhost:8000 +``` + +## 🚀 Running the Application + +### Development Mode + +#### Start Backend (Terminal 1) +```bash +# From project root +make run +# Backend will be available at http://localhost:8000 +``` + +#### Start Frontend (Terminal 2) +```bash +# From frontend directory +cd frontend +pnpm dev + +# Or using npm/yarn +# npm run dev +# yarn dev + +# Frontend will be available at http://localhost:3000 +``` + +### Production Mode + +#### Backend +```bash +make run-prod # Production with multiple workers +``` + +#### Frontend +```bash +cd frontend +pnpm build && pnpm start + +# Or using npm/yarn +# npm run build && npm start +# yarn build && yarn start +``` + +## 🐳 Docker Installation + +### Full Stack with Docker Compose + +```bash +# Build and start all services (backend + database + redis) +make docker-build +make docker-up + +# Initialize database with seed data +make docker-seed +``` + +### Frontend with Docker + +```bash +# From frontend directory +cd frontend + +# Build frontend image +docker build -t evo-ai-frontend . + +# Run frontend container +docker run -p 3000:3000 -e NEXT_PUBLIC_API_URL=http://localhost:8000 evo-ai-frontend +``` + +Or using the provided docker-compose: + +```bash +# From frontend directory +cd frontend +docker-compose up -d +``` + +## 🎯 Getting Started + +After installation, follow these steps: + +1. **Access the Frontend**: Open `http://localhost:3000` +2. **Create Admin Account**: Use the seeded admin credentials or register a new account +3. **Configure MCP Server**: Set up your first MCP server connection +4. **Create Client**: Add a client to organize your agents +5. **Build Your First Agent**: Create and configure your AI agent +6. **Test Agent**: Use the chat interface to interact with your agent + +### Default Admin Credentials + +After running the seeders, you can login with: +- **Email**: Check the seeder output for the generated admin email +- **Password**: Check the seeder output for the generated password + +## 🖥️ API Documentation + +The interactive API documentation is available at: + +- Swagger UI: `http://localhost:8000/docs` +- ReDoc: `http://localhost:8000/redoc` + +## 👨‍💻 Development Commands + +### Backend Commands +```bash +# Database migrations +make alembic-upgrade # Update database to latest version +make alembic-revision message="description" # Create new migration + +# Seeders +make seed-all # Run all seeders + +# Code verification +make lint # Verify code with flake8 +make format # Format code with black +``` + +### Frontend Commands +```bash +# From frontend directory +cd frontend + +# Development +pnpm dev # Start development server +pnpm build # Build for production +pnpm start # Start production server +pnpm lint # Run ESLint +``` + +## 🚀 Configuration + +### Backend Configuration (.env file) + +Key settings include: + +```bash +# Database settings +POSTGRES_CONNECTION_STRING="postgresql://postgres:root@localhost:5432/evo_ai" + +# Redis settings +REDIS_HOST="localhost" +REDIS_PORT=6379 + +# AI Engine configuration +AI_ENGINE="adk" # Options: "adk" (Google Agent Development Kit) or "crewai" (CrewAI framework) + +# JWT settings +JWT_SECRET_KEY="your-jwt-secret-key" + +# Email provider configuration +EMAIL_PROVIDER="sendgrid" # Options: "sendgrid" or "smtp" + +# Encryption for API keys +ENCRYPTION_KEY="your-encryption-key" +``` + +### Frontend Configuration (.env file) + +```bash +# API Configuration +NEXT_PUBLIC_API_URL="http://localhost:8000" # Backend API URL +``` + +> **Note**: While Google ADK is fully supported, the CrewAI engine option is still under active development. For production environments, it's recommended to use the default "adk" engine. + +## 🔐 Authentication + +The API uses JWT (JSON Web Token) authentication with: + +- User registration and email verification +- Login to obtain JWT tokens +- Password recovery flow +- Account lockout after multiple failed login attempts + +## 🚀 Star Us on GitHub + +If you find EvoAI useful, please consider giving us a star! Your support helps us grow our community and continue improving the product. + +[![Star History Chart](https://api.star-history.com/svg?repos=EvolutionAPI/evo-ai&type=Date)](https://www.star-history.com/#EvolutionAPI/evo-ai&Date) + +## 🤝 Contributing + +We welcome contributions from the community! Please read our [Contributing Guidelines](CONTRIBUTING.md) for more details. + +## 📄 License + +This project is licensed under the [Apache License 2.0](./LICENSE). diff --git a/alembic.ini b/alembic.ini new file mode 100644 index 0000000..f7d32c2 --- /dev/null +++ b/alembic.ini @@ -0,0 +1,119 @@ +# A generic, single database configuration. + +[alembic] +# path to migration scripts +# Use forward slashes (/) also on windows to provide an os agnostic path +script_location = migrations + +# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s +# Uncomment the line below if you want the files to be prepended with date and time +# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file +# for all available tokens +# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s + +# sys.path path, will be prepended to sys.path if present. +# defaults to the current working directory. +prepend_sys_path = . + +# timezone to use when rendering the date within the migration file +# as well as the filename. +# If specified, requires the python>=3.9 or backports.zoneinfo library and tzdata library. +# Any required deps can installed by adding `alembic[tz]` to the pip requirements +# string value is passed to ZoneInfo() +# leave blank for localtime +# timezone = + +# max length of characters to apply to the "slug" field +# truncate_slug_length = 40 + +# set to 'true' to run the environment during +# the 'revision' command, regardless of autogenerate +# revision_environment = false + +# set to 'true' to allow .pyc and .pyo files without +# a source .py file to be detected as revisions in the +# versions/ directory +# sourceless = false + +# version location specification; This defaults +# to migrations/versions. When using multiple version +# directories, initial revisions must be specified with --version-path. +# The path separator used here should be the separator specified by "version_path_separator" below. +# version_locations = %(here)s/bar:%(here)s/bat:migrations/versions + +# version path separator; As mentioned above, this is the character used to split +# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep. +# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas. +# Valid values for version_path_separator are: +# +# version_path_separator = : +# version_path_separator = ; +# version_path_separator = space +# version_path_separator = newline +# +# Use os.pathsep. Default configuration used for new projects. +version_path_separator = os + +# set to 'true' to search source files recursively +# in each "version_locations" directory +# new in Alembic version 1.10 +# recursive_version_locations = false + +# the output encoding used when revision files +# are written from script.py.mako +# output_encoding = utf-8 + +sqlalchemy.url = postgresql://postgres:root@localhost:5432/evo_ai + + +[post_write_hooks] +# post_write_hooks defines scripts or Python functions that are run +# on newly generated revision scripts. See the documentation for further +# detail and examples + +# format using "black" - use the console_scripts runner, against the "black" entrypoint +# hooks = black +# black.type = console_scripts +# black.entrypoint = black +# black.options = -l 79 REVISION_SCRIPT_FILENAME + +# lint with attempts to fix using "ruff" - use the exec runner, execute a binary +# hooks = ruff +# ruff.type = exec +# ruff.executable = %(here)s/.venv/bin/ruff +# ruff.options = check --fix REVISION_SCRIPT_FILENAME + +# Logging configuration +[loggers] +keys = root,sqlalchemy,alembic + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARNING +handlers = console +qualname = + +[logger_sqlalchemy] +level = WARNING +handlers = +qualname = sqlalchemy.engine + +[logger_alembic] +level = INFO +handlers = +qualname = alembic + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(levelname)-5.5s [%(name)s] %(message)s +datefmt = %H:%M:%S diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000..02462cc --- /dev/null +++ b/conftest.py @@ -0,0 +1,82 @@ +""" +┌──────────────────────────────────────────────────────────────────────────────┐ +│ @author: Davidson Gomes │ +│ @file: conftest.py │ +│ Developed by: Davidson Gomes │ +│ Creation date: May 13, 2025 │ +│ Contact: contato@evolution-api.com │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @copyright © Evolution API 2025. All rights reserved. │ +│ Licensed under the Apache License, Version 2.0 │ +│ │ +│ You may not use this file except in compliance with the License. │ +│ You may obtain a copy of the License at │ +│ │ +│ http://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +│ Unless required by applicable law or agreed to in writing, software │ +│ distributed under the License is distributed on an "AS IS" BASIS, │ +│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ +│ See the License for the specific language governing permissions and │ +│ limitations under the License. │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @important │ +│ For any future changes to the code in this file, it is recommended to │ +│ include, together with the modification, the information of the developer │ +│ who changed it and the date of modification. │ +└──────────────────────────────────────────────────────────────────────────────┘ +""" + +import pytest +from fastapi.testclient import TestClient +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker +from sqlalchemy.pool import StaticPool + +from src.config.database import Base, get_db +from src.main import app + +# Use in-memory SQLite for tests +SQLALCHEMY_DATABASE_URL = "sqlite:///:memory:" + +engine = create_engine( + SQLALCHEMY_DATABASE_URL, + connect_args={"check_same_thread": False}, + poolclass=StaticPool, +) +TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) + + +@pytest.fixture(scope="function") +def db_session(): + """Creates a fresh database session for each test.""" + Base.metadata.create_all(bind=engine) # Create tables + + connection = engine.connect() + transaction = connection.begin() + session = TestingSessionLocal(bind=connection) + + # Use our test database instead of the standard one + def override_get_db(): + try: + yield session + session.commit() + finally: + session.close() + + app.dependency_overrides[get_db] = override_get_db + + yield session # The test will run here + + # Teardown + transaction.rollback() + connection.close() + Base.metadata.drop_all(bind=engine) + app.dependency_overrides.clear() + + +@pytest.fixture(scope="function") +def client(db_session): + """Creates a FastAPI TestClient with database session fixture.""" + with TestClient(app) as test_client: + yield test_client diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..62bba2c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,56 @@ +version: "3.8" + +services: + api: + image: evoapicloud/evo-ai:latest + depends_on: + - postgres + - redis + environment: + POSTGRES_CONNECTION_STRING: postgresql://postgres:${POSTGRES_PASSWORD:-postgres}@postgres:5432/evo_ai + REDIS_HOST: redis + REDIS_PORT: ${REDIS_PORT:-6379} + REDIS_PASSWORD: ${REDIS_PASSWORD:-""} + REDIS_SSL: "false" + REDIS_KEY_PREFIX: "a2a:" + REDIS_TTL: 3600 + JWT_SECRET_KEY: ${JWT_SECRET_KEY} + SENDGRID_API_KEY: ${SENDGRID_API_KEY} + EMAIL_FROM: ${EMAIL_FROM} + APP_URL: https://evo.api.seuadvogadoja.com.br + LOG_LEVEL: INFO + DEBUG: "false" + volumes: + - ./logs:/app/logs + - ./static:/app/static + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/"] + interval: 30s + timeout: 10s + retries: 5 + + postgres: + image: postgres:14-alpine + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} + POSTGRES_DB: evo_ai + volumes: + - postgres_data:/var/lib/postgresql/data + + redis: + image: redis:alpine + command: + - redis-server + - --appendonly + - "yes" + - --requirepass + - "${REDIS_PASSWORD}" + volumes: + - redis_data:/data + +volumes: + postgres_data: + name: evo-ai-postgres-data + redis_data: + name: evo-ai-redis-data diff --git a/docker_build.sh b/docker_build.sh new file mode 100644 index 0000000..1772280 --- /dev/null +++ b/docker_build.sh @@ -0,0 +1,2 @@ +docker build -t atendai/evoai-api:latest . +docker push atendai/evoai-api:latest diff --git a/frontend/.cursorrules b/frontend/.cursorrules new file mode 100644 index 0000000..5d384dd --- /dev/null +++ b/frontend/.cursorrules @@ -0,0 +1,120 @@ +# Next.js Project Rules + +## Language +- All code, comments, documentation, commits, and PRs MUST be written in English. + +## Architecture + +### Folder Structure +- `/app`: App router pages and API routes + - Route-specific components should be placed in their respective route folders +- `/components`: Reusable UI components + - `/ui`: Shadcn UI components and their derivatives +- `/contexts`: React Context providers +- `/hooks`: Custom React hooks +- `/lib`: Utility functions and configuration +- `/public`: Static assets +- `/services`: API service functions +- `/styles`: Global styles +- `/types`: TypeScript type definitions + +### Component Guidelines +- Use functional components with TypeScript +- Use the `.tsx` extension for React components +- Follow a logical naming convention: + - Complex components: Use PascalCase and create folders with an index.tsx file + - Simple components: Single PascalCase named files + +### State Management +- Use React Context for global state +- Use React hooks for local state +- Avoid prop drilling more than 2 levels deep + +### API & Data Fetching +- Use API service modules in `/services` directory +- Implement proper error handling and loading states +- Use React Query or SWR for complex data fetching where appropriate + +## Development Patterns + +### Code Quality +- Maintain type safety - avoid using `any` type +- Write self-documenting code with descriptive names +- Keep components focused on a single responsibility +- Extract complex logic into custom hooks +- Follow DRY (Don't Repeat Yourself) principle + +### CSS & Styling +- Use Tailwind CSS for styling +- Use Shadcn UI components as base building blocks +- Maintain consistent spacing and sizing + +### Performance +- Avoid unnecessary re-renders +- Optimize images and assets +- Implement code splitting where appropriate +- Use dynamic imports for large components/pages + +### Testing +- Write tests for critical business logic +- Test components in isolation +- Implement end-to-end tests for critical user flows + +## Git Workflow + +### Branch Naming +- Features: `feature/short-description` +- Bugfixes: `fix/short-description` +- Hotfixes: `hotfix/short-description` +- Releases: `release/version` + +## Conventions +- Variable and function names in English +- Log and error messages in English +- Documentation in English +- User-facing content (emails, responses) in English +- Indentation with 4 spaces +- Maximum of 79 characters per line + +## Commit Rules +- Use Conventional Commits format for all commit messages +- Format: `(): ` +- Types: + - `feat`: A new feature + - `fix`: A bug fix + - `docs`: Documentation changes + - `style`: Changes that do not affect code meaning (formatting, etc.) + - `refactor`: Code changes that neither fix a bug nor add a feature + - `perf`: Performance improvements + - `test`: Adding or modifying tests + - `chore`: Changes to build process or auxiliary tools +- Scope is optional and should be the module or component affected +- Description should be concise, in the imperative mood, and not capitalized +- Use body for more detailed explanations if needed +- Reference issues in the footer with `Fixes #123` or `Relates to #123` +- Examples: + - `feat(auth): add password reset functionality` + - `fix(api): correct validation error in client registration` + - `docs: update API documentation for new endpoints` + - `refactor(services): improve error handling in authentication` + +Format: `type(scope): subject` + +Examples: +- `feat(auth): add login form validation` +- `fix(api): resolve user data fetching issue` +- `docs(readme): update installation instructions` +- `style(components): format according to style guide` + +### Pull Requests +- Keep PRs focused on a single feature or fix +- Include descriptive titles and descriptions +- Reference related issues +- Request code reviews from appropriate team members +- Ensure CI checks pass before merging + +## Code Review Guidelines +- Focus on code quality, architecture, and maintainability +- Provide constructive feedback +- Address all review comments before merging +- Maintain a respectful and collaborative tone \ No newline at end of file diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..76b82d9 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,61 @@ +# Dependencies +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Production builds +.next/ +out/ +dist/ + +# Environment variables +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Logs +logs +*.log + +# Temporary files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# IDEs and editors +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Git +.git +.gitignore + +# Docker +Dockerfile* +docker-compose* +.dockerignore + +# Testing +coverage/ +.nyc_output +.coverage + +# Other +.cache/ \ No newline at end of file diff --git a/frontend/.env.example b/frontend/.env.example new file mode 100644 index 0000000..f9feddb --- /dev/null +++ b/frontend/.env.example @@ -0,0 +1 @@ +NEXT_PUBLIC_API_URL=http://localhost:8000 \ No newline at end of file diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..400e48e --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,31 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules + +# next.js +/.next/ +/out/ + +# production +/build + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# Lock files +package-lock.json +yarn.lock + +# env files +.env + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts \ No newline at end of file diff --git a/frontend/CHANGELOG.md b/frontend/CHANGELOG.md new file mode 100644 index 0000000..7a1f920 --- /dev/null +++ b/frontend/CHANGELOG.md @@ -0,0 +1,67 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.0.7] - 2025-05-15 + +### Added + +- Add Task agents +- Add file support for A2A protocol (Agent-to-Agent) endpoints +- Add entrypoint script for dynamic environment variable handling +- Add agent card URL input and copy functionality + +## [0.0.6] - 2025-05-13 + +### Added + +- Agent sharing functionality with third parties via API keys +- Dedicated shared-chat page for accessing shared agents +- Local storage mechanism to save recently used shared agents +- Public access to shared agents without full authentication + +### Changed + +- Add example environment file and update .gitignore +- Add clientId prop to agent-related components and improve agent data processing +- Refactor middleware to handle shared agent routes as public paths +- Update API interceptors to prevent forced logout on shared chat pages + +### security + +- Implement force logout functionality on 401 Unauthorized responses + +## [0.0.5] - 2025-05-13 + +### Changed + +- Update author information in multiple files + +## [0.0.4] - 2025-05-13 + +### Added +- Initial public release +- User-friendly interface for creating and managing AI agents +- Integration with multiple language models (e.g., GPT-4, Claude) +- Client management interface +- Visual configuration for MCP servers +- Custom tools management +- JWT authentication with email verification +- Agent 2 Agent (A2A) protocol support (Google's A2A spec) +- Workflow Agent with ReactFlow for visual workflow creation +- Secure API key management (encrypted storage) +- Agent organization with folders and categories +- Dashboard with agent overview, usage stats, and recent activities +- Agent editor for creating, editing, and configuring agents +- Workflow editor for building and visualizing agent flows +- API key manager for adding, encrypting, and rotating keys +- RESTful API and WebSocket backend integration +- Docker support for containerized deployment +- Complete documentation and contribution guidelines + +--- + +Older versions and future releases will be listed here. diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..fee81f4 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,60 @@ +# Build stage +FROM node:20.15.1-alpine AS builder + +WORKDIR /app + +# Define build arguments with default values +ARG NEXT_PUBLIC_API_URL=https://api.evo-ai.co + +# Install pnpm globally +RUN npm install -g pnpm + +# Copy package files first for better caching +COPY package.json pnpm-lock.yaml ./ + +# Install dependencies +RUN pnpm install --no-frozen-lockfile + +# Copy all source code (this includes tsconfig.json, lib/, etc.) +COPY . . + +# Set environment variables from build arguments +ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} + +# Build the application +RUN pnpm run build + +# Production stage +FROM node:20.15.1-alpine AS runner + +WORKDIR /app + +# Define build arguments again for the runner stage +ARG NEXT_PUBLIC_API_URL=https://api-evoai.evoapicloud.com + +# Install pnpm globally +RUN npm install -g pnpm + +# Install production dependencies only +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --prod --no-frozen-lockfile + +# Copy built assets from builder +COPY --from=builder /app/.next ./.next +COPY --from=builder /app/public ./public +COPY --from=builder /app/next.config.mjs ./ + +# Set environment variables +ENV NODE_ENV=production +ENV PORT=3000 +ENV NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} + +# Script to replace environment variables at runtime +COPY docker-entrypoint.sh ./ +RUN chmod +x ./docker-entrypoint.sh + +# Expose port +EXPOSE 3000 + +# Use entrypoint script to initialize environment variables before starting the app +ENTRYPOINT ["sh", "./docker-entrypoint.sh"] \ No newline at end of file diff --git a/frontend/LICENSE b/frontend/LICENSE new file mode 100644 index 0000000..727e6b0 --- /dev/null +++ b/frontend/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2025 Evolution API + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/frontend/README.md b/frontend/README.md new file mode 100644 index 0000000..baf0498 --- /dev/null +++ b/frontend/README.md @@ -0,0 +1,237 @@ +# Evo AI - AI Agents Platform (Frontend) + +Evo AI is an open-source platform for creating and managing AI agents, enabling integration with different AI models and services. + +## 🚀 Overview + +The Evo AI frontend platform enables: + +- User-friendly interface for creating and managing AI agents +- Integration with different language models +- Client management +- Visual configuration of MCP servers +- Custom tools management +- JWT authentication with email verification +- **Agent 2 Agent (A2A) Protocol Support**: Interface for interoperability between AI agents following Google's A2A specification +- **Workflow Agent with ReactFlow**: Visual interface for building complex agent workflows +- **Secure API Key Management**: Interface for encrypted storage of API keys +- **Agent Organization**: Folder structure for organizing agents by categories + +## 🧩 Agent Creation Interface + +The frontend offers intuitive interfaces for creating different types of agents: + +### 1. LLM Agent (Language Model) + +Interface for configuring agents based on models like GPT-4, Claude, etc. with tools, MCP servers, and sub-agents. + +### 2. A2A Agent (Agent-to-Agent) + +Interface for implementing Google's A2A protocol for agent interoperability. + +### 3. Sequential Agent + +Interface for executing sub-agents in a specific order. + +### 4. Parallel Agent + +Interface for executing multiple sub-agents simultaneously. + +### 5. Loop Agent + +Interface for executing sub-agents in a loop with a defined number of iterations. + +### 6. Workflow Agent + +Visual interface based on ReactFlow for creating complex workflows between agents. + +## 🛠️ Technologies + +- [Next.js](https://nextjs.org/) - React framework for production +- [React](https://reactjs.org/) - JavaScript library for building user interfaces +- [Tailwind CSS](https://tailwindcss.com/) - Utility-first CSS framework +- [Shadcn UI](https://ui.shadcn.com/) - UI component library +- [Radix UI](https://www.radix-ui.com/) - Unstyled, accessible components +- [TypeScript](https://www.typescriptlang.org/) - Typed JavaScript +- [React Query](https://tanstack.com/query/latest) - Data fetching and state management +- [Zustand](https://zustand-demo.pmnd.rs/) - Global state management +- [React Flow](https://reactflow.dev/) - Library for building node-based visual workflows +- [Axios](https://axios-http.com/) - HTTP client for API communication + +## 📋 Requirements + +- Node.js 18+ (LTS recommended) +- npm, yarn, or pnpm package manager +- Evo AI backend running + +## 🔧 Installation + +1. Clone the repository: + +```bash +git clone https://github.com/EvolutionAPI/evo-ai-frontend.git +cd evo-ai-frontend +``` + +2. Install dependencies: + +```bash +npm install +# or +yarn install +# or +pnpm install +``` + +3. Configure environment variables: + +```bash +cp .env.example .env +# Edit the .env file with your settings +``` + +## 🚀 Running the Project + +```bash +# Development mode +npm run dev +# or +yarn dev +# or +pnpm dev + +# Production build +npm run build +# or +yarn build +# or +pnpm build + +# Start production server +npm run start +# or +yarn start +# or +pnpm start +``` + +The project will be available at [http://localhost:3000](http://localhost:3000) + +## 🔐 Authentication + +The frontend implements JWT authentication integrated with the backend: + +- **User Registration**: Form for creating new accounts +- **Email Verification**: Process for verifying via email +- **Login**: Authentication of existing users +- **Password Recovery**: Complete password recovery flow +- **Secure Storage**: Tokens stored in HttpOnly cookies + +## 🖥️ Main Interface Features + +### Dashboard + +Main dashboard showing: +- Agent overview +- Usage statistics +- Recent activities +- Quick links for agent creation + +### Agent Editor + +Complete interface for: +- Creating new agents +- Editing existing agents +- Configuring instructions +- Selecting models +- Setting up API keys + +### Workflow Editor + +Visual editor based on ReactFlow for: +- Creating complex workflows +- Connecting different agents +- Defining conditionals and decision flows +- Visualizing data flow + +### API Key Manager + +Interface for: +- Adding new API keys +- Securely encrypting keys +- Managing existing keys +- Rotating and updating keys + +### Agent Organization + +System for: +- Creating folders and categories +- Organizing agents by type or use case +- Searching and filtering agents + +## 🔄 Backend Integration + +The frontend communicates with the backend through: + +- **RESTful API**: Endpoints for resource management +- **WebSockets**: Real-time communication for agent messages +- **Response Streaming**: Support for streaming model responses + +## 🐳 Docker Support + +The project includes Docker configuration for containerized deployment: + +```bash +# Build the Docker image +./docker_build.sh +# or +docker build -t nextjs-frontend . + +# Run the container +docker run -p 3000:3000 nextjs-frontend +``` + +# 🐳 Docker Compose +```bash +# Copy the .env file +cp .env.example .env + +# Build and deploy + docker-compose up -d --build +``` + +## 🤝 Contributing + +We welcome contributions from the community! Here's how you can help: + +1. Fork the project +2. Create a feature branch (`git checkout -b feature/AmazingFeature`) +3. Make your changes and add tests if possible +4. Run tests and make sure they pass +5. Commit your changes following conventional commits format (`feat: add amazing feature`) +6. Push to the branch (`git push origin feature/AmazingFeature`) +7. Open a Pull Request + +Please read our [Contributing Guidelines](CONTRIBUTING.md) for more details. + +## 📄 License + +This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details. + +**Trademark Notice:** The name "Evo AI" and related branding are protected trademarks. Unauthorized use is prohibited. + +## 👨‍💻 Development Commands + +- `npm run dev` - Start the development server +- `npm run build` - Build the application for production +- `npm run start` - Start the production server +- `npm run lint` - Run ESLint to check code quality +- `npm run format` - Format code with Prettier + +## 🙏 Acknowledgments + +- [Next.js](https://nextjs.org/) +- [React](https://reactjs.org/) +- [Tailwind CSS](https://tailwindcss.com/) +- [Shadcn UI](https://ui.shadcn.com/) +- [ReactFlow](https://reactflow.dev/) diff --git a/frontend/app/agents/AgentCard.tsx b/frontend/app/agents/AgentCard.tsx new file mode 100644 index 0000000..75a25cb --- /dev/null +++ b/frontend/app/agents/AgentCard.tsx @@ -0,0 +1,506 @@ +/* +┌──────────────────────────────────────────────────────────────────────────────┐ +│ @author: Davidson Gomes │ +│ @file: /app/agents/AgentCard.tsx │ +│ Developed by: Davidson Gomes │ +│ Creation date: May 13, 2025 │ +│ Contact: contato@evolution-api.com │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @copyright © Evolution API 2025. All rights reserved. │ +│ Licensed under the Apache License, Version 2.0 │ +│ │ +│ You may not use this file except in compliance with the License. │ +│ You may obtain a copy of the License at │ +│ │ +│ http://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +│ Unless required by applicable law or agreed to in writing, software │ +│ distributed under the License is distributed on an "AS IS" BASIS, │ +│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ +│ See the License for the specific language governing permissions and │ +│ limitations under the License. │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @important │ +│ For any future changes to the code in this file, it is recommended to │ +│ include, together with the modification, the information of the developer │ +│ who changed it and the date of modification. │ +└──────────────────────────────────────────────────────────────────────────────┘ +*/ +"use client"; + +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { Folder } from "@/services/agentService"; +import { Agent, AgentType } from "@/types/agent"; +import { MCPServer } from "@/types/mcpServer"; +import { + ArrowRight, + Bot, + BookOpenCheck, + ChevronDown, + ChevronUp, + Code, + ExternalLink, + GitBranch, + MoveRight, + Pencil, + RefreshCw, + Settings, + Share2, + Trash2, + Workflow, + TextSelect, + Download, + FlaskConical, +} from "lucide-react"; +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import { cn } from "@/lib/utils"; +import { exportAsJson } from "@/lib/utils"; + +interface AgentCardProps { + agent: Agent; + onEdit: (agent: Agent) => void; + onDelete: (agent: Agent) => void; + onMove: (agent: Agent) => void; + onShare?: (agent: Agent) => void; + onWorkflow?: (agentId: string) => void; + availableMCPs?: MCPServer[]; + getApiKeyNameById?: (id: string | undefined) => string | null; + getAgentNameById?: (id: string) => string; + folders?: Folder[]; + agents: Agent[]; +} + +export function AgentCard({ + agent, + onEdit, + onDelete, + onMove, + onShare, + onWorkflow, + availableMCPs = [], + getApiKeyNameById = () => null, + getAgentNameById = (id) => id, + folders = [], + agents, +}: AgentCardProps) { + const [expanded, setExpanded] = useState(false); + const router = useRouter(); + + const getAgentTypeInfo = (type: AgentType) => { + const types: Record< + string, + { + label: string; + icon: React.ElementType; + color: string; + bgColor: string; + badgeClass: string; + } + > = { + llm: { + label: "LLM Agent", + icon: Code, + color: "#00cc7d", + bgColor: "bg-green-500/10", + badgeClass: + "bg-green-900/30 text-green-400 border-green-600/30 hover:bg-green-900/40", + }, + a2a: { + label: "A2A Agent", + icon: ExternalLink, + color: "#6366f1", + bgColor: "bg-indigo-500/10", + badgeClass: + "bg-indigo-900/30 text-indigo-400 border-indigo-600/30 hover:bg-indigo-900/40", + }, + sequential: { + label: "Sequential Agent", + icon: ArrowRight, + color: "#f59e0b", + bgColor: "bg-yellow-500/10", + badgeClass: + "bg-yellow-900/30 text-yellow-400 border-yellow-600/30 hover:bg-yellow-900/40", + }, + parallel: { + label: "Parallel Agent", + icon: GitBranch, + color: "#8b5cf6", + bgColor: "bg-purple-500/10", + badgeClass: + "bg-purple-900/30 text-purple-400 border-purple-600/30 hover:bg-purple-900/40", + }, + loop: { + label: "Loop Agent", + icon: RefreshCw, + color: "#ec4899", + bgColor: "bg-pink-500/10", + badgeClass: + "bg-orange-900/30 text-orange-400 border-orange-600/30 hover:bg-orange-900/40", + }, + workflow: { + label: "Workflow Agent", + icon: Workflow, + color: "#3b82f6", + bgColor: "bg-blue-500/10", + badgeClass: + "bg-blue-900/30 text-blue-400 border-blue-700/40 hover:bg-blue-900/40", + }, + task: { + label: "Task Agent", + icon: BookOpenCheck, + color: "#ef4444", + bgColor: "bg-red-500/10", + badgeClass: + "bg-red-900/30 text-red-400 border-red-600/30 hover:bg-red-900/40", + }, + }; + + return ( + types[type] || { + label: type, + icon: Bot, + color: "#94a3b8", + bgColor: "bg-slate-500/10", + badgeClass: + "bg-slate-900/30 text-slate-400 border-slate-600/30 hover:bg-slate-900/40", + } + ); + }; + + const getAgentTypeIcon = (type: AgentType) => { + const typeInfo = getAgentTypeInfo(type); + const IconComponent = typeInfo.icon; + return ( + + ); + }; + + const getAgentTypeName = (type: AgentType) => { + return getAgentTypeInfo(type).label; + }; + + const getAgentTypeBgColor = (type: AgentType) => { + return getAgentTypeInfo(type).bgColor; + }; + + const getAgentTypeBadgeClass = (type: AgentType) => { + return getAgentTypeInfo(type).badgeClass; + }; + + const getFolderNameById = (id: string) => { + const folder = folders?.find((f) => f.id === id); + return folder?.name || id; + }; + + const getTotalTools = () => { + if (agent.type === "llm" && agent.config?.mcp_servers) { + return agent.config.mcp_servers.reduce( + (total, mcp) => total + (mcp.tools?.length || 0), + 0 + ); + } + return 0; + }; + + const getCreatedAtFormatted = () => { + return new Date(agent.created_at).toLocaleDateString(); + }; + + // Function to export the agent as JSON + const handleExportAgent = () => { + try { + exportAsJson( + agent, + `agent-${agent.name + .replace(/\s+/g, "-") + .toLowerCase()}-${agent.id.substring(0, 8)}`, + true, + agents + ); + } catch (error) { + console.error("Error exporting agent:", error); + } + }; + + // Function to test the A2A agent in the lab + const handleTestA2A = () => { + // Use the agent card URL as base for A2A tests + const agentUrl = agent.agent_card_url?.replace( + "/.well-known/agent.json", + "" + ); + + // Use the API key directly from the agent config + const apiKey = agent.config?.api_key; + + // Build the URL with parameters for the lab tests + const params = new URLSearchParams(); + + if (agentUrl) { + params.set("agent_url", agentUrl); + } + + if (apiKey) { + params.set("api_key", apiKey); + } + + // Redirect to the lab tests in the "lab" tab + const testUrl = `/documentation?${params.toString()}#lab`; + + router.push(testUrl); + }; + + return ( + +
+
+ {getAgentTypeIcon(agent.type)} +

{agent.name}

+
+ + {getAgentTypeName(agent.type)} + +
+ + +
+

+ {agent.description && agent.description.length > 100 + ? `${agent.description.substring(0, 100)}...` + : agent.description} +

+
+ +
+
+ Model: + + {agent.type === "llm" ? agent.model : "N/A"} + +
+ +
+ + {expanded && ( +
+ {agent.folder_id && ( +
+ Folder: + + {getFolderNameById(agent.folder_id)} + +
+ )} + + {agent.type === "llm" && agent.api_key_id && ( +
+ API Key: + + {getApiKeyNameById(agent.api_key_id)} + +
+ )} + + {getTotalTools() > 0 && ( +
+ Tools: + {getTotalTools()} +
+ )} + + {agent.config?.sub_agents && agent.config.sub_agents.length > 0 && ( +
+ Sub-agents: + + {agent.config.sub_agents.length} + +
+ )} + + {agent.type === "workflow" && agent.config?.workflow && ( +
+ Elements: + + {agent.config.workflow.nodes?.length || 0} nodes,{" "} + {agent.config.workflow.edges?.length || 0} connections + +
+ )} + +
+ Created at: + {getCreatedAtFormatted()} +
+ +
+ ID: + {agent.id} +
+
+ )} + +
+ + + + + + + + Test A2A + + onEdit(agent)} + > + + Edit Agent + + onMove(agent)} + > + + Move Agent + + {onWorkflow && agent.type === "workflow" && ( + onWorkflow(agent.id)} + > + + Open Workflow + + )} + + + Export as JSON + + {onShare && ( + onShare(agent)} + > + + Share Agent + + )} + onDelete(agent)} + > + + Delete Agent + + + + + + + ); +} diff --git a/frontend/app/agents/AgentList.tsx b/frontend/app/agents/AgentList.tsx new file mode 100644 index 0000000..6eb55af --- /dev/null +++ b/frontend/app/agents/AgentList.tsx @@ -0,0 +1,130 @@ +/* +┌──────────────────────────────────────────────────────────────────────────────┐ +│ @author: Davidson Gomes │ +│ @file: /app/agents/AgentList.tsx │ +│ Developed by: Davidson Gomes │ +│ Creation date: May 13, 2025 │ +│ Contact: contato@evolution-api.com │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @copyright © Evolution API 2025. All rights reserved. │ +│ Licensed under the Apache License, Version 2.0 │ +│ │ +│ You may not use this file except in compliance with the License. │ +│ You may obtain a copy of the License at │ +│ │ +│ http://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +│ Unless required by applicable law or agreed to in writing, software │ +│ distributed under the License is distributed on an "AS IS" BASIS, │ +│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ +│ See the License for the specific language governing permissions and │ +│ limitations under the License. │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @important │ +│ For any future changes to the code in this file, it is recommended to │ +│ include, together with the modification, the information of the developer │ +│ who changed it and the date of modification. │ +└──────────────────────────────────────────────────────────────────────────────┘ +*/ +"use client"; + +import { Agent } from "@/types/agent"; +import { MCPServer } from "@/types/mcpServer"; +import { AgentCard } from "./AgentCard"; +import { EmptyState } from "./EmptyState"; +import { ApiKey, Folder } from "@/services/agentService"; + +interface AgentListProps { + agents: Agent[]; + isLoading: boolean; + searchTerm: string; + selectedFolderId: string | null; + availableMCPs: MCPServer[]; + getApiKeyNameById: (id: string | undefined) => string | null; + getAgentNameById: (id: string) => string; + onEdit: (agent: Agent) => void; + onDelete: (agent: Agent) => void; + onMove: (agent: Agent) => void; + onShare?: (agent: Agent) => void; + onWorkflow?: (agentId: string) => void; + onClearSearch?: () => void; + onCreateAgent?: () => void; + apiKeys: ApiKey[]; + folders: Folder[]; +} + +export function AgentList({ + agents, + isLoading, + searchTerm, + selectedFolderId, + availableMCPs, + getApiKeyNameById, + getAgentNameById, + onEdit, + onDelete, + onMove, + onShare, + onWorkflow, + onClearSearch, + onCreateAgent, + apiKeys, + folders, +}: AgentListProps) { + if (isLoading) { + return ( +
+
+
+ ); + } + + if (agents.length === 0) { + if (searchTerm) { + return ( + + ); + } else if (selectedFolderId) { + return ( + + ); + } else { + return ( + + ); + } + } + + return ( +
+ {agents.map((agent) => ( + + ))} +
+ ); +} diff --git a/frontend/app/agents/AgentSidebar.tsx b/frontend/app/agents/AgentSidebar.tsx new file mode 100644 index 0000000..1635810 --- /dev/null +++ b/frontend/app/agents/AgentSidebar.tsx @@ -0,0 +1,186 @@ +/* +┌──────────────────────────────────────────────────────────────────────────────┐ +│ @author: Davidson Gomes │ +│ @file: /app/agents/AgentSidebar.tsx │ +│ Developed by: Davidson Gomes │ +│ Creation date: May 13, 2025 │ +│ Contact: contato@evolution-api.com │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @copyright © Evolution API 2025. All rights reserved. │ +│ Licensed under the Apache License, Version 2.0 │ +│ │ +│ You may not use this file except in compliance with the License. │ +│ You may obtain a copy of the License at │ +│ │ +│ http://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +│ Unless required by applicable law or agreed to in writing, software │ +│ distributed under the License is distributed on an "AS IS" BASIS, │ +│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ +│ See the License for the specific language governing permissions and │ +│ limitations under the License. │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @important │ +│ For any future changes to the code in this file, it is recommended to │ +│ include, together with the modification, the information of the developer │ +│ who changed it and the date of modification. │ +└──────────────────────────────────────────────────────────────────────────────┘ +*/ +"use client"; + +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { + Folder, + FolderPlus, + Home, + X, + CircleEllipsis, + Edit, + Trash2, +} from "lucide-react"; + +interface AgentFolder { + id: string; + name: string; + description: string; +} + +interface AgentSidebarProps { + visible: boolean; + folders: AgentFolder[]; + selectedFolderId: string | null; + onSelectFolder: (id: string | null) => void; + onAddFolder: () => void; + onEditFolder: (folder: AgentFolder) => void; + onDeleteFolder: (folder: AgentFolder) => void; + onClose: () => void; +} + +export function AgentSidebar({ + visible, + folders, + selectedFolderId, + onSelectFolder, + onAddFolder, + onEditFolder, + onDeleteFolder, + onClose, +}: AgentSidebarProps) { + return ( + <> + {visible && ( + + )} + +
+
+

+ + Folders +

+
+ + +
+
+ +
+ + + {folders.map((folder) => ( +
+ + +
+ + + + + + { + e.stopPropagation(); + onEditFolder(folder); + }} + > + + Edit + + { + e.stopPropagation(); + onDeleteFolder(folder); + }} + > + + Delete + + + +
+
+ ))} +
+
+ + ); +} diff --git a/frontend/app/agents/AgentTypeSelector.tsx b/frontend/app/agents/AgentTypeSelector.tsx new file mode 100644 index 0000000..35db3de --- /dev/null +++ b/frontend/app/agents/AgentTypeSelector.tsx @@ -0,0 +1,96 @@ +/* +┌──────────────────────────────────────────────────────────────────────────────┐ +│ @author: Davidson Gomes │ +│ @file: /app/agents/AgentTypeSelector.tsx │ +│ Developed by: Davidson Gomes │ +│ Creation date: May 13, 2025 │ +│ Contact: contato@evolution-api.com │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @copyright © Evolution API 2025. All rights reserved. │ +│ Licensed under the Apache License, Version 2.0 │ +│ │ +│ You may not use this file except in compliance with the License. │ +│ You may obtain a copy of the License at │ +│ │ +│ http://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +│ Unless required by applicable law or agreed to in writing, software │ +│ distributed under the License is distributed on an "AS IS" BASIS, │ +│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ +│ See the License for the specific language governing permissions and │ +│ limitations under the License. │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @important │ +│ For any future changes to the code in this file, it is recommended to │ +│ include, together with the modification, the information of the developer │ +│ who changed it and the date of modification. │ +└──────────────────────────────────────────────────────────────────────────────┘ +*/ +"use client"; + +import { AgentType } from "@/types/agent"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { + Code, + ExternalLink, + GitBranch, + RefreshCw, + Workflow, + Users, + BookOpenCheck, +} from "lucide-react"; + +interface AgentTypeSelectorProps { + value: AgentType; + onValueChange: (value: AgentType) => void; + className?: string; +} + +export const agentTypes = [ + { value: "llm", label: "LLM Agent", icon: Code }, + { value: "a2a", label: "A2A Agent", icon: ExternalLink }, + { value: "sequential", label: "Sequential Agent", icon: Workflow }, + { value: "parallel", label: "Parallel Agent", icon: GitBranch }, + { value: "loop", label: "Loop Agent", icon: RefreshCw }, + { value: "workflow", label: "Workflow Agent", icon: Workflow }, + { value: "task", label: "Task Agent", icon: BookOpenCheck }, +]; + +export function AgentTypeSelector({ + value, + onValueChange, + className = "", +}: AgentTypeSelectorProps) { + return ( + + ); +} diff --git a/frontend/app/agents/EmptyState.tsx b/frontend/app/agents/EmptyState.tsx new file mode 100644 index 0000000..b084c01 --- /dev/null +++ b/frontend/app/agents/EmptyState.tsx @@ -0,0 +1,107 @@ +/* +┌──────────────────────────────────────────────────────────────────────────────┐ +│ @author: Davidson Gomes │ +│ @file: /app/agents/EmptyState.tsx │ +│ Developed by: Davidson Gomes │ +│ Creation date: May 13, 2025 │ +│ Contact: contato@evolution-api.com │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @copyright © Evolution API 2025. All rights reserved. │ +│ Licensed under the Apache License, Version 2.0 │ +│ │ +│ You may not use this file except in compliance with the License. │ +│ You may obtain a copy of the License at │ +│ │ +│ http://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +│ Unless required by applicable law or agreed to in writing, software │ +│ distributed under the License is distributed on an "AS IS" BASIS, │ +│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ +│ See the License for the specific language governing permissions and │ +│ limitations under the License. │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @important │ +│ For any future changes to the code in this file, it is recommended to │ +│ include, together with the modification, the information of the developer │ +│ who changed it and the date of modification. │ +└──────────────────────────────────────────────────────────────────────────────┘ +*/ +"use client"; + +import { Button } from "@/components/ui/button"; +import { Folder, Plus, Search, Server } from "lucide-react"; + +interface EmptyStateProps { + type: "no-agents" | "empty-folder" | "search-no-results"; + searchTerm?: string; + onAction?: () => void; + actionLabel?: string; +} + +export function EmptyState({ + type, + searchTerm = "", + onAction, + actionLabel = "Create Agent", +}: EmptyStateProps) { + const getIcon = () => { + switch (type) { + case "empty-folder": + return ; + case "search-no-results": + return ; + case "no-agents": + default: + return ; + } + }; + + const getTitle = () => { + switch (type) { + case "empty-folder": + return "Empty folder"; + case "search-no-results": + return "No agents found"; + case "no-agents": + default: + return "No agents found"; + } + }; + + const getMessage = () => { + switch (type) { + case "empty-folder": + return "This folder is empty. Add agents or create a new one."; + case "search-no-results": + return `We couldn't find any agents that match your search: "${searchTerm}"`; + case "no-agents": + default: + return "You don't have any agents configured. Create your first agent to start!"; + } + }; + + return ( +
+
+ {getIcon()} +
+

{getTitle()}

+

{getMessage()}

+ {onAction && ( + + )} +
+ ); +} diff --git a/frontend/app/agents/SearchInput.tsx b/frontend/app/agents/SearchInput.tsx new file mode 100644 index 0000000..f8e3073 --- /dev/null +++ b/frontend/app/agents/SearchInput.tsx @@ -0,0 +1,153 @@ +/* +┌──────────────────────────────────────────────────────────────────────────────┐ +│ @author: Davidson Gomes │ +│ @file: /app/agents/SearchInput.tsx │ +│ Developed by: Davidson Gomes │ +│ Creation date: May 13, 2025 │ +│ Contact: contato@evolution-api.com │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @copyright © Evolution API 2025. All rights reserved. │ +│ Licensed under the Apache License, Version 2.0 │ +│ │ +│ You may not use this file except in compliance with the License. │ +│ You may obtain a copy of the License at │ +│ │ +│ http://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +│ Unless required by applicable law or agreed to in writing, software │ +│ distributed under the License is distributed on an "AS IS" BASIS, │ +│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ +│ See the License for the specific language governing permissions and │ +│ limitations under the License. │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @important │ +│ For any future changes to the code in this file, it is recommended to │ +│ include, together with the modification, the information of the developer │ +│ who changed it and the date of modification. │ +└──────────────────────────────────────────────────────────────────────────────┘ +*/ +"use client"; + +import { useState } from "react"; +import { Input } from "@/components/ui/input"; +import { Search, X, Filter } from "lucide-react"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Button } from "@/components/ui/button"; +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; + +interface SearchInputProps { + value: string; + onChange: (value: string) => void; + placeholder?: string; + className?: string; + selectedAgentType?: string | null; + onAgentTypeChange?: (type: string | null) => void; + agentTypes?: string[]; +} + +// Using "all" as a special value to represent no filter +const ANY_TYPE_VALUE = "all"; + +export function SearchInput({ + value, + onChange, + placeholder = "Search agents...", + className = "", + selectedAgentType = null, + onAgentTypeChange, + agentTypes = [], +}: SearchInputProps) { + const [isFilterOpen, setIsFilterOpen] = useState(false); + + const handleTypeChange = (value: string) => { + if (onAgentTypeChange) { + onAgentTypeChange(value === ANY_TYPE_VALUE ? null : value); + } + }; + + return ( +
+
+ + onChange(e.target.value)} + autoComplete="off" + className="pl-10 w-full bg-[#222] border-[#444] text-white focus:border-emerald-400 focus:ring-emerald-400/10" + /> + {value && ( + + )} +
+ + {agentTypes.length > 0 && onAgentTypeChange && ( + + + + + +
+
+ Filter by type +
+ + + {selectedAgentType && ( + + )} +
+
+
+ )} +
+ ); +} diff --git a/frontend/app/agents/config/A2AAgentConfig.tsx b/frontend/app/agents/config/A2AAgentConfig.tsx new file mode 100644 index 0000000..99f6a5d --- /dev/null +++ b/frontend/app/agents/config/A2AAgentConfig.tsx @@ -0,0 +1,73 @@ +/* +┌──────────────────────────────────────────────────────────────────────────────┐ +│ @author: Davidson Gomes │ +│ @file: /app/agents/config/A2AAgentConfig.tsx │ +│ Developed by: Davidson Gomes │ +│ Creation date: May 13, 2025 │ +│ Contact: contato@evolution-api.com │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @copyright © Evolution API 2025. All rights reserved. │ +│ Licensed under the Apache License, Version 2.0 │ +│ │ +│ You may not use this file except in compliance with the License. │ +│ You may obtain a copy of the License at │ +│ │ +│ http://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +│ Unless required by applicable law or agreed to in writing, software │ +│ distributed under the License is distributed on an "AS IS" BASIS, │ +│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ +│ See the License for the specific language governing permissions and │ +│ limitations under the License. │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @important │ +│ For any future changes to the code in this file, it is recommended to │ +│ include, together with the modification, the information of the developer │ +│ who changed it and the date of modification. │ +└──────────────────────────────────────────────────────────────────────────────┘ +*/ +"use client"; + +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; + +interface A2AAgentConfigProps { + values: { + agent_card_url?: string; + }; + onChange: (values: any) => void; +} + +export function A2AAgentConfig({ values, onChange }: A2AAgentConfigProps) { + return ( +
+
+ + + onChange({ + ...values, + agent_card_url: e.target.value, + }) + } + placeholder="https://example.com/.well-known/agent-card.json" + className="col-span-3 bg-[#222] border-[#444] text-white" + /> +
+
+

+ Provide the full URL for the JSON file of the Agent Card that describes + this agent. +

+

+ Agent Cards contain metadata, capabilities descriptions and supported + protocols. +

+
+
+ ); +} diff --git a/frontend/app/agents/config/LLMAgentConfig.tsx b/frontend/app/agents/config/LLMAgentConfig.tsx new file mode 100644 index 0000000..9c3d144 --- /dev/null +++ b/frontend/app/agents/config/LLMAgentConfig.tsx @@ -0,0 +1,367 @@ +/* +┌──────────────────────────────────────────────────────────────────────────────┐ +│ @author: Davidson Gomes │ +│ @file: /app/agents/config/LLMAgentConfig.tsx │ +│ Developed by: Davidson Gomes │ +│ Creation date: May 13, 2025 │ +│ Contact: contato@evolution-api.com │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @copyright © Evolution API 2025. All rights reserved. │ +│ Licensed under the Apache License, Version 2.0 │ +│ │ +│ You may not use this file except in compliance with the License. │ +│ You may obtain a copy of the License at │ +│ │ +│ http://www.apache.org/licenses/LICENSE-2.0 │ +│ │ +│ Unless required by applicable law or agreed to in writing, software │ +│ distributed under the License is distributed on an "AS IS" BASIS, │ +│ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. │ +│ See the License for the specific language governing permissions and │ +│ limitations under the License. │ +├──────────────────────────────────────────────────────────────────────────────┤ +│ @important │ +│ For any future changes to the code in this file, it is recommended to │ +│ include, together with the modification, the information of the developer │ +│ who changed it and the date of modification. │ +└──────────────────────────────────────────────────────────────────────────────┘ +*/ +"use client"; + +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Textarea } from "@/components/ui/textarea"; +import { ApiKey } from "@/services/agentService"; +import { Plus, Maximize2, Save } from "lucide-react"; +import { useEffect, useState } from "react"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, +} from "@/components/ui/dialog"; + +interface ModelOption { + value: string; + label: string; + provider: string; +} + +interface LLMAgentConfigProps { + apiKeys: ApiKey[]; + availableModels: ModelOption[]; + values: { + model?: string; + api_key_id?: string; + instruction?: string; + role?: string; + goal?: string; + }; + onChange: (values: any) => void; + onOpenApiKeysDialog: () => void; +} + +export function LLMAgentConfig({ + apiKeys, + availableModels, + values, + onChange, + onOpenApiKeysDialog, +}: LLMAgentConfigProps) { + const [instructionText, setInstructionText] = useState(values.instruction || ""); + const [isInstructionModalOpen, setIsInstructionModalOpen] = useState(false); + const [expandedInstructionText, setExpandedInstructionText] = useState(""); + + useEffect(() => { + setInstructionText(values.instruction || ""); + }, [values.instruction]); + + const handleInstructionChange = (e: React.ChangeEvent) => { + const newValue = e.target.value; + setInstructionText(newValue); + + onChange({ + ...values, + instruction: newValue, + }); + }; + + const handleExpandInstruction = () => { + setExpandedInstructionText(instructionText); + setIsInstructionModalOpen(true); + }; + + const handleSaveExpandedInstruction = () => { + setInstructionText(expandedInstructionText); + onChange({ + ...values, + instruction: expandedInstructionText, + }); + setIsInstructionModalOpen(false); + }; + + return ( +
+
+ +
+ + onChange({ + ...values, + role: e.target.value, + }) + } + placeholder="Ex: Research Assistant, Customer Support, etc." + className="bg-[#222] border-[#444] text-white" + /> +
+ ℹ️ + Define the role or persona that the agent will assume +
+
+
+ +
+ +
+ + onChange({ + ...values, + goal: e.target.value, + }) + } + placeholder="Ex: Find and organize information, Assist customers with inquiries, etc." + className="bg-[#222] border-[#444] text-white" + /> +
+ ℹ️ + Define the main objective or purpose of this agent +
+
+
+ +
+ +
+
+ + + +
+ + {apiKeys.length === 0 && ( +
+ i + + You need to{" "} + {" "} + before creating an agent. + +
+ )} +
+
+ +
+ + { + const searchQuery = e.target.value.toLowerCase(); + const items = document.querySelectorAll('[data-model-item="true"]'); + items.forEach((item) => { + const text = item.textContent?.toLowerCase() || ''; + if (text.includes(searchQuery)) { + (item as HTMLElement).style.display = 'flex'; + } else { + (item as HTMLElement).style.display = 'none'; + } + }); + }} + /> +
+
+ {availableModels + .filter((model) => { + if (!values.api_key_id) return true; + + const selectedKey = apiKeys.find( + (key) => key.id === values.api_key_id + ); + + if (!selectedKey) return true; + + return model.provider === selectedKey.provider; + }) + .map((model) => ( + + {model.label} + + ))} +
+ + +
+ +
+ +
+
+